package api import ( "errors" "net/http" "codeberg.org/SquidSE/ClusterCanvas/service/internal/settings" ) var errUsersManageRequired = errors.New("permission users.manage required") var errNodesReadRequired = errors.New("permission nodes.read required") var errNodesExecRequired = errors.New("permission nodes.exec required") // permissionsForUser returns the union of permissions from the user's groups. func permissionsForUser(user settings.UserCredential, groups []settings.Group) map[string]struct{} { groupByName := make(map[string]settings.Group, len(groups)) for _, group := range groups { groupByName[group.Name] = group } result := make(map[string]struct{}) for _, groupName := range user.GroupNames { group, ok := groupByName[groupName] if !ok { continue } for _, permission := range group.Permissions { result[permission] = struct{}{} } } return result } func userHasPermission(user settings.UserCredential, groups []settings.Group, permission string) bool { _, ok := permissionsForUser(user, groups)[permission] return ok } func permissionList(user settings.UserCredential, groups []settings.Group) []string { set := permissionsForUser(user, groups) ordered := allPermissionList() result := make([]string, 0, len(set)) for _, permission := range ordered { if _, ok := set[permission]; ok { result = append(result, permission) } } return result } func (app *App) authorizeUsersWrite(request *http.Request) error { user, ok := UserFromContext(request.Context()) if !ok { return errors.New("authentication required") } payload, err := loadSettingsOrDefault(app.ConfigDir) if err != nil { return err } if !userHasPermission(user, payload.Groups, "users.manage") { return errUsersManageRequired } return nil } func (app *App) authorizeNodesRead(request *http.Request) error { user, ok := UserFromContext(request.Context()) if !ok { return errors.New("authentication required") } payload, err := loadSettingsOrDefault(app.ConfigDir) if err != nil { return err } if !userHasPermission(user, payload.Groups, "nodes.read") { return errNodesReadRequired } return nil } func (app *App) authorizeNodesExec(request *http.Request) error { user, ok := UserFromContext(request.Context()) if !ok { return errors.New("authentication required") } payload, err := loadSettingsOrDefault(app.ConfigDir) if err != nil { return err } if !userHasPermission(user, payload.Groups, "nodes.exec") { return errNodesExecRequired } return nil }