diff --git a/pkg/auth/client.go b/pkg/auth/client.go index cf63410f0c2efb4c3d2150ce3956a75c5e1cbfab..a758c7ab0976583a1bd032b4b356b96e885507ac 100644 --- a/pkg/auth/client.go +++ b/pkg/auth/client.go @@ -143,7 +143,7 @@ func (c *ClientPrincipal) Client(ctx context.Context) (*clients.Client, error) { } func (c *ClientPrincipal) HasEnvironmentAccess(ctx context.Context, spaceID, envID string) bool { - return hasEnvironmentAccess(ctx, c.environments, c.Role(ctx, spaceID), envID) + return c.Role(ctx, spaceID).CanAccessEnvironment(WithSystem(ctx), c.environments, spaceID, envID) } func (c *ClientPrincipal) getRoleID(ctx context.Context, spaceID string) (string, bool) { @@ -203,7 +203,7 @@ func (c *ClientPrincipal) Rules(ctx context.Context, spaceID, envID string) perm return permission.PrivilegedRuleset{} } - if hasEnvironmentAccess(ctx, c.environments, role, envID) { + if role.CanAccessEnvironment(WithSystem(ctx), c.environments, spaceID, envID) { return role.Rules } return nil diff --git a/pkg/auth/errors.go b/pkg/auth/errors.go index cc127435ee293843a7912cda0b85a599dcac14bc..8522ec94ff4ac7e04e6eabfdca561f698645db9d 100644 --- a/pkg/auth/errors.go +++ b/pkg/auth/errors.go @@ -1,7 +1,10 @@ package auth -import service "git.perx.ru/perxis/perxis/services" +import ( + "git.perx.ru/perxis/perxis-go/pkg/errors" +) var ( - ErrAccessDenied = service.ErrAccessDenied + ErrAccessDenied = errors.PermissionDenied(errors.New("access denied")) + ErrNotFound = errors.NotFound(errors.New("not found")) ) diff --git a/pkg/auth/grpc.go b/pkg/auth/grpc.go index 8cc0e209dfa60e0271287d7b160f6bb9095c83c5..7a566711db76c11b22206d947ba94ecc2bc3b366 100644 --- a/pkg/auth/grpc.go +++ b/pkg/auth/grpc.go @@ -9,10 +9,6 @@ import ( ) const ( - - // todo: объединить OAuth2IdentityMetadata, TLSIdentityMetadata, AuthorizationMetadata - // в один заголовок ?? - OAuth2IdentityMetadata = "x-perxis-identity" TLSIdentityMetadata = "x-forwarded-client-cert" AccessMetadata = "x-perxis-access" @@ -49,7 +45,6 @@ func ContextToGRPC() kitgrpc.ClientRequestFunc { switch p := p.(type) { case *UserPrincipal: if p.GetIdentity(ctx) != "" { - //ctx = metadata.AppendToOutgoingContext(ctx, OAuth2IdentityMetadata, p.GetIdentity(ctx)) (*md)[OAuth2IdentityMetadata] = []string{p.GetIdentity(ctx)} } case *ClientPrincipal: @@ -72,6 +67,8 @@ func ContextToGRPC() kitgrpc.ClientRequestFunc { } } +// PrincipalServerInterceptor - grpc-интерсептор, который используется для получения данных принципала из grpc-метаданы и добавления в контекст ''. В случае, если +// сервис не использует проверку прав 'Principal' к системе, в параметрах передается пустой объект '&PrincipalFactory{}' func PrincipalServerInterceptor(factory *PrincipalFactory) grpc.UnaryServerInterceptor { return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { if md, ok := metadata.FromIncomingContext(ctx); ok { @@ -81,6 +78,8 @@ func PrincipalServerInterceptor(factory *PrincipalFactory) grpc.UnaryServerInter } } +// PrincipalClientInterceptor - grpc-интерсептор, который используется для получения данных принципала. В случае, если +// сервис не использует проверку прав 'Principal' к системе, в параметрах передается пустой объект '&PrincipalFactory{}' func PrincipalClientInterceptor() grpc.UnaryClientInterceptor { return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { md, ok := metadata.FromOutgoingContext(ctx) diff --git a/pkg/auth/principal.go b/pkg/auth/principal.go index f2a3948fc5fbf24038261165ac84c0ef08da9c04..e316083370f85646c7c71adc7842899ccb21a877 100644 --- a/pkg/auth/principal.go +++ b/pkg/auth/principal.go @@ -45,42 +45,42 @@ type OrganizationAccessor interface { Member(ctx context.Context) members.Role } -func hasEnvironmentAccess(ctx context.Context, envsrv environments.Environments, role *roles.Role, envID string) bool { - if role == nil || role.SpaceID == "" || envID == "" { - return false - } - - if role.AllowManagement { - return true - } - - envs := role.Environments - - // Если явно не указаны доступные окружения - доступ по умолчанию к окружению master - if len(envs) == 0 { - envs = []string{environments.DefaultEnvironment} - } - - for _, ce := range envs { - if envID == ce || util.GlobMatch(envID, ce) { - return true - } - } - - e, err := envsrv.Get(WithSystem(ctx), role.SpaceID, envID) - if err != nil || e == nil { - return false - } - - aliases := append(e.Aliases, e.ID) - - for _, ce := range envs { - for _, al := range aliases { - if al == ce || util.GlobMatch(al, ce) { - return true - } - } - } - - return false -} +//func hasEnvironmentAccess(ctx context.Context, envsrv environments.Environments, role *roles.Role, envID string) bool { +// if role == nil || role.SpaceID == "" || envID == "" { +// return false +// } +// +// if role.AllowManagement { +// return true +// } +// +// envs := role.Environments +// +// // Если явно не указаны доступные окружения - доступ по умолчанию к окружению master +// if len(envs) == 0 { +// envs = []string{environments.DefaultEnvironment} +// } +// +// for _, ce := range envs { +// if envID == ce || util.GlobMatch(envID, ce) { +// return true +// } +// } +// +// e, err := envsrv.Get(WithSystem(ctx), role.SpaceID, envID) +// if err != nil || e == nil { +// return false +// } +// +// aliases := append(e.Aliases, e.ID) +// +// for _, ce := range envs { +// for _, al := range aliases { +// if al == ce || util.GlobMatch(al, ce) { +// return true +// } +// } +// } +// +// return false +//} diff --git a/pkg/auth/user.go b/pkg/auth/user.go index 2101848b81d15483801061ccf11345882e7f1f71..d1dc2929ee6aaf939b3e901d52293ce7a43833cd 100644 --- a/pkg/auth/user.go +++ b/pkg/auth/user.go @@ -183,7 +183,7 @@ func (u *UserPrincipal) HasSpaceAccess(ctx context.Context, spaceID string) bool // - Пространство позволяет доступ для не участников (есть роли AnonymousRole/AuthorizedRole/ViewRole) func (u *UserPrincipal) HasAccess(ctx context.Context, spaceID, orgID string) error { if !u.IsValid(ctx) { - return services.ErrAccessDenied + return ErrAccessDenied } if u.IsSystem(ctx) { @@ -211,7 +211,7 @@ func (u *UserPrincipal) HasAccess(ctx context.Context, spaceID, orgID string) er } } - return services.ErrAccessDenied + return ErrAccessDenied } func (u *UserPrincipal) hasRole(ctx context.Context, spaceID string) (bool, error) { @@ -231,9 +231,9 @@ func (u *UserPrincipal) hasRole(ctx context.Context, spaceID string) (bool, erro if rErr == nil { return true, nil } - if errors.Is(cErr, services.ErrNotFound) || errors.Is(rErr, services.ErrNotFound) { + if errors.Is(cErr, ErrNotFound) || errors.Is(rErr, ErrNotFound) { if sp := u.getSpace(ctx, spaceID); sp == nil { - return false, services.ErrNotFound + return false, ErrNotFound } } @@ -250,9 +250,9 @@ func (u *UserPrincipal) hasRole(ctx context.Context, spaceID string) (bool, erro return true, nil } - if errors.Is(cErr, services.ErrNotFound) || errors.Is(rErr, services.ErrNotFound) { + if errors.Is(cErr, ErrNotFound) || errors.Is(rErr, ErrNotFound) { if sp := u.getSpace(ctx, spaceID); sp == nil { - return false, services.ErrNotFound + return false, ErrNotFound } } @@ -306,7 +306,7 @@ func (u *UserPrincipal) Rules(ctx context.Context, spaceID, envID string) permis return nil } - if !hasEnvironmentAccess(ctx, u.environments, role, envID) { + if !role.CanAccessEnvironment(WithSystem(ctx), u.environments, spaceID, envID) { return nil } @@ -331,5 +331,5 @@ func User(ctx context.Context, p Principal) *users.User { } func (u *UserPrincipal) HasEnvironmentAccess(ctx context.Context, spaceID, env string) bool { - return hasEnvironmentAccess(ctx, u.environments, u.Role(ctx, spaceID), env) + return u.Role(ctx, spaceID).CanAccessEnvironment(WithSystem(ctx), u.environments, spaceID, env) } diff --git a/pkg/roles/role.go b/pkg/roles/role.go index 4c284ee5d45026aedfc284ecc16e146e78b56bb2..eecafb64135a8b4545fe7ef894529641ddbab69a 100644 --- a/pkg/roles/role.go +++ b/pkg/roles/role.go @@ -39,25 +39,33 @@ func (r Role) CanAccessEnvironment(ctx context.Context, service environments.Env return false } + if r.AllowManagement { + return true + } + // Если явно не указаны доступные окружения - доступ по умолчанию к окружению master if len(r.Environments) == 0 { r.Environments = []string{environments.DefaultEnvironment} } - if data.Contains(envID, r.Environments) { - return true + for _, e := range r.Environments { + if envID == e || data.GlobMatch(envID, e) { + return true + } } - e, err := service.Get(ctx, spaceID, envID) - if err != nil || e == nil { + env, err := service.Get(ctx, spaceID, envID) + if err != nil || env == nil { return false } - aliases := append(e.Aliases, e.ID) + aliases := append(env.Aliases, env.ID) - for _, ce := range r.Environments { - if data.Contains(ce, aliases) { - return true + for _, e := range r.Environments { + for _, a := range aliases { + if a == e || data.GlobMatch(a, e) { + return true + } } }