@@ -25,9 +25,10 @@ type RBACManager struct {
2525 serverConfig * types.ServerConfig
2626 mu sync.RWMutex
2727
28- groups map [string ][]string // group name to user ids (with group hierarchy resolved)
29- roles map [string ][]types.RBACPermission // role name to permissions (with role: hierarchy resolved)
30- regexCache map [string ]* regexp.Regexp // cache of compiled regex patterns
28+ groups map [string ][]string // group name to user ids (with group hierarchy resolved)
29+ roles map [string ][]types.RBACPermission // role name to permissions (with role: hierarchy resolved)
30+ regexCache map [string ]* regexp.Regexp // cache of compiled regex patterns
31+ customPerms []string // custom permissions are permissions defined by the user. This list does not have the custom: prefix
3132}
3233
3334func NewRBACHandler (logger * types.Logger , rbacConfig * types.RBACConfig , serverConfig * types.ServerConfig ) (* RBACManager , error ) {
@@ -72,6 +73,43 @@ func (h *RBACManager) Authorize(user string, appPathDomain types.AppPathDomain,
7273 return h .checkGrants (user , appPathDomain , permission , groups , isAppLevelPermission )
7374}
7475
76+ // GetCustomPermissions returns the custom permissions set for the user for the given app path domain and app auth setting
77+ // Values in returned list do not have the custom: prefix
78+ func (h * RBACManager ) GetCustomPermissions (user string , appPathDomain types.AppPathDomain , appAuthSetting string ,
79+ groups []string ) ([]string , error ) {
80+ h .mu .RLock ()
81+ defer h .mu .RUnlock ()
82+
83+ if len (h .customPerms ) == 0 {
84+ return nil , nil
85+ }
86+
87+ if ! h .rbacConfig .Enabled {
88+ // rbac is not enabled, authorize all requests
89+ return h .customPerms , nil
90+ }
91+
92+ if user != "" && user == types .ADMIN_USER {
93+ // admin user is always authorized if enabled
94+ return h .customPerms , nil
95+ }
96+
97+ customPerms := make ([]string , 0 )
98+ for _ , perm := range h .customPerms {
99+ authorized , err := h .Authorize (user , appPathDomain , appAuthSetting , types .RBACPermission (perm ), groups , true )
100+ if err != nil {
101+ return nil , err
102+ }
103+ if authorized {
104+ customPerms = append (customPerms , perm )
105+ }
106+ }
107+
108+ h .Trace ().Msgf ("User %s has custom permissions: %v on app %s with auth setting %s groups %v" , user ,
109+ customPerms , appPathDomain .String (), appAuthSetting , groups )
110+ return customPerms , nil
111+ }
112+
75113func (h * RBACManager ) checkGrants (inputUser string , appPathDomain types.AppPathDomain ,
76114 inputPermission types.RBACPermission , groups []string , isAppLevelPermission bool ) (bool , error ) {
77115 for _ , grant := range h .rbacConfig .Grants {
@@ -290,6 +328,22 @@ func (h *RBACManager) initRoleInfo(rbacConfig *types.RBACConfig) (map[string][]t
290328 roles [role ] = permissions
291329 }
292330
331+ // Keep track of all custom perms (deduplicated)
332+ customPermsMap := make (map [string ]bool )
333+ for _ , role := range roles {
334+ for _ , permission := range role {
335+ if strings .HasPrefix (string (permission ), RBAC_CUSTOM_PREFIX ) {
336+ perm := string (permission )[len (RBAC_CUSTOM_PREFIX ):]
337+ customPermsMap [perm ] = true
338+ }
339+ }
340+ }
341+
342+ // Convert map to slice
343+ for perm := range customPermsMap {
344+ h .customPerms = append (h .customPerms , perm )
345+ }
346+
293347 return roles , nil
294348}
295349func (h * RBACManager ) validateGrants (rbacConfig * types.RBACConfig ) error {
@@ -326,6 +380,7 @@ func (h *RBACManager) UpdateRBACConfig(rbacConfig *types.RBACConfig) error {
326380
327381 h .rbacConfig = rbacConfig
328382 h .regexCache = make (map [string ]* regexp.Regexp )
383+ h .customPerms = make ([]string , 0 )
329384
330385 var err error
331386 h .groups , err = h .initGroupInfo (rbacConfig )
0 commit comments