diff --git a/pkg/web_api/submissions.go b/pkg/web_api/submissions.go index 2778b5c..dbcd1b4 100644 --- a/pkg/web_api/submissions.go +++ b/pkg/web_api/submissions.go @@ -12,35 +12,35 @@ import ( "git.itzana.me/strafesnet/maps-service/pkg/service" ) -var( - CreationPhaseSubmissionsLimit = 20 +var ( + CreationPhaseSubmissionsLimit = 20 CreationPhaseSubmissionStatuses = []model.SubmissionStatus{ model.SubmissionStatusChangesRequested, model.SubmissionStatusSubmitted, model.SubmissionStatusUnderConstruction, } // Allow 5 submissions every 10 minutes - CreateSubmissionRateLimit int64 = 5 - CreateSubmissionRecencyWindow = time.Second*600 + CreateSubmissionRateLimit int64 = 5 + CreateSubmissionRecencyWindow = time.Second * 600 ) var ( ErrCreationPhaseSubmissionsLimit = fmt.Errorf("%w: Active submissions limited to 20", ErrPermissionDenied) - ErrUploadedAssetIDAlreadyExists = fmt.Errorf("%w: The submission UploadedAssetID is already set", ErrPermissionDenied) - ErrReleaseInvalidStatus = fmt.Errorf("%w: Only submissions with Uploaded status can be released", ErrPermissionDenied) - ErrReleaseNoUploadedAssetID = fmt.Errorf("%w: Only submissions with a UploadedAssetID can be released", ErrPermissionDenied) - ErrAcceptOwnSubmission = fmt.Errorf("%w: You cannot accept your own submission as the submitter", ErrPermissionDenied) - ErrCreateSubmissionRateLimit = fmt.Errorf("%w: You must not create more than 5 submissions every 10 minutes", ErrTooManyRequests) - ErrDisplayNameNotUnique = fmt.Errorf("%w: Cannot submit: A map exists with the same DisplayName", ErrPermissionDenied) + ErrUploadedAssetIDAlreadyExists = fmt.Errorf("%w: The submission UploadedAssetID is already set", ErrPermissionDenied) + ErrReleaseInvalidStatus = fmt.Errorf("%w: Only submissions with Uploaded status can be released", ErrPermissionDenied) + ErrReleaseNoUploadedAssetID = fmt.Errorf("%w: Only submissions with a UploadedAssetID can be released", ErrPermissionDenied) + ErrAcceptOwnSubmission = fmt.Errorf("%w: You cannot accept your own submission as the submitter", ErrPermissionDenied) + ErrCreateSubmissionRateLimit = fmt.Errorf("%w: You must not create more than 5 submissions every 10 minutes", ErrTooManyRequests) + ErrDisplayNameNotUnique = fmt.Errorf("%w: Cannot submit: A map exists with the same DisplayName", ErrPermissionDenied) ) // POST /submissions func (svc *Service) CreateSubmission(ctx context.Context, request *api.SubmissionTriggerCreate) (*api.OperationID, error) { // sanitization - if request.AssetID<0{ + if request.AssetID < 0 { return nil, ErrNegativeID } - var ModelID=uint64(request.AssetID); + var ModelID = uint64(request.AssetID) userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle) if !ok { @@ -60,7 +60,7 @@ func (svc *Service) CreateSubmission(ctx context.Context, request *api.Submissio creation_submissions, err := svc.inner.ListSubmissions(ctx, filter, model.Page{ Number: 1, Size: int32(CreationPhaseSubmissionsLimit), - },datastore.ListSortDisabled) + }, datastore.ListSortDisabled) if err != nil { return nil, err } @@ -86,8 +86,8 @@ func (svc *Service) CreateSubmission(ctx context.Context, request *api.Submissio } operation, err := svc.inner.CreateOperation(ctx, model.Operation{ - Owner: userId, - StatusID: model.OperationStatusCreated, + Owner: userId, + StatusID: model.OperationStatusCreated, }) if err != nil { return nil, err @@ -110,13 +110,14 @@ func (svc *Service) CreateSubmission(ctx context.Context, request *api.Submissio OperationID: operation.ID, }, nil } + // POST /submissions-admin func (svc *Service) CreateSubmissionAdmin(ctx context.Context, request *api.SubmissionTriggerCreate) (*api.OperationID, error) { // sanitization - if request.AssetID<0{ + if request.AssetID < 0 { return nil, ErrNegativeID } - var ModelID=uint64(request.AssetID); + var ModelID = uint64(request.AssetID) userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle) if !ok { @@ -134,7 +135,7 @@ func (svc *Service) CreateSubmissionAdmin(ctx context.Context, request *api.Subm } // check if caller has required role - has_role := roles & model.RolesSubmissionReview == model.RolesSubmissionReview + has_role := roles&model.RolesSubmissionReview == model.RolesSubmissionReview if !has_role { return nil, ErrPermissionDeniedNeedRoleSubmissionReview } @@ -155,8 +156,8 @@ func (svc *Service) CreateSubmissionAdmin(ctx context.Context, request *api.Subm } operation, err := svc.inner.CreateOperation(ctx, model.Operation{ - Owner: userId, - StatusID: model.OperationStatusCreated, + Owner: userId, + StatusID: model.OperationStatusCreated, }) if err != nil { return nil, err @@ -191,18 +192,18 @@ func (svc *Service) GetSubmission(ctx context.Context, params api.GetSubmissionP return nil, err } return &api.Submission{ - ID: submission.ID, - DisplayName: submission.DisplayName, - Creator: submission.Creator, - GameID: int32(submission.GameID), - CreatedAt: submission.CreatedAt.Unix(), - UpdatedAt: submission.UpdatedAt.Unix(), - Submitter: int64(submission.Submitter), - AssetID: int64(submission.AssetID), - AssetVersion: int64(submission.AssetVersion), - Completed: submission.Completed, + ID: submission.ID, + DisplayName: submission.DisplayName, + Creator: submission.Creator, + GameID: int32(submission.GameID), + CreatedAt: submission.CreatedAt.Unix(), + UpdatedAt: submission.UpdatedAt.Unix(), + Submitter: int64(submission.Submitter), + AssetID: int64(submission.AssetID), + AssetVersion: int64(submission.AssetVersion), + Completed: submission.Completed, UploadedAssetID: api.NewOptInt64(int64(submission.UploadedAssetID)), - StatusID: int32(submission.StatusID), + StatusID: int32(submission.StatusID), }, nil } @@ -214,28 +215,28 @@ func (svc *Service) GetSubmission(ctx context.Context, params api.GetSubmissionP func (svc *Service) ListSubmissions(ctx context.Context, params api.ListSubmissionsParams) (*api.Submissions, error) { filter := service.NewSubmissionFilter() - if display_name, display_name_ok := params.DisplayName.Get(); display_name_ok{ + if display_name, display_name_ok := params.DisplayName.Get(); display_name_ok { filter.SetDisplayName(display_name) } - if creator, creator_ok := params.Creator.Get(); creator_ok{ + if creator, creator_ok := params.Creator.Get(); creator_ok { filter.SetCreator(creator) } - if game_id, game_id_ok := params.GameID.Get(); game_id_ok{ + if game_id, game_id_ok := params.GameID.Get(); game_id_ok { filter.SetGameID(uint32(game_id)) } - if submitter, submitter_ok := params.Submitter.Get(); submitter_ok{ + if submitter, submitter_ok := params.Submitter.Get(); submitter_ok { filter.SetSubmitter(uint64(submitter)) } - if asset_id, asset_id_ok := params.AssetID.Get(); asset_id_ok{ + if asset_id, asset_id_ok := params.AssetID.Get(); asset_id_ok { filter.SetAssetID(uint64(asset_id)) } - if asset_version, asset_version_ok := params.AssetVersion.Get(); asset_version_ok{ + if asset_version, asset_version_ok := params.AssetVersion.Get(); asset_version_ok { filter.SetAssetVersion(uint64(asset_version)) } - if uploaded_asset_id, uploaded_asset_id_ok := params.UploadedAssetID.Get(); uploaded_asset_id_ok{ + if uploaded_asset_id, uploaded_asset_id_ok := params.UploadedAssetID.Get(); uploaded_asset_id_ok { filter.SetUploadedAssetID(uint64(uploaded_asset_id)) } - if status_id, status_id_ok := params.StatusID.Get(); status_id_ok{ + if status_id, status_id_ok := params.StatusID.Get(); status_id_ok { filter.SetStatuses([]model.SubmissionStatus{model.SubmissionStatus(status_id)}) } @@ -244,27 +245,27 @@ func (svc *Service) ListSubmissions(ctx context.Context, params api.ListSubmissi total, items, err := svc.inner.ListSubmissionsWithTotal(ctx, filter, model.Page{ Number: params.Page, Size: params.Limit, - },sort) + }, sort) if err != nil { return nil, err } var resp api.Submissions - resp.Total=total + resp.Total = total for _, item := range items { resp.Submissions = append(resp.Submissions, api.Submission{ - ID: item.ID, - DisplayName: item.DisplayName, - Creator: item.Creator, - GameID: int32(item.GameID), - CreatedAt: item.CreatedAt.Unix(), - UpdatedAt: item.UpdatedAt.Unix(), - Submitter: int64(item.Submitter), - AssetID: int64(item.AssetID), - AssetVersion: int64(item.AssetVersion), - Completed: item.Completed, + ID: item.ID, + DisplayName: item.DisplayName, + Creator: item.Creator, + GameID: int32(item.GameID), + CreatedAt: item.CreatedAt.Unix(), + UpdatedAt: item.UpdatedAt.Unix(), + Submitter: int64(item.Submitter), + AssetID: int64(item.AssetID), + AssetVersion: int64(item.AssetVersion), + Completed: item.Completed, UploadedAssetID: api.NewOptInt64(int64(item.UploadedAssetID)), - StatusID: int32(item.StatusID), + StatusID: int32(item.StatusID), }) } @@ -341,9 +342,9 @@ func (svc *Service) UpdateSubmissionModel(ctx context.Context, params api.Update } event_data := model.AuditEventDataChangeModel{ - OldModelID: OldModelID, + OldModelID: OldModelID, OldModelVersion: OldModelVersion, - NewModelID: NewModelID, + NewModelID: NewModelID, NewModelVersion: NewModelVersion, } @@ -351,7 +352,7 @@ func (svc *Service) UpdateSubmissionModel(ctx context.Context, params api.Update ctx, userId, model.Resource{ - ID: params.SubmissionID, + ID: params.SubmissionID, Type: model.ResourceSubmission, }, event_data, @@ -401,7 +402,7 @@ func (svc *Service) ActionSubmissionReject(ctx context.Context, params api.Actio ctx, userId, model.Resource{ - ID: params.SubmissionID, + ID: params.SubmissionID, Type: model.ResourceSubmission, }, event_data, @@ -456,7 +457,7 @@ func (svc *Service) ActionSubmissionRequestChanges(ctx context.Context, params a ctx, userId, model.Resource{ - ID: params.SubmissionID, + ID: params.SubmissionID, Type: model.ResourceSubmission, }, event_data, @@ -509,7 +510,7 @@ func (svc *Service) ActionSubmissionRevoke(ctx context.Context, params api.Actio ctx, userId, model.Resource{ - ID: params.SubmissionID, + ID: params.SubmissionID, Type: model.ResourceSubmission, }, event_data, @@ -566,8 +567,12 @@ func (svc *Service) ActionSubmissionTriggerSubmit(ctx context.Context, params ap if err != nil { return err } - if len(maps_list) != 0 { - return ErrDisplayNameNotUnique + + // The map search finds substrings, we only want exact matches + for _, m := range maps_list { + if m.DisplayName == submission.DisplayName { + return ErrDisplayNameNotUnique + } } // transaction @@ -601,7 +606,7 @@ func (svc *Service) ActionSubmissionTriggerSubmit(ctx context.Context, params ap ctx, userId, model.Resource{ - ID: params.SubmissionID, + ID: params.SubmissionID, Type: model.ResourceSubmission, }, event_data, @@ -672,7 +677,7 @@ func (svc *Service) ActionSubmissionTriggerSubmitUnchecked(ctx context.Context, ctx, userId, model.Resource{ - ID: params.SubmissionID, + ID: params.SubmissionID, Type: model.ResourceSubmission, }, event_data, @@ -700,7 +705,7 @@ func (svc *Service) ActionSubmissionResetSubmitting(ctx context.Context, params if err != nil { return err } - if time.Now().Before(submission.UpdatedAt.Add(time.Second*10)) { + if time.Now().Before(submission.UpdatedAt.Add(time.Second * 10)) { // the last time the submission was updated must be longer than 10 seconds ago return ErrDelayReset } @@ -729,7 +734,7 @@ func (svc *Service) ActionSubmissionResetSubmitting(ctx context.Context, params ctx, userId, model.Resource{ - ID: params.SubmissionID, + ID: params.SubmissionID, Type: model.ResourceSubmission, }, event_data, @@ -797,7 +802,7 @@ func (svc *Service) ActionSubmissionTriggerUpload(ctx context.Context, params ap ctx, userId, model.Resource{ - ID: params.SubmissionID, + ID: params.SubmissionID, Type: model.ResourceSubmission, }, event_data, @@ -834,7 +839,7 @@ func (svc *Service) ActionSubmissionValidated(ctx context.Context, params api.Ac if err != nil { return err } - if time.Now().Before(submission.UpdatedAt.Add(time.Second*10)) { + if time.Now().Before(submission.UpdatedAt.Add(time.Second * 10)) { // the last time the submission was updated must be longer than 10 seconds ago return ErrDelayReset } @@ -857,7 +862,7 @@ func (svc *Service) ActionSubmissionValidated(ctx context.Context, params api.Ac ctx, userId, model.Resource{ - ID: params.SubmissionID, + ID: params.SubmissionID, Type: model.ResourceSubmission, }, event_data, @@ -929,7 +934,7 @@ func (svc *Service) ActionSubmissionTriggerValidate(ctx context.Context, params ctx, userId, model.Resource{ - ID: params.SubmissionID, + ID: params.SubmissionID, Type: model.ResourceSubmission, }, event_data, @@ -989,7 +994,7 @@ func (svc *Service) ActionSubmissionRetryValidate(ctx context.Context, params ap ctx, userId, model.Resource{ - ID: params.SubmissionID, + ID: params.SubmissionID, Type: model.ResourceSubmission, }, event_data, @@ -1026,7 +1031,7 @@ func (svc *Service) ActionSubmissionAccepted(ctx context.Context, params api.Act if err != nil { return err } - if time.Now().Before(submission.UpdatedAt.Add(time.Second*10)) { + if time.Now().Before(submission.UpdatedAt.Add(time.Second * 10)) { // the last time the submission was updated must be longer than 10 seconds ago return ErrDelayReset } @@ -1049,7 +1054,7 @@ func (svc *Service) ActionSubmissionAccepted(ctx context.Context, params api.Act ctx, userId, model.Resource{ - ID: params.SubmissionID, + ID: params.SubmissionID, Type: model.ResourceSubmission, }, event_data, @@ -1096,11 +1101,11 @@ func (svc *Service) ReleaseSubmissions(ctx context.Context, request []api.Releas id_to_submission := make(map[int64]*model.Submission, len(submissions)) // check each submission to make sure it is ready to release - for _,submission := range submissions{ - if submission.StatusID != model.SubmissionStatusUploaded{ + for _, submission := range submissions { + if submission.StatusID != model.SubmissionStatusUploaded { return nil, ErrReleaseInvalidStatus } - if submission.UploadedAssetID == 0{ + if submission.UploadedAssetID == 0 { return nil, ErrReleaseNoUploadedAssetID } id_to_submission[submission.ID] = &submission @@ -1126,8 +1131,8 @@ func (svc *Service) ReleaseSubmissions(ctx context.Context, request []api.Releas // create a trackable long-running operation operation, err := svc.inner.CreateOperation(ctx, model.Operation{ - Owner: userId, - StatusID: model.OperationStatusCreated, + Owner: userId, + StatusID: model.OperationStatusCreated, }) if err != nil { return nil, err @@ -1149,10 +1154,10 @@ func (svc *Service) ReleaseSubmissions(ctx context.Context, request []api.Releas // CreateSubmissionAuditComment implements createSubmissionAuditComment operation. // -// Post a comment to the audit log +// # Post a comment to the audit log // // POST /submissions/{SubmissionID}/comment -func (svc *Service) CreateSubmissionAuditComment(ctx context.Context, req api.CreateSubmissionAuditCommentReq, params api.CreateSubmissionAuditCommentParams) (error) { +func (svc *Service) CreateSubmissionAuditComment(ctx context.Context, req api.CreateSubmissionAuditCommentReq, params api.CreateSubmissionAuditCommentParams) error { userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle) if !ok { return ErrUserInfo @@ -1193,7 +1198,7 @@ func (svc *Service) CreateSubmissionAuditComment(ctx context.Context, req api.Cr ctx, userId, model.Resource{ - ID: params.SubmissionID, + ID: params.SubmissionID, Type: model.ResourceSubmission, }, event_data, @@ -1209,7 +1214,7 @@ func (svc *Service) ListSubmissionAuditEvents(ctx context.Context, params api.Li return svc.inner.ListAuditEvents( ctx, model.Resource{ - ID: params.SubmissionID, + ID: params.SubmissionID, Type: model.ResourceSubmission, }, model.Page{