From 9e022ca2653daa4d07bfde7e9ce49e482f9fa577 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Sat, 14 Dec 2024 04:06:49 -0800 Subject: [PATCH] submissions: refactor publishing model --- pkg/cmds/serve.go | 23 ++++++++++- pkg/model/submission.go | 10 +++-- pkg/service/security.go | 5 +-- pkg/service/submissions.go | 40 +++---------------- pkg/service_internal/service_internal.go | 25 ++++++++++++ pkg/service_internal/submissions.go | 51 ++++++++++++++++++++++++ 6 files changed, 113 insertions(+), 41 deletions(-) create mode 100644 pkg/service_internal/service_internal.go create mode 100644 pkg/service_internal/submissions.go diff --git a/pkg/cmds/serve.go b/pkg/cmds/serve.go index b59f6bb..5dd6afe 100644 --- a/pkg/cmds/serve.go +++ b/pkg/cmds/serve.go @@ -2,16 +2,19 @@ package cmds import ( "fmt" + "net/http" + "git.itzana.me/strafesnet/go-grpc/auth" "git.itzana.me/strafesnet/maps-service/pkg/api" "git.itzana.me/strafesnet/maps-service/pkg/datastore/gormstore" + internal "git.itzana.me/strafesnet/maps-service/pkg/internal" "git.itzana.me/strafesnet/maps-service/pkg/service" + "git.itzana.me/strafesnet/maps-service/pkg/service_internal" "github.com/nats-io/nats.go" log "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" - "net/http" ) func NewServeCommand() *cli.Command { @@ -62,6 +65,12 @@ func NewServeCommand() *cli.Command { Value: 8080, EnvVars: []string{"PORT"}, }, + &cli.IntFlag{ + Name: "port-internal", + Usage: "Port to listen on for internal api", + Value: 8081, + EnvVars: []string{"PORT_INTERNAL"}, + }, &cli.StringFlag{ Name: "auth-rpc-host", Usage: "Host of auth rpc", @@ -119,5 +128,17 @@ func serve(ctx *cli.Context) error { log.WithError(err).Fatal("failed to initialize api server") } + svc2 := &service_internal.Service{ + DB: db, + Nats: js, + } + + srv2, err := internal.NewServer(svc2, nil, internal.WithPathPrefix("/v1")) + if err != nil { + log.WithError(err).Fatal("failed to initialize api server") + } + + // idk how else to do this + go http.ListenAndServe(fmt.Sprintf(":%d", ctx.Int("port-internal")), srv2) return http.ListenAndServe(fmt.Sprintf(":%d", ctx.Int("port")), srv) } diff --git a/pkg/model/submission.go b/pkg/model/submission.go index cb68897..b0a7736 100644 --- a/pkg/model/submission.go +++ b/pkg/model/submission.go @@ -5,14 +5,18 @@ import "time" type Status int32 const ( - StatusPublished Status = 8 - StatusRejected Status = 7 + // Phase: Final Status + StatusReleased Status = 9 + StatusRejected Status = 8 - StatusPublishing Status = 6 + // Phase: Testing + StatusUploaded Status = 7 // uploaded to the group, but pending release + StatusUploading Status = 6 StatusValidated Status = 5 StatusValidating Status = 4 StatusAccepted Status = 3 + // Phase: Creation StatusChangesRequested Status = 2 StatusSubmitted Status = 1 StatusUnderConstruction Status = 0 diff --git a/pkg/service/security.go b/pkg/service/security.go index 57016d4..4cc0c7e 100644 --- a/pkg/service/security.go +++ b/pkg/service/security.go @@ -23,12 +23,11 @@ var ( type Roles struct { // human roles - SubmissionPublish bool + SubmissionRelease bool SubmissionReview bool ScriptWrite bool // automated roles Maptest bool - Validator bool } type UserInfo struct { @@ -79,7 +78,7 @@ func (svc SecurityHandler) HandleCookieAuth(ctx context.Context, operationName a // fix this when roblox udpates group roles for _, r := range role.Roles { if RoleMapAdmin <= r.Rank { - roles.SubmissionPublish = true + roles.SubmissionRelease = true } if RoleMapCouncil <= r.Rank { roles.SubmissionReview = true diff --git a/pkg/service/submissions.go b/pkg/service/submissions.go index c2af56d..41ab475 100644 --- a/pkg/service/submissions.go +++ b/pkg/service/submissions.go @@ -158,20 +158,6 @@ func (svc *Service) UpdateSubmissionModel(ctx context.Context, params api.Update return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusChangesRequested, model.StatusSubmitted, model.StatusUnderConstruction}, pmap) } -// ActionSubmissionPublish invokes actionSubmissionPublish operation. -// -// Role Validator changes status from Publishing -> Published. -// -// POST /submissions/{SubmissionID}/status/publish -func (svc *Service) ActionSubmissionPublish(ctx context.Context, params api.ActionSubmissionPublishParams) error { - println("[ActionSubmissionPublish] Implicit Validator permission granted!") - - // transaction - smap := datastore.Optional() - smap.Add("status_id", model.StatusPublished) - return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusPublishing}, smap) -} - // ActionSubmissionReject invokes actionSubmissionReject operation. // // Role Reviewer changes status from Submitted -> Rejected. @@ -272,25 +258,25 @@ func (svc *Service) ActionSubmissionSubmit(ctx context.Context, params api.Actio return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusUnderConstruction, model.StatusChangesRequested}, smap) } -// ActionSubmissionTriggerPublish invokes actionSubmissionTriggerPublish operation. +// ActionSubmissionTriggerUpload invokes actionSubmissionTriggerUpload operation. // -// Role Admin changes status from Validated -> Publishing. +// Role Admin changes status from Validated -> Uploading. // -// POST /submissions/{SubmissionID}/status/trigger-publish -func (svc *Service) ActionSubmissionTriggerPublish(ctx context.Context, params api.ActionSubmissionTriggerPublishParams) error { +// POST /submissions/{SubmissionID}/status/trigger-upload +func (svc *Service) ActionSubmissionTriggerUpload(ctx context.Context, params api.ActionSubmissionTriggerUploadParams) error { userInfo, ok := ctx.Value("UserInfo").(UserInfo) if !ok { return ErrUserInfo } // check if caller has required role - if !userInfo.Roles.SubmissionPublish { + if !userInfo.Roles.SubmissionRelease { return ErrPermissionDenied } // transaction smap := datastore.Optional() - smap.Add("status_id", model.StatusPublishing) + smap.Add("status_id", model.StatusUploading) submission, err := svc.DB.Submissions().IfStatusThenUpdateAndGet(ctx, params.SubmissionID, []model.Status{model.StatusValidated}, smap) if err != nil { return err @@ -374,17 +360,3 @@ func (svc *Service) ActionSubmissionTriggerValidate(ctx context.Context, params return nil } - -// ActionSubmissionValidate invokes actionSubmissionValidate operation. -// -// Role Validator changes status from Validating -> Validated. -// -// POST /submissions/{SubmissionID}/status/validate -func (svc *Service) ActionSubmissionValidate(ctx context.Context, params api.ActionSubmissionValidateParams) error { - println("[ActionSubmissionValidate] Implicit Validator permission granted!") - - // transaction - smap := datastore.Optional() - smap.Add("status_id", model.StatusValidated) - return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidating}, smap) -} diff --git a/pkg/service_internal/service_internal.go b/pkg/service_internal/service_internal.go new file mode 100644 index 0000000..9513793 --- /dev/null +++ b/pkg/service_internal/service_internal.go @@ -0,0 +1,25 @@ +package service_internal + +import ( + "context" + internal "git.itzana.me/strafesnet/maps-service/pkg/internal" + "git.itzana.me/strafesnet/maps-service/pkg/datastore" + "github.com/nats-io/nats.go" +) + +type Service struct { + DB datastore.Datastore + Nats nats.JetStreamContext +} + +// yay duplicate code +func (svc *Service) NewError(ctx context.Context, err error) *internal.ErrorStatusCode { + status := 500 + return &internal.ErrorStatusCode{ + StatusCode: status, + Response: internal.Error{ + Code: int64(status), + Message: err.Error(), + }, + } +} diff --git a/pkg/service_internal/submissions.go b/pkg/service_internal/submissions.go new file mode 100644 index 0000000..bc27f1a --- /dev/null +++ b/pkg/service_internal/submissions.go @@ -0,0 +1,51 @@ +package service_internal + +import ( + "context" + + internal "git.itzana.me/strafesnet/maps-service/pkg/internal" + "git.itzana.me/strafesnet/maps-service/pkg/datastore" + "git.itzana.me/strafesnet/maps-service/pkg/model" +) + +// ActionSubmissionValidate invokes actionSubmissionValidate operation. +// +// Role Validator changes status from Validating -> Validated. +// +// POST /submissions/{SubmissionID}/status/validate +func (svc *Service) ActionSubmissionValidated(ctx context.Context, params internal.ActionSubmissionValidatedParams) error { + println("[ActionSubmissionValidate] Implicit Validator permission granted!") + + // transaction + smap := datastore.Optional() + smap.Add("status_id", model.StatusValidated) + return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidating}, smap) +} + +// ActionSubmissionReleased implements actionSubmissionReleased operation. +// +// (Internal endpoint) Role Releaser changes status from Uploaded -> Released. +// +// POST /submissions/{SubmissionID}/status/releaser-released +func (svc *Service) ActionSubmissionReleased(ctx context.Context, params internal.ActionSubmissionReleasedParams) error { + println("[ActionSubmissionReleased] Implicit Validator permission granted!") + + // transaction + smap := datastore.Optional() + smap.Add("status_id", model.StatusReleased) + return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusUploaded}, smap) +} + +// ActionSubmissionUploaded implements actionSubmissionUploaded operation. +// +// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded. +// +// POST /submissions/{SubmissionID}/status/validator-uploaded +func (svc *Service) ActionSubmissionUploaded(ctx context.Context, params internal.ActionSubmissionUploadedParams) error { + println("[ActionSubmissionUploaded] Implicit Validator permission granted!") + + // transaction + smap := datastore.Optional() + smap.Add("status_id", model.StatusUploaded) + return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusUploading}, smap) +}