package web_api import ( "context" "errors" "git.itzana.me/strafesnet/go-grpc/auth" "git.itzana.me/strafesnet/maps-service/pkg/api" "git.itzana.me/strafesnet/maps-service/pkg/model" ) 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 UserInfoHandle struct { // Would love to know a better way to do this svc *SecurityHandler ctx *context.Context sessionId string } type UserInfo struct { UserID uint64 Username string AvatarURL string } func (usr UserInfoHandle) GetUserInfo() (userInfo UserInfo, err error) { session, err := usr.svc.Client.GetSessionUser(*usr.ctx, &auth.IdMessage{ SessionID: usr.sessionId, }) if err != nil { return userInfo, err } userInfo.UserID = session.UserID userInfo.Username = session.Username userInfo.AvatarURL = session.AvatarURL return userInfo, nil } func (usr UserInfoHandle) 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 UserInfoHandle) Validate() (bool, error) { validate, err := usr.svc.Client.ValidateSession(*usr.ctx, &auth.IdMessage{ SessionID: usr.sessionId, }) if err != nil { return false, err } return validate.Valid, nil } func (usr UserInfoHandle) HasRoles(wantRoles model.Roles) (bool, error) { haveroles, err := usr.GetRoles() if err != nil { return false, err } return haveroles & wantRoles == wantRoles, nil } func (usr UserInfoHandle) GetRoles() (model.Roles, error) { roles, err := usr.svc.Client.GetGroupRole(*usr.ctx, &auth.IdMessage{ SessionID: usr.sessionId, }) if err != nil { return model.RolesEmpty, err } // map roles into bitflag rolesBitflag := model.RolesEmpty; for _, r := range roles.Roles { switch model.GroupRole(r.Rank){ case model.RoleQuat, model.RoleItzaname, model.RoleStagingDeveloper: rolesBitflag|=model.RolesAll case model.RoleMapAdmin: rolesBitflag|=model.RolesMapAdmin case model.RoleMapCouncil: rolesBitflag|=model.RolesMapCouncil case model.RoleMapAccess: rolesBitflag|=model.RolesMapAccess } } return rolesBitflag, nil } // RoleThumbnail func (usr UserInfoHandle) HasRoleMapfixUpload() (bool, error) { return usr.HasRoles(model.RolesMapfixUpload) } func (usr UserInfoHandle) HasRoleMapfixReview() (bool, error) { return usr.HasRoles(model.RolesMapfixReview) } func (usr UserInfoHandle) HasRoleMapDownload() (bool, error) { return usr.HasRoles(model.RolesMapDownload) } func (usr UserInfoHandle) HasRoleSubmissionRelease() (bool, error) { return usr.HasRoles(model.RolesSubmissionRelease) } func (usr UserInfoHandle) HasRoleSubmissionUpload() (bool, error) { return usr.HasRoles(model.RolesSubmissionUpload) } func (usr UserInfoHandle) HasRoleSubmissionReview() (bool, error) { return usr.HasRoles(model.RolesSubmissionReview) } func (usr UserInfoHandle) HasRoleScriptWrite() (bool, error) { return usr.HasRoles(model.RolesScriptWrite) } /// Not implemented func (usr UserInfoHandle) 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 } newCtx := context.WithValue(ctx, "UserInfo", UserInfoHandle{ svc: &svc, ctx: &ctx, sessionId: sessionId, }) return newCtx, nil }