package ape import ( "context" "fmt" objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object" apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id" apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain" policyengine "git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine" ) type checkerImpl struct { chainRouter policyengine.ChainRouter headerProvider HeaderProvider } func NewChecker(chainRouter policyengine.ChainRouter, headerProvider HeaderProvider) Checker { return &checkerImpl{ chainRouter: chainRouter, headerProvider: headerProvider, } } type Prm struct { Namespace string Container cid.ID // Object ID is omitted for some methods. Object *oid.ID // If Header is set, then object attributes and properties will be parsed from // a request/response's header. Header *objectV2.Header // Method must be represented only as a constant represented in native schema. Method string // Role must be representedonly as a constant represented in native schema. Role string // An encoded sender's public key string. SenderKey string } var ( errMissingOID = fmt.Errorf("object ID is not set") ) // CheckAPE checks if a request or a response is permitted creating an ape request and passing // it to chain router. func (c *checkerImpl) CheckAPE(ctx context.Context, prm Prm) error { r, err := c.newAPERequest(ctx, prm) if err != nil { return fmt.Errorf("failed to create ape request: %w", err) } status, ruleFound, err := c.chainRouter.IsAllowed(apechain.Ingress, policyengine.NewRequestTarget(prm.Namespace, prm.Container.EncodeToString()), r) if err != nil { return err } if !ruleFound || status == apechain.Allow { return nil } return apeErr(prm.Method, status) } const accessDeniedAPEReasonFmt = "access to operation %s is denied by access policy engine: %s" func apeErr(op string, status apechain.Status) error { errAccessDenied := &apistatus.ObjectAccessDenied{} errAccessDenied.WriteReason(fmt.Sprintf(accessDeniedAPEReasonFmt, op, status.String())) return errAccessDenied }