Access control: Extend GetUserPermissions() to query permissions in org (#83392)

* Access control: Extend GetUserPermissions() to query permissions in specific org

* Use db query to fetch permissions in org

* refactor

* refactor

* use conditional join

* minor refactor

* Add test cases

* Search permissions correctly in OSS vs Enterprise

* Get permissions from memory

* Refactor

* remove unused func

* Add tests for GetUserPermissionsInOrg

* fix linter
This commit is contained in:
Alexander Zobnin
2024-03-04 13:29:13 +01:00
committed by GitHub
parent 67c062acc7
commit 82a88cc83f
9 changed files with 171 additions and 17 deletions
+23 -11
View File
@@ -36,8 +36,8 @@ func (s *AccessControlStore) GetUserPermissions(ctx context.Context, query acces
` + filter
if len(query.RolePrefixes) > 0 {
q += " WHERE ( " + strings.Repeat("role.name LIKE ? OR ", len(query.RolePrefixes))
q = q[:len(q)-4] + " )" // remove last " OR "
q += " WHERE ( " + strings.Repeat("role.name LIKE ? OR ", len(query.RolePrefixes)-1)
q += "role.name LIKE ? )"
for i := range query.RolePrefixes {
params = append(params, query.RolePrefixes[i]+"%")
}
@@ -53,7 +53,7 @@ func (s *AccessControlStore) GetUserPermissions(ctx context.Context, query acces
return result, err
}
// SearchUsersPermissions returns the list of user permissions indexed by UserID
// SearchUsersPermissions returns the list of user permissions in specific organization indexed by UserID
func (s *AccessControlStore) SearchUsersPermissions(ctx context.Context, orgID int64, options accesscontrol.SearchOptions) (map[int64][]accesscontrol.Permission, error) {
type UserRBACPermission struct {
UserID int64 `xorm:"user_id"`
@@ -61,7 +61,13 @@ func (s *AccessControlStore) SearchUsersPermissions(ctx context.Context, orgID i
Scope string `xorm:"scope"`
}
dbPerms := make([]UserRBACPermission, 0)
if err := s.sql.WithDbSession(ctx, func(sess *db.Session) error {
roleNameFilterJoin := ""
if len(options.RolePrefixes) > 0 {
roleNameFilterJoin = "INNER JOIN role AS r on up.role_id = r.id"
}
// Find permissions
q := `
SELECT
@@ -69,21 +75,21 @@ func (s *AccessControlStore) SearchUsersPermissions(ctx context.Context, orgID i
action,
scope
FROM (
SELECT ur.user_id, ur.org_id, p.action, p.scope
SELECT ur.user_id, ur.org_id, p.action, p.scope, ur.role_id
FROM permission AS p
INNER JOIN user_role AS ur on ur.role_id = p.role_id
UNION ALL
SELECT tm.user_id, tr.org_id, p.action, p.scope
SELECT tm.user_id, tr.org_id, p.action, p.scope, tr.role_id
FROM permission AS p
INNER JOIN team_role AS tr ON tr.role_id = p.role_id
INNER JOIN team_member AS tm ON tm.team_id = tr.team_id
UNION ALL
SELECT ou.user_id, ou.org_id, p.action, p.scope
SELECT ou.user_id, ou.org_id, p.action, p.scope, br.role_id
FROM permission AS p
INNER JOIN builtin_role AS br ON br.role_id = p.role_id
INNER JOIN org_user AS ou ON ou.role = br.role
UNION ALL
SELECT sa.user_id, br.org_id, p.action, p.scope
SELECT sa.user_id, br.org_id, p.action, p.scope, br.role_id
FROM permission AS p
INNER JOIN builtin_role AS br ON br.role_id = p.role_id
INNER JOIN (
@@ -91,8 +97,8 @@ func (s *AccessControlStore) SearchUsersPermissions(ctx context.Context, orgID i
FROM ` + s.sql.GetDialect().Quote("user") + ` AS u WHERE u.is_admin
) AS sa ON 1 = 1
WHERE br.role = ?
) AS up
WHERE (org_id = ? OR org_id = ?)
) AS up ` + roleNameFilterJoin + `
WHERE (up.org_id = ? OR up.org_id = ?)
`
params := []any{accesscontrol.RoleGrafanaAdmin, accesscontrol.GlobalOrgID, orgID}
@@ -121,9 +127,15 @@ func (s *AccessControlStore) SearchUsersPermissions(ctx context.Context, orgID i
q += ` AND user_id = ?`
params = append(params, userID)
}
if len(options.RolePrefixes) > 0 {
q += " AND ( " + strings.Repeat("r.name LIKE ? OR ", len(options.RolePrefixes)-1)
q += "r.name LIKE ? )"
for _, prefix := range options.RolePrefixes {
params = append(params, prefix+"%")
}
}
return sess.SQL(q, params...).
Find(&dbPerms)
return sess.SQL(q, params...).Find(&dbPerms)
}); err != nil {
return nil, err
}