submissions: rate limit submit #98
@@ -45,6 +45,7 @@ type Operations interface {
|
||||
Create(ctx context.Context, smap model.Operation) (model.Operation, error)
|
||||
Update(ctx context.Context, id int32, values OptionalMap) error
|
||||
Delete(ctx context.Context, id int32) error
|
||||
CountSince(ctx context.Context, owner int64, since int64) (int64, error)
|
||||
}
|
||||
|
||||
type Submissions interface {
|
||||
|
||||
@@ -53,3 +53,12 @@ func (env *Operations) Delete(ctx context.Context, id int32) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (env *Operations) CountSince(ctx context.Context, owner int64, since int64) (int64, error) {
|
||||
var count int64
|
||||
if err := env.db.Where("owner = ? AND created_at > ?",owner,since).Count(&count).Error; err != nil {
|
||||
return count, err
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user