From 8bf2c92df3f65a6bd7afa14420651c919f3dbfeb Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 27 Dec 2024 17:24:09 -0800 Subject: [PATCH] submissions: refactor auth to only make requests when needed --- pkg/service/script_policy.go | 18 +++++- pkg/service/scripts.go | 18 +++++- pkg/service/security.go | 109 +++++++++++++++++++---------------- pkg/service/submissions.go | 58 +++++++++++++++---- 4 files changed, 136 insertions(+), 67 deletions(-) diff --git a/pkg/service/script_policy.go b/pkg/service/script_policy.go index fcd7b5f..d936a80 100644 --- a/pkg/service/script_policy.go +++ b/pkg/service/script_policy.go @@ -19,7 +19,11 @@ func (svc *Service) CreateScriptPolicy(ctx context.Context, req *api.ScriptPolic return nil, ErrUserInfo } - if !userInfo.Roles.ScriptWrite { + has_role, err := userInfo.HasRoleScriptWrite() + if err != nil { + return nil, err + } + if !has_role { return nil, ErrPermissionDenied } @@ -100,7 +104,11 @@ func (svc *Service) DeleteScriptPolicy(ctx context.Context, params api.DeleteScr return ErrUserInfo } - if !userInfo.Roles.ScriptWrite { + has_role, err := userInfo.HasRoleScriptWrite() + if err != nil { + return err + } + if !has_role { return ErrPermissionDenied } @@ -144,7 +152,11 @@ func (svc *Service) UpdateScriptPolicy(ctx context.Context, req *api.ScriptPolic return ErrUserInfo } - if !userInfo.Roles.ScriptWrite { + has_role, err := userInfo.HasRoleScriptWrite() + if err != nil { + return err + } + if !has_role { return ErrPermissionDenied } diff --git a/pkg/service/scripts.go b/pkg/service/scripts.go index 6be5ed9..ea7f9ca 100644 --- a/pkg/service/scripts.go +++ b/pkg/service/scripts.go @@ -19,7 +19,11 @@ func (svc *Service) CreateScript(ctx context.Context, req *api.ScriptCreate) (*a return nil, ErrUserInfo } - if !userInfo.Roles.ScriptWrite { + has_role, err := userInfo.HasRoleScriptWrite() + if err != nil { + return nil, err + } + if !has_role { return nil, ErrPermissionDenied } @@ -96,7 +100,11 @@ func (svc *Service) DeleteScript(ctx context.Context, params api.DeleteScriptPar return ErrUserInfo } - if !userInfo.Roles.ScriptWrite { + has_role, err := userInfo.HasRoleScriptWrite() + if err != nil { + return err + } + if !has_role { return ErrPermissionDenied } @@ -141,7 +149,11 @@ func (svc *Service) UpdateScript(ctx context.Context, req *api.ScriptUpdate, par return ErrUserInfo } - if !userInfo.Roles.ScriptWrite { + has_role, err := userInfo.HasRoleScriptWrite() + if err != nil { + return err + } + if !has_role { return ErrPermissionDenied } diff --git a/pkg/service/security.go b/pkg/service/security.go index addc5a9..dbff2c2 100644 --- a/pkg/service/security.go +++ b/pkg/service/security.go @@ -14,34 +14,71 @@ var ( ErrInvalidSession = errors.New("Session invalid") ) +type Role int32 var ( // has ScriptWrite - RoleQuat int32 = 255 + RoleQuat Role = 255 // has SubmissionPublish - RoleMapAdmin int32 = 128 + RoleMapAdmin Role = 128 // has SubmissionReview - RoleMapCouncil int32 = 64 + RoleMapCouncil Role = 64 ) -type Roles struct { - // human roles - SubmissionRelease bool - SubmissionReview bool - ScriptWrite bool - // Thumbnail bool - // MapDownload - - // automated roles - Maptest bool -} - type UserInfo struct { - Roles Roles - UserID uint64 + // Would love to know a better way to do this + svc *SecurityHandler + ctx *context.Context + sessionId string } -func (usr UserInfo) IsSubmitter(submitter uint64) bool { - return usr.UserID == submitter +func (usr UserInfo) GetUserID() (uint64, error) { + session, err := usr.svc.Client.GetSessionUser(*usr.ctx, &auth.IdMessage{ + SessionID: usr.sessionId, + }) + if err != nil { + return 0, err + } + return session.UserID, nil +} +func (usr UserInfo) IsSubmitter(submitter uint64) (bool, error) { + userId, err := usr.GetUserID() + if err != nil { + return false, err + } + return userId == submitter, nil +} +func (usr UserInfo) hasRole(role Role) (bool, error) { + roles, err := usr.svc.Client.GetGroupRole(*usr.ctx, &auth.IdMessage{ + SessionID: usr.sessionId, + }) + if err != nil { + return false, err + } + + for _, r := range roles.Roles { + if int32(role) <= r.Rank { + return true, nil + } + } + return false, nil +} + + +// RoleThumbnail +// RoleMapDownload +func (usr UserInfo) HasRoleSubmissionRelease() (bool, error) { + return usr.hasRole(RoleMapAdmin) +} +func (usr UserInfo) HasRoleSubmissionReview() (bool, error) { + return usr.hasRole(RoleMapCouncil) +} +func (usr UserInfo) HasRoleScriptWrite() (bool, error) { + return usr.hasRole(RoleQuat) +} +/// Not implemented +func (usr UserInfo) HasRoleMaptest() (bool, error) { + println("HasRoleMaptest is not implemented!") + return false, nil } type SecurityHandler struct { @@ -54,20 +91,6 @@ func (svc SecurityHandler) HandleCookieAuth(ctx context.Context, operationName a return nil, ErrMissingSessionID } - session, err := svc.Client.GetSessionUser(ctx, &auth.IdMessage{ - SessionID: sessionId, - }) - if err != nil { - return nil, err - } - - role, err := svc.Client.GetGroupRole(ctx, &auth.IdMessage{ - SessionID: sessionId, - }) - if err != nil { - return nil, err - } - validate, err := svc.Client.ValidateSession(ctx, &auth.IdMessage{ SessionID: sessionId, }) @@ -78,24 +101,10 @@ func (svc SecurityHandler) HandleCookieAuth(ctx context.Context, operationName a return nil, ErrInvalidSession } - roles := Roles{} - - // fix this when roblox udpates group roles - for _, r := range role.Roles { - if RoleQuat <= r.Rank { - roles.ScriptWrite = true - } - if RoleMapAdmin <= r.Rank { - roles.SubmissionRelease = true - } - if RoleMapCouncil <= r.Rank { - roles.SubmissionReview = true - } - } - newCtx := context.WithValue(ctx, "UserInfo", UserInfo{ - Roles: roles, - UserID: session.UserID, + svc: &svc, + ctx: &ctx, + sessionId: sessionId, }) return newCtx, nil diff --git a/pkg/service/submissions.go b/pkg/service/submissions.go index 8fd1f4d..e73809f 100644 --- a/pkg/service/submissions.go +++ b/pkg/service/submissions.go @@ -16,12 +16,17 @@ func (svc *Service) CreateSubmission(ctx context.Context, request *api.Submissio return nil, ErrUserInfo } + userId, err := userInfo.GetUserID() + if err != nil { + return nil, err + } + submission, err := svc.DB.Submissions().Create(ctx, model.Submission{ ID: 0, DisplayName: request.DisplayName, Creator: request.Creator, GameID: request.GameID, - Submitter: int64(userInfo.UserID), + Submitter: int64(userId), AssetID: request.AssetID, AssetVersion: request.AssetVersion, Completed: false, @@ -120,15 +125,18 @@ func (svc *Service) SetSubmissionCompleted(ctx context.Context, params api.SetSu return ErrUserInfo } + has_role, err := userInfo.HasRoleMaptest() + if err != nil { + return err + } // check if caller has MaptestGame role (request must originate from a maptest roblox game) - if !userInfo.Roles.Maptest { + if !has_role { return ErrPermissionDenied } pmap := datastore.Optional() pmap.Add("completed", true) - err := svc.DB.Submissions().Update(ctx, params.SubmissionID, pmap) - return err + return svc.DB.Submissions().Update(ctx, params.SubmissionID, pmap) } // UpdateSubmissionModel implements patchSubmissionModel operation. @@ -148,8 +156,12 @@ func (svc *Service) UpdateSubmissionModel(ctx context.Context, params api.Update return err } + has_role, err := userInfo.IsSubmitter(uint64(submission.Submitter)) + if err != nil { + return err + } // check if caller is the submitter - if !userInfo.IsSubmitter(uint64(submission.Submitter)) { + if !has_role { return ErrPermissionDenied } @@ -173,8 +185,12 @@ func (svc *Service) ActionSubmissionReject(ctx context.Context, params api.Actio return ErrUserInfo } + has_role, err := userInfo.HasRoleSubmissionReview() + if err != nil { + return err + } // check if caller has required role - if !userInfo.Roles.SubmissionReview { + if !has_role { return ErrPermissionDenied } @@ -195,8 +211,12 @@ func (svc *Service) ActionSubmissionRequestChanges(ctx context.Context, params a return ErrUserInfo } + has_role, err := userInfo.HasRoleSubmissionReview() + if err != nil { + return err + } // check if caller has required role - if !userInfo.Roles.SubmissionReview { + if !has_role { return ErrPermissionDenied } @@ -223,8 +243,12 @@ func (svc *Service) ActionSubmissionRevoke(ctx context.Context, params api.Actio return err } + has_role, err := userInfo.IsSubmitter(uint64(submission.Submitter)) + if err != nil { + return err + } // check if caller is the submitter - if !userInfo.IsSubmitter(uint64(submission.Submitter)) { + if !has_role { return ErrPermissionDenied } @@ -251,8 +275,12 @@ func (svc *Service) ActionSubmissionSubmit(ctx context.Context, params api.Actio return err } + has_role, err := userInfo.IsSubmitter(uint64(submission.Submitter)) + if err != nil { + return err + } // check if caller is the submitter - if !userInfo.IsSubmitter(uint64(submission.Submitter)) { + if !has_role { return ErrPermissionDenied } @@ -273,8 +301,12 @@ func (svc *Service) ActionSubmissionTriggerUpload(ctx context.Context, params ap return ErrUserInfo } + has_role, err := userInfo.HasRoleSubmissionRelease() + if err != nil { + return err + } // check if caller has required role - if !userInfo.Roles.SubmissionRelease { + if !has_role { return ErrPermissionDenied } @@ -334,8 +366,12 @@ func (svc *Service) ActionSubmissionTriggerValidate(ctx context.Context, params return ErrUserInfo } + has_role, err := userInfo.HasRoleSubmissionReview() + if err != nil { + return err + } // check if caller has required role - if !userInfo.Roles.SubmissionReview { + if !has_role { return ErrPermissionDenied }