diff --git a/main.go b/main.go index 0e55123..e0678cd 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( "janex/admin-dashboard-backend/modules/grouptasks" "janex/admin-dashboard-backend/modules/logger" "janex/admin-dashboard-backend/modules/structs" + "janex/admin-dashboard-backend/modules/systempermissions" "janex/admin-dashboard-backend/modules/utils" "janex/admin-dashboard-backend/routers/router" "janex/admin-dashboard-backend/socketserver" @@ -20,6 +21,8 @@ func init() { config.LoadConfig() logger.InitLogger() utils.ValidatorInit() + systempermissions.InitSystemPermissions() + grouptasks.LoadGroups("") database.InitDatabase() } @@ -68,8 +71,6 @@ func main() { return fiber.ErrUpgradeRequired }) - grouptasks.LoadGroups("") - go socketserver.RunHub() socketserver.WebSocketServer(app) diff --git a/modules/cache/systempermissions.go b/modules/cache/systempermissions.go new file mode 100644 index 0000000..97fad56 --- /dev/null +++ b/modules/cache/systempermissions.go @@ -0,0 +1,47 @@ +package cache + +import "sync" + +var systemPermissions []string +var sp sync.RWMutex + +/* +func AddSystemPermission(permission string) { + sp.Lock() + systemPermissions = append(systemPermissions, permission) + sp.Unlock() +} */ + +func AddSystemPermissions(permissions []string) { + sp.Lock() + + for _, permission := range permissions { + systemPermissions = append(systemPermissions, permission) + } + + sp.Unlock() +} + +func DeleteSystemPermission(permission string) { + sp.Lock() + + for i := 0; i < len(systemPermissions); i++ { + if systemPermissions[i] == permission { + systemPermissions = removeSystemPermission(systemPermissions, i) + break + } + } + + sp.Unlock() +} + +func removeSystemPermission(permissions []string, i int) []string { + return append(permissions[:i], permissions[i+1:]...) +} + +func GetSystemPermissions() []string { + sp.RLock() + defer sp.RUnlock() + + return systemPermissions +} diff --git a/modules/database/database.go b/modules/database/database.go index 57dd229..1d0b3cb 100644 --- a/modules/database/database.go +++ b/modules/database/database.go @@ -2,9 +2,9 @@ package database import ( "fmt" + "janex/admin-dashboard-backend/modules/cache" "janex/admin-dashboard-backend/modules/config" "janex/admin-dashboard-backend/modules/structs" - "janex/admin-dashboard-backend/modules/utils" "time" "github.com/google/uuid" @@ -91,7 +91,9 @@ func handleMasterRolePermissions() (roleId string) { DB.Where("role_id = ?", foundRole.Id).Find(&foundRolePermissions) - systemPermissions := utils.GetSystemPermissions() + log.Debug().Msgf("init database %v", cache.GetSystemPermissions()) + + systemPermissions := cache.GetSystemPermissions() if len(foundRolePermissions) > 0 { // add new permissions if not already present diff --git a/modules/grouptasks/grouptasks.go b/modules/grouptasks/grouptasks.go index 7cad25c..52291d7 100644 --- a/modules/grouptasks/grouptasks.go +++ b/modules/grouptasks/grouptasks.go @@ -8,6 +8,7 @@ import ( "janex/admin-dashboard-backend/modules/cache" "janex/admin-dashboard-backend/modules/database" "janex/admin-dashboard-backend/modules/structs" + "janex/admin-dashboard-backend/modules/systempermissions" "janex/admin-dashboard-backend/modules/utils" "janex/admin-dashboard-backend/socketclients" llog "log" @@ -86,6 +87,8 @@ func LoadGroups(category string) { }, }) } + + systempermissions.AddDynamicGroupTasksPermissions() } const ( diff --git a/modules/systempermissions/systempermissions.go b/modules/systempermissions/systempermissions.go new file mode 100644 index 0000000..ddcaefe --- /dev/null +++ b/modules/systempermissions/systempermissions.go @@ -0,0 +1,44 @@ +package systempermissions + +import ( + "janex/admin-dashboard-backend/modules/cache" + "janex/admin-dashboard-backend/modules/utils" + "strings" +) + +func InitSystemPermissions() { + cache.AddSystemPermissions([]string{ + utils.PermissionGroupTasksHistory, + utils.PermissionAllUsersActionChangeRole, + utils.PermissionScannerUseScanners, + utils.PermissionAdminAreaCreateNewRole, + utils.PermissionAdminAreaUpdateRole, + utils.PermissionAdminAreaDeleteRole, + utils.PermissionAdminAreaMoveRoleUpDown, + utils.PermissionAdminAreaLogs, + }) +} + +// dynamic permissions like group_tasks.overview.XY.new_task are replaced with the category to group_tasks.overview.test.new_task +func AddDynamicGroupTasksPermissions() { + var groupTasksPermissions []string + + var dynamicGroupTasksPermissions = []string{ + utils.PermissionGroupTasksOverviewXYNewTask, + utils.PermissionGroupTasksOverviewXYReloadGroupConfig, + utils.PermissionGroupTasksOverviewXYView, + utils.PermissionGroupTasksHistory, + } + + for _, categoryGroup := range cache.GetCategoryGroups() { + for _, dynamicGroupTasksPermission := range dynamicGroupTasksPermissions { + groupTasksPermissions = append(groupTasksPermissions, ConvertXYPermission(dynamicGroupTasksPermission, categoryGroup.Category)) + } + } + + cache.AddSystemPermissions(groupTasksPermissions) +} + +func ConvertXYPermission(permission string, category string) string { + return strings.Replace(permission, "XY", strings.ToLower(category), 1) +} diff --git a/modules/utils/globals.go b/modules/utils/globals.go index f7898ea..6c4d941 100644 --- a/modules/utils/globals.go +++ b/modules/utils/globals.go @@ -53,6 +53,7 @@ const ( SentCmdAdminAreaRoleDeleted = 22 SentCmdUserRoleUpdated = 23 SentCmdRolePermissionsUpdated = 24 + SentCmdErrorNoPermissions = 25 ) // commands received from web clients @@ -88,28 +89,20 @@ var ( ) const ( - _groupTasks = "group_tasks." - PermissionGroupTasksHistory = _groupTasks + "history" + _groupTasks = "group_tasks." + PermissionGroupTasksOverviewXYNewTask = _groupTasks + "overview.XY.new_task" + PermissionGroupTasksOverviewXYReloadGroupConfig = _groupTasks + "overview.XY.reload_group_config" + PermissionGroupTasksOverviewXYView = _groupTasks + "overview.XY.view" + PermissionGroupTasksHistory = _groupTasks + "history" PermissionAllUsersActionChangeRole = "all_users.action.change_role" PermissionScannerUseScanners = "scanner.use_scanners" - _adminArea = "admin_area." - _adminAreaRoles = _adminArea + "roles." - PermissionAdminAreaAddRole = _adminAreaRoles + "add_role" - PermissionAdminAreaUpdateRole = _adminAreaRoles + "update_role" - PermissionAdminAreaDeleteRole = _adminAreaRoles + "delete_role" - PermissionAdminAreaLogs = _adminArea + "logs" + _adminArea = "admin_area." + _adminAreaRoles = _adminArea + "roles." + PermissionAdminAreaCreateNewRole = _adminAreaRoles + "create_new_role" + PermissionAdminAreaUpdateRole = _adminAreaRoles + "update_role" + PermissionAdminAreaDeleteRole = _adminAreaRoles + "delete_role" + PermissionAdminAreaMoveRoleUpDown = _adminAreaRoles + "move_role_up_down" + PermissionAdminAreaLogs = _adminArea + "logs" ) - -func GetSystemPermissions() []string { - return []string{ - PermissionGroupTasksHistory, - PermissionAllUsersActionChangeRole, - PermissionScannerUseScanners, - PermissionAdminAreaAddRole, - PermissionAdminAreaUpdateRole, - PermissionAdminAreaDeleteRole, - PermissionAdminAreaLogs, - } -} diff --git a/socketclients/socketclients.go b/socketclients/socketclients.go index cc72be4..f601244 100644 --- a/socketclients/socketclients.go +++ b/socketclients/socketclients.go @@ -5,6 +5,7 @@ import ( "janex/admin-dashboard-backend/modules/cache" "janex/admin-dashboard-backend/modules/database" "janex/admin-dashboard-backend/modules/structs" + "janex/admin-dashboard-backend/modules/systempermissions" "janex/admin-dashboard-backend/modules/utils" "time" @@ -380,8 +381,6 @@ func isRoleDisplayNameAvailable(roleDisplayName string) bool { } func AdminAreaUpdateRole(sessionId string, body map[string]interface{}) { - log.Debug().Msgf("update role %v", body) - if body["RoleId"] == nil { log.Error().Msgf("No role id specified in update role %v", body) return @@ -390,10 +389,6 @@ func AdminAreaUpdateRole(sessionId string, body map[string]interface{}) { roleId := body["RoleId"].(string) changes := body["Changes"].(map[string]interface{}) - if changes["AddedPermissions"] != nil { - log.Debug().Msgf("addedPermissions %v", len(changes["AddedPermissions"].([]interface{}))) - } - // user has nothing changed if changes["DisplayName"] == nil && changes["Description"] == nil && @@ -439,8 +434,6 @@ func AdminAreaUpdateRole(sessionId string, body map[string]interface{}) { } database.DB.Create(dbAddedPermissions) - - log.Debug().Msgf("dbAddedPermissions: %v", dbAddedPermissions) } if changes["RemovedPermissions"] != nil { @@ -450,17 +443,11 @@ func AdminAreaUpdateRole(sessionId string, body map[string]interface{}) { for _, removedPermission := range removedPermissions { database.DB.Where("role_id = ?", roleId).Where("permission_id = ?", removedPermission.(string)).Delete(&structs.RolePermission{}) - - log.Debug().Msgf("dbRemovedPermissions: %v", removedPermission) } } database.DB.Model(&structs.Role{}).Where("id = ?", roleId).Updates(&updatedRole) - log.Debug().Msgf("updated role: %v", updatedRole) - - // TODO: check permissions - SendMessageOnlyToSessionId(sessionId, structs.SendSocketMessage{ Cmd: utils.SentCmdAdminAreaRoleUpdated, Body: struct { @@ -602,3 +589,25 @@ func UpdateUserRole(userId string, roleId string) { }, }) } + +func HasPermission(userId string, permission string) bool { + var user structs.User + + database.DB.Where("id = ?", userId).First(&user) + + var rolePermission structs.RolePermission + + database.DB.Where("role_id = ?", user.RoleId).Where("permission_id = ?", permission).Find(&rolePermission) + + return rolePermission.PermissionId == permission +} + +func HasXYPermission(userId string, permission string, category string) bool { + return HasPermission(userId, systempermissions.ConvertXYPermission(permission, category)) +} + +func SendErrorMessageNoPermissions(sessionId string) { + SendMessageOnlyToSessionId(sessionId, structs.SendSocketMessage{ + Cmd: utils.SentCmdErrorNoPermissions, + }) +} diff --git a/socketserver/hub.go b/socketserver/hub.go index be9bffc..efb5763 100644 --- a/socketserver/hub.go +++ b/socketserver/hub.go @@ -99,6 +99,12 @@ func RunHub() { switch receivedMessage.Cmd { case utils.ReceivedCmdStartGroupTasks: category := receivedMessage.Body["category"].(string) + + if !socketclients.HasXYPermission(data.Conn.Locals("userId").(string), utils.PermissionGroupTasksOverviewXYNewTask, category) { + socketclients.SendErrorMessageNoPermissions(data.Conn.Locals("sessionId").(string)) + break + } + groupId := receivedMessage.Body["id"].(string) globalInputsJsonString := utils.MarshalJson(receivedMessage.Body["globalInputs"]) @@ -164,6 +170,11 @@ func RunHub() { case utils.ReceivedCmdReloadGroupTasks: category := receivedMessage.Body["category"].(string) + if !socketclients.HasXYPermission(data.Conn.Locals("userId").(string), utils.PermissionGroupTasksOverviewXYReloadGroupConfig, category) { + socketclients.SendErrorMessageNoPermissions(data.Conn.Locals("sessionId").(string)) + break + } + socketclients.BroadcastMessage(structs.SendSocketMessage{ Cmd: utils.SentCmdReloadingGroupTasks, Body: category, @@ -196,9 +207,10 @@ func RunHub() { socketclients.UpdateUserProfile(data.Conn, receivedMessage.Body["changes"].(map[string]interface{})) break case utils.ReceivedCmdAdminAreaCreateNewRole: - log.Debug().Msgf("create new role") - - // TODO: check permissions + if !socketclients.HasPermission(data.Conn.Locals("userId").(string), utils.PermissionAdminAreaCreateNewRole) { + socketclients.SendErrorMessageNoPermissions(data.Conn.Locals("sessionId").(string)) + break + } role := structs.Role{ Id: uuid.New().String(), @@ -216,15 +228,35 @@ func RunHub() { }) break case utils.ReceivedCmdAdminAreaUpdateRole: + if !socketclients.HasPermission(data.Conn.Locals("userId").(string), utils.PermissionAdminAreaUpdateRole) { + socketclients.SendErrorMessageNoPermissions(data.Conn.Locals("sessionId").(string)) + break + } + socketclients.AdminAreaUpdateRole(data.Conn.Locals("sessionId").(string), receivedMessage.Body) break case utils.ReceivedCmdAdminAreaUpdateRoleSortingOrder: + if !socketclients.HasPermission(data.Conn.Locals("userId").(string), utils.PermissionAdminAreaMoveRoleUpDown) { + socketclients.SendErrorMessageNoPermissions(data.Conn.Locals("sessionId").(string)) + break + } + socketclients.AdminAreaMoveRoleToSortingOrder(receivedMessage.Body) break case utils.ReceivedCmdAdminAreaDeleteRole: + if !socketclients.HasPermission(data.Conn.Locals("userId").(string), utils.PermissionAdminAreaDeleteRole) { + socketclients.SendErrorMessageNoPermissions(data.Conn.Locals("sessionId").(string)) + break + } + socketclients.AdminAreaDeleteRole(receivedMessage.Body) break case utils.ReceivedCmdUpdateUserRole: + if !socketclients.HasPermission(data.Conn.Locals("userId").(string), utils.PermissionAllUsersActionChangeRole) { + socketclients.SendErrorMessageNoPermissions(data.Conn.Locals("sessionId").(string)) + break + } + socketclients.UpdateUserRole(receivedMessage.Body["UserId"].(string), receivedMessage.Body["RoleId"].(string)) break default: