Zanzana: Initial dashboard search (#93093)

* Zanzana: Search in a background and compare results

* refactor

* Search with check

* instrument zanzana client

* add single_read option

* refactor

* refactor move check into separate function

* Fix tests

* refactor

* refactor getFindDashboardsFn

* add resource type to span attributes

* run ListObjects concurrently

* Use list and search in less cases

* adjust metrics buckets

* refactor: move Check and ListObjects to AccessControl implementation

* Revert "Fix tests"

This reverts commit b0c2f072a2.

* refactor: use own types for Check and ListObjects inside accesscontrol package

* Fix search scenario with low limit and empty query string

* more accurate search with checks

* revert

* fix linter

* Revert "revert"

This reverts commit ee5f14eea8.

* add search errors metric

* fix query performance under some conditions

* simplify check strategy

* fix pagination

* refactor findDashboardsZanzanaList

* Iterate over multiple pages while making check request

* refactor listUserResources

* avoid unnecessary db call

* remove unused zclient

* Add notes for SkipAccessControlFilter

* use more accurate check loop

* always use check for search with provided UIDs

* rename single_read to zanzana_only_evaluation

* refactor

* update go workspace

* fix linter

* don't use deprecated fields

* refactor

* fail if no org specified

* refactor

* initial integration tests

* Fix tests

* fix linter errors

* fix linter

* Fix tests

* review suggestions

Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com>

* fix limit

* refactor

* refactor tests

* fix db config in tests

* fix migrator (postgres)

---------

Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com>
This commit is contained in:
Alexander Zobnin
2024-10-04 12:27:10 +02:00
committed by GitHub
co-authored by Gabriel MABILLE
parent f403bc57d5
commit 5d724c2482
18 changed files with 619 additions and 29 deletions
+12 -10
View File
@@ -94,12 +94,12 @@ func (z *ZanzanaSynchroniser) Sync(ctx context.Context) error {
func managedPermissionsCollector(store db.DB) TupleCollector {
return func(ctx context.Context, tuples map[string][]*openfgav1.TupleKey) error {
const collectorID = "managed"
const query = `
query := `
SELECT u.uid as user_uid, t.uid as team_uid, p.action, p.kind, p.identifier, r.org_id
FROM permission p
INNER JOIN role r ON p.role_id = r.id
LEFT JOIN user_role ur ON r.id = ur.role_id
LEFT JOIN user u ON u.id = ur.user_id
LEFT JOIN ` + store.GetDialect().Quote("user") + ` u ON u.id = ur.user_id
LEFT JOIN team_role tr ON r.id = tr.role_id
LEFT JOIN team t ON tr.team_id = t.id
LEFT JOIN builtin_role br ON r.id = br.role_id
@@ -156,11 +156,11 @@ func teamMembershipCollector(store db.DB) TupleCollector {
defer span.End()
const collectorID = "team_membership"
const query = `
query := `
SELECT t.uid as team_uid, u.uid as user_uid, tm.permission
FROM team_member tm
INNER JOIN team t ON tm.team_id = t.id
INNER JOIN user u ON tm.user_id = u.id
INNER JOIN ` + store.GetDialect().Quote("user") + ` u ON tm.user_id = u.id
`
type membership struct {
@@ -253,8 +253,10 @@ func dashboardFolderCollector(store db.DB) TupleCollector {
defer span.End()
const collectorID = "folder"
const query = `
SELECT org_id, uid, folder_uid, is_folder FROM dashboard WHERE is_folder = 0 AND folder_uid IS NOT NULL
query := `
SELECT org_id, uid, folder_uid, is_folder FROM dashboard
WHERE is_folder = ` + store.GetDialect().BooleanStr(false) + `
AND folder_uid IS NOT NULL
`
type dashboard struct {
OrgID int64 `xorm:"org_id"`
@@ -426,10 +428,10 @@ func customRolesCollector(store db.DB) TupleCollector {
func basicRoleAssignemtCollector(store db.DB) TupleCollector {
return func(ctx context.Context, tuples map[string][]*openfgav1.TupleKey) error {
const collectorID = "basic_role_assignment"
const query = `
query := `
SELECT ou.org_id, u.uid as user_uid, ou.role as org_role, u.is_admin
FROM org_user ou
LEFT JOIN user u ON u.id = ou.user_id
LEFT JOIN ` + store.GetDialect().Quote("user") + ` u ON u.id = ou.user_id
`
type Assignment struct {
OrgID int64 `xorm:"org_id"`
@@ -474,11 +476,11 @@ func basicRoleAssignemtCollector(store db.DB) TupleCollector {
func userRoleAssignemtCollector(store db.DB) TupleCollector {
return func(ctx context.Context, tuples map[string][]*openfgav1.TupleKey) error {
const collectorID = "user_role_assignment"
const query = `
query := `
SELECT ur.org_id, u.uid AS user_uid, r.uid AS role_uid, r.name AS role_name
FROM user_role ur
LEFT JOIN role r ON r.id = ur.role_id
LEFT JOIN user u ON u.id = ur.user_id
LEFT JOIN ` + store.GetDialect().Quote("user") + ` u ON u.id = ur.user_id
WHERE r.name NOT LIKE 'managed:%'
`