[#1243] object: Make APE checker set x-headers to request properties #1247

Merged
fyrchik merged 1 commit from aarifullin/frostfs-node:fix/ape_xhead into master 2024-07-16 07:28:49 +00:00
6 changed files with 69 additions and 1 deletions

2
go.mod
View file

@ -10,7 +10,7 @@ require (
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20231101111734-b3ad3335ff65 git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20231101111734-b3ad3335ff65
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240617140730-1a5886e776de git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240617140730-1a5886e776de
git.frostfs.info/TrueCloudLab/hrw v1.2.1 git.frostfs.info/TrueCloudLab/hrw v1.2.1
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240513163744-1f6f4163d40d git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240712081403-2628f6184984
git.frostfs.info/TrueCloudLab/tzhash v1.8.0 git.frostfs.info/TrueCloudLab/tzhash v1.8.0
git.frostfs.info/TrueCloudLab/zapjournald v0.0.0-20240124114243-cb2e66427d02 git.frostfs.info/TrueCloudLab/zapjournald v0.0.0-20240124114243-cb2e66427d02
github.com/cheggaaa/pb v1.0.29 github.com/cheggaaa/pb v1.0.29

BIN
go.sum

Binary file not shown.

View file

@ -7,6 +7,7 @@ import (
"fmt" "fmt"
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object" objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
aperequest "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/ape/request" aperequest "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/ape/request"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/ape/router" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/ape/router"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
@ -79,6 +80,9 @@ type Prm struct {
// The request's bearer token. It is used in order to check APE overrides with the token. // The request's bearer token. It is used in order to check APE overrides with the token.
BearerToken *bearer.Token BearerToken *bearer.Token
// XHeaders from the request.
XHeaders []session.XHeader
} }
var ( var (

View file

@ -10,6 +10,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
"git.frostfs.info/TrueCloudLab/frostfs-contract/frostfsid/client" "git.frostfs.info/TrueCloudLab/frostfs-contract/frostfsid/client"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
frostfsidcore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/frostfsid" frostfsidcore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/frostfsid"
@ -240,6 +241,7 @@ var apeCheckTestCases = []struct {
object *string object *string
methods []string methods []string
header testHeader header testHeader
xHeaders []session.XHeader
containerRules []chain.Rule containerRules []chain.Rule
groupidRules []chain.Rule groupidRules []chain.Rule
expectAPEErr bool expectAPEErr bool
@ -367,6 +369,52 @@ var apeCheckTestCases = []struct {
}, },
expectAPEErr: true, expectAPEErr: true,
}, },
{
name: "oid required requests are denied by xheader",
container: containerID,
object: stringPtr(objectID),
methods: methodsRequiredOID,
header: testHeader{
headerObjSDK: &headerObjectSDKParams{
attributes: []struct {
key string
val string
}{
{
key: "attr1",
val: "attribute_value",
},
},
},
fromHeaderProvider: true,
},
xHeaders: []session.XHeader{
func() (xhead session.XHeader) {
xhead.SetKey("X-Test-ID")
xhead.SetValue("aezakmi")
return
}(),
},
containerRules: []chain.Rule{
{
Status: chain.AccessDenied,
Actions: chain.Actions{Names: methodsRequiredOID},
Resources: chain.Resources{
Names: []string{fmt.Sprintf(nativeschema.ResourceFormatRootContainerObject, containerID, objectID)},
},
Any: true,
Condition: []chain.Condition{
{
Op: chain.CondStringLike,
Kind: chain.KindRequest,
Key: fmt.Sprintf(commonschema.PropertyKeyFrostFSXHeader, "X-Test-ID"),
Value: "aezakmi",
},
},
},
},
expectAPEErr: true,
},
{ {
name: "optional oid requests reached quota limit by an attribute", name: "optional oid requests reached quota limit by an attribute",
container: containerID, container: containerID,

View file

@ -126,6 +126,12 @@ func (c *checkerImpl) newAPERequest(ctx context.Context, prm Prm) (aperequest.Re
nativeschema.PropertyKeyActorPublicKey: prm.SenderKey, nativeschema.PropertyKeyActorPublicKey: prm.SenderKey,
nativeschema.PropertyKeyActorRole: prm.Role, nativeschema.PropertyKeyActorRole: prm.Role,
} }
for _, xhead := range prm.XHeaders {
xheadKey := fmt.Sprintf(commonschema.PropertyKeyFrostFSXHeader, xhead.GetKey())
reqProps[xheadKey] = xhead.GetValue()
}
var err error var err error
reqProps, err = c.fillWithUserClaimTags(reqProps, prm) reqProps, err = c.fillWithUserClaimTags(reqProps, prm)
if err != nil { if err != nil {

View file

@ -111,6 +111,7 @@ func (g *getStreamBasicChecker) Send(resp *objectV2.GetResponse) error {
Role: g.role, Role: g.role,
SoftAPECheck: g.softAPECheck, SoftAPECheck: g.softAPECheck,
BearerToken: g.bearerToken, BearerToken: g.bearerToken,
XHeaders: resp.GetMetaHeader().GetXHeaders(),
} }
if err := g.apeChecker.CheckAPE(g.Context(), prm); err != nil { if err := g.apeChecker.CheckAPE(g.Context(), prm); err != nil {
@ -154,6 +155,7 @@ func (c *Service) Get(request *objectV2.GetRequest, stream objectSvc.GetObjectSt
SoftAPECheck: reqCtx.SoftAPECheck, SoftAPECheck: reqCtx.SoftAPECheck,
WithoutHeaderRequest: true, WithoutHeaderRequest: true,
BearerToken: reqCtx.BearerToken, BearerToken: reqCtx.BearerToken,
XHeaders: request.GetMetaHeader().GetXHeaders(),
}) })
if err != nil { if err != nil {
return toStatusErr(err) return toStatusErr(err)
@ -200,6 +202,7 @@ func (p *putStreamBasicChecker) Send(ctx context.Context, request *objectV2.PutR
Role: nativeSchemaRole(reqCtx.Role), Role: nativeSchemaRole(reqCtx.Role),
SoftAPECheck: reqCtx.SoftAPECheck, SoftAPECheck: reqCtx.SoftAPECheck,
BearerToken: reqCtx.BearerToken, BearerToken: reqCtx.BearerToken,
XHeaders: request.GetMetaHeader().GetXHeaders(),
} }
if err := p.apeChecker.CheckAPE(ctx, prm); err != nil { if err := p.apeChecker.CheckAPE(ctx, prm); err != nil {
@ -245,6 +248,7 @@ func (c *Service) Head(ctx context.Context, request *objectV2.HeadRequest) (*obj
SoftAPECheck: reqCtx.SoftAPECheck, SoftAPECheck: reqCtx.SoftAPECheck,
WithoutHeaderRequest: true, WithoutHeaderRequest: true,
BearerToken: reqCtx.BearerToken, BearerToken: reqCtx.BearerToken,
XHeaders: request.GetMetaHeader().GetXHeaders(),
}) })
if err != nil { if err != nil {
return nil, toStatusErr(err) return nil, toStatusErr(err)
@ -285,6 +289,7 @@ func (c *Service) Head(ctx context.Context, request *objectV2.HeadRequest) (*obj
ContainerOwner: reqCtx.ContainerOwner, ContainerOwner: reqCtx.ContainerOwner,
SoftAPECheck: reqCtx.SoftAPECheck, SoftAPECheck: reqCtx.SoftAPECheck,
BearerToken: reqCtx.BearerToken, BearerToken: reqCtx.BearerToken,
XHeaders: request.GetMetaHeader().GetXHeaders(),
}) })
if err != nil { if err != nil {
return nil, toStatusErr(err) return nil, toStatusErr(err)
@ -314,6 +319,7 @@ func (c *Service) Search(request *objectV2.SearchRequest, stream objectSvc.Searc
ContainerOwner: reqCtx.ContainerOwner, ContainerOwner: reqCtx.ContainerOwner,
SoftAPECheck: reqCtx.SoftAPECheck, SoftAPECheck: reqCtx.SoftAPECheck,
BearerToken: reqCtx.BearerToken, BearerToken: reqCtx.BearerToken,
XHeaders: request.GetMetaHeader().GetXHeaders(),
}) })
if err != nil { if err != nil {
return toStatusErr(err) return toStatusErr(err)
@ -343,6 +349,7 @@ func (c *Service) Delete(ctx context.Context, request *objectV2.DeleteRequest) (
ContainerOwner: reqCtx.ContainerOwner, ContainerOwner: reqCtx.ContainerOwner,
SoftAPECheck: reqCtx.SoftAPECheck, SoftAPECheck: reqCtx.SoftAPECheck,
BearerToken: reqCtx.BearerToken, BearerToken: reqCtx.BearerToken,
XHeaders: request.GetMetaHeader().GetXHeaders(),
}) })
if err != nil { if err != nil {
return nil, toStatusErr(err) return nil, toStatusErr(err)
@ -377,6 +384,7 @@ func (c *Service) GetRange(request *objectV2.GetRangeRequest, stream objectSvc.G
ContainerOwner: reqCtx.ContainerOwner, ContainerOwner: reqCtx.ContainerOwner,
SoftAPECheck: reqCtx.SoftAPECheck, SoftAPECheck: reqCtx.SoftAPECheck,
BearerToken: reqCtx.BearerToken, BearerToken: reqCtx.BearerToken,
XHeaders: request.GetMetaHeader().GetXHeaders(),
}) })
if err != nil { if err != nil {
return toStatusErr(err) return toStatusErr(err)
@ -406,6 +414,7 @@ func (c *Service) GetRangeHash(ctx context.Context, request *objectV2.GetRangeHa
ContainerOwner: reqCtx.ContainerOwner, ContainerOwner: reqCtx.ContainerOwner,
SoftAPECheck: reqCtx.SoftAPECheck, SoftAPECheck: reqCtx.SoftAPECheck,
BearerToken: reqCtx.BearerToken, BearerToken: reqCtx.BearerToken,
XHeaders: request.GetMetaHeader().GetXHeaders(),
} }
if err = c.apeChecker.CheckAPE(ctx, prm); err != nil { if err = c.apeChecker.CheckAPE(ctx, prm); err != nil {
@ -445,6 +454,7 @@ func (c *Service) PutSingle(ctx context.Context, request *objectV2.PutSingleRequ
ContainerOwner: reqCtx.ContainerOwner, ContainerOwner: reqCtx.ContainerOwner,
SoftAPECheck: reqCtx.SoftAPECheck, SoftAPECheck: reqCtx.SoftAPECheck,
BearerToken: reqCtx.BearerToken, BearerToken: reqCtx.BearerToken,
XHeaders: request.GetMetaHeader().GetXHeaders(),
} }
if err = c.apeChecker.CheckAPE(ctx, prm); err != nil { if err = c.apeChecker.CheckAPE(ctx, prm); err != nil {