forked from TrueCloudLab/frostfs-node
114 lines
3.6 KiB
Go
114 lines
3.6 KiB
Go
package ape
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
|
frostfsidcore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/frostfsid"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/netmap"
|
|
checkercore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/common/ape"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
|
policyengine "git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
|
nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
|
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
|
)
|
|
|
|
type checkerImpl struct {
|
|
checkerCore checkercore.CheckCore
|
|
frostFSIDClient frostfsidcore.SubjectProvider
|
|
headerProvider HeaderProvider
|
|
nm netmap.Source
|
|
cnrSource container.Source
|
|
nodePK []byte
|
|
}
|
|
|
|
func NewChecker(localOverrideStorage policyengine.LocalOverrideStorage, morphChainStorage policyengine.MorphRuleChainStorageReader, headerProvider HeaderProvider, frostFSIDClient frostfsidcore.SubjectProvider, nm netmap.Source, st netmap.State, cnrSource container.Source, nodePK []byte) Checker {
|
|
return &checkerImpl{
|
|
checkerCore: checkercore.New(localOverrideStorage, morphChainStorage, frostFSIDClient, st),
|
|
frostFSIDClient: frostFSIDClient,
|
|
headerProvider: headerProvider,
|
|
nm: nm,
|
|
cnrSource: cnrSource,
|
|
nodePK: nodePK,
|
|
}
|
|
}
|
|
|
|
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
|
|
|
|
// An encoded container's owner user ID.
|
|
ContainerOwner user.ID
|
|
|
|
// If SoftAPECheck is set to true, then NoRuleFound is interpreted as allow.
|
|
SoftAPECheck bool
|
|
|
|
// The request's bearer token. It is used in order to check APE overrides with the token.
|
|
BearerToken *bearer.Token
|
|
|
|
// XHeaders from the request.
|
|
XHeaders []session.XHeader
|
|
}
|
|
|
|
var errMissingOID = errors.New("object ID is not set")
|
|
|
|
// CheckAPE prepares an APE-request and checks if it is permitted by policies.
|
|
func (c *checkerImpl) CheckAPE(ctx context.Context, prm Prm) error {
|
|
// APE check is ignored for some inter-node requests.
|
|
if prm.Role == nativeschema.PropertyValueContainerRoleContainer {
|
|
return nil
|
|
} else if prm.Role == nativeschema.PropertyValueContainerRoleIR {
|
|
switch prm.Method {
|
|
case nativeschema.MethodGetObject,
|
|
nativeschema.MethodHeadObject,
|
|
nativeschema.MethodSearchObject,
|
|
nativeschema.MethodRangeObject,
|
|
nativeschema.MethodHashObject:
|
|
return nil
|
|
default:
|
|
}
|
|
}
|
|
|
|
r, err := c.newAPERequest(ctx, prm)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create ape request: %w", err)
|
|
}
|
|
pub, err := keys.NewPublicKeyFromString(prm.SenderKey)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return c.checkerCore.CheckAPE(checkercore.CheckPrm{
|
|
Request: r,
|
|
PublicKey: pub,
|
|
Namespace: prm.Namespace,
|
|
Container: prm.Container,
|
|
ContainerOwner: prm.ContainerOwner,
|
|
BearerToken: prm.BearerToken,
|
|
SoftAPECheck: prm.SoftAPECheck,
|
|
})
|
|
}
|