|
|
|
@ -13,24 +13,30 @@ import ( |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
type flatResourcePermission struct { |
|
|
|
|
ID int64 `xorm:"id"` |
|
|
|
|
ResourceID string `xorm:"resource_id"` |
|
|
|
|
RoleName string |
|
|
|
|
Action string |
|
|
|
|
Scope string |
|
|
|
|
UserId int64 |
|
|
|
|
UserLogin string |
|
|
|
|
UserEmail string |
|
|
|
|
TeamId int64 |
|
|
|
|
TeamEmail string |
|
|
|
|
Team string |
|
|
|
|
BuiltInRole string |
|
|
|
|
Created time.Time |
|
|
|
|
Updated time.Time |
|
|
|
|
ID int64 `xorm:"id"` |
|
|
|
|
RoleName string |
|
|
|
|
Action string |
|
|
|
|
// Scope is what is stored in the database
|
|
|
|
|
Scope string |
|
|
|
|
// ResourceScope is what we ask for
|
|
|
|
|
ResourceScope string |
|
|
|
|
UserId int64 |
|
|
|
|
UserLogin string |
|
|
|
|
UserEmail string |
|
|
|
|
TeamId int64 |
|
|
|
|
TeamEmail string |
|
|
|
|
Team string |
|
|
|
|
BuiltInRole string |
|
|
|
|
Created time.Time |
|
|
|
|
Updated time.Time |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (p *flatResourcePermission) Managed() bool { |
|
|
|
|
return strings.HasPrefix(p.RoleName, "managed:") |
|
|
|
|
func (p *flatResourcePermission) IsManaged() bool { |
|
|
|
|
return strings.HasPrefix(p.RoleName, "managed:") && !p.IsInherited() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (p *flatResourcePermission) IsInherited() bool { |
|
|
|
|
return p.Scope != p.ResourceScope |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (s *AccessControlStore) SetUserResourcePermission( |
|
|
|
@ -236,7 +242,7 @@ func (s *AccessControlStore) setResourcePermission( |
|
|
|
|
keep = append(keep, id) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
permissions, err := s.getResourcePermissions(sess, cmd.ResourceID, keep) |
|
|
|
|
permissions, err := s.getResourcePermissionsByIds(sess, cmd.Resource, cmd.ResourceID, keep) |
|
|
|
|
if err != nil { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
@ -249,12 +255,12 @@ func (s *AccessControlStore) setResourcePermission( |
|
|
|
|
return permission, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (s *AccessControlStore) GetResourcesPermissions(ctx context.Context, orgID int64, query types.GetResourcesPermissionsQuery) ([]accesscontrol.ResourcePermission, error) { |
|
|
|
|
func (s *AccessControlStore) GetResourcePermissions(ctx context.Context, orgID int64, query types.GetResourcePermissionsQuery) ([]accesscontrol.ResourcePermission, error) { |
|
|
|
|
var result []accesscontrol.ResourcePermission |
|
|
|
|
|
|
|
|
|
err := s.sql.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { |
|
|
|
|
var err error |
|
|
|
|
result, err = s.getResourcesPermissions(sess, orgID, query) |
|
|
|
|
result, err = s.getResourcePermissions(sess, orgID, query) |
|
|
|
|
return err |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
@ -273,19 +279,16 @@ func (s *AccessControlStore) createResourcePermission(sess *sqlstore.DBSession, |
|
|
|
|
return permission.ID, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (s *AccessControlStore) getResourcesPermissions(sess *sqlstore.DBSession, orgID int64, query types.GetResourcesPermissionsQuery) ([]accesscontrol.ResourcePermission, error) { |
|
|
|
|
func (s *AccessControlStore) getResourcePermissions(sess *sqlstore.DBSession, orgID int64, query types.GetResourcePermissionsQuery) ([]accesscontrol.ResourcePermission, error) { |
|
|
|
|
if len(query.Actions) == 0 { |
|
|
|
|
return nil, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if len(query.ResourceIDs) == 0 { |
|
|
|
|
return nil, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
rawSelect := ` |
|
|
|
|
SELECT |
|
|
|
|
p.*, |
|
|
|
|
r.name as role_name, |
|
|
|
|
? as resource_scope, |
|
|
|
|
` |
|
|
|
|
|
|
|
|
|
userSelect := rawSelect + ` |
|
|
|
@ -334,25 +337,31 @@ func (s *AccessControlStore) getResourcesPermissions(sess *sqlstore.DBSession, o |
|
|
|
|
builtinFrom := rawFrom + ` |
|
|
|
|
INNER JOIN builtin_role br ON r.id = br.role_id AND (br.org_id = 0 OR br.org_id = ?) |
|
|
|
|
` |
|
|
|
|
where := ` |
|
|
|
|
WHERE (r.org_id = ? OR r.org_id = 0) |
|
|
|
|
AND (p.scope = '*' OR p.scope = ? OR p.scope = ? OR p.scope IN (?` + strings.Repeat(",?", len(query.ResourceIDs)-1) + `)) |
|
|
|
|
AND p.action IN (?` + strings.Repeat(",?", len(query.Actions)-1) + `) |
|
|
|
|
` |
|
|
|
|
|
|
|
|
|
if query.OnlyManaged { |
|
|
|
|
where += `AND r.name LIKE 'managed:%'` |
|
|
|
|
} |
|
|
|
|
where := `WHERE (r.org_id = ? OR r.org_id = 0) AND (p.scope = '*' OR p.scope = ? OR p.scope = ? OR p.scope = ?` |
|
|
|
|
|
|
|
|
|
scope := accesscontrol.GetResourceScope(query.Resource, query.ResourceID) |
|
|
|
|
|
|
|
|
|
args := []interface{}{ |
|
|
|
|
scope, |
|
|
|
|
orgID, |
|
|
|
|
orgID, |
|
|
|
|
accesscontrol.GetResourceAllScope(query.Resource), |
|
|
|
|
accesscontrol.GetResourceAllIDScope(query.Resource), |
|
|
|
|
scope, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if len(query.InheritedScopes) > 0 { |
|
|
|
|
where += ` OR p.scope IN(?` + strings.Repeat(",?", len(query.InheritedScopes)-1) + `)` |
|
|
|
|
for _, scope := range query.InheritedScopes { |
|
|
|
|
args = append(args, scope) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for _, id := range query.ResourceIDs { |
|
|
|
|
args = append(args, accesscontrol.GetResourceScope(query.Resource, id)) |
|
|
|
|
where += `) AND p.action IN (?` + strings.Repeat(",?", len(query.Actions)-1) + `)` |
|
|
|
|
|
|
|
|
|
if query.OnlyManaged { |
|
|
|
|
where += `AND r.name LIKE 'managed:%'` |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for _, a := range query.Actions { |
|
|
|
@ -386,33 +395,16 @@ func (s *AccessControlStore) getResourcesPermissions(sess *sqlstore.DBSession, o |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
scopeAll := accesscontrol.GetResourceAllScope(query.Resource) |
|
|
|
|
scopeAllIDs := accesscontrol.GetResourceAllIDScope(query.Resource) |
|
|
|
|
|
|
|
|
|
byResource := make(map[string][]flatResourcePermission) |
|
|
|
|
// Add resourceIds and generate permissions for `*`, `resource:*` and `resource:id:*`
|
|
|
|
|
for _, id := range query.ResourceIDs { |
|
|
|
|
scope := accesscontrol.GetResourceScope(query.Resource, id) |
|
|
|
|
for _, p := range queryResults { |
|
|
|
|
if p.Scope == scope || p.Scope == scopeAll || p.Scope == scopeAllIDs || p.Scope == "*" { |
|
|
|
|
p.ResourceID = id |
|
|
|
|
byResource[p.ResourceID] = append(byResource[p.ResourceID], p) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var result []accesscontrol.ResourcePermission |
|
|
|
|
for _, permissions := range byResource { |
|
|
|
|
users, teams, builtins := groupPermissionsByAssignment(permissions) |
|
|
|
|
for _, p := range users { |
|
|
|
|
result = append(result, flatPermissionsToResourcePermissions(p)...) |
|
|
|
|
} |
|
|
|
|
for _, p := range teams { |
|
|
|
|
result = append(result, flatPermissionsToResourcePermissions(p)...) |
|
|
|
|
} |
|
|
|
|
for _, p := range builtins { |
|
|
|
|
result = append(result, flatPermissionsToResourcePermissions(p)...) |
|
|
|
|
} |
|
|
|
|
users, teams, builtins := groupPermissionsByAssignment(queryResults) |
|
|
|
|
for _, p := range users { |
|
|
|
|
result = append(result, flatPermissionsToResourcePermissions(p)...) |
|
|
|
|
} |
|
|
|
|
for _, p := range teams { |
|
|
|
|
result = append(result, flatPermissionsToResourcePermissions(p)...) |
|
|
|
|
} |
|
|
|
|
for _, p := range builtins { |
|
|
|
|
result = append(result, flatPermissionsToResourcePermissions(p)...) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return result, nil |
|
|
|
@ -439,7 +431,7 @@ func groupPermissionsByAssignment(permissions []flatResourcePermission) (map[int |
|
|
|
|
func flatPermissionsToResourcePermissions(permissions []flatResourcePermission) []accesscontrol.ResourcePermission { |
|
|
|
|
var managed, provisioned []flatResourcePermission |
|
|
|
|
for _, p := range permissions { |
|
|
|
|
if p.Managed() { |
|
|
|
|
if p.IsManaged() { |
|
|
|
|
managed = append(managed, p) |
|
|
|
|
} else { |
|
|
|
|
provisioned = append(provisioned, p) |
|
|
|
@ -470,7 +462,6 @@ func flatPermissionsToResourcePermission(permissions []flatResourcePermission) * |
|
|
|
|
first := permissions[0] |
|
|
|
|
return &accesscontrol.ResourcePermission{ |
|
|
|
|
ID: first.ID, |
|
|
|
|
ResourceID: first.ResourceID, |
|
|
|
|
RoleName: first.RoleName, |
|
|
|
|
Actions: actions, |
|
|
|
|
Scope: first.Scope, |
|
|
|
@ -483,6 +474,7 @@ func flatPermissionsToResourcePermission(permissions []flatResourcePermission) * |
|
|
|
|
BuiltInRole: first.BuiltInRole, |
|
|
|
|
Created: first.Created, |
|
|
|
|
Updated: first.Updated, |
|
|
|
|
IsManaged: first.IsManaged(), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -582,7 +574,7 @@ func (s *AccessControlStore) getOrCreateManagedRole(sess *sqlstore.DBSession, or |
|
|
|
|
return &role, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (s *AccessControlStore) getResourcePermissions(sess *sqlstore.DBSession, resourceID string, ids []int64) ([]flatResourcePermission, error) { |
|
|
|
|
func (s *AccessControlStore) getResourcePermissionsByIds(sess *sqlstore.DBSession, resource, resourceID string, ids []int64) ([]flatResourcePermission, error) { |
|
|
|
|
var result []flatResourcePermission |
|
|
|
|
if len(ids) == 0 { |
|
|
|
|
return result, nil |
|
|
|
@ -590,7 +582,7 @@ func (s *AccessControlStore) getResourcePermissions(sess *sqlstore.DBSession, re |
|
|
|
|
rawSql := ` |
|
|
|
|
SELECT |
|
|
|
|
p.*, |
|
|
|
|
? AS resource_id, |
|
|
|
|
? as resource_scope, |
|
|
|
|
ur.user_id AS user_id, |
|
|
|
|
u.login AS user_login, |
|
|
|
|
u.email AS user_email, |
|
|
|
@ -610,7 +602,7 @@ func (s *AccessControlStore) getResourcePermissions(sess *sqlstore.DBSession, re |
|
|
|
|
` |
|
|
|
|
|
|
|
|
|
args := make([]interface{}, 0, len(ids)+1) |
|
|
|
|
args = append(args, resourceID) |
|
|
|
|
args = append(args, accesscontrol.GetResourceScope(resource, resourceID)) |
|
|
|
|
for _, id := range ids { |
|
|
|
|
args = append(args, id) |
|
|
|
|
} |
|
|
|
|