forked from TrueCloudLab/frostfs-node
[#1243] object: Make APE checker set x-headers to request properties
* Update go.mod, go.sum; * Add x-headers to request properties; * Add a unit-test. Signed-off-by: Airat Arifullin <a.arifullin@yadro.com>
This commit is contained in:
parent
39866a957c
commit
d5dc14c639
6 changed files with 69 additions and 1 deletions
2
go.mod
2
go.mod
|
@ -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
BIN
go.sum
Binary file not shown.
|
@ -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 (
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue