|
|
@@ -21,38 +21,36 @@ func (p PermissionBits) Has(permission PermissionBits) bool {
|
|
|
return p&permission != 0
|
|
|
}
|
|
|
|
|
|
-func logAclNotMatched(cfg *config.Config, aclFunction string, user *authpublic.AuthenticatedUser, action *config.Action, acl *config.AccessControlList) {
|
|
|
+func logAclNotMatched(cfg *config.Config, aclFunction string, user *authpublic.AuthenticatedUser, resourceTitle string, acl *config.AccessControlList) {
|
|
|
if cfg.LogDebugOptions.AclNotMatched {
|
|
|
log.WithFields(log.Fields{
|
|
|
- "User": user.Username,
|
|
|
- "Action": action.Title,
|
|
|
- "ACL": acl.Name,
|
|
|
+ "User": user.Username,
|
|
|
+ "Resource": resourceTitle,
|
|
|
+ "ACL": acl.Name,
|
|
|
}).Debugf("%v - ACL Not Matched", aclFunction)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func logAclMatched(cfg *config.Config, aclFunction string, user *authpublic.AuthenticatedUser, action *config.Action, acl *config.AccessControlList) {
|
|
|
- actionTitle := "N/A"
|
|
|
-
|
|
|
- if action != nil {
|
|
|
- actionTitle = action.Title
|
|
|
+func logAclMatched(cfg *config.Config, aclFunction string, user *authpublic.AuthenticatedUser, resourceTitle string, acl *config.AccessControlList) {
|
|
|
+ if resourceTitle == "" {
|
|
|
+ resourceTitle = "N/A"
|
|
|
}
|
|
|
|
|
|
if cfg.LogDebugOptions.AclMatched {
|
|
|
log.WithFields(log.Fields{
|
|
|
- "User": user.Username,
|
|
|
- "Action": actionTitle,
|
|
|
- "ACL": acl.Name,
|
|
|
+ "User": user.Username,
|
|
|
+ "Resource": resourceTitle,
|
|
|
+ "ACL": acl.Name,
|
|
|
}).Debugf("%v - Matched ACL", aclFunction)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func logAclNoneMatched(cfg *config.Config, aclFunction string, user *authpublic.AuthenticatedUser, action *config.Action, defaultPermission bool) {
|
|
|
+func logAclNoneMatched(cfg *config.Config, aclFunction string, user *authpublic.AuthenticatedUser, resourceTitle string, defaultPermission bool) {
|
|
|
if cfg.LogDebugOptions.AclNoneMatched {
|
|
|
log.WithFields(log.Fields{
|
|
|
- "User": user.Username,
|
|
|
- "Action": action.Title,
|
|
|
- "Default": defaultPermission,
|
|
|
+ "User": user.Username,
|
|
|
+ "Resource": resourceTitle,
|
|
|
+ "Default": defaultPermission,
|
|
|
}).Debugf("%v - No ACLs Matched, returning default permission", aclFunction)
|
|
|
}
|
|
|
}
|
|
|
@@ -81,12 +79,12 @@ func permissionsConfigToBits(permissions config.PermissionsList) PermissionBits
|
|
|
return ret
|
|
|
}
|
|
|
|
|
|
-func aclCheck(requiredPermission PermissionBits, defaultValue bool, cfg *config.Config, aclFunction string, user *authpublic.AuthenticatedUser, action *config.Action) bool {
|
|
|
- relevantAcls := getRelevantAcls(cfg, action.Acls, user)
|
|
|
+func aclCheck(requiredPermission PermissionBits, defaultValue bool, cfg *config.Config, aclFunction string, user *authpublic.AuthenticatedUser, resourceTitle string, resourceAcls []string, includeAddToEvery bool) bool {
|
|
|
+ relevantAcls := getRelevantAcls(cfg, resourceAcls, user, includeAddToEvery)
|
|
|
|
|
|
if cfg.LogDebugOptions.AclCheckStarted {
|
|
|
log.WithFields(log.Fields{
|
|
|
- "actionTitle": action.Title,
|
|
|
+ "resourceTitle": resourceTitle,
|
|
|
"username": user.Username,
|
|
|
"usergroupLine": user.UsergroupLine,
|
|
|
"relevantAcls": len(relevantAcls),
|
|
|
@@ -98,27 +96,27 @@ func aclCheck(requiredPermission PermissionBits, defaultValue bool, cfg *config.
|
|
|
permissionBits := permissionsConfigToBits(acl.Permissions)
|
|
|
|
|
|
if permissionBits.Has(requiredPermission) {
|
|
|
- logAclMatched(cfg, aclFunction, user, action, acl)
|
|
|
+ logAclMatched(cfg, aclFunction, user, resourceTitle, acl)
|
|
|
|
|
|
return true
|
|
|
- } else {
|
|
|
- logAclNotMatched(cfg, aclFunction, user, action, acl)
|
|
|
}
|
|
|
+
|
|
|
+ logAclNotMatched(cfg, aclFunction, user, resourceTitle, acl)
|
|
|
}
|
|
|
|
|
|
- logAclNoneMatched(cfg, aclFunction, user, action, cfg.DefaultPermissions.Logs)
|
|
|
+ logAclNoneMatched(cfg, aclFunction, user, resourceTitle, defaultValue)
|
|
|
|
|
|
return defaultValue
|
|
|
}
|
|
|
|
|
|
// IsAllowedLogs checks if a AuthenticatedUser is allowed to view an action's logs
|
|
|
func IsAllowedLogs(cfg *config.Config, user *authpublic.AuthenticatedUser, action *config.Action) bool {
|
|
|
- return aclCheck(Logs, cfg.DefaultPermissions.Logs, cfg, "isAllowedLogs", user, action)
|
|
|
+ return aclCheck(Logs, cfg.DefaultPermissions.Logs, cfg, "isAllowedLogs", user, action.Title, action.Acls, true)
|
|
|
}
|
|
|
|
|
|
// IsAllowedExec checks if a AuthenticatedUser is allowed to execute an Action
|
|
|
func IsAllowedExec(cfg *config.Config, user *authpublic.AuthenticatedUser, action *config.Action) bool {
|
|
|
- return aclCheck(Exec, cfg.DefaultPermissions.Exec, cfg, "isAllowedExec", user, action)
|
|
|
+ return aclCheck(Exec, cfg.DefaultPermissions.Exec, cfg, "isAllowedExec", user, action.Title, action.Acls, true)
|
|
|
}
|
|
|
|
|
|
// IsAllowedView checks if a User is allowed to view an Action
|
|
|
@@ -127,36 +125,40 @@ func IsAllowedView(cfg *config.Config, user *authpublic.AuthenticatedUser, actio
|
|
|
return false
|
|
|
}
|
|
|
|
|
|
- return aclCheck(View, cfg.DefaultPermissions.View, cfg, "isAllowedView", user, action)
|
|
|
+ return aclCheck(View, cfg.DefaultPermissions.View, cfg, "isAllowedView", user, action.Title, action.Acls, true)
|
|
|
}
|
|
|
|
|
|
func IsAllowedKill(cfg *config.Config, user *authpublic.AuthenticatedUser, action *config.Action) bool {
|
|
|
- return aclCheck(Kill, cfg.DefaultPermissions.Kill, cfg, "isAllowedKill", user, action)
|
|
|
+ return aclCheck(Kill, cfg.DefaultPermissions.Kill, cfg, "isAllowedKill", user, action.Title, action.Acls, true)
|
|
|
}
|
|
|
|
|
|
-func isACLRelevantToAction(actionAcls []string, acl *config.AccessControlList, user *authpublic.AuthenticatedUser) bool {
|
|
|
- if !slices.Contains(user.Acls, acl.Name) {
|
|
|
- // If the user does not have this ACL, then it is not relevant
|
|
|
-
|
|
|
- return false
|
|
|
+// IsAllowedViewDashboard checks if a user may see a root dashboard.
|
|
|
+// Dashboards with no acls are unrestricted. AddToEveryAction does not apply.
|
|
|
+func IsAllowedViewDashboard(cfg *config.Config, user *authpublic.AuthenticatedUser, dashboard *config.DashboardComponent) bool {
|
|
|
+ if dashboard == nil || len(dashboard.Acls) == 0 {
|
|
|
+ return true
|
|
|
}
|
|
|
|
|
|
- if acl.AddToEveryAction {
|
|
|
- return true
|
|
|
+ return aclCheck(View, cfg.DefaultPermissions.View, cfg, "isAllowedViewDashboard", user, dashboard.Title, dashboard.Acls, false)
|
|
|
+}
|
|
|
+
|
|
|
+func isACLRelevant(resourceAcls []string, acl *config.AccessControlList, user *authpublic.AuthenticatedUser, includeAddToEvery bool) bool {
|
|
|
+ if !slices.Contains(user.Acls, acl.Name) {
|
|
|
+ return false
|
|
|
}
|
|
|
|
|
|
- if slices.Contains(actionAcls, acl.Name) {
|
|
|
+ if includeAddToEvery && acl.AddToEveryAction {
|
|
|
return true
|
|
|
}
|
|
|
|
|
|
- return false
|
|
|
+ return slices.Contains(resourceAcls, acl.Name)
|
|
|
}
|
|
|
|
|
|
-func getRelevantAcls(cfg *config.Config, actionAcls []string, user *authpublic.AuthenticatedUser) []*config.AccessControlList {
|
|
|
+func getRelevantAcls(cfg *config.Config, resourceAcls []string, user *authpublic.AuthenticatedUser, includeAddToEvery bool) []*config.AccessControlList {
|
|
|
var ret []*config.AccessControlList
|
|
|
|
|
|
for _, acl := range cfg.AccessControlLists {
|
|
|
- if isACLRelevantToAction(actionAcls, acl, user) {
|
|
|
+ if isACLRelevant(resourceAcls, acl, user, includeAddToEvery) {
|
|
|
ret = append(ret, acl)
|
|
|
}
|
|
|
}
|