maps-service/pkg/service/security.go
Quaternions 8bf2c92df3
All checks were successful
continuous-integration/drone/push Build is passing
submissions: refactor auth to only make requests when needed
2024-12-27 17:25:18 -08:00

112 lines
2.4 KiB
Go

package service
import (
"context"
"errors"
"git.itzana.me/strafesnet/go-grpc/auth"
"git.itzana.me/strafesnet/maps-service/pkg/api"
)
var (
// ErrMissingSessionID there is no session id
ErrMissingSessionID = errors.New("SessionID missing")
// ErrInvalidSession caller does not have a valid session
ErrInvalidSession = errors.New("Session invalid")
)
type Role int32
var (
// has ScriptWrite
RoleQuat Role = 255
// has SubmissionPublish
RoleMapAdmin Role = 128
// has SubmissionReview
RoleMapCouncil Role = 64
)
type UserInfo struct {
// Would love to know a better way to do this
svc *SecurityHandler
ctx *context.Context
sessionId string
}
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 {
Client auth.AuthServiceClient
}
func (svc SecurityHandler) HandleCookieAuth(ctx context.Context, operationName api.OperationName, t api.CookieAuth) (context.Context, error) {
sessionId := t.GetAPIKey()
if sessionId == "" {
return nil, ErrMissingSessionID
}
validate, err := svc.Client.ValidateSession(ctx, &auth.IdMessage{
SessionID: sessionId,
})
if err != nil {
return nil, err
}
if !validate.Valid {
return nil, ErrInvalidSession
}
newCtx := context.WithValue(ctx, "UserInfo", UserInfo{
svc: &svc,
ctx: &ctx,
sessionId: sessionId,
})
return newCtx, nil
}