mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Zanzana: handle service accounts (#97123)
* add service account to the schema * sync managed permissions for service accounts * sync SA basic roles * sync SA roles * Fix endless loop in reconciler while read openfga
This commit is contained in:
parent
feecd30687
commit
c8caf787d4
@ -115,7 +115,7 @@ func folderTreeCollector(store db.DB) legacyTupleCollector {
|
|||||||
func managedPermissionsCollector(store db.DB, kind string) legacyTupleCollector {
|
func managedPermissionsCollector(store db.DB, kind string) legacyTupleCollector {
|
||||||
return func(ctx context.Context, orgID int64) (map[string]map[string]*openfgav1.TupleKey, error) {
|
return func(ctx context.Context, orgID int64) (map[string]map[string]*openfgav1.TupleKey, error) {
|
||||||
query := `
|
query := `
|
||||||
SELECT u.uid as user_uid, t.uid as team_uid, p.action, p.kind, p.identifier, r.org_id, br.role as basic_role_name
|
SELECT u.uid as user_uid, u.is_service_account as is_service_account, t.uid as team_uid, p.action, p.kind, p.identifier, r.org_id, br.role as basic_role_name
|
||||||
FROM permission p
|
FROM permission p
|
||||||
INNER JOIN role r ON p.role_id = r.id
|
INNER JOIN role r ON p.role_id = r.id
|
||||||
LEFT JOIN user_role ur ON r.id = ur.role_id
|
LEFT JOIN user_role ur ON r.id = ur.role_id
|
||||||
@ -128,12 +128,13 @@ func managedPermissionsCollector(store db.DB, kind string) legacyTupleCollector
|
|||||||
AND p.kind = ?
|
AND p.kind = ?
|
||||||
`
|
`
|
||||||
type Permission struct {
|
type Permission struct {
|
||||||
Action string `xorm:"action"`
|
Action string `xorm:"action"`
|
||||||
Kind string
|
Kind string
|
||||||
Identifier string
|
Identifier string
|
||||||
UserUID string `xorm:"user_uid"`
|
UserUID string `xorm:"user_uid"`
|
||||||
TeamUID string `xorm:"team_uid"`
|
IsServiceAccount bool `xorm:"is_service_account"`
|
||||||
BasicRoleName string `xorm:"basic_role_name"`
|
TeamUID string `xorm:"team_uid"`
|
||||||
|
BasicRoleName string `xorm:"basic_role_name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var permissions []Permission
|
var permissions []Permission
|
||||||
@ -149,7 +150,9 @@ func managedPermissionsCollector(store db.DB, kind string) legacyTupleCollector
|
|||||||
|
|
||||||
for _, p := range permissions {
|
for _, p := range permissions {
|
||||||
var subject string
|
var subject string
|
||||||
if len(p.UserUID) > 0 {
|
if len(p.UserUID) > 0 && p.IsServiceAccount {
|
||||||
|
subject = zanzana.NewTupleEntry(zanzana.TypeServiceAccount, p.UserUID, "")
|
||||||
|
} else if len(p.UserUID) > 0 {
|
||||||
subject = zanzana.NewTupleEntry(zanzana.TypeUser, p.UserUID, "")
|
subject = zanzana.NewTupleEntry(zanzana.TypeUser, p.UserUID, "")
|
||||||
} else if len(p.TeamUID) > 0 {
|
} else if len(p.TeamUID) > 0 {
|
||||||
subject = zanzana.NewTupleEntry(zanzana.TypeTeam, p.TeamUID, zanzana.RelationTeamMember)
|
subject = zanzana.NewTupleEntry(zanzana.TypeTeam, p.TeamUID, zanzana.RelationTeamMember)
|
||||||
@ -198,16 +201,19 @@ func tupleStringWithoutCondition(tuple *openfgav1.TupleKey) string {
|
|||||||
func basicRoleBindingsCollector(store db.DB) legacyTupleCollector {
|
func basicRoleBindingsCollector(store db.DB) legacyTupleCollector {
|
||||||
return func(ctx context.Context, orgID int64) (map[string]map[string]*openfgav1.TupleKey, error) {
|
return func(ctx context.Context, orgID int64) (map[string]map[string]*openfgav1.TupleKey, error) {
|
||||||
query := `
|
query := `
|
||||||
SELECT ou.org_id, u.uid as user_uid, ou.role as org_role
|
SELECT
|
||||||
|
ou.org_id, u.uid as user_uid,
|
||||||
|
u.is_service_account as is_service_account,
|
||||||
|
ou.role as org_role
|
||||||
FROM org_user ou
|
FROM org_user ou
|
||||||
LEFT JOIN ` + store.GetDialect().Quote("user") + ` u ON u.id = ou.user_id
|
LEFT JOIN ` + store.GetDialect().Quote("user") + ` u ON u.id = ou.user_id
|
||||||
WHERE ou.org_id = ?
|
WHERE ou.org_id = ?
|
||||||
AND NOT u.is_service_account
|
|
||||||
`
|
`
|
||||||
// FIXME: handle service admin role
|
// FIXME: handle service admin role
|
||||||
type Binding struct {
|
type Binding struct {
|
||||||
UserUID string `xorm:"user_uid"`
|
UserUID string `xorm:"user_uid"`
|
||||||
OrgRole string `xorm:"org_role"`
|
IsServiceAccount bool `xorm:"is_service_account"`
|
||||||
|
OrgRole string `xorm:"org_role"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var bindings []Binding
|
var bindings []Binding
|
||||||
@ -222,8 +228,13 @@ func basicRoleBindingsCollector(store db.DB) legacyTupleCollector {
|
|||||||
tuples := make(map[string]map[string]*openfgav1.TupleKey)
|
tuples := make(map[string]map[string]*openfgav1.TupleKey)
|
||||||
|
|
||||||
for _, b := range bindings {
|
for _, b := range bindings {
|
||||||
|
userType := zanzana.TypeUser
|
||||||
|
if b.IsServiceAccount {
|
||||||
|
userType = zanzana.TypeServiceAccount
|
||||||
|
}
|
||||||
|
|
||||||
tuple := &openfgav1.TupleKey{
|
tuple := &openfgav1.TupleKey{
|
||||||
User: zanzana.NewTupleEntry(zanzana.TypeUser, b.UserUID, ""),
|
User: zanzana.NewTupleEntry(userType, b.UserUID, ""),
|
||||||
Relation: zanzana.RelationAssignee,
|
Relation: zanzana.RelationAssignee,
|
||||||
Object: zanzana.NewTupleEntry(zanzana.TypeRole, zanzana.TranslateBasicRole(b.OrgRole), ""),
|
Object: zanzana.NewTupleEntry(zanzana.TypeRole, zanzana.TranslateBasicRole(b.OrgRole), ""),
|
||||||
}
|
}
|
||||||
@ -286,7 +297,7 @@ func teamRoleBindingsCollector(store db.DB) legacyTupleCollector {
|
|||||||
func userRoleBindingsCollector(store db.DB) legacyTupleCollector {
|
func userRoleBindingsCollector(store db.DB) legacyTupleCollector {
|
||||||
return func(ctx context.Context, orgID int64) (map[string]map[string]*openfgav1.TupleKey, error) {
|
return func(ctx context.Context, orgID int64) (map[string]map[string]*openfgav1.TupleKey, error) {
|
||||||
query := `
|
query := `
|
||||||
SELECT u.uid AS user_uid, r.uid AS role_uid
|
SELECT u.uid AS user_uid, u.is_service_account as is_service_account, r.uid AS role_uid
|
||||||
FROM user_role ur
|
FROM user_role ur
|
||||||
INNER JOIN ` + store.GetDialect().Quote("user") + ` u ON ur.user_id = u.id
|
INNER JOIN ` + store.GetDialect().Quote("user") + ` u ON ur.user_id = u.id
|
||||||
INNER JOIN role r ON ur.role_id = r.id
|
INNER JOIN role r ON ur.role_id = r.id
|
||||||
@ -294,8 +305,9 @@ func userRoleBindingsCollector(store db.DB) legacyTupleCollector {
|
|||||||
AND r.name NOT LIKE 'managed:%'
|
AND r.name NOT LIKE 'managed:%'
|
||||||
`
|
`
|
||||||
type Binding struct {
|
type Binding struct {
|
||||||
UserUID string `xorm:"user_uid"`
|
UserUID string `xorm:"user_uid"`
|
||||||
RoleUID string `xorm:"role_uid"`
|
IsServiceAccount bool `xorm:"is_service_account"`
|
||||||
|
RoleUID string `xorm:"role_uid"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var bindings []Binding
|
var bindings []Binding
|
||||||
@ -310,8 +322,13 @@ func userRoleBindingsCollector(store db.DB) legacyTupleCollector {
|
|||||||
tuples := make(map[string]map[string]*openfgav1.TupleKey)
|
tuples := make(map[string]map[string]*openfgav1.TupleKey)
|
||||||
|
|
||||||
for _, b := range bindings {
|
for _, b := range bindings {
|
||||||
|
userType := zanzana.TypeUser
|
||||||
|
if b.IsServiceAccount {
|
||||||
|
userType = zanzana.TypeServiceAccount
|
||||||
|
}
|
||||||
|
|
||||||
tuple := &openfgav1.TupleKey{
|
tuple := &openfgav1.TupleKey{
|
||||||
User: zanzana.NewTupleEntry(zanzana.TypeUser, b.UserUID, ""),
|
User: zanzana.NewTupleEntry(userType, b.UserUID, ""),
|
||||||
Relation: zanzana.RelationAssignee,
|
Relation: zanzana.RelationAssignee,
|
||||||
Object: zanzana.NewTupleEntry(zanzana.TypeRole, b.RoleUID, ""),
|
Object: zanzana.NewTupleEntry(zanzana.TypeRole, b.RoleUID, ""),
|
||||||
}
|
}
|
||||||
@ -397,7 +414,8 @@ func zanzanaCollector(relations []string) zanzanaTupleCollector {
|
|||||||
|
|
||||||
for c != "" {
|
for c != "" {
|
||||||
res, err := client.Read(ctx, &authzextv1.ReadRequest{
|
res, err := client.Read(ctx, &authzextv1.ReadRequest{
|
||||||
Namespace: namespace,
|
ContinuationToken: c,
|
||||||
|
Namespace: namespace,
|
||||||
TupleKey: &authzextv1.ReadRequestTupleKey{
|
TupleKey: &authzextv1.ReadRequestTupleKey{
|
||||||
Object: object,
|
Object: object,
|
||||||
Relation: relation,
|
Relation: relation,
|
||||||
|
@ -10,12 +10,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
TypeUser string = "user"
|
TypeUser string = "user"
|
||||||
TypeTeam string = "team"
|
TypeServiceAccount string = "service-account"
|
||||||
TypeRole string = "role"
|
TypeTeam string = "team"
|
||||||
TypeFolder string = "folder"
|
TypeRole string = "role"
|
||||||
TypeResource string = "resource"
|
TypeFolder string = "folder"
|
||||||
TypeNamespace string = "namespace"
|
TypeResource string = "resource"
|
||||||
|
TypeNamespace string = "namespace"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -2,28 +2,30 @@ module core
|
|||||||
|
|
||||||
type namespace
|
type namespace
|
||||||
relations
|
relations
|
||||||
define view: [user, team#member, role#assignee] or edit
|
define view: [user, service-account, team#member, role#assignee] or edit
|
||||||
define edit: [user, team#member, role#assignee] or admin
|
define edit: [user, service-account, team#member, role#assignee] or admin
|
||||||
define admin: [user, team#member, role#assignee]
|
define admin: [user, service-account, team#member, role#assignee]
|
||||||
|
|
||||||
define read: [user, team#member, role#assignee] or view
|
define read: [user, service-account, team#member, role#assignee] or view
|
||||||
define create: [user, team#member, role#assignee] or edit
|
define create: [user, service-account, team#member, role#assignee] or edit
|
||||||
define write: [user, team#member, role#assignee] or edit
|
define write: [user, service-account, team#member, role#assignee] or edit
|
||||||
define delete: [user, team#member, role#assignee] or edit
|
define delete: [user, service-account, team#member, role#assignee] or edit
|
||||||
define permissions_read: [user, team#member, role#assignee] or admin
|
define permissions_read: [user, service-account, team#member, role#assignee] or admin
|
||||||
define permissions_write: [user, team#member, role#assignee] or admin
|
define permissions_write: [user, service-account, team#member, role#assignee] or admin
|
||||||
|
|
||||||
type user
|
type user
|
||||||
|
|
||||||
|
type service-account
|
||||||
|
|
||||||
type role
|
type role
|
||||||
relations
|
relations
|
||||||
define assignee: [user, team#member, role#assignee]
|
define assignee: [user, service-account, team#member, role#assignee]
|
||||||
|
|
||||||
type team
|
type team
|
||||||
relations
|
relations
|
||||||
# Action sets
|
# Action sets
|
||||||
define admin: [user]
|
define admin: [user, service-account]
|
||||||
define member: [user] or admin
|
define member: [user, service-account] or admin
|
||||||
|
|
||||||
define read: [role#assignee] or member
|
define read: [role#assignee] or member
|
||||||
define write: [role#assignee] or admin
|
define write: [role#assignee] or admin
|
||||||
|
@ -5,13 +5,13 @@ type folder
|
|||||||
define parent: [folder]
|
define parent: [folder]
|
||||||
|
|
||||||
# Action sets
|
# Action sets
|
||||||
define view: [user, team#member, role#assignee] or edit or view from parent
|
define view: [user, service-account, team#member, role#assignee] or edit or view from parent
|
||||||
define edit: [user, team#member, role#assignee] or admin or edit from parent
|
define edit: [user, service-account, team#member, role#assignee] or admin or edit from parent
|
||||||
define admin: [user, team#member, role#assignee] or admin from parent
|
define admin: [user, service-account, team#member, role#assignee] or admin from parent
|
||||||
|
|
||||||
define read: [user, team#member, role#assignee] or view or read from parent
|
define read: [user, service-account, team#member, role#assignee] or view or read from parent
|
||||||
define create: [user, team#member, role#assignee] or edit or create from parent
|
define create: [user, service-account, team#member, role#assignee] or edit or create from parent
|
||||||
define write: [user, team#member, role#assignee] or edit or write from parent
|
define write: [user, service-account, team#member, role#assignee] or edit or write from parent
|
||||||
define delete: [user, team#member, role#assignee] or edit or delete from parent
|
define delete: [user, service-account, team#member, role#assignee] or edit or delete from parent
|
||||||
define permissions_read: [user, team#member, role#assignee] or admin or permissions_read from parent
|
define permissions_read: [user, service-account, team#member, role#assignee] or admin or permissions_read from parent
|
||||||
define permissions_write: [user, team#member, role#assignee] or admin or permissions_write from parent
|
define permissions_write: [user, service-account, team#member, role#assignee] or admin or permissions_write from parent
|
||||||
|
@ -2,28 +2,28 @@ module resource
|
|||||||
|
|
||||||
extend type folder
|
extend type folder
|
||||||
relations
|
relations
|
||||||
define resource_view: [user, team#member, role#assignee] or resource_edit or resource_view from parent
|
define resource_view: [user, service-account, team#member, role#assignee] or resource_edit or resource_view from parent
|
||||||
define resource_edit: [user, team#member, role#assignee] or resource_admin or resource_edit from parent
|
define resource_edit: [user, service-account, team#member, role#assignee] or resource_admin or resource_edit from parent
|
||||||
define resource_admin: [user, team#member, role#assignee] or resource_admin from parent
|
define resource_admin: [user, service-account, team#member, role#assignee] or resource_admin from parent
|
||||||
|
|
||||||
define resource_read: [user with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_view or resource_read from parent
|
define resource_read: [user with folder_group_filter, service-account with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_view or resource_read from parent
|
||||||
define resource_create: [user with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_edit or resource_create from parent
|
define resource_create: [user with folder_group_filter, service-account with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_edit or resource_create from parent
|
||||||
define resource_write: [user with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_edit or resource_write from parent
|
define resource_write: [user with folder_group_filter, service-account with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_edit or resource_write from parent
|
||||||
define resource_delete: [user with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_edit or resource_delete from parent
|
define resource_delete: [user with folder_group_filter, service-account with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_edit or resource_delete from parent
|
||||||
define resource_permissions_read: [user with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_admin or resource_permissions_read from parent
|
define resource_permissions_read: [user with folder_group_filter, service-account with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_admin or resource_permissions_read from parent
|
||||||
define resource_permissions_write: [user with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_admin or resource_permissions_write from parent
|
define resource_permissions_write: [user with folder_group_filter, service-account with folder_group_filter, team#member with folder_group_filter, role#assignee with folder_group_filter] or resource_admin or resource_permissions_write from parent
|
||||||
|
|
||||||
type resource
|
type resource
|
||||||
relations
|
relations
|
||||||
define view: [user with group_filter, team#member with group_filter, role#assignee with group_filter] or edit
|
define view: [user with group_filter, service-account with group_filter, team#member with group_filter, role#assignee with group_filter] or edit
|
||||||
define edit: [user with group_filter, team#member with group_filter, role#assignee with group_filter] or admin
|
define edit: [user with group_filter, service-account with group_filter, team#member with group_filter, role#assignee with group_filter] or admin
|
||||||
define admin: [user with group_filter, team#member with group_filter, role#assignee with group_filter]
|
define admin: [user with group_filter, service-account with group_filter, team#member with group_filter, role#assignee with group_filter]
|
||||||
|
|
||||||
define read: [user with group_filter, team#member with group_filter, role#assignee with group_filter] or view
|
define read: [user with group_filter, service-account with group_filter, team#member with group_filter, role#assignee with group_filter] or view
|
||||||
define write: [user with group_filter, team#member with group_filter, role#assignee with group_filter] or edit
|
define write: [user with group_filter, service-account with group_filter, team#member with group_filter, role#assignee with group_filter] or edit
|
||||||
define delete: [user with group_filter, team#member with group_filter, role#assignee with group_filter] or edit
|
define delete: [user with group_filter, service-account with group_filter, team#member with group_filter, role#assignee with group_filter] or edit
|
||||||
define permissions_read: [user with group_filter, team#member with group_filter, role#assignee with group_filter] or admin
|
define permissions_read: [user with group_filter, service-account with group_filter, team#member with group_filter, role#assignee with group_filter] or admin
|
||||||
define permissions_write: [user with group_filter, team#member with group_filter, role#assignee with group_filter] or admin
|
define permissions_write: [user with group_filter, service-account with group_filter, team#member with group_filter, role#assignee with group_filter] or admin
|
||||||
|
|
||||||
condition group_filter(requested_group: string, group_resource: string) {
|
condition group_filter(requested_group: string, group_resource: string) {
|
||||||
requested_group == group_resource
|
requested_group == group_resource
|
||||||
|
@ -11,12 +11,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
TypeUser = common.TypeUser
|
TypeUser = common.TypeUser
|
||||||
TypeTeam = common.TypeTeam
|
TypeServiceAccount = common.TypeServiceAccount
|
||||||
TypeRole = common.TypeRole
|
TypeTeam = common.TypeTeam
|
||||||
TypeFolder = common.TypeFolder
|
TypeRole = common.TypeRole
|
||||||
TypeResource = common.TypeResource
|
TypeFolder = common.TypeFolder
|
||||||
TypeNamespace = common.TypeNamespace
|
TypeResource = common.TypeResource
|
||||||
|
TypeNamespace = common.TypeNamespace
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
Loading…
Reference in New Issue
Block a user