Skip to content
Snippets Groups Projects
Select Git revision
  • 8aab3d5f917e1f1b3109b37205f09156ca787e72
  • master default protected
  • feature/PRXS-3383-CollectionsRankSortAPI
  • fix/PRXS-3401-ValidateValidationOpts
  • feature/3149-LocaleCodeAsID-Feature
  • feature/PRXS-3383-CollectionsSort
  • feature/3109-SerializeFeature
  • release/0.33
  • feature/3109-RecoverySchema
  • feature/3109-feature
  • fix/PRXS-3369-ValidateFields
  • refactor/PRXS-3306-MovePkgGroup1
  • refactor/6-pkg-refactor-expr
  • fix/PRXS-3360-TemplateBuilderPatch
  • feature/3293-MongoV2
  • feature/3272-GoVersionUp
  • feature/PRXS-3218-HideTemplateActions
  • feature/PRXS-3234-PruneIdents
  • feature/3146-UpdateItemStorageInterface
  • feature/3274-ObjectIndexesFixes
  • feature/PRXS-3143-3235-ReferenceOptions
  • v0.33.1
  • v0.32.0
  • v0.31.1
  • v0.31.0
  • v0.30.0
  • v0.29.0
  • v0.28.0
  • v0.27.0-alpha.1+16
  • v0.27.0-alpha.1+15
  • v0.27.0-alpha.1+14
  • v0.27.0-alpha.1+13
  • v0.27.0-alpha.1+12
  • v0.27.0-alpha.1+11
  • v0.27.0-alpha.1+10
  • v0.27.0-alpha.1+9
  • v0.27.0-alpha.1+8
  • v0.27.0-alpha.1+7
  • v0.27.0-alpha.1+6
  • v0.27.0-alpha.1+5
  • v0.27.0-alpha.1+4
41 results

client.go

