Bläddra i källkod

feat(syncing-server): reduced abuse thresholds for free users

Karol Sójko 1 år sedan
förälder
incheckning
f9ff16dc3b

+ 4 - 2
packages/syncing-server/bin/server.ts

@@ -119,8 +119,10 @@ void container.load().then((container) => {
     container.get<boolean>(TYPES.Sync_STRICT_ABUSE_PROTECTION),
     container.get<number>(TYPES.Sync_ITEM_OPERATIONS_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES),
     container.get<number>(TYPES.Sync_ITEM_OPERATIONS_ABUSE_THRESHOLD),
-    container.get<number>(TYPES.Sync_PAYLOAD_SIZE_ABUSE_THRESHOLD),
-    container.get<number>(TYPES.Sync_PAYLOAD_SIZE_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES),
+    container.get<number>(TYPES.Sync_FREE_USERS_ITEM_OPERATIONS_ABUSE_THRESHOLD),
+    container.get<number>(TYPES.Sync_UPLOAD_BANDWIDTH_ABUSE_THRESHOLD),
+    container.get<number>(TYPES.Sync_FREE_USERS_UPLOAD_BANDWIDTH_ABUSE_THRESHOLD),
+    container.get<number>(TYPES.Sync_UPLOAD_BANDWIDTH_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES),
     container.get<winston.Logger>(TYPES.Sync_Logger),
   )
 

+ 26 - 8
packages/syncing-server/src/Bootstrap/Container.ts

@@ -479,7 +479,14 @@ export class ContainerConfigLoader {
     container
       .bind(TYPES.Sync_ITEM_OPERATIONS_ABUSE_THRESHOLD)
       .toConstantValue(
-        env.get('ITEM_OPERATIONS_ABUSE_THRESHOLD', true) ? +env.get('ITEM_OPERATIONS_ABUSE_THRESHOLD', true) : 500,
+        env.get('ITEM_OPERATIONS_ABUSE_THRESHOLD', true) ? +env.get('ITEM_OPERATIONS_ABUSE_THRESHOLD', true) : 1000,
+      )
+    container
+      .bind(TYPES.Sync_FREE_USERS_ITEM_OPERATIONS_ABUSE_THRESHOLD)
+      .toConstantValue(
+        env.get('FREE_USERS_ITEM_OPERATIONS_ABUSE_THRESHOLD', true)
+          ? +env.get('FREE_USERS_ITEM_OPERATIONS_ABUSE_THRESHOLD', true)
+          : 500,
       )
     container
       .bind(TYPES.Sync_ITEM_OPERATIONS_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES)
@@ -489,15 +496,24 @@ export class ContainerConfigLoader {
           : 5,
       )
     container
-      .bind(TYPES.Sync_PAYLOAD_SIZE_ABUSE_THRESHOLD)
+      .bind(TYPES.Sync_UPLOAD_BANDWIDTH_ABUSE_THRESHOLD)
+      .toConstantValue(
+        env.get('UPLOAD_BANDWIDTH_ABUSE_THRESHOLD', true)
+          ? +env.get('UPLOAD_BANDWIDTH_ABUSE_THRESHOLD', true)
+          : 100_000_000,
+      )
+    container
+      .bind(TYPES.Sync_FREE_USERS_UPLOAD_BANDWIDTH_ABUSE_THRESHOLD)
       .toConstantValue(
-        env.get('PAYLOAD_SIZE_ABUSE_THRESHOLD', true) ? +env.get('PAYLOAD_SIZE_ABUSE_THRESHOLD', true) : 20_000_000,
+        env.get('FREE_USERS_UPLOAD_BANDWIDTH_ABUSE_THRESHOLD', true)
+          ? +env.get('FREE_USERS_UPLOAD_BANDWIDTH_ABUSE_THRESHOLD', true)
+          : 50_000_000,
       )
     container
-      .bind(TYPES.Sync_PAYLOAD_SIZE_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES)
+      .bind(TYPES.Sync_UPLOAD_BANDWIDTH_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES)
       .toConstantValue(
-        env.get('PAYLOAD_SIZE_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES', true)
-          ? +env.get('PAYLOAD_SIZE_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES', true)
+        env.get('UPLOAD_BANDWIDTH_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES', true)
+          ? +env.get('UPLOAD_BANDWIDTH_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES', true)
           : 5,
       )
     container.bind(TYPES.Sync_AUTH_JWT_SECRET).toConstantValue(env.get('AUTH_JWT_SECRET'))
@@ -1145,8 +1161,10 @@ export class ContainerConfigLoader {
             container.get<boolean>(TYPES.Sync_STRICT_ABUSE_PROTECTION),
             container.get<number>(TYPES.Sync_ITEM_OPERATIONS_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES),
             container.get<number>(TYPES.Sync_ITEM_OPERATIONS_ABUSE_THRESHOLD),
-            container.get<number>(TYPES.Sync_PAYLOAD_SIZE_ABUSE_THRESHOLD),
-            container.get<number>(TYPES.Sync_PAYLOAD_SIZE_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES),
+            container.get<number>(TYPES.Sync_FREE_USERS_ITEM_OPERATIONS_ABUSE_THRESHOLD),
+            container.get<number>(TYPES.Sync_UPLOAD_BANDWIDTH_ABUSE_THRESHOLD),
+            container.get<number>(TYPES.Sync_FREE_USERS_UPLOAD_BANDWIDTH_ABUSE_THRESHOLD),
+            container.get<number>(TYPES.Sync_UPLOAD_BANDWIDTH_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES),
             container.get<ControllerContainerInterface>(TYPES.Sync_ControllerContainer),
           ),
         )

+ 5 - 3
packages/syncing-server/src/Bootstrap/Types.ts

@@ -47,9 +47,11 @@ const TYPES = {
     'Sync_ITEM_OPERATIONS_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES',
   ),
   Sync_ITEM_OPERATIONS_ABUSE_THRESHOLD: Symbol.for('Sync_ITEM_OPERATIONS_ABUSE_THRESHOLD'),
-  Sync_PAYLOAD_SIZE_ABUSE_THRESHOLD: Symbol.for('Sync_PAYLOAD_SIZE_ABUSE_THRESHOLD'),
-  Sync_PAYLOAD_SIZE_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES: Symbol.for(
-    'Sync_PAYLOAD_SIZE_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES',
+  Sync_FREE_USERS_ITEM_OPERATIONS_ABUSE_THRESHOLD: Symbol.for('Sync_FREE_USERS_ITEM_OPERATIONS_ABUSE_THRESHOLD'),
+  Sync_UPLOAD_BANDWIDTH_ABUSE_THRESHOLD: Symbol.for('Sync_UPLOAD_BANDWIDTH_ABUSE_THRESHOLD'),
+  Sync_FREE_USERS_UPLOAD_BANDWIDTH_ABUSE_THRESHOLD: Symbol.for('Sync_FREE_USERS_UPLOAD_BANDWIDTH_ABUSE_THRESHOLD'),
+  Sync_UPLOAD_BANDWIDTH_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES: Symbol.for(
+    'Sync_UPLOAD_BANDWIDTH_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES',
   ),
   // use cases
   Sync_SyncItems: Symbol.for('Sync_SyncItems'),

+ 7 - 2
packages/syncing-server/src/Infra/InversifyExpressUtils/AnnotatedItemsController.ts

@@ -29,8 +29,11 @@ export class AnnotatedItemsController extends BaseItemsController {
     @inject(TYPES.Sync_ITEM_OPERATIONS_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES)
     override itemOperationsAbuseTimeframeLengthInMinutes: number,
     @inject(TYPES.Sync_ITEM_OPERATIONS_ABUSE_THRESHOLD) override itemOperationsAbuseThreshold: number,
-    @inject(TYPES.Sync_PAYLOAD_SIZE_ABUSE_THRESHOLD) override payloadSizeAbuseThreshold: number,
-    @inject(TYPES.Sync_PAYLOAD_SIZE_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES)
+    @inject(TYPES.Sync_FREE_USERS_ITEM_OPERATIONS_ABUSE_THRESHOLD)
+    override freeUsersItemOperationsAbuseThreshold: number,
+    @inject(TYPES.Sync_UPLOAD_BANDWIDTH_ABUSE_THRESHOLD) override payloadSizeAbuseThreshold: number,
+    @inject(TYPES.Sync_FREE_USERS_UPLOAD_BANDWIDTH_ABUSE_THRESHOLD) override freeUsersPayloadSizeAbuseThreshold: number,
+    @inject(TYPES.Sync_UPLOAD_BANDWIDTH_ABUSE_TIMEFRAME_LENGTH_IN_MINUTES)
     override payloadSizeAbuseTimeframeLengthInMinutes: number,
   ) {
     super(
@@ -44,7 +47,9 @@ export class AnnotatedItemsController extends BaseItemsController {
       strictAbuseProtection,
       itemOperationsAbuseTimeframeLengthInMinutes,
       itemOperationsAbuseThreshold,
+      freeUsersItemOperationsAbuseThreshold,
       payloadSizeAbuseThreshold,
+      freeUsersPayloadSizeAbuseThreshold,
       payloadSizeAbuseTimeframeLengthInMinutes,
     )
   }

+ 4 - 2
packages/syncing-server/src/Infra/InversifyExpressUtils/Base/BaseItemsController.ts

@@ -28,7 +28,9 @@ export class BaseItemsController extends BaseHttpController {
     protected strictAbuseProtection: boolean,
     protected itemOperationsAbuseTimeframeLengthInMinutes: number,
     protected itemOperationsAbuseThreshold: number,
+    protected freeUsersItemOperationsAbuseThreshold: number,
     protected payloadSizeAbuseThreshold: number,
+    protected freeUsersPayloadSizeAbuseThreshold: number,
     protected payloadSizeAbuseTimeframeLengthInMinutes: number,
     private controllerContainer?: ControllerContainerInterface,
   ) {
@@ -46,7 +48,7 @@ export class BaseItemsController extends BaseHttpController {
     const checkForItemOperationsAbuseResult = await this.checkForTrafficAbuse.execute({
       metricToCheck: Metric.NAMES.ItemOperation,
       userUuid: locals.user.uuid,
-      threshold: this.itemOperationsAbuseThreshold,
+      threshold: locals.isFreeUser ? this.freeUsersItemOperationsAbuseThreshold : this.itemOperationsAbuseThreshold,
       timeframeLengthInMinutes: this.itemOperationsAbuseTimeframeLengthInMinutes,
     })
     if (checkForItemOperationsAbuseResult.isFailed()) {
@@ -61,7 +63,7 @@ export class BaseItemsController extends BaseHttpController {
     const checkForPayloadSizeAbuseResult = await this.checkForTrafficAbuse.execute({
       metricToCheck: Metric.NAMES.ContentSizeUtilized,
       userUuid: locals.user.uuid,
-      threshold: this.payloadSizeAbuseThreshold,
+      threshold: locals.isFreeUser ? this.freeUsersPayloadSizeAbuseThreshold : this.payloadSizeAbuseThreshold,
       timeframeLengthInMinutes: this.payloadSizeAbuseTimeframeLengthInMinutes,
     })
     if (checkForPayloadSizeAbuseResult.isFailed()) {

+ 6 - 3
packages/syncing-server/src/Infra/gRPC/SyncingServer.ts

@@ -21,7 +21,9 @@ export class SyncingServer implements ISyncingServer {
     private strictAbuseProtection: boolean,
     private itemOperationsAbuseTimeframeLengthInMinutes: number,
     private itemOperationsAbuseThreshold: number,
+    private freeUsersItemOperationsAbuseThreshold: number,
     private payloadSizeAbuseThreshold: number,
+    private freeUsersPayloadSizeAbuseThreshold: number,
     private payloadSizeAbuseTimeframeLengthInMinutes: number,
     private logger: Logger,
   ) {}
@@ -32,11 +34,12 @@ export class SyncingServer implements ISyncingServer {
   ): Promise<void> {
     try {
       const userUuid = call.metadata.get('x-user-uuid').pop() as string
+      const isFreeUser = call.metadata.get('x-is-free-user').pop() === 'true'
 
       const checkForItemOperationsAbuseResult = await this.checkForTrafficAbuse.execute({
         metricToCheck: Metric.NAMES.ItemOperation,
         userUuid,
-        threshold: this.itemOperationsAbuseThreshold,
+        threshold: isFreeUser ? this.freeUsersItemOperationsAbuseThreshold : this.itemOperationsAbuseThreshold,
         timeframeLengthInMinutes: this.itemOperationsAbuseTimeframeLengthInMinutes,
       })
       if (checkForItemOperationsAbuseResult.isFailed()) {
@@ -63,7 +66,7 @@ export class SyncingServer implements ISyncingServer {
       const checkForPayloadSizeAbuseResult = await this.checkForTrafficAbuse.execute({
         metricToCheck: Metric.NAMES.ContentSizeUtilized,
         userUuid,
-        threshold: this.payloadSizeAbuseThreshold,
+        threshold: isFreeUser ? this.freeUsersPayloadSizeAbuseThreshold : this.payloadSizeAbuseThreshold,
         timeframeLengthInMinutes: this.payloadSizeAbuseTimeframeLengthInMinutes,
       })
       if (checkForPayloadSizeAbuseResult.isFailed()) {
@@ -158,7 +161,7 @@ export class SyncingServer implements ISyncingServer {
         readOnlyAccess,
         sessionUuid: call.metadata.get('x-session-uuid').pop() as string,
         sharedVaultUuids,
-        isFreeUser: call.metadata.get('x-is-free-user').pop() === 'true',
+        isFreeUser,
       })
       if (syncResult.isFailed()) {
         const metadata = new grpc.Metadata()