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:
Iraq Jaber
2025-03-12 11:39:25 +00:00
parent 306ce97828
commit 255d77a6e9
12 changed files with 87 additions and 46 deletions

View File

@@ -1172,6 +1172,34 @@ DefaultInstance:
# If an audit log retention is set using an instance limit, it will overwrite the system default. # If an audit log retention is set using an instance limit, it will overwrite the system default.
AuditLogRetention: 0s # ZITADEL_AUDITLOGRETENTION AuditLogRetention: 0s # ZITADEL_AUDITLOGRETENTION
SystemAuthZ:
# Configure the RolePermissionMappings by environment variable using JSON notation:
# ZITADEL_INTERNALAUTHZ_ROLEPERMISSIONMAPPINGS='[{"role": "IAM_OWNER", "permissions": ["iam.write"]}, {"role": "ORG_OWNER", "permissions": ["org.write"]}]'
# Beware that if you configure the RolePermissionMappings by environment variable, all the default RolePermissionMappings are lost.
#
# Warning: RolePermissionMappings are synhronized to the database.
# Changes here will only be applied after running `zitadel setup` or `zitadel start-from-setup`.
RolePermissionMappings:
- Role: "SYSTEM_OWNER"
Permissions:
- "system.instance.read"
- "system.instance.write"
- "system.instance.delete"
- "system.domain.read"
- "system.domain.write"
- "system.domain.delete"
- "system.debug.read"
- "system.debug.write"
- "system.debug.delete"
- "system.feature.read"
- "system.feature.write"
- "system.feature.delete"
- "system.limits.write"
- "system.limits.delete"
- "system.quota.write"
- "system.quota.delete"
- "system.iam.member.read"
InternalAuthZ: InternalAuthZ:
# Configure the RolePermissionMappings by environment variable using JSON notation: # Configure the RolePermissionMappings by environment variable using JSON notation:
# ZITADEL_INTERNALAUTHZ_ROLEPERMISSIONMAPPINGS='[{"role": "IAM_OWNER", "permissions": ["iam.write"]}, {"role": "ORG_OWNER", "permissions": ["org.write"]}]' # ZITADEL_INTERNALAUTHZ_ROLEPERMISSIONMAPPINGS='[{"role": "IAM_OWNER", "permissions": ["iam.write"]}, {"role": "ORG_OWNER", "permissions": ["org.write"]}]'

View File

