diff --git a/groupTasks/groups/janex-acryl/index.json b/groupTasks/janex-acryl/index.json similarity index 100% rename from groupTasks/groups/janex-acryl/index.json rename to groupTasks/janex-acryl/index.json diff --git a/groupTasks/groups/janex-acryl/test.py b/groupTasks/janex-acryl/test.py similarity index 100% rename from groupTasks/groups/janex-acryl/test.py rename to groupTasks/janex-acryl/test.py diff --git a/groupTasks/groups/testa/index.json b/groupTasks/testa/index.json similarity index 100% rename from groupTasks/groups/testa/index.json rename to groupTasks/testa/index.json diff --git a/modules/cache/categorygroup.go b/modules/cache/categorygroup.go index 5072266..95bba77 100644 --- a/modules/cache/categorygroup.go +++ b/modules/cache/categorygroup.go @@ -41,6 +41,30 @@ func GetCategoryGroupByCategory(category string) structs.CategoryGroup { return structs.CategoryGroup{} } +func ExistsCategory(category string) bool { + cgMu.RLock() + defer cgMu.RUnlock() + + for _, categoryGroup := range categoryGroups { + if categoryGroup.Category == category { + return true + } + } + + return false +} + +func RemoveCategory(category string) { + cgMu.Lock() + defer cgMu.Unlock() + + for index, categoryGroup := range categoryGroups { + if categoryGroup.Category == category { + categoryGroups = append(categoryGroups[:index], categoryGroups[index+1:]...) + } + } +} + func RemoveAllCategoryGroupsByCategory(category string) { for index, categoryGroup := range GetCategoryGroups() { if categoryGroup.Category == category { diff --git a/modules/grouptasks/grouptasks.go b/modules/grouptasks/grouptasks.go index 53b285a..b1d9bb3 100644 --- a/modules/grouptasks/grouptasks.go +++ b/modules/grouptasks/grouptasks.go @@ -36,8 +36,6 @@ func InitLoadCategoryGroups() { files, err := os.ReadDir(config.Cfg.FolderPaths.GroupTasksGroups + entry.Name()) - log.Debug().Msgf("entry %v", entry.Name()) - if err != nil { log.Error().Msg("Failed to read groups directory files, error: " + err.Error()) return @@ -1155,3 +1153,82 @@ func InstallPythonPackages(userId string, category string, groupId string) { Body: messageBody, }) } + +func CheckWhichCategoriesAreAvailable() []string { + entries, err := os.ReadDir(config.Cfg.FolderPaths.GroupTasksGroups) + + if err != nil { + log.Error().Msgf("Error reading group tasks groups folder %s", err.Error()) + } + + // loop throught cached categories and check if for the category exists an folder + // if not delete the category from cache + for _, category := range cache.GetCategoryGroups() { + + entries, err := os.ReadDir(config.Cfg.FolderPaths.GroupTasksGroups) + + if err != nil { + log.Error().Msgf("Error reading group tasks groups folder %s", err.Error()) + } + + var exists bool + + for _, entry := range entries { + if entry.Name() == category.Category { + exists = true + } + } + + if !exists { + cache.RemoveCategory(category.Category) + } + } + + // loop throught all folders in group tasks groups folder and add them to cache if not already in cache + var categories []string + + for _, entry := range entries { + if !entry.IsDir() { + continue + } + + categories = append(categories, entry.Name()) + + // add category to cache if not already in cache + if !cache.ExistsCategory(entry.Name()) { + files, err := os.ReadDir(config.Cfg.FolderPaths.GroupTasksGroups + entry.Name()) + + if err != nil { + log.Error().Msgf("Error reading group tasks groups folder %s", err.Error()) + return categories + } + + for _, file := range files { + if file.Name() == "index.json" { + content, err := os.ReadFile(config.Cfg.FolderPaths.GroupTasksGroups + entry.Name() + "/index.json") + + if err != nil { + log.Error().Msg("Failed to read file content, error: " + err.Error()) + return categories + } + + var group structs.Group + + json.Unmarshal(content, &group) + + group.Id = entry.Name() + + cache.AddCategoryGroup(group) + } + } + } + } + + systempermissions.HandleMasterRolePermissions() + + // TODO: sent new master role permissions to ws topic + + // TODO: send category list to ws users (check permissions) + + return categories +} diff --git a/modules/systempermissions/systempermissions.go b/modules/systempermissions/systempermissions.go index a45b023..33322d3 100644 --- a/modules/systempermissions/systempermissions.go +++ b/modules/systempermissions/systempermissions.go @@ -46,7 +46,7 @@ func RemoveDynamicGroupTasksPermissionsByCategory(category string) []string { } func CreateMasterRoleIfNotExist() { - masterRoleId := handleMasterRolePermissions() + masterRoleId := HandleMasterRolePermissions() createDefaultAdminUser(masterRoleId) } @@ -83,7 +83,7 @@ func createDefaultAdminUser(masterRoleId string) { log.Info().Msgf("Password: %s", string(pw)) } -func handleMasterRolePermissions() (roleId string) { +func HandleMasterRolePermissions() (roleId string) { // create admin role if not already existing role := structs.Role{ Id: uuid.New().String(), diff --git a/modules/utils/globals.go b/modules/utils/globals.go index c6083c9..23dbfbe 100644 --- a/modules/utils/globals.go +++ b/modules/utils/globals.go @@ -51,78 +51,80 @@ var ( // commands sent to web clients const ( - SentCmdInitUserSocketConnection = 1 - SentCmdUpdateConnectedUsers = 2 - SentCmdNewGroupTaskStarted = 3 - SentCmdNewGroupTaskStep = 4 - SentCmdUpdateGroupTaskStep = 5 - SentCmdUpdateGroupTask = 6 - SentCmdReloadingGroupTasks = 7 - SentCmdGroupTasksReloaded = 8 - SentCmdUpdateUserSessions = 9 - SentCmdUpdateAllUsersUserAvatar = 10 - SentCmdNewScanner = 11 - SentCmdDeleteScanner = 12 - SentCmdUpdateScannerUsedBy = 13 - SentCmdScanResult = 14 - SentCmdUpdateScannerLastUsed = 15 - SentCmdTaskLocked = 16 - SentCmdTaskUnlocked = 17 - SentCmdUserProfileUpdated = 18 - SentCmdAdminAreaNewRoleCreated = 19 - SentCmdAdminAreaRoleUpdated = 20 - SentCmdAdminAreaUpdateRoleSortingOrder = 21 - SentCmdAdminAreaRoleDeleted = 22 - SentCmdAllUsersUserRoleUpdated = 23 - SentCmdRolePermissionsUpdated = 24 - SentCmdErrorNoPermissions = 25 - SentCmdAllUsersNewUserCreated = 26 - SentCmdAllUsersUserDeleted = 27 - SentCmdAllUsersUserDeactivation = 28 - SentCmdGroupTasksCategoryGroupChanges = 29 - SentCmdNewUserApiKeyCreated = 30 - SentCmdDeletedUserApiKey = 31 - SentCmdNewApiKeyUsageCount = 32 - SentCmdInstallingPythonPackages = 33 - SentCmdInstallingPythonPackagesFailed = 34 - SentCmdInstallingPythonPackagesFinished = 35 - SentCmdInstallingGlobalPythonPackages = 36 - SentCmdInstallingGlobalPythonPackagesFailed = 37 - SentCmdInstallingGlobalPythonPackagesFinished = 38 - SentCmdUpdateUsers = 39 - SentCmdCheckingForGroupTasksCategoryGroupChanges = 40 - SentCmdNewNotification = 41 - SentCmdAllNotificationsDeleted = 42 - SentCmdOneNotificationDeleted = 43 + SentCmdInitUserSocketConnection = 1 + SentCmdUpdateConnectedUsers = 2 + SentCmdNewGroupTaskStarted = 3 + SentCmdNewGroupTaskStep = 4 + SentCmdUpdateGroupTaskStep = 5 + SentCmdUpdateGroupTask = 6 + SentCmdReloadingGroupTasks = 7 + SentCmdGroupTasksReloaded = 8 + SentCmdUpdateUserSessions = 9 + SentCmdUpdateAllUsersUserAvatar = 10 + SentCmdNewScanner = 11 + SentCmdDeleteScanner = 12 + SentCmdUpdateScannerUsedBy = 13 + SentCmdScanResult = 14 + SentCmdUpdateScannerLastUsed = 15 + SentCmdTaskLocked = 16 + SentCmdTaskUnlocked = 17 + SentCmdUserProfileUpdated = 18 + SentCmdAdminAreaNewRoleCreated = 19 + SentCmdAdminAreaRoleUpdated = 20 + SentCmdAdminAreaUpdateRoleSortingOrder = 21 + SentCmdAdminAreaRoleDeleted = 22 + SentCmdAllUsersUserRoleUpdated = 23 + SentCmdRolePermissionsUpdated = 24 + SentCmdErrorNoPermissions = 25 + SentCmdAllUsersNewUserCreated = 26 + SentCmdAllUsersUserDeleted = 27 + SentCmdAllUsersUserDeactivation = 28 + SentCmdGroupTasksCategoryGroupChanges = 29 + SentCmdNewUserApiKeyCreated = 30 + SentCmdDeletedUserApiKey = 31 + SentCmdNewApiKeyUsageCount = 32 + SentCmdInstallingPythonPackages = 33 + SentCmdInstallingPythonPackagesFailed = 34 + SentCmdInstallingPythonPackagesFinished = 35 + SentCmdInstallingGlobalPythonPackages = 36 + SentCmdInstallingGlobalPythonPackagesFailed = 37 + SentCmdInstallingGlobalPythonPackagesFinished = 38 + SentCmdUpdateUsers = 39 + SentCmdCheckingForGroupTasksCategoryGroupChanges = 40 + SentCmdNewNotification = 41 + SentCmdAllNotificationsDeleted = 42 + SentCmdOneNotificationDeleted = 43 + SentCmdAdminAreaManageCheckedForAvailableCategories = 44 ) // commands received from web clients const ( - ReceivedCmdStartGroupTasks = 1 - ReceivedCmdTaskFailedTryAgainRunTaskStep = 2 - ReceivedCmdTaskContinueTaskStep = 3 - ReceivedCmdReloadGroupTasks = 4 - ReceivedCmdTaskLocking = 5 - ReceivedCmdUpdateUserProfile = 6 - ReceivedCmdAdminAreaCreateNewRole = 7 - ReceivedCmdAdminAreaUpdateRole = 8 - ReceivedCmdAdminAreaUpdateRoleSortingOrder = 9 - ReceivedCmdAdminAreaDeleteRole = 10 - ReceivedCmdAllUsersUpdateUserRole = 11 - ReceivedCmdAllUsersCreateNewUser = 12 - ReceivedCmdAllUsersDeleteUser = 13 - ReceivedCmdAllUsersUserDeactivation = 14 - ReceivedCmdScannersUseScanners = 15 - ReceivedCmdScannersDisconnectScanner = 16 - ReceivedCmdGroupTasksCheckingForCategoryGroupChanges = 17 - ReceivedCmdHandleUserActionTaskStep = 18 - ReceivedCmdCreateNewUserApiKey = 19 - ReceivedCmdDeleteUserApiKey = 20 - ReceivedCmdGroupTasksInstallPythonPackages = 21 - ReceivedCmdGroupTasksInstallGlobalPythonPackages = 22 - ReceivedCmdSubscribeToTopic = 23 - ReceivedCmdDeleteAllNotifications = 24 - ReceivedCmdDeleteOneNotification = 25 + ReceivedCmdStartGroupTasks = 1 + ReceivedCmdTaskFailedTryAgainRunTaskStep = 2 + ReceivedCmdTaskContinueTaskStep = 3 + ReceivedCmdReloadGroupTasks = 4 + ReceivedCmdTaskLocking = 5 + ReceivedCmdUpdateUserProfile = 6 + ReceivedCmdAdminAreaCreateNewRole = 7 + ReceivedCmdAdminAreaUpdateRole = 8 + ReceivedCmdAdminAreaUpdateRoleSortingOrder = 9 + ReceivedCmdAdminAreaDeleteRole = 10 + ReceivedCmdAllUsersUpdateUserRole = 11 + ReceivedCmdAllUsersCreateNewUser = 12 + ReceivedCmdAllUsersDeleteUser = 13 + ReceivedCmdAllUsersUserDeactivation = 14 + ReceivedCmdScannersUseScanners = 15 + ReceivedCmdScannersDisconnectScanner = 16 + ReceivedCmdGroupTasksCheckingForCategoryGroupChanges = 17 + ReceivedCmdHandleUserActionTaskStep = 18 + ReceivedCmdCreateNewUserApiKey = 19 + ReceivedCmdDeleteUserApiKey = 20 + ReceivedCmdGroupTasksInstallPythonPackages = 21 + ReceivedCmdGroupTasksInstallGlobalPythonPackages = 22 + ReceivedCmdSubscribeToTopic = 23 + ReceivedCmdDeleteAllNotifications = 24 + ReceivedCmdDeleteOneNotification = 25 + ReceivedCmdAdminAreaManageCheckWhichCategoriesAreAvailable = 26 ) const ( @@ -177,13 +179,15 @@ const ( PermissionAllUsersActionUserDeactivation = "all_users.action.user_deactivation" PermissionScannerUseScanners = "scanner.use_scanners" - _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" + _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" + PermissionAdminAreaManage = _adminArea + "manage" + PermissionAdminAreaManageCheckWhichCategoriesAreAvailable = _adminArea + "manage.check_which_categories_are_available" PermissionUserProfileApiKeys = "user_profile.api_keys" ) @@ -205,6 +209,8 @@ var SystemPermissions = []string{ PermissionAdminAreaDeleteRole, PermissionAdminAreaMoveRoleUpDown, PermissionAdminAreaLogs, + PermissionAdminAreaManage, + PermissionAdminAreaManageCheckWhichCategoriesAreAvailable, PermissionUserProfileApiKeys, } @@ -226,4 +232,6 @@ const ( SubscribedTopicAdminAreaRoles = "/admin-area/roles" SubscribedTopicUsers = "/users" SubscribedTopicUserProfile = "/user-profile" + + SubscribedTopicAdminAreaManage = "/admin-area/manage" ) diff --git a/routers/router/api/v1/user/user.go b/routers/router/api/v1/user/user.go index cb179f7..c03a51a 100644 --- a/routers/router/api/v1/user/user.go +++ b/routers/router/api/v1/user/user.go @@ -10,6 +10,7 @@ import ( "slices" "github.com/gofiber/fiber/v2" + "github.com/rs/zerolog/log" ) func UserInfo(c *fiber.Ctx) error { @@ -41,6 +42,8 @@ func UserInfo(c *fiber.Ctx) error { var categories []string for _, categoryGroup := range cache.GetCategoryGroups() { + log.Info().Msgf("categoryGroup: %s", categoryGroup.Category) + if socketclients.HasXYPermission(user.Id, utils.PermissionGroupTasksOverviewXYView, categoryGroup.Category) { categories = append(categories, categoryGroup.Category) } diff --git a/socketserver/hub.go b/socketserver/hub.go index 29aa415..d51a833 100644 --- a/socketserver/hub.go +++ b/socketserver/hub.go @@ -362,6 +362,19 @@ func RunHub() { break case utils.ReceivedCmdDeleteOneNotification: notification.DeleteOneNotification(data.Conn.Locals("userId").(string), receivedMessage.Body["notificationId"].(string)) + break + case utils.ReceivedCmdAdminAreaManageCheckWhichCategoriesAreAvailable: + if !socketclients.HasPermission(data.Conn.Locals("userId").(string), utils.PermissionAdminAreaManageCheckWhichCategoriesAreAvailable) { + socketclients.SendErrorMessageNoPermissions(data.Conn.Locals("sessionId").(string)) + } + + socketclients.BroadcastMessageToTopic( + utils.SubscribedTopicAdminAreaManage, + structs.SendSocketMessage{ + Cmd: utils.SentCmdAdminAreaManageCheckedForAvailableCategories, + Body: grouptasks.CheckWhichCategoriesAreAvailable(), + }) + break default: log.Error().Msgf("Received unknown message: %v", receivedMessage) break