Blame
  • client.go 5.45 KiB
    package auth
    
    import (
    	"context"
    	"fmt"
    
    	"git.perx.ru/perxis/perxis-go/pkg/clients"
    	"git.perx.ru/perxis/perxis-go/pkg/collaborators"
    	"git.perx.ru/perxis/perxis-go/pkg/environments"
    	"git.perx.ru/perxis/perxis-go/pkg/errors"
    	"git.perx.ru/perxis/perxis-go/pkg/members"
    	"git.perx.ru/perxis/perxis-go/pkg/permission"
    	"git.perx.ru/perxis/perxis-go/pkg/roles"
    	"git.perx.ru/perxis/perxis-go/pkg/service"
    	"git.perx.ru/perxis/perxis-go/pkg/spaces"
    )
    
    type ClientPrincipal struct {
    	identity *clients.GetByParams
    	spaceID  string
    	space    *spaces.Space
    
    	client  *clients.Client
    	invalid bool
    
    	spaces        spaces.Spaces
    	environments  environments.Environments
    	clients       clients.Clients
    	roles         roles.Roles
    	collaborators collaborators.Collaborators
    }
    
    func NewClientPrincipal(identity *clients.GetByParams) *ClientPrincipal {
    	return &ClientPrincipal{identity: identity}
    }
    
    func (c ClientPrincipal) Format(f fmt.State, verb rune) {
    	var identity string
    	switch {
    	case c.identity == nil:
    		identity = "<nil>"
    	case c.identity.APIKey != "":
    		identity = fmt.Sprintf("APIKey: '%s'", c.identity.APIKey)
    	case c.identity.OAuthClientID != "":
    		identity = fmt.Sprintf("OAuthClientID: '%s'", c.identity.OAuthClientID)
    	case c.identity.TLSSubject != "":
    		identity = fmt.Sprintf("TLSSubject: '%s'", c.identity.TLSSubject)
    	}
    
    	var id string
    	if c.client != nil {
    		id = c.client.ID
    	}
    
    	_, _ = f.Write([]byte(fmt.Sprintf("ClientPrincipal{ID: '%s', Identity: {%s}}", id, identity)))
    }
    
    func (c *ClientPrincipal) Space(spaceID string) SpaceAccessor {
    	c.spaceID = spaceID
    	c.space = nil
    	c.invalid = false
    	c.client = nil
    	return c
    }
    
    // nolint:unused
    func (c *ClientPrincipal) getSpace(ctx context.Context, spaceID string) *spaces.Space {
    	if spaceID == "" {
    		return nil
    	}
    	space, _ := c.spaces.Get(WithSystem(ctx), spaceID)
    	return space
    }
    
    func (ClientPrincipal) IsSystem(ctx context.Context) bool {
    	return false
    }
    
    func (c *ClientPrincipal) IsManagementAllowed(ctx context.Context, spaceID string) error {
    	if !c.IsValid(ctx) {
    		return service.ErrAccessDenied
    	}
    
    	if role := c.Role(ctx, spaceID); role != nil && role.AllowManagement {
    		return nil
    	}
    
    	return service.ErrAccessDenied
    }
    
    func (c *ClientPrincipal) Member(ctx context.Context) members.Role {
    	return members.NotMember
    }
    
    func (c *ClientPrincipal) HasSpaceAccess(ctx context.Context, spaceID string) bool {
    	if c.spaceID == "" {
    		return false
    	}
    	client, _ := c.Client(ctx)
    	return client != nil && client.SpaceID == spaceID
    }
    
    func (c *ClientPrincipal) GetID(ctx context.Context) string {
    	client, _ := c.Client(ctx)
    	if client == nil {
    		return ""
    	}
    	return client.ID
    }
    
    func (c *ClientPrincipal) GetIdentity(ctx context.Context) *clients.GetByParams {
    	return c.identity
    }
    
    func (c *ClientPrincipal) IsValid(ctx context.Context) bool {
    	if c == nil {
    		return false
    	}
    	client, _ := c.Client(ctx)
    	return client != nil
    }
    
    func (c *ClientPrincipal) Client(ctx context.Context) (*clients.Client, error) {
    	if c.invalid {
    		return nil, nil
    	}
    
    	if c.client != nil {
    		return c.client, nil
    	}
    
    	if c.clients == nil {
    		c.invalid = true
    		return nil, nil
    	}
    
    	client, err := c.clients.GetBy(WithSystem(ctx), c.spaceID, c.identity)
    	if err != nil || client == nil || client.IsDisabled() {
    		c.invalid = true
    		return nil, err
    	}
    
    	c.client = client
    	return c.client, nil
    }
    
    func (c *ClientPrincipal) HasEnvironmentAccess(ctx context.Context, spaceID, envID string) bool {
    	return hasEnvironmentAccess(ctx, c.environments, c.Role(ctx, spaceID), envID)
    }
    
    func (c *ClientPrincipal) getRoleID(ctx context.Context, spaceID string) (string, bool) {
    
    	if c.spaceID == "" || spaceID == "" {
    		return "", false
    	}
    
    	if spaceID == c.spaceID {
    		cl, _ := c.Client(ctx)
    		if cl == nil || cl.RoleID == "" {
    			return "", false
    		}
    
    		return cl.RoleID, true
    	}
    
    	rID, err := c.collaborators.Get(WithSystem(ctx), spaceID, c.spaceID)
    	if err != nil {
    		rID = roles.ViewRole
    	}
    	return rID, true
    
    }
    
    func (c *ClientPrincipal) Role(ctx context.Context, spaceID string) *roles.Role {
    	if c.spaceID == "" {
    		return nil
    	}
    
    	rID, ok := c.getRoleID(ctx, spaceID)
    	if !ok {
    		return nil
    	}
    
    	role, err := c.roles.Get(WithSystem(ctx), spaceID, rID)
    	if err == nil {
    		// c.hasRole = true
    		// c.role = role
    		return role
    	}
    
    	return nil
    }
    
    func (c *ClientPrincipal) Rules(ctx context.Context, spaceID, envID string) permission.Ruleset {
    	if c.spaceID == "" || spaceID == "" || envID == "" {
    		return nil
    	}
    
    	role := c.Role(ctx, spaceID)
    	if role == nil {
    		return nil
    	}
    
    	if role.AllowManagement {
    		return permission.PrivilegedRuleset{}
    	}
    
    	if hasEnvironmentAccess(ctx, c.environments, role, envID) {
    		return role.Rules
    	}
    	return nil
    }
    
    func (c *ClientPrincipal) HasAccess(ctx context.Context, spaceID, orgID string) error {
    	if !c.IsValid(ctx) {
    		return service.ErrAccessDenied
    	}
    
    	if c.IsSystem(ctx) {
    		return nil
    	}
    
    	if spaceID != "" {
    		if c.spaceID == "" {
    			return service.ErrAccessDenied
    		}
    
    		client, _ := c.Client(ctx)
    		if client != nil && client.SpaceID == spaceID {
    			return nil
    		}
    	}
    
    	if c.Member(ctx).IsPrivileged() {
    		return nil
    	}
    
    	return service.ErrAccessDenied
    }
    
    // nolint:unused
    func (c *ClientPrincipal) hasRole(ctx context.Context, spaceID string) (bool, error) {
    	if c.spaceID == "" {
    		return false, nil
    	}
    
    	client, err := c.Client(ctx)
    	if err != nil && errors.Is(err, service.ErrNotFound) {
    		if sp := c.getSpace(ctx, spaceID); sp == nil {
    			return false, service.ErrNotFound
    		}
    	}
    	if client != nil && client.SpaceID == spaceID {
    		return true, nil
    	}
    
    	return false, nil
    }