package ape import ( "context" "fmt" "strconv" objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object" aperequest "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/ape/request" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user" nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native" ) var defaultRequest = aperequest.Request{} func nativeSchemaRole(role acl.Role) string { switch role { case acl.RoleOwner: return nativeschema.PropertyValueContainerRoleOwner case acl.RoleContainer: return nativeschema.PropertyValueContainerRoleContainer case acl.RoleInnerRing: return nativeschema.PropertyValueContainerRoleIR case acl.RoleOthers: return nativeschema.PropertyValueContainerRoleOthers default: return "" } } func resourceName(cid cid.ID, oid *oid.ID, namespace string) string { if namespace == "root" || namespace == "" { if oid != nil { return fmt.Sprintf(nativeschema.ResourceFormatRootContainerObject, cid.EncodeToString(), oid.EncodeToString()) } return fmt.Sprintf(nativeschema.ResourceFormatRootContainerObjects, cid.EncodeToString()) } if oid != nil { return fmt.Sprintf(nativeschema.ResourceFormatNamespaceContainerObject, namespace, cid.EncodeToString(), oid.EncodeToString()) } return fmt.Sprintf(nativeschema.ResourceFormatNamespaceContainerObjects, namespace, cid.EncodeToString()) } // objectProperties collects object properties from address parameters and a header if it is passed. func objectProperties(cnr cid.ID, oid *oid.ID, cnrOwner user.ID, header *objectV2.Header) map[string]string { objectProps := map[string]string{ nativeschema.PropertyKeyObjectContainerID: cnr.EncodeToString(), } objectProps[nativeschema.PropertyKeyContainerOwnerID] = cnrOwner.EncodeToString() if oid != nil { objectProps[nativeschema.PropertyKeyObjectID] = oid.String() } if header == nil { return objectProps } objV2 := new(objectV2.Object) objV2.SetHeader(header) objSDK := objectSDK.NewFromV2(objV2) objectProps[nativeschema.PropertyKeyObjectVersion] = objSDK.Version().String() objectProps[nativeschema.PropertyKeyObjectOwnerID] = objSDK.OwnerID().EncodeToString() objectProps[nativeschema.PropertyKeyObjectCreationEpoch] = strconv.Itoa(int(objSDK.CreationEpoch())) objectProps[nativeschema.PropertyKeyObjectPayloadLength] = strconv.Itoa(int(objSDK.PayloadSize())) objectProps[nativeschema.PropertyKeyObjectType] = objSDK.Type().String() pcs, isSet := objSDK.PayloadChecksum() if isSet { objectProps[nativeschema.PropertyKeyObjectPayloadHash] = pcs.String() } hcs, isSet := objSDK.PayloadHomomorphicHash() if isSet { objectProps[nativeschema.PropertyKeyObjectHomomorphicHash] = hcs.String() } for _, attr := range header.GetAttributes() { objectProps[attr.GetKey()] = attr.GetValue() } return objectProps } // newAPERequest creates an APE request to be passed to a chain router. It collects resource properties from // header provided by headerProvider. If it cannot be found in headerProvider, then properties are // initialized from header given in prm (if it is set). Otherwise, just CID and OID are set to properties. func (c *checkerImpl) newAPERequest(ctx context.Context, prm Prm) (aperequest.Request, error) { switch prm.Method { case nativeschema.MethodGetObject, nativeschema.MethodHeadObject, nativeschema.MethodRangeObject, nativeschema.MethodHashObject, nativeschema.MethodDeleteObject: if prm.Object == nil { return defaultRequest, fmt.Errorf("method %s: %w", prm.Method, errMissingOID) } case nativeschema.MethodSearchObject, nativeschema.MethodPutObject: default: return defaultRequest, fmt.Errorf("unknown method: %s", prm.Method) } var header *objectV2.Header if prm.Header != nil { header = prm.Header } else if prm.Object != nil && !prm.WithoutHeaderRequest { headerObjSDK, err := c.headerProvider.GetHeader(ctx, prm.Container, *prm.Object) if err == nil { header = headerObjSDK.ToV2().GetHeader() } } return aperequest.NewRequest( prm.Method, aperequest.NewResource( resourceName(prm.Container, prm.Object, prm.Namespace), objectProperties(prm.Container, prm.Object, prm.ContainerOwner, header), ), map[string]string{ nativeschema.PropertyKeyActorPublicKey: prm.SenderKey, nativeschema.PropertyKeyActorRole: prm.Role, }, ), nil }