mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-22 13:17:41 +00:00
fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! feat(permissions): Addeding system user support for permission check v2
This commit is contained in:
3
Makefile
3
Makefile
@@ -113,8 +113,7 @@ core_unit_test:
|
||||
|
||||
.PHONY: core_integration_db_up
|
||||
core_integration_db_up:
|
||||
# docker compose -f internal/integration/config/docker-compose.yaml up --pull always --wait $${INTEGRATION_DB_FLAVOR} cache
|
||||
docker compose -f internal/integration/config/docker-compose.yaml up --wait $${INTEGRATION_DB_FLAVOR} cache
|
||||
docker compose -f internal/integration/config/docker-compose.yaml up --pull always --wait $${INTEGRATION_DB_FLAVOR} cache
|
||||
|
||||
.PHONY: core_integration_db_down
|
||||
core_integration_db_down:
|
||||
|
@@ -28,10 +28,8 @@ type Migration struct {
|
||||
Machine *id.Config
|
||||
}
|
||||
|
||||
var (
|
||||
//go:embed defaults.yaml
|
||||
defaultConfig []byte
|
||||
)
|
||||
//go:embed defaults.yaml
|
||||
var defaultConfig []byte
|
||||
|
||||
func mustNewMigrationConfig(v *viper.Viper) *Migration {
|
||||
config := new(Migration)
|
||||
|
@@ -43,14 +43,14 @@ BEGIN
|
||||
END;
|
||||
|
||||
-- Return the organizations where permission were granted thru org-level roles
|
||||
SELECT array_agg(org_id) INTO org_ids
|
||||
SELECT array_agg(sub.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
|
||||
);
|
||||
) AS sub;
|
||||
RETURN;
|
||||
END;
|
||||
$$;
|
||||
|
@@ -3,44 +3,69 @@ DROP FUNCTION IF EXISTS eventstore.permitted_orgs;
|
||||
CREATE OR REPLACE FUNCTION eventstore.permitted_orgs(
|
||||
instanceId TEXT
|
||||
, userId TEXT
|
||||
, system_user_perms JSONB
|
||||
, perm TEXT
|
||||
, system_user_memeber_type INTEGER[]
|
||||
, system_user_instance_id TEXT[]
|
||||
, system_user_aggregate_id TEXT[]
|
||||
, system_user_permissions TEXT[][]
|
||||
, system_user_permissions_length INTEGER[]
|
||||
, filter_orgs TEXT
|
||||
|
||||
, org_ids OUT TEXT[]
|
||||
)
|
||||
LANGUAGE 'plpgsql'
|
||||
STABLE
|
||||
-- STABLE
|
||||
AS $$
|
||||
DECLARE
|
||||
matched_roles TEXT[]; -- roles containing permission
|
||||
BEGIN
|
||||
|
||||
IF system_user_memeber_type IS NOT NULL THEN
|
||||
-- if system user
|
||||
IF jsonb_array_length(system_user_perms) = 0 THEN
|
||||
DECLARE
|
||||
system_user_permission_found bool;
|
||||
has_instance_or_iam_permission bool;
|
||||
BEGIN
|
||||
SELECT result.perm_found INTO system_user_permission_found
|
||||
FROM (SELECT eventstore.get_org_permission(perm, instanceId,filter_orgs,
|
||||
system_user_memeber_type, system_user_instance_id, system_user_aggregate_id,
|
||||
system_user_permissions, system_user_permissions_length) AS perm_found) AS result;
|
||||
|
||||
IF system_user_permission_found THEN
|
||||
DROP TABLE IF EXISTS matching_system_user_perms;
|
||||
CREATE TEMPORARY TABLE matching_system_user_perms (
|
||||
member_type TEXT,
|
||||
-- instance_id TEXT,
|
||||
aggregate_id TEXT,
|
||||
object_id TEXT,
|
||||
permission TEXT
|
||||
) ON COMMIT DROP;
|
||||
|
||||
|
||||
INSERT INTO matching_system_user_perms
|
||||
(SELECT * FROM eventstore.get_system_permissions(system_user_perms, perm));
|
||||
|
||||
-- check instance or iam level
|
||||
SELECT true INTO has_instance_or_iam_permission
|
||||
FROM matching_system_user_perms msup
|
||||
WHERE (msup.member_type = 'System' AND msup.aggregate_id = '')
|
||||
OR (msup.member_type = 'System' AND msup.aggregate_id = instanceId)
|
||||
OR (msup.member_type = 'IAM' AND msup.aggregate_id = instanceId)
|
||||
LIMIT 1;
|
||||
|
||||
IF has_instance_or_iam_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;
|
||||
END IF;
|
||||
END;
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
-- SELECT array_agg(msup.aggregate_id) INTO org_ids
|
||||
-- FROM matching_system_user_perms msup
|
||||
-- WHERE msup.instance_id = instanceId
|
||||
-- AND msup.member_type = 'Organization'
|
||||
-- AND CASE WHEN filter_orgs != ''
|
||||
-- THEN msup.aggregate_id IN (filter_orgs)
|
||||
-- ELSE TRUE END;
|
||||
-- RETURN;
|
||||
|
||||
END;
|
||||
END IF;
|
||||
|
||||
SELECT array_agg(rp.role) INTO matched_roles
|
||||
FROM eventstore.role_permissions rp
|
||||
WHERE rp.instance_id = instanceId
|
||||
@@ -82,84 +107,32 @@ BEGIN
|
||||
END;
|
||||
$$;
|
||||
|
||||
DROP FUNCTION IF EXISTS eventstore.get_org_permission;
|
||||
CREATE OR REPLACE FUNCTION eventstore.get_org_permission(
|
||||
perm TEXT
|
||||
, instance_idd TEXT
|
||||
, org_id TEXT
|
||||
, system_user_memeber_type INTEGER[]
|
||||
, sustem_user_instance_id TEXT[]
|
||||
, system_user_aggregate_id TEXT[]
|
||||
, system_user_permissions TEXT[][]
|
||||
, system_user_permissions_length INTEGER[]
|
||||
-- , outt OUT TEXT[]
|
||||
, outt OUT BOOL
|
||||
|
||||
|
||||
|
||||
DROP FUNCTION IF EXISTS eventstore.get_system_permissions;
|
||||
CREATE OR REPLACE FUNCTION eventstore.get_system_permissions(
|
||||
permissions_json JSONB
|
||||
, permm TEXT
|
||||
-- , res OUT eventstore.system_perms
|
||||
)
|
||||
LANGUAGE 'plpgsql'
|
||||
AS $$
|
||||
DECLARE
|
||||
i INTEGER;
|
||||
length INTEGER;
|
||||
permission_length INTEGER;
|
||||
BEGIN
|
||||
-- outt := FALSE;
|
||||
length := array_length(system_user_memeber_type, 1);
|
||||
-- length := 3;
|
||||
|
||||
DROP TABLE IF EXISTS permissions;
|
||||
CREATE TEMPORARY TABLE permissions (
|
||||
member_type INTEGER,
|
||||
instance_id TEXT,
|
||||
RETURNS TABLE (
|
||||
member_type TEXT,
|
||||
-- instance_id TEXT,
|
||||
aggregate_id TEXT,
|
||||
object_id TEXT,
|
||||
permission TEXT
|
||||
);
|
||||
|
||||
-- <<outer_loop>>
|
||||
FOR i IN 1..length LOOP
|
||||
-- only interested in organization level and higher
|
||||
IF system_user_memeber_type[i] > 3 THEN
|
||||
CONTINUE;
|
||||
END IF;
|
||||
permission_length := system_user_permissions_length[i];
|
||||
|
||||
FOR j IN 1..permission_length LOOP
|
||||
IF system_user_permissions[i][j] != perm THEN
|
||||
CONTINUE;
|
||||
END IF;
|
||||
INSERT INTO permissions (member_type, instance_id, aggregate_id, permission) VALUES
|
||||
(system_user_memeber_type[i], sustem_user_instance_id[i], system_user_aggregate_id[i], system_user_permissions[i][j] );
|
||||
-- outt := 555;
|
||||
-- RETURN;
|
||||
END LOOP;
|
||||
END LOOP;
|
||||
|
||||
-- outt := (SELECT permission FROM permissions LIMIT 1);
|
||||
SELECT result.res INTO outt
|
||||
FROM (SELECT TRUE AS res FROM permissions p
|
||||
WHERE
|
||||
-- check instance id
|
||||
CASE WHEN p.member_type = 1 OR p.member_type = 2 THEN -- System or IAM
|
||||
p.aggregate_id = instance_idd
|
||||
-- OR p.instance_id IS NULL
|
||||
OR p.instance_id = ''
|
||||
ELSE
|
||||
p.instance_id = instance_idd
|
||||
-- OR p.instance_id IS NULL
|
||||
OR p.instance_id = ''
|
||||
END
|
||||
AND
|
||||
-- check organization
|
||||
CASE WHEN p.member_type = 3 THEN -- organization
|
||||
p.aggregate_id = org_id
|
||||
ELSE
|
||||
TRUE
|
||||
END
|
||||
Limit 1
|
||||
) AS result;
|
||||
|
||||
DROP TABLE permissions;
|
||||
|
||||
) AS $$
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
SELECT * FROM (
|
||||
SELECT
|
||||
(perm)->>'member_type' AS member_type,
|
||||
(perm)->>'aggregate_id' AS agregate_id,
|
||||
(perm)->>'object_id' AS objectId,
|
||||
permis AS permission
|
||||
FROM jsonb_array_elements(permissions_json) AS perm
|
||||
CROSS JOIN jsonb_array_elements_text(perm->'permissions') AS permis) as p
|
||||
WHERE p.permission = permm;
|
||||
END;
|
||||
$$;
|
||||
|
||||
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
@@ -1,7 +1,6 @@
|
||||
package start
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
@@ -131,7 +130,6 @@ func MustNewConfig(v *viper.Viper) *Config {
|
||||
|
||||
// Copy the global role permissions mappings to the instance until we allow instance-level configuration over the API.
|
||||
config.DefaultInstance.RolePermissionMappings = config.InternalAuthZ.RolePermissionMappings
|
||||
fmt.Printf("@@ >>>>>>>>>>>>>>>>>>>>>>>>>>>> config.SystemAuthZ = %+v\n", config.SystemAuthZ)
|
||||
|
||||
return config
|
||||
}
|
||||
|
@@ -32,7 +32,7 @@ func CheckUserAuthorization(ctx context.Context, req interface{}, token, orgID,
|
||||
|
||||
if requiredAuthOption.Permission == authenticated {
|
||||
return func(parent context.Context) context.Context {
|
||||
parent = addGetSystemUserRolesFuncToCtx(parent, SystemAuthConfig.RolePermissionMappings, nil, ctxData)
|
||||
parent = addGetSystemUserRolesFuncToCtx(parent, SystemAuthConfig.RolePermissionMappings, ctxData)
|
||||
return context.WithValue(parent, dataKey, ctxData)
|
||||
}, nil
|
||||
}
|
||||
@@ -53,7 +53,7 @@ func CheckUserAuthorization(ctx context.Context, req interface{}, token, orgID,
|
||||
parent = context.WithValue(parent, dataKey, ctxData)
|
||||
parent = context.WithValue(parent, allPermissionsKey, allPermissions)
|
||||
parent = context.WithValue(parent, requestPermissionsKey, requestedPermissions)
|
||||
parent = addGetSystemUserRolesFuncToCtx(parent, SystemAuthConfig.RolePermissionMappings, requestedPermissions, ctxData)
|
||||
parent = addGetSystemUserRolesFuncToCtx(parent, SystemAuthConfig.RolePermissionMappings, ctxData)
|
||||
return parent
|
||||
}, nil
|
||||
}
|
||||
@@ -130,42 +130,34 @@ func GetAllPermissionCtxIDs(perms []string) []string {
|
||||
return ctxIDs
|
||||
}
|
||||
|
||||
type SystemUserAuthParams struct {
|
||||
MemberType []int32
|
||||
InstanceID []string
|
||||
AggregateID []string
|
||||
Permissions [][]string
|
||||
PermissionsLength []int32
|
||||
type SystemUserPermissionsDBQuery struct {
|
||||
MemberType string `json:"member_type"`
|
||||
AggregateID string `json:"aggregate_id"`
|
||||
ObjectID string `json:"object_id"`
|
||||
Permissions []string `json:"permissions"`
|
||||
}
|
||||
|
||||
func addGetSystemUserRolesFuncToCtx(ctx context.Context, systemUserRoleMap []RoleMapping, requestedPermissions []string, ctxData CtxData) context.Context {
|
||||
func addGetSystemUserRolesFuncToCtx(ctx context.Context, systemUserRoleMap []RoleMapping, ctxData CtxData) context.Context {
|
||||
if len(ctxData.SystemMemberships) == 0 {
|
||||
return ctx
|
||||
// } else if ctxData.SystemMemberships[0].MemberType == MemberTypeSystem {
|
||||
} else {
|
||||
ctx = context.WithValue(ctx, systemUserRolesFuncKey, func() func(ctx context.Context) *SystemUserAuthParams {
|
||||
var systemUserAuthParams *SystemUserAuthParams
|
||||
ctx = context.WithValue(ctx, systemUserRolesFuncKey, func() func(ctx context.Context) []SystemUserPermissionsDBQuery {
|
||||
var systemUserPermissionsDbJsonQueryStruct []SystemUserPermissionsDBQuery
|
||||
chann := make(chan struct{}, 1)
|
||||
return func(ctx context.Context) *SystemUserAuthParams {
|
||||
if systemUserAuthParams != nil {
|
||||
return systemUserAuthParams
|
||||
return func(ctx context.Context) []SystemUserPermissionsDBQuery {
|
||||
if systemUserPermissionsDbJsonQueryStruct != nil {
|
||||
return systemUserPermissionsDbJsonQueryStruct
|
||||
}
|
||||
|
||||
chann <- struct{}{}
|
||||
defer func() {
|
||||
<-chann
|
||||
}()
|
||||
if systemUserAuthParams != nil {
|
||||
return systemUserAuthParams
|
||||
if systemUserPermissionsDbJsonQueryStruct != nil {
|
||||
return systemUserPermissionsDbJsonQueryStruct
|
||||
}
|
||||
|
||||
systemUserAuthParams = &SystemUserAuthParams{
|
||||
MemberType: make([]int32, len(ctxData.SystemMemberships)),
|
||||
InstanceID: make([]string, len(ctxData.SystemMemberships)),
|
||||
AggregateID: make([]string, len(ctxData.SystemMemberships)),
|
||||
Permissions: make([][]string, len(ctxData.SystemMemberships)),
|
||||
PermissionsLength: make([]int32, len(ctxData.SystemMemberships)),
|
||||
}
|
||||
systemUserPermissionsDbJsonQueryStruct = make([]SystemUserPermissionsDBQuery, len(ctxData.SystemMemberships))
|
||||
|
||||
for i, systemPerm := range ctxData.SystemMemberships {
|
||||
permissions := []string{}
|
||||
@@ -175,25 +167,23 @@ func addGetSystemUserRolesFuncToCtx(ctx context.Context, systemUserRoleMap []Rol
|
||||
slices.Sort(permissions)
|
||||
permissions = slices.Compact(permissions)
|
||||
|
||||
systemUserAuthParams.MemberType[i] = MemberTypeServerToMemberTypeDBMap[systemPerm.MemberType]
|
||||
systemUserAuthParams.InstanceID[i] = systemPerm.InstanceID
|
||||
systemUserAuthParams.AggregateID[i] = systemPerm.AggregateID
|
||||
systemUserAuthParams.Permissions[i] = permissions
|
||||
systemUserAuthParams.PermissionsLength[i] = int32(len(permissions))
|
||||
systemUserPermissionsDbJsonQueryStruct[i].MemberType = MemberTypeServerToMemberTypeDBMap[systemPerm.MemberType]
|
||||
systemUserPermissionsDbJsonQueryStruct[i].AggregateID = systemPerm.AggregateID
|
||||
systemUserPermissionsDbJsonQueryStruct[i].Permissions = permissions
|
||||
}
|
||||
return systemUserAuthParams
|
||||
return systemUserPermissionsDbJsonQueryStruct
|
||||
}
|
||||
}())
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
func GetSystemUserAuthParams(ctx context.Context) (*SystemUserAuthParams, error) {
|
||||
func GetSystemUserPermissions(ctx context.Context) ([]SystemUserPermissionsDBQuery, error) {
|
||||
getSystemUserRolesFuncValue := ctx.Value(systemUserRolesFuncKey)
|
||||
if getSystemUserRolesFuncValue == nil {
|
||||
return &SystemUserAuthParams{}, nil
|
||||
return nil, nil
|
||||
}
|
||||
getSystemUserRolesFunc, ok := getSystemUserRolesFuncValue.(func(context.Context) *SystemUserAuthParams)
|
||||
getSystemUserRolesFunc, ok := getSystemUserRolesFuncValue.(func(context.Context) []SystemUserPermissionsDBQuery)
|
||||
if !ok {
|
||||
return nil, errors.New("unable to obtain systems role func")
|
||||
}
|
||||
|
@@ -72,10 +72,10 @@ const (
|
||||
MemberTypeSystem
|
||||
)
|
||||
|
||||
var MemberTypeServerToMemberTypeDBMap map[MemberType]int32 = map[MemberType]int32{
|
||||
MemberTypeSystem: 1,
|
||||
MemberTypeIAM: 2,
|
||||
MemberTypeOrganization: 3,
|
||||
var MemberTypeServerToMemberTypeDBMap map[MemberType]string = map[MemberType]string{
|
||||
MemberTypeSystem: "System",
|
||||
MemberTypeIAM: "IAM",
|
||||
MemberTypeOrganization: "Organization",
|
||||
}
|
||||
|
||||
type TokenVerifier interface {
|
||||
|
@@ -32,8 +32,8 @@ func getUserPermissions(ctx context.Context, resolver MembershipsResolver, requi
|
||||
|
||||
if ctxData.SystemMemberships != nil {
|
||||
// for when we get rid of internalAuthz
|
||||
// requestedPermissions, allPermissions = mapMembershipsToPermissions(requiredPerm, ctxData.SystemMemberships, SystemUserRoleMappings)
|
||||
requestedPermissions, allPermissions = mapMembershipsToPermissions(requiredPerm, ctxData.SystemMemberships, roleMappings)
|
||||
requestedPermissions, allPermissions = mapMembershipsToPermissions(requiredPerm, ctxData.SystemMemberships, SystemUserRoleMappings)
|
||||
// requestedPermissions, allPermissions = mapMembershipsToPermissions(requiredPerm, ctxData.SystemMemberships, roleMappings)
|
||||
return requestedPermissions, allPermissions, nil
|
||||
}
|
||||
|
||||
|
@@ -4,13 +4,11 @@ import (
|
||||
"context"
|
||||
"crypto/rsa"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
"github.com/zitadel/logging"
|
||||
"github.com/zitadel/oidc/v3/pkg/op"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/crypto"
|
||||
@@ -33,14 +31,7 @@ func StartSystemTokenVerifierFromConfig(issuer string, keys map[string]*SystemAP
|
||||
}
|
||||
for _, membership := range key.Memberships {
|
||||
switch membership.MemberType {
|
||||
case MemberTypeSystem, MemberTypeIAM:
|
||||
systemUsers[userID] = key.Memberships
|
||||
case MemberTypeOrganization:
|
||||
if membership.AggregateID != "" && membership.InstanceID == "" {
|
||||
errorMsg := fmt.Sprintf("system user %s must include InstancID if AggregateID is set for member type Organization", userID)
|
||||
logging.Error(errorMsg)
|
||||
return nil, errors.New(errorMsg)
|
||||
}
|
||||
case MemberTypeSystem, MemberTypeIAM, MemberTypeOrganization:
|
||||
systemUsers[userID] = key.Memberships
|
||||
case MemberTypeUnspecified, MemberTypeProject, MemberTypeProjectGrant:
|
||||
return nil, errors.New("for system users, only the membership types System, IAM and Organization are supported")
|
||||
@@ -76,7 +67,7 @@ func (s *SystemTokenVerifierFromConfig) VerifySystemToken(ctx context.Context, t
|
||||
for _, membership := range systemUserMemberships {
|
||||
if membership.MemberType == MemberTypeSystem ||
|
||||
membership.MemberType == MemberTypeIAM && GetInstance(ctx).InstanceID() == membership.AggregateID ||
|
||||
membership.MemberType == MemberTypeOrganization && orgID == membership.AggregateID && GetInstance(ctx).InstanceID() == membership.InstanceID {
|
||||
membership.MemberType == MemberTypeOrganization && orgID == membership.AggregateID {
|
||||
matchingMemberships = append(matchingMemberships, membership)
|
||||
}
|
||||
}
|
||||
|
@@ -130,13 +130,6 @@ SystemAuthZ:
|
||||
- "system.quota.write"
|
||||
- "system.quota.delete"
|
||||
- "system.iam.member.read"
|
||||
- Role: "SYSTEM_OWNER_VIEWER"
|
||||
Permissions:
|
||||
- "system.instance.read"
|
||||
- "system.domain.read"
|
||||
- "system.debug.read"
|
||||
- "system.feature.read"
|
||||
- "system.iam.member.read"
|
||||
- Role: "IAM_OWNER"
|
||||
Permissions:
|
||||
- "iam.read"
|
||||
@@ -235,47 +228,10 @@ SystemAuthZ:
|
||||
- "userschema.delete"
|
||||
- "session.read"
|
||||
- "session.delete"
|
||||
- Role: "IAM_OWNER_VIEWER"
|
||||
Permissions:
|
||||
- "iam.read"
|
||||
- "iam.policy.read"
|
||||
- "iam.member.read"
|
||||
- "iam.idp.read"
|
||||
- "iam.action.read"
|
||||
- "iam.flow.read"
|
||||
- "iam.restrictions.read"
|
||||
- "iam.feature.read"
|
||||
- "iam.web_key.read"
|
||||
- "iam.debug.read"
|
||||
- "org.read"
|
||||
- "org.member.read"
|
||||
- "org.idp.read"
|
||||
- "org.action.read"
|
||||
- "org.flow.read"
|
||||
- "org.feature.read"
|
||||
- "user.read"
|
||||
- "user.global.read"
|
||||
- "user.grant.read"
|
||||
- "user.membership.read"
|
||||
- "user.feature.read"
|
||||
- "policy.read"
|
||||
- "project.read"
|
||||
- "project.member.read"
|
||||
- "project.role.read"
|
||||
- "project.app.read"
|
||||
- "project.grant.read"
|
||||
- "project.grant.member.read"
|
||||
- "events.read"
|
||||
- "milestones.read"
|
||||
- "action.target.read"
|
||||
- "action.execution.read"
|
||||
- "userschema.read"
|
||||
- "session.read"
|
||||
- Role: "IAM_ORG_MANAGER"
|
||||
- Role: "ORG_OWNER"
|
||||
Permissions:
|
||||
- "org.read"
|
||||
- "org.global.read"
|
||||
- "org.create"
|
||||
- "org.write"
|
||||
- "org.delete"
|
||||
- "org.member.read"
|
||||
@@ -321,7 +277,6 @@ SystemAuthZ:
|
||||
- "project.role.delete"
|
||||
- "project.app.read"
|
||||
- "project.app.write"
|
||||
- "project.app.delete"
|
||||
- "project.grant.read"
|
||||
- "project.grant.write"
|
||||
- "project.grant.delete"
|
||||
@@ -329,74 +284,3 @@ SystemAuthZ:
|
||||
- "project.grant.member.write"
|
||||
- "project.grant.member.delete"
|
||||
- "session.delete"
|
||||
- Role: "IAM_USER_MANAGER"
|
||||
Permissions:
|
||||
- "org.read"
|
||||
- "org.global.read"
|
||||
- "org.member.read"
|
||||
- "org.member.delete"
|
||||
- "user.read"
|
||||
- "user.global.read"
|
||||
- "user.write"
|
||||
- "user.delete"
|
||||
- "user.grant.read"
|
||||
- "user.grant.write"
|
||||
- "user.grant.delete"
|
||||
- "user.membership.read"
|
||||
- "user.passkey.write"
|
||||
- "user.feature.read"
|
||||
- "user.feature.write"
|
||||
- "user.feature.delete"
|
||||
- "project.read"
|
||||
- "project.member.read"
|
||||
- "project.role.read"
|
||||
- "project.app.read"
|
||||
- "project.grant.read"
|
||||
- "project.grant.write"
|
||||
- "project.grant.delete"
|
||||
- "project.grant.member.read"
|
||||
- "session.delete"
|
||||
- Role: "IAM_ADMIN_IMPERSONATOR"
|
||||
Permissions:
|
||||
- "admin.impersonation"
|
||||
- "impersonation"
|
||||
- Role: "IAM_END_USER_IMPERSONATOR"
|
||||
Permissions:
|
||||
- "impersonation"
|
||||
- Role: "IAM_LOGIN_CLIENT"
|
||||
Permissions:
|
||||
- "iam.read"
|
||||
- "iam.policy.read"
|
||||
- "iam.member.read"
|
||||
- "iam.member.write"
|
||||
- "iam.idp.read"
|
||||
- "iam.feature.read"
|
||||
- "iam.restrictions.read"
|
||||
- "org.read"
|
||||
- "org.member.read"
|
||||
- "org.member.write"
|
||||
- "org.idp.read"
|
||||
- "org.feature.read"
|
||||
- "user.read"
|
||||
- "user.write"
|
||||
- "user.grant.read"
|
||||
- "user.grant.write"
|
||||
- "user.membership.read"
|
||||
- "user.credential.write"
|
||||
- "user.passkey.write"
|
||||
- "user.feature.read"
|
||||
- "policy.read"
|
||||
- "project.read"
|
||||
- "project.member.read"
|
||||
- "project.member.write"
|
||||
- "project.role.read"
|
||||
- "project.app.read"
|
||||
- "project.member.read"
|
||||
- "project.member.write"
|
||||
- "project.grant.read"
|
||||
- "project.grant.member.read"
|
||||
- "project.grant.member.write"
|
||||
- "session.read"
|
||||
- "session.link"
|
||||
- "session.delete"
|
||||
- "userschema.read"
|
||||
|
@@ -2,6 +2,7 @@ package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
@@ -11,48 +12,63 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// eventstore.permitted_orgs(instanceid text, userid text, perm text, system_user_perms text[], filter_orgs text)
|
||||
wherePermittedOrgsClause = "%s = ANY(eventstore.permitted_orgs(?, ?, ?, ?, ?, ?, ?, ?, ?))"
|
||||
// eventstore.permitted_orgs(instanceid text, userid text, system_user_perms JSONB, perm text filter_orgs text)
|
||||
wherePermittedOrgsClause = "%s = ANY(eventstore.permitted_orgs(?, ?, ?, ?, ?))"
|
||||
wherePermittedOrgsOrCurrentUserClause = "(" + wherePermittedOrgsClause + " OR %s = ?" + ")"
|
||||
)
|
||||
|
||||
// wherePermittedOrgs sets a `WHERE` clause to the query that filters the orgs
|
||||
// for which the authenticated user has the requested permission for.
|
||||
// The user ID is taken from the context.
|
||||
//
|
||||
// The `orgIDColumn` specifies the table column to which this filter must be applied,
|
||||
// and is typically the `resource_owner` column in ZITADEL.
|
||||
// We use full identifiers in the query builder so this function should be
|
||||
// called with something like `UserResourceOwnerCol.identifier()` for example.
|
||||
func wherePermittedOrgs(ctx context.Context, query sq.SelectBuilder, systemUserAuthParams *authz.SystemUserAuthParams, filterOrgIds, orgIDColumn, permission string) sq.SelectBuilder {
|
||||
func wherePermittedOrgs(ctx context.Context, query sq.SelectBuilder, systemUserPermission []authz.SystemUserPermissionsDBQuery, filterOrgIds, orgIDColumn, permission string) (sq.SelectBuilder, error) {
|
||||
userID := authz.GetCtxData(ctx).UserID
|
||||
logging.WithFields("permission_check_v2_flag", authz.GetFeatures(ctx).PermissionCheckV2, "org_id_column", orgIDColumn, "permission", permission, "user_id", userID).Debug("permitted orgs check used")
|
||||
|
||||
systemUserPermissionsJson := "[]"
|
||||
if systemUserPermission != nil {
|
||||
systemUserPermissionsBytes, err := json.Marshal(systemUserPermission)
|
||||
if err != nil {
|
||||
return query, err
|
||||
}
|
||||
systemUserPermissionsJson = string(systemUserPermissionsBytes)
|
||||
}
|
||||
|
||||
return query.Where(
|
||||
fmt.Sprintf(wherePermittedOrgsClause, orgIDColumn),
|
||||
authz.GetInstance(ctx).InstanceID(),
|
||||
userID,
|
||||
systemUserPermissionsJson,
|
||||
systemUserPermission,
|
||||
permission,
|
||||
systemUserAuthParams,
|
||||
filterOrgIds,
|
||||
)
|
||||
), nil
|
||||
}
|
||||
|
||||
func wherePermittedOrgsOrCurrentUser(ctx context.Context, query sq.SelectBuilder, systemUserAuthParams *authz.SystemUserAuthParams, filterOrgIds, orgIDColumn, userIdColum, permission string) sq.SelectBuilder {
|
||||
func wherePermittedOrgsOrCurrentUser(ctx context.Context, query sq.SelectBuilder, systemUserPermission []authz.SystemUserPermissionsDBQuery, filterOrgIds, orgIDColumn, userIdColum, permission string) (sq.SelectBuilder, error) {
|
||||
userID := authz.GetCtxData(ctx).UserID
|
||||
logging.WithFields("permission_check_v2_flag", authz.GetFeatures(ctx).PermissionCheckV2, "org_id_column", orgIDColumn, "user_id_colum", userIdColum, "permission", permission, "user_id", userID).Debug("permitted orgs check used")
|
||||
|
||||
systemUserPermissionsJson := "[]"
|
||||
if systemUserPermission != nil {
|
||||
systemUserPermissionsBytes, err := json.Marshal(systemUserPermission)
|
||||
if err != nil {
|
||||
return query, err
|
||||
}
|
||||
systemUserPermissionsJson = string(systemUserPermissionsBytes)
|
||||
}
|
||||
fmt.Printf("@@ >>>>>>>>>>>>>>>>>>>>>>>>>>>> systemUserPermissionsJson = %+v\n", systemUserPermissionsJson)
|
||||
|
||||
return query.Where(
|
||||
fmt.Sprintf(wherePermittedOrgsOrCurrentUserClause, orgIDColumn, userIdColum),
|
||||
authz.GetInstance(ctx).InstanceID(),
|
||||
userID,
|
||||
systemUserPermissionsJson,
|
||||
permission,
|
||||
systemUserAuthParams.MemberType,
|
||||
systemUserAuthParams.InstanceID,
|
||||
systemUserAuthParams.AggregateID,
|
||||
systemUserAuthParams.Permissions,
|
||||
systemUserAuthParams.PermissionsLength,
|
||||
filterOrgIds,
|
||||
userID,
|
||||
)
|
||||
), nil
|
||||
}
|
||||
|
@@ -658,11 +658,14 @@ func (q *Queries) searchUsers(ctx context.Context, queries *UserSearchQueries, f
|
||||
})
|
||||
if permissionCheckV2 {
|
||||
// extract system user roles
|
||||
systemUserPermissions, err := authz.GetSystemUserAuthParams(ctx)
|
||||
systemUserPermissions, err := authz.GetSystemUserPermissions(ctx)
|
||||
if err != nil {
|
||||
return nil, zerrors.ThrowInternal(err, "QUERY-GS9gs", "Errors.Internal")
|
||||
}
|
||||
query = wherePermittedOrgsOrCurrentUser(ctx, query, systemUserPermissions, filterOrgIds, UserResourceOwnerCol.identifier(), UserIDCol.identifier(), domain.PermissionUserRead)
|
||||
query, err = wherePermittedOrgsOrCurrentUser(ctx, query, systemUserPermissions, filterOrgIds, UserResourceOwnerCol.identifier(), UserIDCol.identifier(), domain.PermissionUserRead)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
stmt, args, err := query.ToSql()
|
||||
|
Reference in New Issue
Block a user