diff --git a/modules/auth/permissions/rbac.go b/modules/auth/permissions/rbac.go index eee2ce5..fc1b5d0 100644 --- a/modules/auth/permissions/rbac.go +++ b/modules/auth/permissions/rbac.go @@ -27,6 +27,7 @@ var ( ScopeAdminDataStore = ScopeDataStore("*") ScopeAdminNumberStore = ScopeNumberStore("*") + ScopeAdminUsers = ScopeUsers("*") ) // ScopePetPictures -- Pet pictures @@ -56,6 +57,15 @@ func ScopeNumberStore(value string) Scope { } } +// ScopeUsers -- Admin users +func ScopeUsers(value string) Scope { + return Scope{ + Name: "users", + Description: "Users", + Value: value, + } +} + type Role struct { Name string Description string @@ -72,6 +82,7 @@ var ( ScopeAdminRateLimit, ScopeAdminDataStore, ScopeAdminNumberStore, + ScopeAdminUsers, }, } @@ -84,6 +95,7 @@ var ( ScopeAdminRateLimit, ScopeAdminDataStore, ScopeAdminNumberStore, + ScopeAdminUsers, }, } ) diff --git a/modules/auth/users/handler.go b/modules/auth/users/handler.go index 9c0cb29..63af588 100644 --- a/modules/auth/users/handler.go +++ b/modules/auth/users/handler.go @@ -6,6 +6,8 @@ import ( mw "github.com/NeuralNexusDev/neuralnexus-api/middleware" "github.com/NeuralNexusDev/neuralnexus-api/modules/auth" accountlinking "github.com/NeuralNexusDev/neuralnexus-api/modules/auth/linking" + perms "github.com/NeuralNexusDev/neuralnexus-api/modules/auth/permissions" + sess "github.com/NeuralNexusDev/neuralnexus-api/modules/auth/session" "github.com/NeuralNexusDev/neuralnexus-api/modules/database" "github.com/NeuralNexusDev/neuralnexus-api/responses" ) @@ -38,6 +40,11 @@ func GetUserHandler(service Service) http.HandlerFunc { // GetUserFromPlatformHandler - Get a user from a platform func GetUserFromPlatformHandler(service Service) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + session := r.Context().Value(mw.SessionKey).(*sess.Session) + if !session.HasPermission(perms.ScopeAdminUsers) { + responses.Forbidden(w, r, "You do not have permission to get users") + return + } platform := accountlinking.Platform(r.PathValue("platform")) platformID := r.PathValue("platform_id") user, err := service.GetUserFromPlatform(platform, platformID) @@ -49,9 +56,32 @@ func GetUserFromPlatformHandler(service Service) http.HandlerFunc { } } +// GetUserPermissionsHandler - Get a user's permissions +func GetUserPermissionsHandler(service Service) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + session := r.Context().Value(mw.SessionKey).(*sess.Session) + userID := r.PathValue("user_id") + if session.UserID != userID && !session.HasPermission(perms.ScopeAdminUsers) { + responses.Forbidden(w, r, "You do not have permission to get user permissions") + return + } + permissions, err := service.GetUserPermissions(userID) + if err != nil { + responses.NotFound(w, r, "User not found") + return + } + responses.StructOK(w, r, permissions) + } +} + // UpdateUserHandler - Update a user func UpdateUserHandler(service Service) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + session := r.Context().Value(mw.SessionKey).(*sess.Session) + if !session.HasPermission(perms.ScopeAdminUsers) { + responses.Forbidden(w, r, "You do not have permission to update users") + return + } userID := r.PathValue("user_id") var user auth.Account err := responses.DecodeStruct(r, &user) @@ -72,6 +102,11 @@ func UpdateUserHandler(service Service) http.HandlerFunc { // UpdateUserFromPlatformHandler - Update a user from a platform func UpdateUserFromPlatformHandler(service Service) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + session := r.Context().Value(mw.SessionKey).(*sess.Session) + if !session.HasPermission(perms.ScopeAdminUsers) { + responses.Forbidden(w, r, "You do not have permission to update users") + return + } platform := accountlinking.Platform(r.PathValue("platform")) platformID := r.PathValue("platform_id") var data accountlinking.Data @@ -92,6 +127,11 @@ func UpdateUserFromPlatformHandler(service Service) http.HandlerFunc { // DeleteUserHandler - Delete a user func DeleteUserHandler(service Service) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + session := r.Context().Value(mw.SessionKey).(*sess.Session) + if !session.HasPermission(perms.ScopeAdminUsers) { + responses.Forbidden(w, r, "You do not have permission to delete users") + return + } userID := r.PathValue("user_id") err := service.DeleteUser(userID) if err != nil { diff --git a/modules/auth/users/service.go b/modules/auth/users/service.go index 68310d9..e5413ca 100644 --- a/modules/auth/users/service.go +++ b/modules/auth/users/service.go @@ -1,16 +1,19 @@ package users import ( + "log" "time" "github.com/NeuralNexusDev/neuralnexus-api/modules/auth" accountlinking "github.com/NeuralNexusDev/neuralnexus-api/modules/auth/linking" + perms "github.com/NeuralNexusDev/neuralnexus-api/modules/auth/permissions" ) // Service - The service interface type Service interface { GetUser(userID string) (*auth.Account, error) GetUserFromPlatform(platform accountlinking.Platform, platformID string) (*auth.Account, error) + GetUserPermissions(userID string) ([]string, error) UpdateUser(user *auth.Account) (*auth.Account, error) UpdateUserFromPlatform(platform accountlinking.Platform, platformID string, data accountlinking.Data) (*auth.Account, error) DeleteUser(userID string) error @@ -41,6 +44,26 @@ func (s *service) GetUserFromPlatform(platform accountlinking.Platform, platform return s.as.GetAccountByID(la.UserID) } +// GetUserPermissions - Get a user's permissions +func (s *service) GetUserPermissions(userID string) ([]string, error) { + a, err := s.as.GetAccountByID(userID) + if err != nil { + return nil, err + } + permissions := []string{} + for _, r := range a.Roles { + role, err := perms.GetRoleByName(r) + if err != nil { + log.Println(err) + continue + } + for _, p := range role.Permissions { + permissions = append(permissions, p.Name+"|"+p.Value) + } + } + return permissions, nil +} + // UpdateUser - Update a user func (s *service) UpdateUser(user *auth.Account) (*auth.Account, error) { account, err := s.as.GetAccountByID(user.UserID)