submissions: refactor auth to only make requests when needed
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Quaternions 2024-12-27 17:24:09 -08:00
parent 0d549a46d4
commit 8bf2c92df3
4 changed files with 136 additions and 67 deletions

View File

@ -19,7 +19,11 @@ func (svc *Service) CreateScriptPolicy(ctx context.Context, req *api.ScriptPolic
return nil, ErrUserInfo return nil, ErrUserInfo
} }
if !userInfo.Roles.ScriptWrite { has_role, err := userInfo.HasRoleScriptWrite()
if err != nil {
return nil, err
}
if !has_role {
return nil, ErrPermissionDenied return nil, ErrPermissionDenied
} }
@ -100,7 +104,11 @@ func (svc *Service) DeleteScriptPolicy(ctx context.Context, params api.DeleteScr
return ErrUserInfo return ErrUserInfo
} }
if !userInfo.Roles.ScriptWrite { has_role, err := userInfo.HasRoleScriptWrite()
if err != nil {
return err
}
if !has_role {
return ErrPermissionDenied return ErrPermissionDenied
} }
@ -144,7 +152,11 @@ func (svc *Service) UpdateScriptPolicy(ctx context.Context, req *api.ScriptPolic
return ErrUserInfo return ErrUserInfo
} }
if !userInfo.Roles.ScriptWrite { has_role, err := userInfo.HasRoleScriptWrite()
if err != nil {
return err
}
if !has_role {
return ErrPermissionDenied return ErrPermissionDenied
} }

View File

@ -19,7 +19,11 @@ func (svc *Service) CreateScript(ctx context.Context, req *api.ScriptCreate) (*a
return nil, ErrUserInfo return nil, ErrUserInfo
} }
if !userInfo.Roles.ScriptWrite { has_role, err := userInfo.HasRoleScriptWrite()
if err != nil {
return nil, err
}
if !has_role {
return nil, ErrPermissionDenied return nil, ErrPermissionDenied
} }
@ -96,7 +100,11 @@ func (svc *Service) DeleteScript(ctx context.Context, params api.DeleteScriptPar
return ErrUserInfo return ErrUserInfo
} }
if !userInfo.Roles.ScriptWrite { has_role, err := userInfo.HasRoleScriptWrite()
if err != nil {
return err
}
if !has_role {
return ErrPermissionDenied return ErrPermissionDenied
} }
@ -141,7 +149,11 @@ func (svc *Service) UpdateScript(ctx context.Context, req *api.ScriptUpdate, par
return ErrUserInfo return ErrUserInfo
} }
if !userInfo.Roles.ScriptWrite { has_role, err := userInfo.HasRoleScriptWrite()
if err != nil {
return err
}
if !has_role {
return ErrPermissionDenied return ErrPermissionDenied
} }

View File

