mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 21:17:32 +00:00
feat: updating eventstore.permitted_orgs sql function (#9309)
# Which Problems Are Solved Performance issue for GRPC call `zitadel.user.v2.UserService.ListUsers` due to lack of org filtering on `ListUsers` # Additional Context Replace this example with links to related issues, discussions, discord threads, or other sources with more context. Use the Closing #issue syntax for issues that are resolved with this PR. - Closes https://github.com/zitadel/zitadel/issues/9191 --------- Co-authored-by: Iraq Jaber <IraqJaber@gmail.com> Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
This commit is contained in:
39
cmd/setup/49.go
Normal file
39
cmd/setup/49.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package setup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"embed"
|
||||
"fmt"
|
||||
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
)
|
||||
|
||||
type InitPermittedOrgsFunction struct {
|
||||
eventstoreClient *database.DB
|
||||
}
|
||||
|
||||
var (
|
||||
//go:embed 49/*.sql
|
||||
permittedOrgsFunction embed.FS
|
||||
)
|
||||
|
||||
func (mig *InitPermittedOrgsFunction) Execute(ctx context.Context, _ eventstore.Event) error {
|
||||
statements, err := readStatements(permittedOrgsFunction, "49", "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, stmt := range statements {
|
||||
logging.WithFields("file", stmt.file, "migration", mig.String()).Info("execute statement")
|
||||
if _, err := mig.eventstoreClient.ExecContext(ctx, stmt.query); err != nil {
|
||||
return fmt.Errorf("%s %s: %w", mig.String(), stmt.file, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*InitPermittedOrgsFunction) String() string {
|
||||
return "49_init_permitted_orgs_function"
|
||||
}
|
56
cmd/setup/49/01-permitted_orgs_function.sql
Normal file
56
cmd/setup/49/01-permitted_orgs_function.sql
Normal file
@@ -0,0 +1,56 @@
|
||||
DROP FUNCTION IF EXISTS eventstore.permitted_orgs;
|
||||
|
||||
CREATE OR REPLACE FUNCTION eventstore.permitted_orgs(
|
||||
instanceId TEXT
|
||||
, userId TEXT
|
||||
, perm TEXT
|
||||
, filter_orgs TEXT
|
||||
|
||||
, org_ids OUT TEXT[]
|
||||
)
|
||||
LANGUAGE 'plpgsql'
|
||||
STABLE
|
||||
AS $$
|
||||
DECLARE
|
||||
matched_roles TEXT[]; -- roles containing permission
|
||||
BEGIN
|
||||
SELECT array_agg(rp.role) INTO matched_roles
|
||||
FROM eventstore.role_permissions rp
|
||||
WHERE rp.instance_id = instanceId
|
||||
AND rp.permission = perm;
|
||||
|
||||
-- First try if the permission was granted thru an instance-level role
|
||||
DECLARE
|
||||
has_instance_permission bool;
|
||||
BEGIN
|
||||
SELECT true INTO has_instance_permission
|
||||
FROM eventstore.instance_members im
|
||||
WHERE im.role = ANY(matched_roles)
|
||||
AND im.instance_id = instanceId
|
||||
AND im.user_id = userId
|
||||
LIMIT 1;
|
||||
|
||||
IF has_instance_permission THEN
|
||||
-- Return all organizations or only those in filter_orgs
|
||||
SELECT array_agg(o.org_id) INTO org_ids
|
||||
FROM eventstore.instance_orgs o
|
||||
WHERE o.instance_id = instanceId
|
||||
AND CASE WHEN filter_orgs != ''
|
||||
THEN o.org_id IN (filter_orgs)
|
||||
ELSE TRUE END;
|
||||
RETURN;
|
||||
END IF;
|
||||
END;
|
||||
|
||||
-- Return the organizations where permission were granted thru org-level roles
|
||||
SELECT array_agg(org_id) INTO org_ids
|
||||
FROM (
|
||||
SELECT DISTINCT om.org_id
|
||||
FROM eventstore.org_members om
|
||||
WHERE om.role = ANY(matched_roles)
|
||||
AND om.instance_id = instanceID
|
||||
AND om.user_id = userId
|
||||
);
|
||||
RETURN;
|
||||
END;
|
||||
$$;
|
@@ -137,6 +137,7 @@ type Steps struct {
|
||||
s46InitPermissionFunctions *InitPermissionFunctions
|
||||
s47FillMembershipFields *FillMembershipFields
|
||||
s48Apps7SAMLConfigsLoginVersion *Apps7SAMLConfigsLoginVersion
|
||||
s49InitPermittedOrgsFunction *InitPermittedOrgsFunction
|
||||
}
|
||||
|
||||
func MustNewSteps(v *viper.Viper) *Steps {
|
||||
|
@@ -174,6 +174,7 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
|
||||
steps.s46InitPermissionFunctions = &InitPermissionFunctions{eventstoreClient: dbClient}
|
||||
steps.s47FillMembershipFields = &FillMembershipFields{eventstore: eventstoreClient}
|
||||
steps.s48Apps7SAMLConfigsLoginVersion = &Apps7SAMLConfigsLoginVersion{dbClient: dbClient}
|
||||
steps.s49InitPermittedOrgsFunction = &InitPermittedOrgsFunction{eventstoreClient: dbClient}
|
||||
|
||||
err = projection.Create(ctx, dbClient, eventstoreClient, config.Projections, nil, nil, nil)
|
||||
logging.OnError(err).Fatal("unable to start projections")
|
||||
@@ -238,6 +239,7 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
|
||||
steps.s45CorrectProjectOwners,
|
||||
steps.s46InitPermissionFunctions,
|
||||
steps.s47FillMembershipFields,
|
||||
steps.s49InitPermittedOrgsFunction,
|
||||
} {
|
||||
mustExecuteMigration(ctx, eventstoreClient, step, "migration failed")
|
||||
}
|
||||
|
Reference in New Issue
Block a user