diff --git a/groupTasks/groups/baumeister copy/index.json b/groupTasks/groups/baumeister copy/index.json new file mode 100644 index 0000000..e1e95cf --- /dev/null +++ b/groupTasks/groups/baumeister copy/index.json @@ -0,0 +1,42 @@ +{ + "category": "BaumeisterGGG", + "name": "baumeister 4555", + "tasks": [ + { + "name": "Test1", + "onFinish": "pause", + "undoPossible": false, + "scriptPath": "", + "parameters": [] + }, + { + "name": "Test2", + "onFinish": "nextStep", + "undoPossible": false, + "scriptPath": "", + "parameters": [] + }, + { + "name": "Test3", + "onFinish": "nextStep", + "undoPossible": false, + "scriptPath": "", + "parameters": [] + }, + { + "name": "Test3", + "onFinish": "nextStep", + "undoPossible": false, + "scriptPath": "", + "parameters": [] + }, + { + "name": "Test3", + "onFinish": "nextStep", + "undoPossible": false, + "scriptPath": "", + "parameters": [] + } + ] + } + \ No newline at end of file diff --git a/groupTasks/groups/baumeister/index.json b/groupTasks/groups/baumeister/index.json new file mode 100644 index 0000000..06af8b9 --- /dev/null +++ b/groupTasks/groups/baumeister/index.json @@ -0,0 +1,42 @@ +{ + "category": "BaumeisterFFFF", + "name": "baumeister AAA", + "tasks": [ + { + "name": "Test1", + "onFinish": "pause", + "undoPossible": false, + "scriptPath": "", + "parameters": [] + }, + { + "name": "Test2", + "onFinish": "nextStep", + "undoPossible": false, + "scriptPath": "", + "parameters": [] + }, + { + "name": "Test3", + "onFinish": "nextStep", + "undoPossible": false, + "scriptPath": "", + "parameters": [] + }, + { + "name": "Test3", + "onFinish": "nextStep", + "undoPossible": false, + "scriptPath": "", + "parameters": [] + }, + { + "name": "Test3", + "onFinish": "nextStep", + "undoPossible": false, + "scriptPath": "", + "parameters": [] + } + ] + } + \ No newline at end of file diff --git a/main.go b/main.go index ccd24da..171ab38 100644 --- a/main.go +++ b/main.go @@ -34,7 +34,7 @@ func init() { utils.ValidatorInit() logger.InitLanguageLogMessages() systempermissions.InitSystemPermissions() - grouptasks.LoadGroups("") + grouptasks.InitLoadCategoryGroups() database.InitDatabase() } diff --git a/modules/cache/categorygroup.go b/modules/cache/categorygroup.go index 080cfc9..0692da1 100644 --- a/modules/cache/categorygroup.go +++ b/modules/cache/categorygroup.go @@ -25,10 +25,22 @@ func AddCategoryGroup(group structs.Group) { } categoryGroup.Groups = append(categoryGroup.Groups, group) - categoryGroups = append(categoryGroups, categoryGroup) } +func GetCategoryGroupByCategory(category string) structs.CategoryGroup { + cgMu.RLock() + defer cgMu.RUnlock() + + for _, categoryGroup := range categoryGroups { + if categoryGroup.Category == category { + return categoryGroup + } + } + + return structs.CategoryGroup{} +} + func RemoveAllCategoryGroupsByCategory(category string) { for index, categoryGroup := range GetCategoryGroups() { if categoryGroup.Category == category { diff --git a/modules/cache/systempermissions.go b/modules/cache/systempermissions.go index 97fad56..1d0b8c1 100644 --- a/modules/cache/systempermissions.go +++ b/modules/cache/systempermissions.go @@ -1,6 +1,10 @@ package cache -import "sync" +import ( + "sync" + + "github.com/rs/zerolog/log" +) var systemPermissions []string var sp sync.RWMutex @@ -22,6 +26,20 @@ func AddSystemPermissions(permissions []string) { sp.Unlock() } +func DeleteSystemPermissions(permissions []string) { + sp.Lock() + + for i, permission := range permissions { + if systemPermissions[i] == permission { + log.Debug().Msgf("delete permission %s", permission) + systemPermissions = removeSystemPermission(systemPermissions, i) + } + } + + sp.Unlock() +} + +/* func DeleteSystemPermission(permission string) { sp.Lock() @@ -33,7 +51,7 @@ func DeleteSystemPermission(permission string) { } sp.Unlock() -} +} */ func removeSystemPermission(permissions []string, i int) []string { return append(permissions[:i], permissions[i+1:]...) diff --git a/modules/grouptasks/grouptasks.go b/modules/grouptasks/grouptasks.go index 09f294a..a410b78 100644 --- a/modules/grouptasks/grouptasks.go +++ b/modules/grouptasks/grouptasks.go @@ -13,7 +13,6 @@ import ( "janex/admin-dashboard-backend/modules/systempermissions" "janex/admin-dashboard-backend/modules/utils" "janex/admin-dashboard-backend/socketclients" - llog "log" "os" "os/exec" "path/filepath" @@ -24,23 +23,22 @@ import ( "github.com/rs/zerolog/log" ) -func LoadGroups(category string) { +func InitLoadCategoryGroups() { entries, err := os.ReadDir(config.Cfg.FolderPaths.GroupTasksGroups) if err != nil { - llog.Fatal(err) - return + panic(err) } - if category != "" { - cache.RemoveAllCategoryGroupsByCategory(category) - } - - var updatedGroups []structs.Group - for _, entry := range entries { + if !entry.IsDir() { + continue + } + 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 @@ -61,31 +59,332 @@ func LoadGroups(category string) { group.Id = entry.Name() - if category == "" || group.Category == category { + cache.AddCategoryGroup(group) + } + } + } + + systempermissions.AddDynamicGroupTasksPermissions() +} + +func ReloadCategoryGroups(category string) { + entries, err := os.ReadDir(config.Cfg.FolderPaths.GroupTasksGroups) + + if err != nil { + panic(err) + } + + cache.RemoveAllCategoryGroupsByCategory(category) + + var categoryGroups []structs.Group + + // looping through groups directory + for _, entry := range entries { + if !entry.IsDir() { + continue + } + + 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 + } + + 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 + } + + var group structs.Group + + json.Unmarshal(content, &group) + + group.Id = entry.Name() + + if group.Category == category { cache.AddCategoryGroup(group) - updatedGroups = append(updatedGroups, group) + log.Debug().Msgf("added group %v", group) + + categoryGroups = append(categoryGroups, group) + } else { + log.Debug().Msgf("not added group %v", group) } } } } - if category != "" { + log.Debug().Msgf("categoryGroups %v", categoryGroups) + + if len(categoryGroups) > 0 { socketclients.BroadcastMessage(structs.SendSocketMessage{ Cmd: utils.SentCmdGroupTasksReloaded, Body: struct { - Category string - UpdatedGroups []structs.Group + Category string + CategoryGroups []structs.Group }{ - Category: category, - UpdatedGroups: updatedGroups, + Category: category, + CategoryGroups: categoryGroups, + }, + }) + } else { // category was removed + socketclients.BroadcastMessage(structs.SendSocketMessage{ + Cmd: utils.SentCmdGroupTasksReloaded, + Body: struct { + RemovedCategory string + RemovedPermissions []string + }{ + RemovedCategory: category, + RemovedPermissions: systempermissions.RemoveDynamicGroupTasksPermissionsByCategory(category), }, }) } - - systempermissions.AddDynamicGroupTasksPermissions() } +func LookingForCategoryGroupChanges() { + entries, err := os.ReadDir(config.Cfg.FolderPaths.GroupTasksGroups) + + if err != nil { + panic(err) + } + + var foundCategoryGroups []structs.Group + + // looping through groups directory + for _, entry := range entries { + if !entry.IsDir() { + continue + } + + 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 + } + + 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 + } + + var group structs.Group + + json.Unmarshal(content, &group) + + group.Id = entry.Name() + + foundCategoryGroups = append(foundCategoryGroups, group) + } + } + } + + cachedCategoryGroups := cache.GetCategoryGroups() + var newGroupTasksPermissions []string + var newCategories []string + + var newCategoryGroups []structs.CategoryGroup + + for _, foundCategoryGroup := range foundCategoryGroups { + // check for new added category groups + if !existsCategoryGroup(foundCategoryGroup.Category, cachedCategoryGroups) { + cache.AddCategoryGroup(foundCategoryGroup) + + if !isInList(foundCategoryGroup.Category, newCategories) { + newCategories = append(newCategories, foundCategoryGroup.Category) + } + } + } + + log.Debug().Msgf("new categories %v", newCategories) + + for _, newCategory := range newCategories { + dynamicPermissions := systempermissions.AddDynamicGroupTasksPermissionsByCategory(newCategory) + newGroupTasksPermissions = append(newGroupTasksPermissions, dynamicPermissions...) + cache.AddSystemPermissions(dynamicPermissions) + + cGroup := cache.GetCategoryGroupByCategory(newCategory) + newCategoryGroups = append(newCategoryGroups, cGroup) + } + + var removedCategoryGroups []string + var removedGroupTasksPermissions []string + + for _, cachedCategoryGroup := range cachedCategoryGroups { + if !existsGroup(cachedCategoryGroup.Category, foundCategoryGroups) { + removedCategoryGroups = append(removedCategoryGroups, cachedCategoryGroup.Category) + cache.RemoveAllCategoryGroupsByCategory(cachedCategoryGroup.Category) + + removedGroupTasksPermissions = append(removedGroupTasksPermissions, systempermissions.RemoveDynamicGroupTasksPermissionsByCategory(cachedCategoryGroup.Category)...) + } + } + + log.Debug().Msgf("New permissions %v", newGroupTasksPermissions) + log.Debug().Msgf("New category groups %v", newCategoryGroups) + log.Debug().Msgf("Removed category groups %v", removedCategoryGroups) + log.Debug().Msgf("Removed permissions %v", removedGroupTasksPermissions) + + socketclients.BroadcastMessage(structs.SendSocketMessage{ + Cmd: utils.SentCmdGroupTasksCategoryGroupChanges, + Body: struct { + NewPermissions []string + NewCategoryGroups []structs.CategoryGroup + RemovedCategoryGroups []string + RemovedPermissions []string + }{ + NewPermissions: newGroupTasksPermissions, + NewCategoryGroups: newCategoryGroups, + RemovedCategoryGroups: removedCategoryGroups, + RemovedPermissions: removedGroupTasksPermissions, + }}) +} + +func isInList(value string, list []string) bool { + for _, x := range list { + if x == value { + return true + } + } + + return false +} + +func existsCategoryGroup(category string, categoryGroupsList []structs.CategoryGroup) bool { + for _, categoryGroup := range categoryGroupsList { + if categoryGroup.Category == category { + return true + } + } + + return false +} + +func existsGroup(category string, groupsList []structs.Group) bool { + for _, group := range groupsList { + if group.Category == category { + return true + } + } + + return false +} + +/* +func LoadGroups(loadingType uint8, category string) { + entries, err := os.ReadDir(config.Cfg.FolderPaths.GroupTasksGroups) + + if err != nil { + panic(err) + } + + if loadingType == LoadingTypeCategoryReload { + cache.RemoveAllCategoryGroupsByCategory(category) + } + + /* + - ordner gelöscht + - ordner dazu gekommen +*/ +/* + var categoryGroups []structs.Group + //var deletedCategories []string + + // looping through groups directory + for _, entry := range entries { + if !entry.IsDir() { + continue + } + + if loadingType == LoadingTypeCheckingForChanges { + // + entry nicht in category group list = neuer dazu gekommen + // - entry in der liste aber kein ordner dafür = ein task gelöscht + } + + 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 + } + + 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 + } + + var group structs.Group + + json.Unmarshal(content, &group) + + group.Id = entry.Name() + + if loadingType == LoadingTypeInit || + loadingType == LoadingTypeCategoryReload && group.Category == category || + loadingType == LoadingTypeCheckingForChanges { + cache.AddCategoryGroup(group) + + log.Debug().Msgf("added group %v", group) + + categoryGroups = append(categoryGroups, group) + } else { + log.Debug().Msgf("not added group %v", group) + } + } + } + } + + if loadingType == LoadingTypeCategoryReload { + log.Debug().Msgf("categoryGroups %v", categoryGroups) + + if len(categoryGroups) > 0 { + socketclients.BroadcastMessage(structs.SendSocketMessage{ + Cmd: utils.SentCmdGroupTasksReloaded, + Body: struct { + Category string + CategoryGroups []structs.Group + }{ + Category: category, + CategoryGroups: categoryGroups, + }, + }) + } else { // category was removed + socketclients.BroadcastMessage(structs.SendSocketMessage{ + Cmd: utils.SentCmdGroupTasksCategoryGroupsUpdate, + Body: struct { + RemovedCategory string + }{ + RemovedCategory: category, + }, + }) + + // TODO: remove dynmaic group permissions + } + } + + if loadingType == LoadingTypeInit { + systempermissions.AddDynamicGroupTasksPermissions() + } +} */ + const ( RunGroupTaskStartTypeNormal = 0 RunGroupTaskStartTypeTryAgain = 1 @@ -488,7 +787,7 @@ func StartUnlockLockedGroupTaskStepsTicker() { for range ticker.C { for index, taskStep := range cache.GetLockedGroupTaskSteps() { - if time.Since(taskStep.LockedAt).Seconds() > 3 { + if time.Since(taskStep.LockedAt).Seconds() > utils.GroupTaskLockedTime { cache.RemoveLockedGroupTaskStep(index) socketclients.BroadcastMessage( diff --git a/modules/systempermissions/systempermissions.go b/modules/systempermissions/systempermissions.go index 0150e29..e5eda27 100644 --- a/modules/systempermissions/systempermissions.go +++ b/modules/systempermissions/systempermissions.go @@ -4,11 +4,14 @@ import ( "janex/admin-dashboard-backend/modules/cache" "janex/admin-dashboard-backend/modules/utils" "strings" + + "github.com/rs/zerolog/log" ) func InitSystemPermissions() { cache.AddSystemPermissions([]string{ utils.PermissionGroupTasksHistory, + utils.PermissionGroupTasksCheckingForCategoryGroupChanges, utils.PermissionAllUsersActionChangeRole, utils.PermissionAllUsersActionDeleteUser, utils.PermissionAllUsersActionUserDeactivation, @@ -24,22 +27,43 @@ func InitSystemPermissions() { // 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, - } + var newGroupTasksPermissions []string for _, categoryGroup := range cache.GetCategoryGroups() { - for _, dynamicGroupTasksPermission := range dynamicGroupTasksPermissions { - groupTasksPermissions = append(groupTasksPermissions, ConvertXYPermission(dynamicGroupTasksPermission, categoryGroup.Category)) + for _, dynamicGroupTasksPermission := range utils.DynamicGroupTasksPermissions { + newGroupTasksPermissions = append(newGroupTasksPermissions, ConvertXYPermission(dynamicGroupTasksPermission, categoryGroup.Category)) } } - cache.AddSystemPermissions(groupTasksPermissions) + cache.AddSystemPermissions(newGroupTasksPermissions) +} + +func AddDynamicGroupTasksPermissionsByCategory(category string) []string { + var newGroupTasksPermissions []string + + for _, dynamicGroupTasksPermission := range utils.DynamicGroupTasksPermissions { + newGroupTasksPermissions = append(newGroupTasksPermissions, ConvertXYPermission(dynamicGroupTasksPermission, category)) + } + + log.Debug().Msgf("AddDynamicGroupTasksPermissionsByCategory: %v", newGroupTasksPermissions) + + cache.AddSystemPermissions(newGroupTasksPermissions) + + return newGroupTasksPermissions +} + +func RemoveDynamicGroupTasksPermissionsByCategory(category string) []string { + var permissions []string + + for _, dynamicGroupTasksPermission := range utils.DynamicGroupTasksPermissions { + permissions = append(permissions, ConvertXYPermission(dynamicGroupTasksPermission, category)) + } + + log.Debug().Msgf("DynamicGroupTasksPermissions %v", permissions) + + cache.DeleteSystemPermissions(permissions) + + return permissions } func ConvertXYPermission(permission string, category string) string { diff --git a/modules/utils/globals.go b/modules/utils/globals.go index acb7b41..f4e2098 100644 --- a/modules/utils/globals.go +++ b/modules/utils/globals.go @@ -60,26 +60,28 @@ const ( SentCmdAllUsersNewUserCreated = 26 SentCmdAllUsersUserDeleted = 27 SentCmdAllUsersUserDeactivation = 28 + SentCmdGroupTasksCategoryGroupChanges = 29 ) // 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 + 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 ) const ( @@ -99,12 +101,19 @@ var ( } ) +var DynamicGroupTasksPermissions = []string{ + PermissionGroupTasksOverviewXYNewTask, + PermissionGroupTasksOverviewXYReloadGroupConfig, + PermissionGroupTasksOverviewXYView, +} + const ( - _groupTasks = "group_tasks." - PermissionGroupTasksOverviewXYNewTask = _groupTasks + "overview.XY.new_task" - PermissionGroupTasksOverviewXYReloadGroupConfig = _groupTasks + "overview.XY.reload_group_config" - PermissionGroupTasksOverviewXYView = _groupTasks + "overview.XY.view" - 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" + PermissionGroupTasksCheckingForCategoryGroupChanges = _groupTasks + "checking_for_category_group_changes" PermissionAllUsersCreateNewUser = "all_users.create_new_user" PermissionAllUsersActionChangeRole = "all_users.action.change_role" diff --git a/socketserver/hub.go b/socketserver/hub.go index 0c18d29..42abd15 100644 --- a/socketserver/hub.go +++ b/socketserver/hub.go @@ -221,7 +221,7 @@ func RunHub() { Body: category, }) - grouptasks.LoadGroups(category) + grouptasks.ReloadCategoryGroups(category) logger.AddGroupTasksLog(structs.LogMessage{ Id: 1, @@ -358,6 +358,14 @@ func RunHub() { socketclients.ScannersUpdateScannerUsedByUserId("", receivedMessage.Body["ScannerId"].(string)) break + case utils.ReceivedCmdGroupTasksCheckingForCategoryGroupChanges: + if !socketclients.HasPermission(data.Conn.Locals("userId").(string), utils.PermissionGroupTasksCheckingForCategoryGroupChanges) { + socketclients.SendErrorMessageNoPermissions(data.Conn.Locals("sessionId").(string)) + break + } + + grouptasks.LookingForCategoryGroupChanges() + break default: log.Error().Msgf("Received unknown message: %v", receivedMessage)