diff --git a/pkg/service/mapfixes.go b/pkg/service/mapfixes.go index a0e9e02..17fe5e0 100644 --- a/pkg/service/mapfixes.go +++ b/pkg/service/mapfixes.go @@ -27,12 +27,16 @@ var( model.MapfixStatusValidating, model.MapfixStatusAccepted, } + // Allow 5 mapfixes every 10 minutes + CreateMapfixRateLimit int64 = 5 + CreateMapfixRecencyWindow = time.Second*600 ) var ( ErrCreationPhaseMapfixesLimit = errors.New("Active mapfixes limited to 20") ErrActiveMapfixSameTargetAssetID = errors.New("There is an active mapfix with the same TargetAssetID") ErrAcceptOwnMapfix = fmt.Errorf("%w: You cannot accept your own mapfix as the submitter", ErrPermissionDenied) + ErrCreateMapfixRateLimit = errors.New("You must not create more than 5 mapfixes every 10 minutes") ) // POST /mapfixes @@ -76,6 +80,21 @@ func (svc *Service) CreateMapfix(ctx context.Context, request *api.MapfixTrigger } } + // Check if too many operations have been created recently + { + count, err := svc.DB.Operations().CountSince(ctx, + int64(userId), + time.Now().Add(-CreateMapfixRecencyWindow).Unix(), + ) + if err != nil { + return nil, err + } + + if CreateMapfixRateLimit < count { + return nil, ErrCreateMapfixRateLimit + } + } + operation, err := svc.DB.Operations().Create(ctx, model.Operation{ Owner: int64(userId), StatusID: model.OperationStatusCreated, diff --git a/pkg/service/submissions.go b/pkg/service/submissions.go index ea89032..c9a6a80 100644 --- a/pkg/service/submissions.go +++ b/pkg/service/submissions.go @@ -27,6 +27,9 @@ var( model.SubmissionStatusValidating, model.SubmissionStatusAcceptedUnvalidated, } + // Allow 5 submissions every 10 minutes + CreateSubmissionRateLimit int64 = 5 + CreateSubmissionRecencyWindow = time.Second*600 ) var ( @@ -35,6 +38,7 @@ var ( ErrReleaseInvalidStatus = errors.New("Only submissions with Uploaded status can be released") ErrReleaseNoUploadedAssetID = errors.New("Only submissions with a UploadedAssetID can be released") ErrAcceptOwnSubmission = fmt.Errorf("%w: You cannot accept your own submission as the submitter", ErrPermissionDenied) + ErrCreateSubmissionRateLimit = errors.New("You must not create more than 5 submissions every 10 minutes") ) // POST /submissions @@ -66,6 +70,22 @@ func (svc *Service) CreateSubmission(ctx context.Context, request *api.Submissio return nil, ErrCreationPhaseSubmissionsLimit } } + + // Check if too many operations have been created recently + { + count, err := svc.DB.Operations().CountSince(ctx, + int64(userId), + time.Now().Add(-CreateSubmissionRecencyWindow).Unix(), + ) + if err != nil { + return nil, err + } + + if CreateSubmissionRateLimit < count { + return nil, ErrCreateSubmissionRateLimit + } + } + operation, err := svc.DB.Operations().Create(ctx, model.Operation{ Owner: int64(userId), StatusID: model.OperationStatusCreated,