@@ -147,7 +147,7 @@ func projections(
sessionTokenVerifier, sessionTokenVerifier,
func(q *query.Queries) domain.PermissionCheck { func(q *query.Queries) domain.PermissionCheck {
return func(ctx context.Context, permission, orgID, resourceID string) (err error) { return func(ctx context.Context, permission, orgID, resourceID string) (err error) {
return internal_authz.CheckPermission(ctx, &authz_es.UserMembershipRepo{Queries: q}, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID) return internal_authz.CheckPermission(ctx, &authz_es.UserMembershipRepo{Queries: q}, nil, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
} }
}, },
0, 0,
@@ -184,7 +184,7 @@ func projections(
keys.Target, keys.Target,
&http.Client{}, &http.Client{},
func(ctx context.Context, permission, orgID, resourceID string) (err error) { func(ctx context.Context, permission, orgID, resourceID string) (err error) {
return internal_authz.CheckPermission(ctx, authZRepo, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID) return internal_authz.CheckPermission(ctx, authZRepo, nil, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
}, },
sessionTokenVerifier, sessionTokenVerifier,
config.OIDC.DefaultAccessTokenLifetime, config.OIDC.DefaultAccessTokenLifetime,

View File

@@ -410,7 +410,7 @@ func startCommandsQueries(
sessionTokenVerifier, sessionTokenVerifier,
func(q *query.Queries) domain.PermissionCheck { func(q *query.Queries) domain.PermissionCheck {
return func(ctx context.Context, permission, orgID, resourceID string) (err error) { return func(ctx context.Context, permission, orgID, resourceID string) (err error) {
return internal_authz.CheckPermission(ctx, &authz_es.UserMembershipRepo{Queries: q}, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID) return internal_authz.CheckPermission(ctx, &authz_es.UserMembershipRepo{Queries: q}, nil, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
} }
}, },
0, // not needed for projections 0, // not needed for projections
@@ -435,7 +435,7 @@ func startCommandsQueries(
authZRepo, err := authz.Start(queries, eventstoreClient, dbClient, keys.OIDC, config.ExternalSecure) authZRepo, err := authz.Start(queries, eventstoreClient, dbClient, keys.OIDC, config.ExternalSecure)
logging.OnError(err).Fatal("unable to start authz repo") logging.OnError(err).Fatal("unable to start authz repo")
permissionCheck := func(ctx context.Context, permission, orgID, resourceID string) (err error) { permissionCheck := func(ctx context.Context, permission, orgID, resourceID string) (err error) {
return internal_authz.CheckPermission(ctx, authZRepo, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID) return internal_authz.CheckPermission(ctx, authZRepo, nil, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
} }
commands, err := command.StartCommands(ctx, commands, err := command.StartCommands(ctx,

View File

@@ -1,6 +1,7 @@
package start package start
import ( import (
"fmt"
"time" "time"
"github.com/mitchellh/mapstructure" "github.com/mitchellh/mapstructure"
@@ -11,7 +12,7 @@ import (
"github.com/zitadel/zitadel/cmd/hooks" "github.com/zitadel/zitadel/cmd/hooks"
"github.com/zitadel/zitadel/internal/actions" "github.com/zitadel/zitadel/internal/actions"
admin_es "github.com/zitadel/zitadel/internal/admin/repository/eventsourcing" admin_es "github.com/zitadel/zitadel/internal/admin/repository/eventsourcing"
internal_authz "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/api/http/middleware" "github.com/zitadel/zitadel/internal/api/http/middleware"
"github.com/zitadel/zitadel/internal/api/oidc" "github.com/zitadel/zitadel/internal/api/oidc"
"github.com/zitadel/zitadel/internal/api/saml" "github.com/zitadel/zitadel/internal/api/saml"
@@ -65,12 +66,13 @@ type Config struct {
Login login.Config Login login.Config
Console console.Config Console console.Config
AssetStorage static_config.AssetStorageConfig AssetStorage static_config.AssetStorageConfig
InternalAuthZ internal_authz.Config InternalAuthZ authz.Config
SystemAuthZ authz.Config
SystemDefaults systemdefaults.SystemDefaults SystemDefaults systemdefaults.SystemDefaults
EncryptionKeys *encryption.EncryptionKeyConfig EncryptionKeys *encryption.EncryptionKeyConfig
DefaultInstance command.InstanceSetup DefaultInstance command.InstanceSetup
AuditLogRetention time.Duration AuditLogRetention time.Duration
SystemAPIUsers map[string]*internal_authz.SystemAPIUser SystemAPIUsers map[string]*authz.SystemAPIUser
CustomerPortal string CustomerPortal string
Machine *id.Config Machine *id.Config
Actions *actions.Config Actions *actions.Config
@@ -94,12 +96,12 @@ func MustNewConfig(v *viper.Viper) *Config {
err := v.Unmarshal(config, err := v.Unmarshal(config,
viper.DecodeHook(mapstructure.ComposeDecodeHookFunc( viper.DecodeHook(mapstructure.ComposeDecodeHookFunc(
hooks.SliceTypeStringDecode[*domain.CustomMessageText], hooks.SliceTypeStringDecode[*domain.CustomMessageText],
hooks.SliceTypeStringDecode[internal_authz.RoleMapping], hooks.SliceTypeStringDecode[authz.RoleMapping],
hooks.MapTypeStringDecode[string, *internal_authz.SystemAPIUser], hooks.MapTypeStringDecode[string, *authz.SystemAPIUser],
hooks.MapHTTPHeaderStringDecode, hooks.MapHTTPHeaderStringDecode,
database.DecodeHook, database.DecodeHook,
actions.HTTPConfigDecodeHook, actions.HTTPConfigDecodeHook,
hook.EnumHookFunc(internal_authz.MemberTypeString), hook.EnumHookFunc(authz.MemberTypeString),
hooks.MapTypeStringDecode[domain.Feature, any], hooks.MapTypeStringDecode[domain.Feature, any],
hooks.SliceTypeStringDecode[*command.SetQuota], hooks.SliceTypeStringDecode[*command.SetQuota],
hook.Base64ToBytesHookFunc(), hook.Base64ToBytesHookFunc(),
@@ -129,6 +131,7 @@ func MustNewConfig(v *viper.Viper) *Config {
// Copy the global role permissions mappings to the instance until we allow instance-level configuration over the API. // Copy the global role permissions mappings to the instance until we allow instance-level configuration over the API.
config.DefaultInstance.RolePermissionMappings = config.InternalAuthZ.RolePermissionMappings config.DefaultInstance.RolePermissionMappings = config.InternalAuthZ.RolePermissionMappings
fmt.Printf("@@ >>>>>>>>>>>>>>>>>>>>>>>>>>>> config.SystemAuthZ = %+v\n", config.SystemAuthZ)
return config return config
} }

View File

@@ -174,6 +174,12 @@ func startZitadel(ctx context.Context, config *Config, masterKey string, server
return fmt.Errorf("unable to start caches: %w", err) return fmt.Errorf("unable to start caches: %w", err)
} }
systemPermissions := make([]string, 0)
// for _, roleMapping := range config.SystemAuthZ.RolePermissionMappings {
// systemPermissions = append(systemPermissions, roleMapping.Permissions...)
// }
// config.InternalAuthZ.SystemUserPermissions = systemPermissions
queries, err := query.StartQueries( queries, err := query.StartQueries(
ctx, ctx,
eventstoreClient, eventstoreClient,
@@ -192,7 +198,7 @@ func startZitadel(ctx context.Context, config *Config, masterKey string, server
sessionTokenVerifier, sessionTokenVerifier,
func(q *query.Queries) domain.PermissionCheck { func(q *query.Queries) domain.PermissionCheck {
return func(ctx context.Context, permission, orgID, resourceID string) (err error) { return func(ctx context.Context, permission, orgID, resourceID string) (err error) {
return internal_authz.CheckPermission(ctx, &authz_es.UserMembershipRepo{Queries: q}, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID) return internal_authz.CheckPermission(ctx, &authz_es.UserMembershipRepo{Queries: q}, systemPermissions, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
} }
}, },
config.AuditLogRetention, config.AuditLogRetention,
@@ -208,7 +214,7 @@ func startZitadel(ctx context.Context, config *Config, masterKey string, server
return fmt.Errorf("error starting authz repo: %w", err) return fmt.Errorf("error starting authz repo: %w", err)
} }
permissionCheck := func(ctx context.Context, permission, orgID, resourceID string) (err error) { permissionCheck := func(ctx context.Context, permission, orgID, resourceID string) (err error) {
return internal_authz.CheckPermission(ctx, authZRepo, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID) return internal_authz.CheckPermission(ctx, authZRepo, systemPermissions, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
} }
storage, err := config.AssetStorage.NewStorage(dbClient.DB) storage, err := config.AssetStorage.NewStorage(dbClient.DB)
@@ -407,7 +413,8 @@ func startAPIs(
http_util.WithMaxAge(int(math.Floor(config.Quotas.Access.ExhaustedCookieMaxAge.Seconds()))), http_util.WithMaxAge(int(math.Floor(config.Quotas.Access.ExhaustedCookieMaxAge.Seconds()))),
) )
limitingAccessInterceptor := middleware.NewAccessInterceptor(accessSvc, exhaustedCookieHandler, &config.Quotas.Access.AccessConfig) limitingAccessInterceptor := middleware.NewAccessInterceptor(accessSvc, exhaustedCookieHandler, &config.Quotas.Access.AccessConfig)
apis, err := api.New(ctx, config.Port, router, queries, verifier, config.InternalAuthZ, tlsConfig, config.ExternalDomain, append(config.InstanceHostHeaders, config.PublicHostHeaders...), limitingAccessInterceptor)
apis, err := api.New(ctx, config.Port, router, queries, verifier, config.SystemAuthZ, config.InternalAuthZ, tlsConfig, config.ExternalDomain, append(config.InstanceHostHeaders, config.PublicHostHeaders...), limitingAccessInterceptor)
if err != nil { if err != nil {
return nil, fmt.Errorf("error creating api %w", err) return nil, fmt.Errorf("error creating api %w", err)
} }
@@ -600,7 +607,7 @@ func listen(ctx context.Context, router *mux.Router, port uint16, tlsConfig *tls
go func() { go func() {
logging.Infof("server is listening on %s", lis.Addr().String()) logging.Infof("server is listening on %s", lis.Addr().String())
if tlsConfig != nil { if tlsConfig != nil {
//we don't need to pass the files here, because we already initialized the TLS config on the server // we don't need to pass the files here, because we already initialized the TLS config on the server
errCh <- http1Server.ServeTLS(lis, "", "") errCh <- http1Server.ServeTLS(lis, "", "")
} else { } else {
errCh <- http1Server.Serve(lis) errCh <- http1Server.Serve(lis)

View File

@@ -15,7 +15,7 @@ import (
healthpb "google.golang.org/grpc/health/grpc_health_v1" healthpb "google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/reflection" "google.golang.org/grpc/reflection"
internal_authz "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/api/grpc/server" "github.com/zitadel/zitadel/internal/api/grpc/server"
http_util "github.com/zitadel/zitadel/internal/api/http" http_util "github.com/zitadel/zitadel/internal/api/http"
http_mw "github.com/zitadel/zitadel/internal/api/http/middleware" http_mw "github.com/zitadel/zitadel/internal/api/http/middleware"
@@ -29,7 +29,7 @@ import (
type API struct { type API struct {
port uint16 port uint16
grpcServer *grpc.Server grpcServer *grpc.Server
verifier internal_authz.APITokenVerifier verifier authz.APITokenVerifier
health healthCheck health healthCheck
router *mux.Router router *mux.Router
hostHeaders []string hostHeaders []string
@@ -72,8 +72,9 @@ func New(
port uint16, port uint16,
router *mux.Router, router *mux.Router,
queries *query.Queries, queries *query.Queries,
verifier internal_authz.APITokenVerifier, verifier authz.APITokenVerifier,
authZ internal_authz.Config, systemAuthz authz.Config,
authZ authz.Config,
tlsConfig *tls.Config, tlsConfig *tls.Config,
externalDomain string, externalDomain string,
hostHeaders []string, hostHeaders []string,
@@ -89,7 +90,7 @@ func New(
hostHeaders: hostHeaders, hostHeaders: hostHeaders,
} }
api.grpcServer = server.CreateServer(api.verifier, authZ, queries, externalDomain, tlsConfig, accessInterceptor.AccessService()) api.grpcServer = server.CreateServer(api.verifier, systemAuthz, authZ, queries, externalDomain, tlsConfig, accessInterceptor.AccessService())
api.grpcGateway, err = server.CreateGateway(ctx, port, hostHeaders, accessInterceptor, tlsConfig) api.grpcGateway, err = server.CreateGateway(ctx, port, hostHeaders, accessInterceptor, tlsConfig)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -20,7 +20,7 @@ const (
// - the organisation (**either** provided by ID or verified domain) exists // - the organisation (**either** provided by ID or verified domain) exists
// - the user is permitted to call the requested endpoint (permission option in proto) // - the user is permitted to call the requested endpoint (permission option in proto)
// it will pass the [CtxData] and permission of the user into the ctx [context.Context] // it will pass the [CtxData] and permission of the user into the ctx [context.Context]
func CheckUserAuthorization(ctx context.Context, req interface{}, token, orgID, orgDomain string, verifier APITokenVerifier, authConfig Config, requiredAuthOption Option, method string) (ctxSetter func(context.Context) context.Context, err error) { func CheckUserAuthorization(ctx context.Context, req interface{}, token, orgID, orgDomain string, verifier APITokenVerifier, SystemAuthConfig Config, authConfig Config, requiredAuthOption Option, method string) (ctxSetter func(context.Context) context.Context, err error) {
ctx, span := tracing.NewServerInterceptorSpan(ctx) ctx, span := tracing.NewServerInterceptorSpan(ctx)
defer func() { span.EndWithError(err) }() defer func() { span.EndWithError(err) }()
@@ -31,12 +31,12 @@ func CheckUserAuthorization(ctx context.Context, req interface{}, token, orgID,
if requiredAuthOption.Permission == authenticated { if requiredAuthOption.Permission == authenticated {
return func(parent context.Context) context.Context { return func(parent context.Context) context.Context {
parent = addGetSystemUserRolesFuncToCtx(parent, ctxData) parent = addGetSystemUserRolesFuncToCtx(parent, SystemAuthConfig.RolePermissionMappings, ctxData)
return context.WithValue(parent, dataKey, ctxData) return context.WithValue(parent, dataKey, ctxData)
}, nil }, nil
} }
requestedPermissions, allPermissions, err := getUserPermissions(ctx, verifier, requiredAuthOption.Permission, authConfig.RolePermissionMappings, ctxData, ctxData.OrgID) requestedPermissions, allPermissions, err := getUserPermissions(ctx, verifier, requiredAuthOption.Permission, SystemAuthConfig.RolePermissionMappings, authConfig.RolePermissionMappings, ctxData, ctxData.OrgID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -52,7 +52,7 @@ func CheckUserAuthorization(ctx context.Context, req interface{}, token, orgID,
parent = context.WithValue(parent, dataKey, ctxData) parent = context.WithValue(parent, dataKey, ctxData)
parent = context.WithValue(parent, allPermissionsKey, allPermissions) parent = context.WithValue(parent, allPermissionsKey, allPermissions)
parent = context.WithValue(parent, requestPermissionsKey, requestedPermissions) parent = context.WithValue(parent, requestPermissionsKey, requestedPermissions)
parent = addGetSystemUserRolesFuncToCtx(parent, ctxData) parent = addGetSystemUserRolesFuncToCtx(parent, SystemAuthConfig.RolePermissionMappings, ctxData)
return parent return parent
}, nil }, nil
} }
@@ -129,17 +129,17 @@ func GetAllPermissionCtxIDs(perms []string) []string {
return ctxIDs return ctxIDs
} }
func addGetSystemUserRolesFuncToCtx(ctx context.Context, ctxData CtxData) context.Context { func addGetSystemUserRolesFuncToCtx(ctx context.Context, systemUserRoleMap []RoleMapping, ctxData CtxData) context.Context {
if len(ctxData.SystemMemberships) != 0 { if len(ctxData.SystemMemberships) != 0 && ctxData.SystemMemberships[0].MemberType == MemberTypeSystem {
ctx = context.WithValue(ctx, systemUserRolesFuncKey, func() func(ctx context.Context) ([]string, error) { ctx = context.WithValue(ctx, systemUserRolesFuncKey, func() func(ctx context.Context) ([]string, error) {
var roles []string var permissions []string
return func(ctx context.Context) ([]string, error) { return func(ctx context.Context) ([]string, error) {
if roles != nil { if permissions != nil {
return roles, nil return permissions, nil
} }
var err error var err error
roles, err = getSystemUserRoles(ctx) permissions, err = getSystemUserPermissions(ctx, systemUserRoleMap)
return roles, err return permissions, err
} }
}()) }())
} }
@@ -158,17 +158,15 @@ func GetSystemUserRoles(ctx context.Context) ([]string, error) {
return getSystemUserRolesFunc(ctx) return getSystemUserRolesFunc(ctx)
} }
func getSystemUserRoles(ctx context.Context) ([]string, error) { func getSystemUserPermissions(ctx context.Context, systemUserRoleMap []RoleMapping) ([]string, error) {
ctxData, ok := ctx.Value(dataKey).(CtxData) ctxData, ok := ctx.Value(dataKey).(CtxData)
if !ok { if !ok {
return nil, errors.New("unable to obtain ctxData") return nil, errors.New("unable to obtain ctxData")
} }
var roles []string var permissions []string
if ctxData.SystemMemberships != nil { for _, member := range ctxData.SystemMemberships {
for _, member := range ctxData.SystemMemberships { permissions = append(permissions, member.Roles...)
roles = append(roles, member.Roles...)
}
} }
return roles, nil return permissions, nil
} }

View File

@@ -55,6 +55,9 @@ type Membership struct {
ObjectID string ObjectID string
Roles []string Roles []string
// aggregate all the permissions for each role
Permissions []string
} }
type MemberType int32 type MemberType int32

View File

@@ -7,7 +7,7 @@ import (
"github.com/zitadel/zitadel/internal/zerrors" "github.com/zitadel/zitadel/internal/zerrors"
) )
func CheckPermission(ctx context.Context, resolver MembershipsResolver, roleMappings []RoleMapping, permission, orgID, resourceID string) (err error) { func CheckPermission(ctx context.Context, resolver MembershipsResolver, systemPermissions []string, roleMappings []RoleMapping, permission, orgID, resourceID string) (err error) {
requestedPermissions, _, err := getUserPermissions(ctx, resolver, permission, roleMappings, GetCtxData(ctx), orgID) requestedPermissions, _, err := getUserPermissions(ctx, resolver, permission, roleMappings, GetCtxData(ctx), orgID)
if err != nil { if err != nil {
return err return err
@@ -22,7 +22,7 @@ func CheckPermission(ctx context.Context, resolver MembershipsResolver, roleMapp
// getUserPermissions retrieves the memberships of the authenticated user (on instance and provided organisation level), // getUserPermissions retrieves the memberships of the authenticated user (on instance and provided organisation level),
// and maps them to permissions. It will return the requested permission(s) and all other granted permissions separately. // and maps them to permissions. It will return the requested permission(s) and all other granted permissions separately.
func getUserPermissions(ctx context.Context, resolver MembershipsResolver, requiredPerm string, roleMappings []RoleMapping, ctxData CtxData, orgID string) (requestedPermissions, allPermissions []string, err error) { func getUserPermissions(ctx context.Context, resolver MembershipsResolver, requiredPerm string, SystemUserRoleMappings []RoleMapping, roleMappings []RoleMapping, ctxData CtxData, orgID string) (requestedPermissions, allPermissions []string, err error) {
ctx, span := tracing.NewSpan(ctx) ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }() defer func() { span.EndWithError(err) }()
@@ -31,7 +31,7 @@ func getUserPermissions(ctx context.Context, resolver MembershipsResolver, requi
} }
if ctxData.SystemMemberships != nil { if ctxData.SystemMemberships != nil {
requestedPermissions, allPermissions = mapMembershipsToPermissions(requiredPerm, ctxData.SystemMemberships, roleMappings) requestedPermissions, allPermissions = mapMembershipsToPermissions(requiredPerm, ctxData.SystemMemberships, SystemUserRoleMappings)
return requestedPermissions, allPermissions, nil return requestedPermissions, allPermissions, nil
} }

View File

@@ -13,13 +13,13 @@ import (
"github.com/zitadel/zitadel/internal/telemetry/tracing" "github.com/zitadel/zitadel/internal/telemetry/tracing"
) )
func AuthorizationInterceptor(verifier authz.APITokenVerifier, authConfig authz.Config) grpc.UnaryServerInterceptor { func AuthorizationInterceptor(verifier authz.APITokenVerifier, systemUserPermissions authz.Config, authConfig authz.Config) grpc.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
return authorize(ctx, req, info, handler, verifier, authConfig) return authorize(ctx, req, info, handler, verifier, systemUserPermissions, authConfig)
} }
} }
func authorize(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler, verifier authz.APITokenVerifier, authConfig authz.Config) (_ interface{}, err error) { func authorize(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler, verifier authz.APITokenVerifier, systemUserPermissions authz.Config, authConfig authz.Config) (_ interface{}, err error) {
authOpt, needsToken := verifier.CheckAuthMethod(info.FullMethod) authOpt, needsToken := verifier.CheckAuthMethod(info.FullMethod)
if !needsToken { if !needsToken {
return handler(ctx, req) return handler(ctx, req)
@@ -34,7 +34,7 @@ func authorize(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo,
} }
orgID, orgDomain := orgIDAndDomainFromRequest(authCtx, req) orgID, orgDomain := orgIDAndDomainFromRequest(authCtx, req)
ctxSetter, err := authz.CheckUserAuthorization(authCtx, req, authToken, orgID, orgDomain, verifier, authConfig, authOpt, info.FullMethod) ctxSetter, err := authz.CheckUserAuthorization(authCtx, req, authToken, orgID, orgDomain, verifier, systemUserPermissions, authConfig, authOpt, info.FullMethod)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -36,6 +36,7 @@ type WithGatewayPrefix interface {
func CreateServer( func CreateServer(
verifier authz.APITokenVerifier, verifier authz.APITokenVerifier,
systemAuthz authz.Config,
authConfig authz.Config, authConfig authz.Config,
queries *query.Queries, queries *query.Queries,
externalDomain string, externalDomain string,
@@ -53,7 +54,7 @@ func CreateServer(
middleware.AccessStorageInterceptor(accessSvc), middleware.AccessStorageInterceptor(accessSvc),
middleware.ErrorHandler(), middleware.ErrorHandler(),
middleware.LimitsInterceptor(system_pb.SystemService_ServiceDesc.ServiceName), middleware.LimitsInterceptor(system_pb.SystemService_ServiceDesc.ServiceName),
middleware.AuthorizationInterceptor(verifier, authConfig), middleware.AuthorizationInterceptor(verifier, systemAuthz, authConfig),
middleware.TranslationHandler(), middleware.TranslationHandler(),
middleware.QuotaExhaustedInterceptor(accessSvc, system_pb.SystemService_ServiceDesc.ServiceName), middleware.QuotaExhaustedInterceptor(accessSvc, system_pb.SystemService_ServiceDesc.ServiceName),
middleware.ExecutionHandler(queries), middleware.ExecutionHandler(queries),

View File

@@ -71,7 +71,7 @@ func authorize(r *http.Request, verifier authz.APITokenVerifier, authConfig auth
return nil, zerrors.ThrowUnauthenticated(nil, "AUT-1179", "auth header missing") return nil, zerrors.ThrowUnauthenticated(nil, "AUT-1179", "auth header missing")
} }
ctxSetter, err := authz.CheckUserAuthorization(authCtx, &httpReq{}, authToken, http_util.GetOrgID(r), "", verifier, authConfig, authOpt, r.RequestURI) ctxSetter, err := authz.CheckUserAuthorization(authCtx, &httpReq{}, authToken, http_util.GetOrgID(r), "", verifier, authConfig, authConfig, authOpt, r.RequestURI)
if err != nil { if err != nil {
return nil, err return nil, err
} }