@ -14,34 +14,71 @@ var (
ErrInvalidSession = errors.New("Session invalid") ErrInvalidSession = errors.New("Session invalid")
) )
type Role int32
var ( var (
// has ScriptWrite // has ScriptWrite
RoleQuat int32 = 255 RoleQuat Role = 255
// has SubmissionPublish // has SubmissionPublish
RoleMapAdmin int32 = 128 RoleMapAdmin Role = 128
// has SubmissionReview // 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 { type UserInfo struct {
Roles Roles // Would love to know a better way to do this
UserID uint64 svc *SecurityHandler
ctx *context.Context
sessionId string
} }
func (usr UserInfo) IsSubmitter(submitter uint64) bool { func (usr UserInfo) GetUserID() (uint64, error) {
return usr.UserID == submitter 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 { type SecurityHandler struct {
@ -54,20 +91,6 @@ func (svc SecurityHandler) HandleCookieAuth(ctx context.Context, operationName a
return nil, ErrMissingSessionID 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{ validate, err := svc.Client.ValidateSession(ctx, &auth.IdMessage{
SessionID: sessionId, SessionID: sessionId,
}) })
@ -78,24 +101,10 @@ func (svc SecurityHandler) HandleCookieAuth(ctx context.Context, operationName a
return nil, ErrInvalidSession 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{ newCtx := context.WithValue(ctx, "UserInfo", UserInfo{
Roles: roles, svc: &svc,
UserID: session.UserID, ctx: &ctx,
sessionId: sessionId,
}) })
return newCtx, nil return newCtx, nil

View File

@ -16,12 +16,17 @@ func (svc *Service) CreateSubmission(ctx context.Context, request *api.Submissio
return nil, ErrUserInfo return nil, ErrUserInfo
} }
userId, err := userInfo.GetUserID()
if err != nil {
return nil, err
}
submission, err := svc.DB.Submissions().Create(ctx, model.Submission{ submission, err := svc.DB.Submissions().Create(ctx, model.Submission{
ID: 0, ID: 0,
DisplayName: request.DisplayName, DisplayName: request.DisplayName,
Creator: request.Creator, Creator: request.Creator,
GameID: request.GameID, GameID: request.GameID,
Submitter: int64(userInfo.UserID), Submitter: int64(userId),
AssetID: request.AssetID, AssetID: request.AssetID,
AssetVersion: request.AssetVersion, AssetVersion: request.AssetVersion,
Completed: false, Completed: false,
@ -120,15 +125,18 @@ func (svc *Service) SetSubmissionCompleted(ctx context.Context, params api.SetSu
return ErrUserInfo 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) // check if caller has MaptestGame role (request must originate from a maptest roblox game)
if !userInfo.Roles.Maptest { if !has_role {
return ErrPermissionDenied return ErrPermissionDenied
} }
pmap := datastore.Optional() pmap := datastore.Optional()
pmap.Add("completed", true) pmap.Add("completed", true)
err := svc.DB.Submissions().Update(ctx, params.SubmissionID, pmap) return svc.DB.Submissions().Update(ctx, params.SubmissionID, pmap)
return err
} }
// UpdateSubmissionModel implements patchSubmissionModel operation. // UpdateSubmissionModel implements patchSubmissionModel operation.
@ -148,8 +156,12 @@ func (svc *Service) UpdateSubmissionModel(ctx context.Context, params api.Update
return err return err
} }
has_role, err := userInfo.IsSubmitter(uint64(submission.Submitter))
if err != nil {
return err
}
// check if caller is the submitter // check if caller is the submitter
if !userInfo.IsSubmitter(uint64(submission.Submitter)) { if !has_role {
return ErrPermissionDenied return ErrPermissionDenied
} }
@ -173,8 +185,12 @@ func (svc *Service) ActionSubmissionReject(ctx context.Context, params api.Actio
return ErrUserInfo return ErrUserInfo
} }
has_role, err := userInfo.HasRoleSubmissionReview()
if err != nil {
return err
}
// check if caller has required role // check if caller has required role
if !userInfo.Roles.SubmissionReview { if !has_role {
return ErrPermissionDenied return ErrPermissionDenied
} }
@ -195,8 +211,12 @@ func (svc *Service) ActionSubmissionRequestChanges(ctx context.Context, params a
return ErrUserInfo return ErrUserInfo
} }
has_role, err := userInfo.HasRoleSubmissionReview()
if err != nil {
return err
}
// check if caller has required role // check if caller has required role
if !userInfo.Roles.SubmissionReview { if !has_role {
return ErrPermissionDenied return ErrPermissionDenied
} }
@ -223,8 +243,12 @@ func (svc *Service) ActionSubmissionRevoke(ctx context.Context, params api.Actio
return err return err
} }
has_role, err := userInfo.IsSubmitter(uint64(submission.Submitter))
if err != nil {
return err
}
// check if caller is the submitter // check if caller is the submitter
if !userInfo.IsSubmitter(uint64(submission.Submitter)) { if !has_role {
return ErrPermissionDenied return ErrPermissionDenied
} }
@ -251,8 +275,12 @@ func (svc *Service) ActionSubmissionSubmit(ctx context.Context, params api.Actio
return err return err
} }
has_role, err := userInfo.IsSubmitter(uint64(submission.Submitter))
if err != nil {
return err
}
// check if caller is the submitter // check if caller is the submitter
if !userInfo.IsSubmitter(uint64(submission.Submitter)) { if !has_role {
return ErrPermissionDenied return ErrPermissionDenied
} }
@ -273,8 +301,12 @@ func (svc *Service) ActionSubmissionTriggerUpload(ctx context.Context, params ap
return ErrUserInfo return ErrUserInfo
} }
has_role, err := userInfo.HasRoleSubmissionRelease()
if err != nil {
return err
}
// check if caller has required role // check if caller has required role
if !userInfo.Roles.SubmissionRelease { if !has_role {
return ErrPermissionDenied return ErrPermissionDenied
} }
@ -334,8 +366,12 @@ func (svc *Service) ActionSubmissionTriggerValidate(ctx context.Context, params
return ErrUserInfo return ErrUserInfo
} }
has_role, err := userInfo.HasRoleSubmissionReview()
if err != nil {
return err
}
// check if caller has required role // check if caller has required role
if !userInfo.Roles.SubmissionReview { if !has_role {
return ErrPermissionDenied return ErrPermissionDenied
} }