mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-23 08:48:05 +00:00
fixup! fixup! fixup! fixup! fixup! fixup! fixup! Merge branch 'main' into syste-users-permissions
Tims requested changes
This commit is contained in:
@@ -28,8 +28,10 @@ type Migration struct {
|
||||
Machine *id.Config
|
||||
}
|
||||
|
||||
//go:embed defaults.yaml
|
||||
var defaultConfig []byte
|
||||
var (
|
||||
//go:embed defaults.yaml
|
||||
defaultConfig []byte
|
||||
)
|
||||
|
||||
func mustNewMigrationConfig(v *viper.Viper) *Migration {
|
||||
config := new(Migration)
|
||||
|
@@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
type InitPermittedOrgsFunction52 struct {
|
||||
eventstoreClient *database.DB
|
||||
dbClient *database.DB
|
||||
}
|
||||
|
||||
//go:embed 52/*.sql
|
||||
@@ -25,7 +25,7 @@ func (mig *InitPermittedOrgsFunction52) Execute(ctx context.Context, _ eventstor
|
||||
}
|
||||
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 {
|
||||
if _, err := mig.dbClient.ExecContext(ctx, stmt.query); err != nil {
|
||||
return fmt.Errorf("%s %s: %w", mig.String(), stmt.file, err)
|
||||
}
|
||||
}
|
||||
|
@@ -2,6 +2,22 @@ DROP FUNCTION IF EXISTS eventstore.get_system_permissions;
|
||||
|
||||
CREATE OR REPLACE FUNCTION eventstore.get_system_permissions(
|
||||
permissions_json JSONB
|
||||
/*
|
||||
[
|
||||
{
|
||||
"member_type": "System",
|
||||
"aggregate_id": "",
|
||||
"object_id": "",
|
||||
"permissions": ["iam.read", "iam.write", "iam.polic.read"]
|
||||
},
|
||||
{
|
||||
"member_type": "IAM",
|
||||
"aggregate_id": "310716990375453665",
|
||||
"object_id": "",
|
||||
"permissions": ["iam.read", "iam.write", "iam.polic.read"]
|
||||
}
|
||||
]
|
||||
*/
|
||||
, permm TEXT
|
||||
)
|
||||
RETURNS TABLE (
|
||||
|
@@ -1,3 +1,111 @@
|
||||
DROP FUNCTION IF EXISTS eventstore.check_system_user_perms;
|
||||
|
||||
CREATE OR REPLACE FUNCTION eventstore.check_system_user_perms(
|
||||
system_user_perms JSONB
|
||||
, perm TEXT
|
||||
, filter_orgs TEXT
|
||||
|
||||
, org_ids OUT TEXT[]
|
||||
)
|
||||
LANGUAGE 'plpgsql'
|
||||
AS $$
|
||||
DECLARE
|
||||
has_instance_or_iam_permission bool;
|
||||
member_type_found bool;
|
||||
aggregate_ids TEXT;
|
||||
check_aggregates bool;
|
||||
BEGIN
|
||||
|
||||
DROP TABLE IF EXISTS matching_system_user_perms;
|
||||
CREATE TEMPORARY TABLE matching_system_user_perms (
|
||||
member_type TEXT,
|
||||
aggregate_id TEXT,
|
||||
object_id TEXT
|
||||
) ON COMMIT DROP;
|
||||
|
||||
INSERT INTO matching_system_user_perms
|
||||
(SELECT * FROM eventstore.get_system_permissions(system_user_perms, perm));
|
||||
|
||||
-- System member type
|
||||
SELECT TRUE INTO member_type_found
|
||||
FROM matching_system_user_perms msup
|
||||
WHERE msup.member_type = 'System'
|
||||
LIMIT 1;
|
||||
|
||||
IF member_type_found 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
|
||||
CASE WHEN filter_orgs != ''
|
||||
THEN o.org_id IN (filter_orgs)
|
||||
ELSE TRUE END;
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
-- IAM member type
|
||||
SELECT TRUE, array_agg(msup.aggregate_id) INTO member_type_found, aggregate_ids
|
||||
FROM matching_system_user_perms msup
|
||||
WHERE msup.member_type = 'IAM'
|
||||
GROUP BY msup.member_type
|
||||
LIMIT 1;
|
||||
|
||||
IF member_type_found THEN
|
||||
IF (SELECT FALSE WHERE '' = ANY (aggregate_ids::TEXT[])) = FALSE THEN
|
||||
check_aggregates := FALSE;
|
||||
ELSE
|
||||
check_aggregates := TRUE;
|
||||
END IF;
|
||||
|
||||
-- Return all organizations or only those in filter_orgs
|
||||
SELECT array_agg(o.org_id) INTO org_ids
|
||||
FROM eventstore.instance_orgs o
|
||||
WHERE CASE
|
||||
WHEN check_aggregates THEN
|
||||
o.instance_id = ANY (aggregate_ids::TEXT[])
|
||||
ELSE
|
||||
TRUE
|
||||
END
|
||||
AND CASE WHEN filter_orgs != ''
|
||||
THEN o.org_id IN (filter_orgs)
|
||||
ELSE TRUE END;
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
-- Organization member type
|
||||
SELECT TRUE, array_agg(msup.aggregate_id) INTO member_type_found, aggregate_ids
|
||||
FROM matching_system_user_perms msup
|
||||
WHERE msup.member_type = 'Organization'
|
||||
GROUP BY msup.member_type
|
||||
LIMIT 1;
|
||||
|
||||
IF member_type_found THEN
|
||||
member_type_found := FALSE;
|
||||
-- if any of the aggregate_ids = '', then we search on all organization
|
||||
IF (SELECT FALSE WHERE '' = ANY (aggregate_ids::TEXT[])) = FALSE THEN
|
||||
check_aggregates := FALSE;
|
||||
ELSE
|
||||
check_aggregates := TRUE;
|
||||
END IF;
|
||||
|
||||
-- Return all organizations or only those in filter_orgs
|
||||
SELECT array_agg(o.org_id) INTO org_ids
|
||||
FROM eventstore.instance_orgs o
|
||||
WHERE
|
||||
CASE
|
||||
WHEN check_aggregates THEN
|
||||
o.org_id = ANY (aggregate_ids::TEXT[])
|
||||
ELSE
|
||||
TRUE
|
||||
END
|
||||
AND CASE WHEN filter_orgs != ''
|
||||
THEN o.org_id IN (filter_orgs)
|
||||
ELSE TRUE END;
|
||||
RETURN;
|
||||
END IF;
|
||||
END;
|
||||
$$;
|
||||
|
||||
DROP FUNCTION IF EXISTS eventstore.permitted_orgs;
|
||||
|
||||
CREATE OR REPLACE FUNCTION eventstore.permitted_orgs(
|
||||
@@ -14,104 +122,9 @@ AS $$
|
||||
BEGIN
|
||||
|
||||
-- if system user
|
||||
IF jsonb_array_length(system_user_perms) != 0 THEN
|
||||
DECLARE
|
||||
has_instance_or_iam_permission bool;
|
||||
member_type_found bool;
|
||||
aggregate_ids TEXT;
|
||||
check_aggregates bool;
|
||||
BEGIN
|
||||
|
||||
DROP TABLE IF EXISTS matching_system_user_perms;
|
||||
CREATE TEMPORARY TABLE matching_system_user_perms (
|
||||
member_type TEXT,
|
||||
aggregate_id TEXT,
|
||||
object_id TEXT
|
||||
) ON COMMIT DROP;
|
||||
|
||||
|
||||
INSERT INTO matching_system_user_perms
|
||||
(SELECT * FROM eventstore.get_system_permissions(system_user_perms, perm));
|
||||
|
||||
-- System member type
|
||||
SELECT TRUE INTO member_type_found
|
||||
FROM matching_system_user_perms msup
|
||||
WHERE msup.member_type = 'System'
|
||||
LIMIT 1;
|
||||
|
||||
IF member_type_found 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
|
||||
CASE WHEN filter_orgs != ''
|
||||
THEN o.org_id IN (filter_orgs)
|
||||
ELSE TRUE END;
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
-- IAM member type
|
||||
SELECT TRUE, array_agg(msup.aggregate_id) INTO member_type_found, aggregate_ids
|
||||
FROM matching_system_user_perms msup
|
||||
WHERE msup.member_type = 'IAM'
|
||||
GROUP BY msup.member_type
|
||||
LIMIT 1;
|
||||
|
||||
IF member_type_found THEN
|
||||
IF (SELECT FALSE WHERE '' = ANY (aggregate_ids::TEXT[])) = FALSE THEN
|
||||
check_aggregates := FALSE;
|
||||
ELSE
|
||||
check_aggregates := TRUE;
|
||||
END IF;
|
||||
|
||||
-- Return all organizations or only those in filter_orgs
|
||||
SELECT array_agg(o.org_id) INTO org_ids
|
||||
FROM eventstore.instance_orgs o
|
||||
WHERE CASE
|
||||
WHEN check_aggregates THEN
|
||||
o.instance_id = ANY (aggregate_ids::TEXT[])
|
||||
ELSE
|
||||
TRUE
|
||||
END
|
||||
AND CASE WHEN filter_orgs != ''
|
||||
THEN o.org_id IN (filter_orgs)
|
||||
ELSE TRUE END;
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
-- Organization member type
|
||||
SELECT TRUE, array_agg(msup.aggregate_id) INTO member_type_found, aggregate_ids
|
||||
FROM matching_system_user_perms msup
|
||||
WHERE msup.member_type = 'Organization'
|
||||
GROUP BY msup.member_type
|
||||
LIMIT 1;
|
||||
|
||||
IF member_type_found THEN
|
||||
member_type_found := FALSE;
|
||||
-- if any of the aggregate_ids = '', then we search on all organization
|
||||
IF (SELECT FALSE WHERE '' = ANY (aggregate_ids::TEXT[])) = FALSE THEN
|
||||
check_aggregates := FALSE;
|
||||
ELSE
|
||||
check_aggregates := TRUE;
|
||||
END IF;
|
||||
|
||||
-- Return all organizations or only those in filter_orgs
|
||||
SELECT array_agg(o.org_id) INTO org_ids
|
||||
FROM eventstore.instance_orgs o
|
||||
WHERE
|
||||
CASE
|
||||
WHEN check_aggregates THEN
|
||||
o.org_id = ANY (aggregate_ids::TEXT[])
|
||||
ELSE
|
||||
TRUE
|
||||
END
|
||||
AND CASE WHEN filter_orgs != ''
|
||||
THEN o.org_id IN (filter_orgs)
|
||||
ELSE TRUE END;
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
END;
|
||||
IF system_user_perms IS NOT NULL THEN
|
||||
org_ids := eventstore.check_system_user_perms(system_user_perms, perm, filter_orgs)
|
||||
RETURN;
|
||||
ELSE
|
||||
DECLARE
|
||||
matched_roles TEXT[]; -- roles containing permission
|
||||
@@ -154,7 +167,6 @@ BEGIN
|
||||
AND om.instance_id = instanceID
|
||||
AND om.user_id = userId
|
||||
) AS sub;
|
||||
RETURN;
|
||||
END;
|
||||
END IF;
|
||||
END;
|
||||
|
@@ -12,7 +12,7 @@ import (
|
||||
"github.com/zitadel/zitadel/cmd/encryption"
|
||||
"github.com/zitadel/zitadel/cmd/hooks"
|
||||
"github.com/zitadel/zitadel/internal/actions"
|
||||
internal_authz "github.com/zitadel/zitadel/internal/api/authz"
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
"github.com/zitadel/zitadel/internal/api/oidc"
|
||||
"github.com/zitadel/zitadel/internal/api/ui/login"
|
||||
"github.com/zitadel/zitadel/internal/cache/connector"
|
||||
@@ -33,7 +33,8 @@ type Config struct {
|
||||
Database database.Config
|
||||
Caches *connector.CachesConfig
|
||||
SystemDefaults systemdefaults.SystemDefaults
|
||||
InternalAuthZ internal_authz.Config
|
||||
InternalAuthZ authz.Config
|
||||
SystemAuthZ authz.Config
|
||||
ExternalDomain string
|
||||
ExternalPort uint16
|
||||
ExternalSecure bool
|
||||
@@ -51,7 +52,7 @@ type Config struct {
|
||||
Login login.Config
|
||||
WebAuthNName string
|
||||
Telemetry *handlers.TelemetryPusherConfig
|
||||
SystemAPIUsers map[string]*internal_authz.SystemAPIUser
|
||||
SystemAPIUsers map[string]*authz.SystemAPIUser
|
||||
}
|
||||
|
||||
type InitProjections struct {
|
||||
@@ -66,12 +67,12 @@ func MustNewConfig(v *viper.Viper) *Config {
|
||||
err := v.Unmarshal(config,
|
||||
viper.DecodeHook(mapstructure.ComposeDecodeHookFunc(
|
||||
hooks.SliceTypeStringDecode[*domain.CustomMessageText],
|
||||
hooks.SliceTypeStringDecode[internal_authz.RoleMapping],
|
||||
hooks.MapTypeStringDecode[string, *internal_authz.SystemAPIUser],
|
||||
hooks.SliceTypeStringDecode[authz.RoleMapping],
|
||||
hooks.MapTypeStringDecode[string, *authz.SystemAPIUser],
|
||||
hooks.MapHTTPHeaderStringDecode,
|
||||
database.DecodeHook,
|
||||
actions.HTTPConfigDecodeHook,
|
||||
hook.EnumHookFunc(internal_authz.MemberTypeString),
|
||||
hook.EnumHookFunc(authz.MemberTypeString),
|
||||
hook.Base64ToBytesHookFunc(),
|
||||
hook.TagToLanguageHookFunc(),
|
||||
mapstructure.StringToTimeDurationHookFunc(),
|
||||
|
@@ -178,7 +178,7 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
|
||||
steps.s49InitPermittedOrgsFunction = &InitPermittedOrgsFunction{eventstoreClient: dbClient}
|
||||
steps.s50IDPTemplate6UsePKCE = &IDPTemplate6UsePKCE{dbClient: dbClient}
|
||||
steps.s51IDPTemplate6RootCA = &IDPTemplate6RootCA{dbClient: dbClient}
|
||||
steps.s52InitPermittedOrgsFunction = &InitPermittedOrgsFunction52{eventstoreClient: dbClient}
|
||||
steps.s52InitPermittedOrgsFunction = &InitPermittedOrgsFunction52{dbClient: dbClient}
|
||||
|
||||
err = projection.Create(ctx, dbClient, eventstoreClient, config.Projections, nil, nil, nil)
|
||||
logging.OnError(err).Fatal("unable to start projections")
|
||||
@@ -412,7 +412,7 @@ func startCommandsQueries(
|
||||
sessionTokenVerifier,
|
||||
func(q *query.Queries) domain.PermissionCheck {
|
||||
return func(ctx context.Context, permission, orgID, resourceID string) (err error) {
|
||||
return internal_authz.CheckPermission(ctx, &authz_es.UserMembershipRepo{Queries: q}, nil, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
|
||||
return internal_authz.CheckPermission(ctx, &authz_es.UserMembershipRepo{Queries: q}, config.SystemAuthZ.RolePermissionMappings, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
|
||||
}
|
||||
},
|
||||
0, // not needed for projections
|
||||
@@ -437,7 +437,7 @@ func startCommandsQueries(
|
||||
authZRepo, err := authz.Start(queries, eventstoreClient, dbClient, keys.OIDC, config.ExternalSecure)
|
||||
logging.OnError(err).Fatal("unable to start authz repo")
|
||||
permissionCheck := func(ctx context.Context, permission, orgID, resourceID string) (err error) {
|
||||
return internal_authz.CheckPermission(ctx, authZRepo, nil, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
|
||||
return internal_authz.CheckPermission(ctx, authZRepo, config.SystemAuthZ.RolePermissionMappings, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
|
||||
}
|
||||
|
||||
commands, err := command.StartCommands(ctx,
|
||||
|
@@ -495,7 +495,7 @@ func startAPIs(
|
||||
}
|
||||
instanceInterceptor := middleware.InstanceInterceptor(queries, config.ExternalDomain, login.IgnoreInstanceEndpoints...)
|
||||
assetsCache := middleware.AssetsCacheInterceptor(config.AssetStorage.Cache.MaxAge, config.AssetStorage.Cache.SharedMaxAge)
|
||||
apis.RegisterHandlerOnPrefix(assets.HandlerPrefix, assets.NewHandler(commands, verifier, config.InternalAuthZ, id.SonyFlakeGenerator(), store, queries, middleware.CallDurationHandler, instanceInterceptor.Handler, assetsCache.Handler, limitingAccessInterceptor.Handle))
|
||||
apis.RegisterHandlerOnPrefix(assets.HandlerPrefix, assets.NewHandler(commands, verifier, config.SystemAuthZ, config.InternalAuthZ, id.SonyFlakeGenerator(), store, queries, middleware.CallDurationHandler, instanceInterceptor.Handler, assetsCache.Handler, limitingAccessInterceptor.Handle))
|
||||
|
||||
apis.RegisterHandlerOnPrefix(idp.HandlerPrefix, idp.NewHandler(commands, queries, keys.IDPConfig, instanceInterceptor.Handler))
|
||||
|
||||
@@ -539,7 +539,7 @@ func startAPIs(
|
||||
keys.User,
|
||||
&config.SCIM,
|
||||
instanceInterceptor.HandlerFuncWithError,
|
||||
middleware.AuthorizationInterceptor(verifier, config.InternalAuthZ).HandlerFuncWithError))
|
||||
middleware.AuthorizationInterceptor(verifier, config.SystemAuthZ, config.InternalAuthZ).HandlerFuncWithError))
|
||||
|
||||
c, err := console.Start(config.Console, config.ExternalSecure, oidcServer.IssuerFromRequest, middleware.CallDurationHandler, instanceInterceptor.Handler, limitingAccessInterceptor, config.CustomerPortal)
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user