submissions: reject duplicate submissions
All checks were successful
continuous-integration/drone/push Build is passing

closes #6
This commit is contained in:
Quaternions 2024-12-27 19:10:48 -08:00
parent c95d10a0d4
commit c04ba33f9c

View File

@ -3,6 +3,7 @@ package service
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"errors"
"git.itzana.me/strafesnet/maps-service/pkg/api" "git.itzana.me/strafesnet/maps-service/pkg/api"
"git.itzana.me/strafesnet/maps-service/pkg/datastore" "git.itzana.me/strafesnet/maps-service/pkg/datastore"
@ -10,7 +11,28 @@ import (
) )
var( var(
ActiveSubmissionsLimit = 20 CreationPhaseSubmissionsLimit = 20
CreationPhaseSubmissionStatuses = []model.Status{
model.StatusChangesRequested,
model.StatusSubmitted,
model.StatusUnderConstruction,
}
ActiveSubmissionStatuses = []model.Status{
model.StatusUploaded,
model.StatusUploading,
model.StatusValidated,
model.StatusValidating,
model.StatusAccepted,
model.StatusChangesRequested,
model.StatusSubmitted,
model.StatusUnderConstruction,
}
)
var (
ErrCreationPhaseSubmissionsLimit = errors.New("Active submissions limited to 20")
ErrActiveSubmissionSameAssetID = errors.New("There is an active submission with the same AssetID")
ErrActiveSubmissionSameTargetAssetID = errors.New("There is an active submission with the same TargetAssetID")
) )
// POST /submissions // POST /submissions
@ -25,19 +47,57 @@ func (svc *Service) CreateSubmission(ctx context.Context, request *api.Submissio
return nil, err return nil, err
} }
// Check if user's submissions in the creation phase exceeds the limit
{
filter := datastore.Optional() filter := datastore.Optional()
filter.Add("submitter", int64(userId)) filter.Add("submitter", int64(userId))
filter.Add("status_id", []model.Status{model.StatusChangesRequested, model.StatusSubmitted, model.StatusUnderConstruction}) filter.Add("status_id", CreationPhaseSubmissionStatuses)
active_submissions, err := svc.DB.Submissions().List(ctx, filter, model.Page{ creation_submissions, err := svc.DB.Submissions().List(ctx, filter, model.Page{
Number: 1, Number: 1,
Size: int32(ActiveSubmissionsLimit), Size: int32(CreationPhaseSubmissionsLimit),
}) })
if err != nil { if err != nil {
return nil, err return nil, err
} }
if ActiveSubmissionsLimit <= len(active_submissions) { if CreationPhaseSubmissionsLimit <= len(creation_submissions) {
return nil, ErrPermissionDenied return nil, ErrCreationPhaseSubmissionsLimit
}
}
// Check if an active submission with the same asset id exists
{
filter := datastore.Optional()
filter.Add("asset_id", request.AssetID)
filter.Add("asset_version", request.AssetVersion)
filter.Add("status_id", ActiveSubmissionStatuses)
active_submissions, err := svc.DB.Submissions().List(ctx, filter, model.Page{
Number: 1,
Size: 1,
})
if err != nil {
return nil, err
}
if len(active_submissions) != 0{
return nil, ErrActiveSubmissionSameAssetID
}
}
// Check if an active submission with the same target asset id exists
if request.TargetAssetID.IsSet() && request.TargetAssetID.Value != 0{
filter := datastore.Optional()
filter.Add("target_asset_id", request.TargetAssetID.Value)
filter.Add("status_id", ActiveSubmissionStatuses)
active_submissions, err := svc.DB.Submissions().List(ctx, filter, model.Page{
Number: 1,
Size: 1,
})
if err != nil {
return nil, err
}
if len(active_submissions) != 0{
return nil, ErrActiveSubmissionSameTargetAssetID
}
} }
submission, err := svc.DB.Submissions().Create(ctx, model.Submission{ submission, err := svc.DB.Submissions().Create(ctx, model.Submission{