[#1] Add route to get object info
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
parent
d9798cbce8
commit
066656ac48
14 changed files with 1032 additions and 70 deletions
|
@ -8,8 +8,10 @@ package models
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/go-openapi/errors"
|
||||||
"github.com/go-openapi/strfmt"
|
"github.com/go-openapi/strfmt"
|
||||||
"github.com/go-openapi/swag"
|
"github.com/go-openapi/swag"
|
||||||
|
"github.com/go-openapi/validate"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Attribute attribute
|
// Attribute attribute
|
||||||
|
@ -18,14 +20,47 @@ import (
|
||||||
type Attribute struct {
|
type Attribute struct {
|
||||||
|
|
||||||
// key
|
// key
|
||||||
Key string `json:"key,omitempty"`
|
// Required: true
|
||||||
|
Key *string `json:"key"`
|
||||||
|
|
||||||
// value
|
// value
|
||||||
Value string `json:"value,omitempty"`
|
// Required: true
|
||||||
|
Value *string `json:"value"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates this attribute
|
// Validate validates this attribute
|
||||||
func (m *Attribute) Validate(formats strfmt.Registry) error {
|
func (m *Attribute) Validate(formats strfmt.Registry) error {
|
||||||
|
var res []error
|
||||||
|
|
||||||
|
if err := m.validateKey(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateValue(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res) > 0 {
|
||||||
|
return errors.CompositeValidationError(res...)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Attribute) validateKey(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.Required("key", "body", m.Key); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Attribute) validateValue(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.Required("value", "body", m.Value); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/go-openapi/errors"
|
"github.com/go-openapi/errors"
|
||||||
"github.com/go-openapi/strfmt"
|
"github.com/go-openapi/strfmt"
|
||||||
"github.com/go-openapi/swag"
|
"github.com/go-openapi/swag"
|
||||||
|
"github.com/go-openapi/validate"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ContainerInfo container info
|
// ContainerInfo container info
|
||||||
|
@ -21,22 +22,28 @@ import (
|
||||||
type ContainerInfo struct {
|
type ContainerInfo struct {
|
||||||
|
|
||||||
// attributes
|
// attributes
|
||||||
|
// Required: true
|
||||||
Attributes []*Attribute `json:"attributes"`
|
Attributes []*Attribute `json:"attributes"`
|
||||||
|
|
||||||
// basic Acl
|
// basic Acl
|
||||||
BasicACL string `json:"basicAcl,omitempty"`
|
// Required: true
|
||||||
|
BasicACL *string `json:"basicAcl"`
|
||||||
|
|
||||||
// container Id
|
// container Id
|
||||||
ContainerID string `json:"containerId,omitempty"`
|
// Required: true
|
||||||
|
ContainerID *string `json:"containerId"`
|
||||||
|
|
||||||
// owner Id
|
// owner Id
|
||||||
OwnerID string `json:"ownerId,omitempty"`
|
// Required: true
|
||||||
|
OwnerID *string `json:"ownerId"`
|
||||||
|
|
||||||
// placement policy
|
// placement policy
|
||||||
PlacementPolicy string `json:"placementPolicy,omitempty"`
|
// Required: true
|
||||||
|
PlacementPolicy *string `json:"placementPolicy"`
|
||||||
|
|
||||||
// version
|
// version
|
||||||
Version string `json:"version,omitempty"`
|
// Required: true
|
||||||
|
Version *string `json:"version"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates this container info
|
// Validate validates this container info
|
||||||
|
@ -47,6 +54,26 @@ func (m *ContainerInfo) Validate(formats strfmt.Registry) error {
|
||||||
res = append(res, err)
|
res = append(res, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := m.validateBasicACL(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateContainerID(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateOwnerID(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validatePlacementPolicy(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateVersion(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
if len(res) > 0 {
|
if len(res) > 0 {
|
||||||
return errors.CompositeValidationError(res...)
|
return errors.CompositeValidationError(res...)
|
||||||
}
|
}
|
||||||
|
@ -54,8 +81,9 @@ func (m *ContainerInfo) Validate(formats strfmt.Registry) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ContainerInfo) validateAttributes(formats strfmt.Registry) error {
|
func (m *ContainerInfo) validateAttributes(formats strfmt.Registry) error {
|
||||||
if swag.IsZero(m.Attributes) { // not required
|
|
||||||
return nil
|
if err := validate.Required("attributes", "body", m.Attributes); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(m.Attributes); i++ {
|
for i := 0; i < len(m.Attributes); i++ {
|
||||||
|
@ -79,6 +107,51 @@ func (m *ContainerInfo) validateAttributes(formats strfmt.Registry) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *ContainerInfo) validateBasicACL(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.Required("basicAcl", "body", m.BasicACL); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ContainerInfo) validateContainerID(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.Required("containerId", "body", m.ContainerID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ContainerInfo) validateOwnerID(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.Required("ownerId", "body", m.OwnerID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ContainerInfo) validatePlacementPolicy(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.Required("placementPolicy", "body", m.PlacementPolicy); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ContainerInfo) validateVersion(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.Required("version", "body", m.Version); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// ContextValidate validate this container info based on the context it is used
|
// ContextValidate validate this container info based on the context it is used
|
||||||
func (m *ContainerInfo) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
func (m *ContainerInfo) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||||
var res []error
|
var res []error
|
||||||
|
|
171
gen/models/object_info.go
Normal file
171
gen/models/object_info.go
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
// Code generated by go-swagger; DO NOT EDIT.
|
||||||
|
|
||||||
|
package models
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the swagger generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/go-openapi/errors"
|
||||||
|
"github.com/go-openapi/strfmt"
|
||||||
|
"github.com/go-openapi/swag"
|
||||||
|
"github.com/go-openapi/validate"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ObjectInfo object info
|
||||||
|
// Example: {"attribute":[{"key":"Timestamp","value":"1648810072"},{"key":"Name","value":"object"}],"containerId":"5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv","objectId":"8N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd","ownerId":"NbUgTSFvPmsRxmGeWpuuGeJUoRoi6PErcM"}
|
||||||
|
//
|
||||||
|
// swagger:model ObjectInfo
|
||||||
|
type ObjectInfo struct {
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
// Required: true
|
||||||
|
Attributes []*Attribute `json:"attributes"`
|
||||||
|
|
||||||
|
// container Id
|
||||||
|
// Required: true
|
||||||
|
ContainerID *string `json:"containerId"`
|
||||||
|
|
||||||
|
// object Id
|
||||||
|
// Required: true
|
||||||
|
ObjectID *string `json:"objectId"`
|
||||||
|
|
||||||
|
// owner Id
|
||||||
|
// Required: true
|
||||||
|
OwnerID *string `json:"ownerId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validates this object info
|
||||||
|
func (m *ObjectInfo) Validate(formats strfmt.Registry) error {
|
||||||
|
var res []error
|
||||||
|
|
||||||
|
if err := m.validateAttributes(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateContainerID(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateObjectID(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateOwnerID(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res) > 0 {
|
||||||
|
return errors.CompositeValidationError(res...)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ObjectInfo) validateAttributes(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.Required("attributes", "body", m.Attributes); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(m.Attributes); i++ {
|
||||||
|
if swag.IsZero(m.Attributes[i]) { // not required
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.Attributes[i] != nil {
|
||||||
|
if err := m.Attributes[i].Validate(formats); err != nil {
|
||||||
|
if ve, ok := err.(*errors.Validation); ok {
|
||||||
|
return ve.ValidateName("attributes" + "." + strconv.Itoa(i))
|
||||||
|
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||||
|
return ce.ValidateName("attributes" + "." + strconv.Itoa(i))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ObjectInfo) validateContainerID(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.Required("containerId", "body", m.ContainerID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ObjectInfo) validateObjectID(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.Required("objectId", "body", m.ObjectID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ObjectInfo) validateOwnerID(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.Required("ownerId", "body", m.OwnerID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContextValidate validate this object info based on the context it is used
|
||||||
|
func (m *ObjectInfo) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||||
|
var res []error
|
||||||
|
|
||||||
|
if err := m.contextValidateAttributes(ctx, formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res) > 0 {
|
||||||
|
return errors.CompositeValidationError(res...)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ObjectInfo) contextValidateAttributes(ctx context.Context, formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
for i := 0; i < len(m.Attributes); i++ {
|
||||||
|
|
||||||
|
if m.Attributes[i] != nil {
|
||||||
|
if err := m.Attributes[i].ContextValidate(ctx, formats); err != nil {
|
||||||
|
if ve, ok := err.(*errors.Validation); ok {
|
||||||
|
return ve.ValidateName("attributes" + "." + strconv.Itoa(i))
|
||||||
|
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||||
|
return ce.ValidateName("attributes" + "." + strconv.Itoa(i))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBinary interface implementation
|
||||||
|
func (m *ObjectInfo) MarshalBinary() ([]byte, error) {
|
||||||
|
if m == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return swag.WriteJSON(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBinary interface implementation
|
||||||
|
func (m *ObjectInfo) UnmarshalBinary(b []byte) error {
|
||||||
|
var res ObjectInfo
|
||||||
|
if err := swag.ReadJSON(b, &res); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*m = res
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -155,18 +155,10 @@ func init() {
|
||||||
},
|
},
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "string",
|
"$ref": "#/parameters/signatureParam"
|
||||||
"description": "Base64 encoded signature for bearer token",
|
|
||||||
"name": "X-Neofs-Token-Signature",
|
|
||||||
"in": "header",
|
|
||||||
"required": true
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"$ref": "#/parameters/signatureKeyParam"
|
||||||
"description": "Hex encoded the public part of the key that signed the bearer token",
|
|
||||||
"name": "X-Neofs-Token-signature-Key",
|
|
||||||
"in": "header",
|
|
||||||
"required": true
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -273,18 +265,52 @@ func init() {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"parameters": [
|
"parameters": [
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/signatureParam"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/signatureKeyParam"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"/objects/{containerId}/{objectId}": {
|
||||||
|
"get": {
|
||||||
|
"summary": "Get object info by address and",
|
||||||
|
"operationId": "getObjectInfo",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Object info",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/ObjectInfo"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/Error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/signatureParam"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/parameters/signatureKeyParam"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Base64 encoded signature for bearer token",
|
"description": "Base58 encoded container id",
|
||||||
"name": "X-Neofs-Token-Signature",
|
"name": "containerId",
|
||||||
"in": "header",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Hex encoded the public part of the key that signed the bearer token",
|
"description": "Base58 encoded object id",
|
||||||
"name": "X-Neofs-Token-Signature-Key",
|
"name": "objectId",
|
||||||
"in": "header",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -300,6 +326,10 @@ func init() {
|
||||||
},
|
},
|
||||||
"Attribute": {
|
"Attribute": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"key",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"key": {
|
"key": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
@ -325,6 +355,14 @@ func init() {
|
||||||
},
|
},
|
||||||
"ContainerInfo": {
|
"ContainerInfo": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"containerId",
|
||||||
|
"version",
|
||||||
|
"ownerId",
|
||||||
|
"basicAcl",
|
||||||
|
"placementPolicy",
|
||||||
|
"attributes"
|
||||||
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"attributes": {
|
"attributes": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
@ -413,6 +451,47 @@ func init() {
|
||||||
"STRING_NOT_EQUAL"
|
"STRING_NOT_EQUAL"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"ObjectInfo": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"containerId",
|
||||||
|
"objectId",
|
||||||
|
"ownerId",
|
||||||
|
"attributes"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"attributes": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/Attribute"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"containerId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"objectId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"ownerId": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"example": {
|
||||||
|
"attribute": [
|
||||||
|
{
|
||||||
|
"key": "Timestamp",
|
||||||
|
"value": "1648810072"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Name",
|
||||||
|
"value": "object"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"containerId": "5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv",
|
||||||
|
"objectId": "8N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd",
|
||||||
|
"ownerId": "NbUgTSFvPmsRxmGeWpuuGeJUoRoi6PErcM"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Operation": {
|
"Operation": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
|
@ -555,8 +634,25 @@ func init() {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"parameters": {
|
||||||
|
"signatureKeyParam": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Hex encoded the public part of the key that signed the bearer token",
|
||||||
|
"name": "X-Neofs-Token-Signature-Key",
|
||||||
|
"in": "header",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"signatureParam": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Base64 encoded signature for bearer token",
|
||||||
|
"name": "X-Neofs-Token-Signature",
|
||||||
|
"in": "header",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
},
|
||||||
"securityDefinitions": {
|
"securityDefinitions": {
|
||||||
"BearerAuth": {
|
"BearerAuth": {
|
||||||
|
"description": "Bearer token body to provide with NeoFS request. Must have 'Bearer ' prefix.",
|
||||||
"type": "apiKey",
|
"type": "apiKey",
|
||||||
"name": "Authorization",
|
"name": "Authorization",
|
||||||
"in": "header"
|
"in": "header"
|
||||||
|
@ -715,7 +811,7 @@ func init() {
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Hex encoded the public part of the key that signed the bearer token",
|
"description": "Hex encoded the public part of the key that signed the bearer token",
|
||||||
"name": "X-Neofs-Token-signature-Key",
|
"name": "X-Neofs-Token-Signature-Key",
|
||||||
"in": "header",
|
"in": "header",
|
||||||
"required": true
|
"required": true
|
||||||
}
|
}
|
||||||
|
@ -839,6 +935,56 @@ func init() {
|
||||||
"required": true
|
"required": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"/objects/{containerId}/{objectId}": {
|
||||||
|
"get": {
|
||||||
|
"summary": "Get object info by address and",
|
||||||
|
"operationId": "getObjectInfo",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Object info",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/ObjectInfo"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/Error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Base64 encoded signature for bearer token",
|
||||||
|
"name": "X-Neofs-Token-Signature",
|
||||||
|
"in": "header",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Hex encoded the public part of the key that signed the bearer token",
|
||||||
|
"name": "X-Neofs-Token-Signature-Key",
|
||||||
|
"in": "header",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Base58 encoded container id",
|
||||||
|
"name": "containerId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Base58 encoded object id",
|
||||||
|
"name": "objectId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
|
@ -851,6 +997,10 @@ func init() {
|
||||||
},
|
},
|
||||||
"Attribute": {
|
"Attribute": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"key",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"key": {
|
"key": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
@ -876,6 +1026,14 @@ func init() {
|
||||||
},
|
},
|
||||||
"ContainerInfo": {
|
"ContainerInfo": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"containerId",
|
||||||
|
"version",
|
||||||
|
"ownerId",
|
||||||
|
"basicAcl",
|
||||||
|
"placementPolicy",
|
||||||
|
"attributes"
|
||||||
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"attributes": {
|
"attributes": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
@ -964,6 +1122,47 @@ func init() {
|
||||||
"STRING_NOT_EQUAL"
|
"STRING_NOT_EQUAL"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"ObjectInfo": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"containerId",
|
||||||
|
"objectId",
|
||||||
|
"ownerId",
|
||||||
|
"attributes"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"attributes": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/Attribute"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"containerId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"objectId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"ownerId": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"example": {
|
||||||
|
"attribute": [
|
||||||
|
{
|
||||||
|
"key": "Timestamp",
|
||||||
|
"value": "1648810072"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Name",
|
||||||
|
"value": "object"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"containerId": "5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv",
|
||||||
|
"objectId": "8N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd",
|
||||||
|
"ownerId": "NbUgTSFvPmsRxmGeWpuuGeJUoRoi6PErcM"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Operation": {
|
"Operation": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
|
@ -1106,8 +1305,25 @@ func init() {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"parameters": {
|
||||||
|
"signatureKeyParam": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Hex encoded the public part of the key that signed the bearer token",
|
||||||
|
"name": "X-Neofs-Token-Signature-Key",
|
||||||
|
"in": "header",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"signatureParam": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Base64 encoded signature for bearer token",
|
||||||
|
"name": "X-Neofs-Token-Signature",
|
||||||
|
"in": "header",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
},
|
||||||
"securityDefinitions": {
|
"securityDefinitions": {
|
||||||
"BearerAuth": {
|
"BearerAuth": {
|
||||||
|
"description": "Bearer token body to provide with NeoFS request. Must have 'Bearer ' prefix.",
|
||||||
"type": "apiKey",
|
"type": "apiKey",
|
||||||
"name": "Authorization",
|
"name": "Authorization",
|
||||||
"in": "header"
|
"in": "header"
|
||||||
|
|
71
gen/restapi/operations/get_object_info.go
Normal file
71
gen/restapi/operations/get_object_info.go
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
// Code generated by go-swagger; DO NOT EDIT.
|
||||||
|
|
||||||
|
package operations
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-openapi/runtime/middleware"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neofs-rest-gw/gen/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetObjectInfoHandlerFunc turns a function with the right signature into a get object info handler
|
||||||
|
type GetObjectInfoHandlerFunc func(GetObjectInfoParams, *models.Principal) middleware.Responder
|
||||||
|
|
||||||
|
// Handle executing the request and returning a response
|
||||||
|
func (fn GetObjectInfoHandlerFunc) Handle(params GetObjectInfoParams, principal *models.Principal) middleware.Responder {
|
||||||
|
return fn(params, principal)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetObjectInfoHandler interface for that can handle valid get object info params
|
||||||
|
type GetObjectInfoHandler interface {
|
||||||
|
Handle(GetObjectInfoParams, *models.Principal) middleware.Responder
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGetObjectInfo creates a new http.Handler for the get object info operation
|
||||||
|
func NewGetObjectInfo(ctx *middleware.Context, handler GetObjectInfoHandler) *GetObjectInfo {
|
||||||
|
return &GetObjectInfo{Context: ctx, Handler: handler}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* GetObjectInfo swagger:route GET /objects/{containerId}/{objectId} getObjectInfo
|
||||||
|
|
||||||
|
Get object info by address and
|
||||||
|
|
||||||
|
*/
|
||||||
|
type GetObjectInfo struct {
|
||||||
|
Context *middleware.Context
|
||||||
|
Handler GetObjectInfoHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *GetObjectInfo) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
route, rCtx, _ := o.Context.RouteInfo(r)
|
||||||
|
if rCtx != nil {
|
||||||
|
*r = *rCtx
|
||||||
|
}
|
||||||
|
var Params = NewGetObjectInfoParams()
|
||||||
|
uprinc, aCtx, err := o.Context.Authorize(r, route)
|
||||||
|
if err != nil {
|
||||||
|
o.Context.Respond(rw, r, route.Produces, route, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if aCtx != nil {
|
||||||
|
*r = *aCtx
|
||||||
|
}
|
||||||
|
var principal *models.Principal
|
||||||
|
if uprinc != nil {
|
||||||
|
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
|
||||||
|
o.Context.Respond(rw, r, route.Produces, route, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res := o.Handler.Handle(Params, principal) // actually handle the request
|
||||||
|
o.Context.Respond(rw, r, route.Produces, route, res)
|
||||||
|
|
||||||
|
}
|
154
gen/restapi/operations/get_object_info_parameters.go
Normal file
154
gen/restapi/operations/get_object_info_parameters.go
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
// Code generated by go-swagger; DO NOT EDIT.
|
||||||
|
|
||||||
|
package operations
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the swagger generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-openapi/errors"
|
||||||
|
"github.com/go-openapi/runtime/middleware"
|
||||||
|
"github.com/go-openapi/strfmt"
|
||||||
|
"github.com/go-openapi/validate"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewGetObjectInfoParams creates a new GetObjectInfoParams object
|
||||||
|
//
|
||||||
|
// There are no default values defined in the spec.
|
||||||
|
func NewGetObjectInfoParams() GetObjectInfoParams {
|
||||||
|
|
||||||
|
return GetObjectInfoParams{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetObjectInfoParams contains all the bound params for the get object info operation
|
||||||
|
// typically these are obtained from a http.Request
|
||||||
|
//
|
||||||
|
// swagger:parameters getObjectInfo
|
||||||
|
type GetObjectInfoParams struct {
|
||||||
|
|
||||||
|
// HTTP Request Object
|
||||||
|
HTTPRequest *http.Request `json:"-"`
|
||||||
|
|
||||||
|
/*Base64 encoded signature for bearer token
|
||||||
|
Required: true
|
||||||
|
In: header
|
||||||
|
*/
|
||||||
|
XNeofsTokenSignature string
|
||||||
|
/*Hex encoded the public part of the key that signed the bearer token
|
||||||
|
Required: true
|
||||||
|
In: header
|
||||||
|
*/
|
||||||
|
XNeofsTokenSignatureKey string
|
||||||
|
/*Base58 encoded container id
|
||||||
|
Required: true
|
||||||
|
In: path
|
||||||
|
*/
|
||||||
|
ContainerID string
|
||||||
|
/*Base58 encoded object id
|
||||||
|
Required: true
|
||||||
|
In: path
|
||||||
|
*/
|
||||||
|
ObjectID string
|
||||||
|
}
|
||||||
|
|
||||||
|
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
|
||||||
|
// for simple values it will use straight method calls.
|
||||||
|
//
|
||||||
|
// To ensure default values, the struct must have been initialized with NewGetObjectInfoParams() beforehand.
|
||||||
|
func (o *GetObjectInfoParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
|
||||||
|
var res []error
|
||||||
|
|
||||||
|
o.HTTPRequest = r
|
||||||
|
|
||||||
|
if err := o.bindXNeofsTokenSignature(r.Header[http.CanonicalHeaderKey("X-Neofs-Token-Signature")], true, route.Formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := o.bindXNeofsTokenSignatureKey(r.Header[http.CanonicalHeaderKey("X-Neofs-Token-Signature-Key")], true, route.Formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rContainerID, rhkContainerID, _ := route.Params.GetOK("containerId")
|
||||||
|
if err := o.bindContainerID(rContainerID, rhkContainerID, route.Formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rObjectID, rhkObjectID, _ := route.Params.GetOK("objectId")
|
||||||
|
if err := o.bindObjectID(rObjectID, rhkObjectID, route.Formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
if len(res) > 0 {
|
||||||
|
return errors.CompositeValidationError(res...)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindXNeofsTokenSignature binds and validates parameter XNeofsTokenSignature from header.
|
||||||
|
func (o *GetObjectInfoParams) bindXNeofsTokenSignature(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||||
|
if !hasKey {
|
||||||
|
return errors.Required("X-Neofs-Token-Signature", "header", rawData)
|
||||||
|
}
|
||||||
|
var raw string
|
||||||
|
if len(rawData) > 0 {
|
||||||
|
raw = rawData[len(rawData)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required: true
|
||||||
|
|
||||||
|
if err := validate.RequiredString("X-Neofs-Token-Signature", "header", raw); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
o.XNeofsTokenSignature = raw
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindXNeofsTokenSignatureKey binds and validates parameter XNeofsTokenSignatureKey from header.
|
||||||
|
func (o *GetObjectInfoParams) bindXNeofsTokenSignatureKey(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||||
|
if !hasKey {
|
||||||
|
return errors.Required("X-Neofs-Token-Signature-Key", "header", rawData)
|
||||||
|
}
|
||||||
|
var raw string
|
||||||
|
if len(rawData) > 0 {
|
||||||
|
raw = rawData[len(rawData)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required: true
|
||||||
|
|
||||||
|
if err := validate.RequiredString("X-Neofs-Token-Signature-Key", "header", raw); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
o.XNeofsTokenSignatureKey = raw
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindContainerID binds and validates parameter ContainerID from path.
|
||||||
|
func (o *GetObjectInfoParams) bindContainerID(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||||
|
var raw string
|
||||||
|
if len(rawData) > 0 {
|
||||||
|
raw = rawData[len(rawData)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required: true
|
||||||
|
// Parameter is provided by construction from the route
|
||||||
|
o.ContainerID = raw
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindObjectID binds and validates parameter ObjectID from path.
|
||||||
|
func (o *GetObjectInfoParams) bindObjectID(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||||
|
var raw string
|
||||||
|
if len(rawData) > 0 {
|
||||||
|
raw = rawData[len(rawData)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required: true
|
||||||
|
// Parameter is provided by construction from the route
|
||||||
|
o.ObjectID = raw
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
100
gen/restapi/operations/get_object_info_responses.go
Normal file
100
gen/restapi/operations/get_object_info_responses.go
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
// Code generated by go-swagger; DO NOT EDIT.
|
||||||
|
|
||||||
|
package operations
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the swagger generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-openapi/runtime"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neofs-rest-gw/gen/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetObjectInfoOKCode is the HTTP code returned for type GetObjectInfoOK
|
||||||
|
const GetObjectInfoOKCode int = 200
|
||||||
|
|
||||||
|
/*GetObjectInfoOK Object info
|
||||||
|
|
||||||
|
swagger:response getObjectInfoOK
|
||||||
|
*/
|
||||||
|
type GetObjectInfoOK struct {
|
||||||
|
|
||||||
|
/*
|
||||||
|
In: Body
|
||||||
|
*/
|
||||||
|
Payload *models.ObjectInfo `json:"body,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGetObjectInfoOK creates GetObjectInfoOK with default headers values
|
||||||
|
func NewGetObjectInfoOK() *GetObjectInfoOK {
|
||||||
|
|
||||||
|
return &GetObjectInfoOK{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPayload adds the payload to the get object info o k response
|
||||||
|
func (o *GetObjectInfoOK) WithPayload(payload *models.ObjectInfo) *GetObjectInfoOK {
|
||||||
|
o.Payload = payload
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPayload sets the payload to the get object info o k response
|
||||||
|
func (o *GetObjectInfoOK) SetPayload(payload *models.ObjectInfo) {
|
||||||
|
o.Payload = payload
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteResponse to the client
|
||||||
|
func (o *GetObjectInfoOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||||
|
|
||||||
|
rw.WriteHeader(200)
|
||||||
|
if o.Payload != nil {
|
||||||
|
payload := o.Payload
|
||||||
|
if err := producer.Produce(rw, payload); err != nil {
|
||||||
|
panic(err) // let the recovery middleware deal with this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetObjectInfoBadRequestCode is the HTTP code returned for type GetObjectInfoBadRequest
|
||||||
|
const GetObjectInfoBadRequestCode int = 400
|
||||||
|
|
||||||
|
/*GetObjectInfoBadRequest Bad request
|
||||||
|
|
||||||
|
swagger:response getObjectInfoBadRequest
|
||||||
|
*/
|
||||||
|
type GetObjectInfoBadRequest struct {
|
||||||
|
|
||||||
|
/*
|
||||||
|
In: Body
|
||||||
|
*/
|
||||||
|
Payload models.Error `json:"body,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGetObjectInfoBadRequest creates GetObjectInfoBadRequest with default headers values
|
||||||
|
func NewGetObjectInfoBadRequest() *GetObjectInfoBadRequest {
|
||||||
|
|
||||||
|
return &GetObjectInfoBadRequest{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPayload adds the payload to the get object info bad request response
|
||||||
|
func (o *GetObjectInfoBadRequest) WithPayload(payload models.Error) *GetObjectInfoBadRequest {
|
||||||
|
o.Payload = payload
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPayload sets the payload to the get object info bad request response
|
||||||
|
func (o *GetObjectInfoBadRequest) SetPayload(payload models.Error) {
|
||||||
|
o.Payload = payload
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteResponse to the client
|
||||||
|
func (o *GetObjectInfoBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||||
|
|
||||||
|
rw.WriteHeader(400)
|
||||||
|
payload := o.Payload
|
||||||
|
if err := producer.Produce(rw, payload); err != nil {
|
||||||
|
panic(err) // let the recovery middleware deal with this
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,6 +50,9 @@ func NewNeofsRestGwAPI(spec *loads.Document) *NeofsRestGwAPI {
|
||||||
GetContainerHandler: GetContainerHandlerFunc(func(params GetContainerParams) middleware.Responder {
|
GetContainerHandler: GetContainerHandlerFunc(func(params GetContainerParams) middleware.Responder {
|
||||||
return middleware.NotImplemented("operation GetContainer has not yet been implemented")
|
return middleware.NotImplemented("operation GetContainer has not yet been implemented")
|
||||||
}),
|
}),
|
||||||
|
GetObjectInfoHandler: GetObjectInfoHandlerFunc(func(params GetObjectInfoParams, principal *models.Principal) middleware.Responder {
|
||||||
|
return middleware.NotImplemented("operation GetObjectInfo has not yet been implemented")
|
||||||
|
}),
|
||||||
PutContainerHandler: PutContainerHandlerFunc(func(params PutContainerParams, principal *models.Principal) middleware.Responder {
|
PutContainerHandler: PutContainerHandlerFunc(func(params PutContainerParams, principal *models.Principal) middleware.Responder {
|
||||||
return middleware.NotImplemented("operation PutContainer has not yet been implemented")
|
return middleware.NotImplemented("operation PutContainer has not yet been implemented")
|
||||||
}),
|
}),
|
||||||
|
@ -110,6 +113,8 @@ type NeofsRestGwAPI struct {
|
||||||
AuthHandler AuthHandler
|
AuthHandler AuthHandler
|
||||||
// GetContainerHandler sets the operation handler for the get container operation
|
// GetContainerHandler sets the operation handler for the get container operation
|
||||||
GetContainerHandler GetContainerHandler
|
GetContainerHandler GetContainerHandler
|
||||||
|
// GetObjectInfoHandler sets the operation handler for the get object info operation
|
||||||
|
GetObjectInfoHandler GetObjectInfoHandler
|
||||||
// PutContainerHandler sets the operation handler for the put container operation
|
// PutContainerHandler sets the operation handler for the put container operation
|
||||||
PutContainerHandler PutContainerHandler
|
PutContainerHandler PutContainerHandler
|
||||||
// PutObjectHandler sets the operation handler for the put object operation
|
// PutObjectHandler sets the operation handler for the put object operation
|
||||||
|
@ -201,6 +206,9 @@ func (o *NeofsRestGwAPI) Validate() error {
|
||||||
if o.GetContainerHandler == nil {
|
if o.GetContainerHandler == nil {
|
||||||
unregistered = append(unregistered, "GetContainerHandler")
|
unregistered = append(unregistered, "GetContainerHandler")
|
||||||
}
|
}
|
||||||
|
if o.GetObjectInfoHandler == nil {
|
||||||
|
unregistered = append(unregistered, "GetObjectInfoHandler")
|
||||||
|
}
|
||||||
if o.PutContainerHandler == nil {
|
if o.PutContainerHandler == nil {
|
||||||
unregistered = append(unregistered, "PutContainerHandler")
|
unregistered = append(unregistered, "PutContainerHandler")
|
||||||
}
|
}
|
||||||
|
@ -314,6 +322,10 @@ func (o *NeofsRestGwAPI) initHandlerCache() {
|
||||||
o.handlers["GET"] = make(map[string]http.Handler)
|
o.handlers["GET"] = make(map[string]http.Handler)
|
||||||
}
|
}
|
||||||
o.handlers["GET"]["/containers/{containerId}"] = NewGetContainer(o.context, o.GetContainerHandler)
|
o.handlers["GET"]["/containers/{containerId}"] = NewGetContainer(o.context, o.GetContainerHandler)
|
||||||
|
if o.handlers["GET"] == nil {
|
||||||
|
o.handlers["GET"] = make(map[string]http.Handler)
|
||||||
|
}
|
||||||
|
o.handlers["GET"]["/objects/{containerId}/{objectId}"] = NewGetObjectInfo(o.context, o.GetObjectInfoHandler)
|
||||||
if o.handlers["PUT"] == nil {
|
if o.handlers["PUT"] == nil {
|
||||||
o.handlers["PUT"] = make(map[string]http.Handler)
|
o.handlers["PUT"] = make(map[string]http.Handler)
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ func (o *PutContainerParams) BindRequest(r *http.Request, route *middleware.Matc
|
||||||
res = append(res, err)
|
res = append(res, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := o.bindXNeofsTokenSignatureKey(r.Header[http.CanonicalHeaderKey("X-Neofs-Token-signature-Key")], true, route.Formats); err != nil {
|
if err := o.bindXNeofsTokenSignatureKey(r.Header[http.CanonicalHeaderKey("X-Neofs-Token-Signature-Key")], true, route.Formats); err != nil {
|
||||||
res = append(res, err)
|
res = append(res, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ func (o *PutContainerParams) bindXNeofsTokenSignature(rawData []string, hasKey b
|
||||||
// bindXNeofsTokenSignatureKey binds and validates parameter XNeofsTokenSignatureKey from header.
|
// bindXNeofsTokenSignatureKey binds and validates parameter XNeofsTokenSignatureKey from header.
|
||||||
func (o *PutContainerParams) bindXNeofsTokenSignatureKey(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
func (o *PutContainerParams) bindXNeofsTokenSignatureKey(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||||
if !hasKey {
|
if !hasKey {
|
||||||
return errors.Required("X-Neofs-Token-signature-Key", "header", rawData)
|
return errors.Required("X-Neofs-Token-Signature-Key", "header", rawData)
|
||||||
}
|
}
|
||||||
var raw string
|
var raw string
|
||||||
if len(rawData) > 0 {
|
if len(rawData) > 0 {
|
||||||
|
@ -133,7 +133,7 @@ func (o *PutContainerParams) bindXNeofsTokenSignatureKey(rawData []string, hasKe
|
||||||
|
|
||||||
// Required: true
|
// Required: true
|
||||||
|
|
||||||
if err := validate.RequiredString("X-Neofs-Token-signature-Key", "header", raw); err != nil {
|
if err := validate.RequiredString("X-Neofs-Token-Signature-Key", "header", raw); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
o.XNeofsTokenSignatureKey = raw
|
o.XNeofsTokenSignatureKey = raw
|
||||||
|
|
|
@ -41,10 +41,10 @@ type BearerToken struct {
|
||||||
type ContextKey string
|
type ContextKey string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// BearerPrefix is the prefix for authorization token
|
// BearerPrefix is the prefix for authorization token.
|
||||||
BearerPrefix = "Bearer "
|
BearerPrefix = "Bearer "
|
||||||
|
|
||||||
// ContextKeyRequestID is the ContextKey for RequestID
|
// ContextKeyRequestID is the ContextKey for RequestID.
|
||||||
ContextKeyRequestID ContextKey = "requestID"
|
ContextKeyRequestID ContextKey = "requestID"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -62,9 +62,13 @@ func (a *API) Configure(api *operations.NeofsRestGwAPI) http.Handler {
|
||||||
api.ServeError = errors.ServeError
|
api.ServeError = errors.ServeError
|
||||||
|
|
||||||
api.AuthHandler = operations.AuthHandlerFunc(a.PostAuth)
|
api.AuthHandler = operations.AuthHandlerFunc(a.PostAuth)
|
||||||
|
|
||||||
api.PutObjectHandler = operations.PutObjectHandlerFunc(a.PutObjects)
|
api.PutObjectHandler = operations.PutObjectHandlerFunc(a.PutObjects)
|
||||||
|
api.GetObjectInfoHandler = operations.GetObjectInfoHandlerFunc(a.GetObjectInfo)
|
||||||
|
|
||||||
api.PutContainerHandler = operations.PutContainerHandlerFunc(a.PutContainers)
|
api.PutContainerHandler = operations.PutContainerHandlerFunc(a.PutContainers)
|
||||||
api.GetContainerHandler = operations.GetContainerHandlerFunc(a.GetContainer)
|
api.GetContainerHandler = operations.GetContainerHandlerFunc(a.GetContainer)
|
||||||
|
|
||||||
api.BearerAuthAuth = func(s string) (*models.Principal, error) {
|
api.BearerAuthAuth = func(s string) (*models.Principal, error) {
|
||||||
if !strings.HasPrefix(s, BearerPrefix) {
|
if !strings.HasPrefix(s, BearerPrefix) {
|
||||||
return nil, fmt.Errorf("has not bearer token")
|
return nil, fmt.Errorf("has not bearer token")
|
||||||
|
|
|
@ -62,15 +62,18 @@ func (a *API) GetContainer(params operations.GetContainerParams) middleware.Resp
|
||||||
|
|
||||||
attrs := make([]*models.Attribute, len(cnr.Attributes()))
|
attrs := make([]*models.Attribute, len(cnr.Attributes()))
|
||||||
for i, attr := range cnr.Attributes() {
|
for i, attr := range cnr.Attributes() {
|
||||||
attrs[i] = &models.Attribute{Key: attr.Key(), Value: attr.Value()}
|
attrs[i] = &models.Attribute{
|
||||||
|
Key: NewString(attr.Key()),
|
||||||
|
Value: NewString(attr.Value()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := &models.ContainerInfo{
|
resp := &models.ContainerInfo{
|
||||||
ContainerID: params.ContainerID,
|
ContainerID: NewString(params.ContainerID),
|
||||||
Version: cnr.Version().String(),
|
Version: NewString(cnr.Version().String()),
|
||||||
OwnerID: cnr.OwnerID().String(),
|
OwnerID: NewString(cnr.OwnerID().String()),
|
||||||
BasicACL: acl.BasicACL(cnr.BasicACL()).String(),
|
BasicACL: NewString(acl.BasicACL(cnr.BasicACL()).String()),
|
||||||
PlacementPolicy: strings.Join(policy.Encode(cnr.PlacementPolicy()), " "),
|
PlacementPolicy: NewString(strings.Join(policy.Encode(cnr.PlacementPolicy()), " ")),
|
||||||
Attributes: attrs,
|
Attributes: attrs,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,10 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neofs-sdk-go/object/address"
|
||||||
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"github.com/go-openapi/runtime/middleware"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/acl"
|
"github.com/nspcc-dev/neofs-api-go/v2/acl"
|
||||||
|
@ -18,6 +22,7 @@ import (
|
||||||
|
|
||||||
// PutObjects handler that uploads object to NeoFS.
|
// PutObjects handler that uploads object to NeoFS.
|
||||||
func (a *API) PutObjects(params operations.PutObjectParams, principal *models.Principal) middleware.Responder {
|
func (a *API) PutObjects(params operations.PutObjectParams, principal *models.Principal) middleware.Responder {
|
||||||
|
errorResponse := operations.NewPutObjectBadRequest()
|
||||||
ctx := params.HTTPRequest.Context()
|
ctx := params.HTTPRequest.Context()
|
||||||
|
|
||||||
bt := &BearerToken{
|
bt := &BearerToken{
|
||||||
|
@ -28,17 +33,18 @@ func (a *API) PutObjects(params operations.PutObjectParams, principal *models.Pr
|
||||||
|
|
||||||
btoken, err := prepareBearerToken(bt)
|
btoken, err := prepareBearerToken(bt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return operations.NewPutObjectBadRequest().WithPayload(models.Error(err.Error()))
|
return errorResponse.WithPayload(models.Error(err.Error()))
|
||||||
}
|
}
|
||||||
|
|
||||||
var cnrID cid.ID
|
var cnrID cid.ID
|
||||||
if err = cnrID.Parse(*params.Object.ContainerID); err != nil {
|
if err = cnrID.Parse(*params.Object.ContainerID); err != nil {
|
||||||
return operations.NewPutObjectBadRequest().WithPayload(models.Error(err.Error()))
|
a.log.Error("invalid container id", zap.Error(err))
|
||||||
|
return errorResponse.WithPayload("invalid container id")
|
||||||
}
|
}
|
||||||
|
|
||||||
payload, err := base64.StdEncoding.DecodeString(params.Object.Payload)
|
payload, err := base64.StdEncoding.DecodeString(params.Object.Payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return operations.NewPutObjectBadRequest().WithPayload(models.Error(err.Error()))
|
return errorResponse.WithPayload(models.Error(err.Error()))
|
||||||
}
|
}
|
||||||
|
|
||||||
prm := PrmAttributes{
|
prm := PrmAttributes{
|
||||||
|
@ -47,7 +53,7 @@ func (a *API) PutObjects(params operations.PutObjectParams, principal *models.Pr
|
||||||
}
|
}
|
||||||
attributes, err := GetObjectAttributes(ctx, params.HTTPRequest.Header, a.pool, prm)
|
attributes, err := GetObjectAttributes(ctx, params.HTTPRequest.Header, a.pool, prm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return operations.NewPutObjectBadRequest().WithPayload(models.Error(err.Error()))
|
return errorResponse.WithPayload(models.Error(err.Error()))
|
||||||
}
|
}
|
||||||
|
|
||||||
obj := object.New()
|
obj := object.New()
|
||||||
|
@ -62,7 +68,7 @@ func (a *API) PutObjects(params operations.PutObjectParams, principal *models.Pr
|
||||||
|
|
||||||
objID, err := a.pool.PutObject(ctx, prmPut)
|
objID, err := a.pool.PutObject(ctx, prmPut)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return operations.NewPutObjectBadRequest().WithPayload(models.Error(err.Error()))
|
return errorResponse.WithPayload(NewError(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
var resp operations.PutObjectOKBody
|
var resp operations.PutObjectOKBody
|
||||||
|
@ -72,6 +78,61 @@ func (a *API) PutObjects(params operations.PutObjectParams, principal *models.Pr
|
||||||
return operations.NewPutObjectOK().WithPayload(&resp)
|
return operations.NewPutObjectOK().WithPayload(&resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetObjectInfo handler that get object info.
|
||||||
|
func (a *API) GetObjectInfo(params operations.GetObjectInfoParams, principal *models.Principal) middleware.Responder {
|
||||||
|
errorResponse := operations.NewGetObjectInfoBadRequest()
|
||||||
|
ctx := params.HTTPRequest.Context()
|
||||||
|
|
||||||
|
var cnrID cid.ID
|
||||||
|
if err := cnrID.Parse(params.ContainerID); err != nil {
|
||||||
|
a.log.Error("invalid container id", zap.Error(err))
|
||||||
|
return errorResponse.WithPayload("invalid container id")
|
||||||
|
}
|
||||||
|
var objID oid.ID
|
||||||
|
if err := objID.Parse(params.ObjectID); err != nil {
|
||||||
|
a.log.Error("invalid object id", zap.Error(err))
|
||||||
|
return errorResponse.WithPayload("invalid object id")
|
||||||
|
}
|
||||||
|
|
||||||
|
bt := &BearerToken{
|
||||||
|
Token: string(*principal),
|
||||||
|
Signature: params.XNeofsTokenSignature,
|
||||||
|
Key: params.XNeofsTokenSignatureKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
btoken, err := prepareBearerToken(bt)
|
||||||
|
if err != nil {
|
||||||
|
return errorResponse.WithPayload(NewError(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
var prm pool.PrmObjectHead
|
||||||
|
addr := address.NewAddress()
|
||||||
|
addr.SetContainerID(&cnrID)
|
||||||
|
addr.SetObjectID(&objID)
|
||||||
|
prm.SetAddress(*addr)
|
||||||
|
prm.UseBearer(btoken)
|
||||||
|
|
||||||
|
objInfo, err := a.pool.HeadObject(ctx, prm)
|
||||||
|
if err != nil {
|
||||||
|
return errorResponse.WithPayload(NewError(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp models.ObjectInfo
|
||||||
|
resp.ContainerID = NewString(params.ContainerID)
|
||||||
|
resp.ObjectID = NewString(params.ObjectID)
|
||||||
|
resp.OwnerID = NewString(objInfo.OwnerID().String())
|
||||||
|
resp.Attributes = make([]*models.Attribute, len(objInfo.Attributes()))
|
||||||
|
|
||||||
|
for i, attr := range objInfo.Attributes() {
|
||||||
|
resp.Attributes[i] = &models.Attribute{
|
||||||
|
Key: NewString(attr.Key()),
|
||||||
|
Value: NewString(attr.Value()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return operations.NewGetObjectInfoOK().WithPayload(&resp)
|
||||||
|
}
|
||||||
|
|
||||||
func prepareBearerToken(bt *BearerToken) (*token.BearerToken, error) {
|
func prepareBearerToken(bt *BearerToken) (*token.BearerToken, error) {
|
||||||
btoken, err := getBearerToken(bt.Token)
|
btoken, err := getBearerToken(bt.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -9,6 +9,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neofs-rest-gw/gen/models"
|
||||||
|
|
||||||
objectv2 "github.com/nspcc-dev/neofs-api-go/v2/object"
|
objectv2 "github.com/nspcc-dev/neofs-api-go/v2/object"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
|
@ -216,3 +218,7 @@ func updateExpirationHeader(headers map[string]string, durations *epochDurations
|
||||||
func NewString(val string) *string {
|
func NewString(val string) *string {
|
||||||
return &val
|
return &val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewError(err error) models.Error {
|
||||||
|
return models.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
112
spec/rest.yaml
112
spec/rest.yaml
|
@ -15,10 +15,25 @@ securityDefinitions:
|
||||||
type: apiKey
|
type: apiKey
|
||||||
in: header
|
in: header
|
||||||
name: Authorization
|
name: Authorization
|
||||||
|
description: Bearer token body to provide with NeoFS request. Must have 'Bearer ' prefix.
|
||||||
|
|
||||||
security:
|
security:
|
||||||
- BearerAuth: [ ]
|
- BearerAuth: [ ]
|
||||||
|
|
||||||
|
parameters:
|
||||||
|
signatureParam:
|
||||||
|
in: header
|
||||||
|
name: X-Neofs-Token-Signature
|
||||||
|
description: Base64 encoded signature for bearer token
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
signatureKeyParam:
|
||||||
|
in: header
|
||||||
|
name: X-Neofs-Token-Signature-Key
|
||||||
|
description: Hex encoded the public part of the key that signed the bearer token
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
|
||||||
paths:
|
paths:
|
||||||
/auth:
|
/auth:
|
||||||
post:
|
post:
|
||||||
|
@ -66,20 +81,8 @@ paths:
|
||||||
|
|
||||||
/objects:
|
/objects:
|
||||||
parameters:
|
parameters:
|
||||||
- in: header
|
- $ref: '#/parameters/signatureParam'
|
||||||
name: X-Neofs-Token-Signature
|
- $ref: '#/parameters/signatureKeyParam'
|
||||||
description: Base64 encoded signature for bearer token
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
# example:
|
|
||||||
# BGtqMEpzxTabrdIIIDAnL79Cs7bm46+8lsFaMMU+LCKw/ujEjF0r5mVLKixWmxoreuj1E0BXWcqp9d3wGV6Hc9I=
|
|
||||||
- in: header
|
|
||||||
name: X-Neofs-Token-Signature-Key
|
|
||||||
description: Hex encoded the public part of the key that signed the bearer token
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
# example:
|
|
||||||
# 031a6c6fbbdf02ca351745fa86b9ba5a9452d785ac4f7fc2b7548ca2a46c4fcf4a
|
|
||||||
put:
|
put:
|
||||||
operationId: putObject
|
operationId: putObject
|
||||||
summary: Upload object to NeoFS
|
summary: Upload object to NeoFS
|
||||||
|
@ -129,22 +132,37 @@ paths:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/Error'
|
$ref: '#/definitions/Error'
|
||||||
|
|
||||||
|
/objects/{containerId}/{objectId}:
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/parameters/signatureParam'
|
||||||
|
- $ref: '#/parameters/signatureKeyParam'
|
||||||
|
- in: path
|
||||||
|
name: containerId
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
description: Base58 encoded container id
|
||||||
|
- in: path
|
||||||
|
name: objectId
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
description: Base58 encoded object id
|
||||||
|
get:
|
||||||
|
operationId: getObjectInfo
|
||||||
|
summary: Get object info by address and
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Object info
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/ObjectInfo'
|
||||||
|
400:
|
||||||
|
description: Bad request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/Error'
|
||||||
|
|
||||||
/containers:
|
/containers:
|
||||||
parameters:
|
parameters:
|
||||||
- in: header
|
- $ref: '#/parameters/signatureParam'
|
||||||
name: X-Neofs-Token-Signature
|
- $ref: '#/parameters/signatureKeyParam'
|
||||||
description: Base64 encoded signature for bearer token
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
# example:
|
|
||||||
# BEvF1N0heytTXn1p2ZV3jN8YM25YkG4FxHmPeq2kWP5HeHCAN4cDjONyX6Bh30Ypw6Kfch2nYOfhiL+rClYQJ9Q=
|
|
||||||
- in: header
|
|
||||||
name: X-Neofs-Token-signature-Key
|
|
||||||
description: Hex encoded the public part of the key that signed the bearer token
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
# example:
|
|
||||||
# 031a6c6fbbdf02ca351745fa86b9ba5a9452d785ac4f7fc2b7548ca2a46c4fcf4a
|
|
||||||
put:
|
put:
|
||||||
operationId: putContainer
|
operationId: putContainer
|
||||||
summary: Create new container in NeoFS
|
summary: Create new container in NeoFS
|
||||||
|
@ -364,6 +382,13 @@ definitions:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/Attribute'
|
$ref: '#/definitions/Attribute'
|
||||||
|
required:
|
||||||
|
- containerId
|
||||||
|
- version
|
||||||
|
- ownerId
|
||||||
|
- basicAcl
|
||||||
|
- placementPolicy
|
||||||
|
- attributes
|
||||||
example:
|
example:
|
||||||
containerId: 5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv
|
containerId: 5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv
|
||||||
version: "2.11"
|
version: "2.11"
|
||||||
|
@ -375,6 +400,34 @@ definitions:
|
||||||
value: "1648810072"
|
value: "1648810072"
|
||||||
- key: Name
|
- key: Name
|
||||||
value: container
|
value: container
|
||||||
|
ObjectInfo:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
containerId:
|
||||||
|
type: string
|
||||||
|
objectId:
|
||||||
|
type: string
|
||||||
|
ownerId:
|
||||||
|
type: string
|
||||||
|
attributes:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/Attribute'
|
||||||
|
required:
|
||||||
|
- containerId
|
||||||
|
- objectId
|
||||||
|
- ownerId
|
||||||
|
- attributes
|
||||||
|
example:
|
||||||
|
containerId: 5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv
|
||||||
|
objectId: 8N3o7Dtr6T1xteCt6eRwhpmJ7JhME58Hyu1dvaswuTDd
|
||||||
|
ownerId: NbUgTSFvPmsRxmGeWpuuGeJUoRoi6PErcM
|
||||||
|
attribute:
|
||||||
|
- key: Timestamp
|
||||||
|
value: "1648810072"
|
||||||
|
- key: Name
|
||||||
|
value: object
|
||||||
|
|
||||||
Attribute:
|
Attribute:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
@ -382,6 +435,9 @@ definitions:
|
||||||
type: string
|
type: string
|
||||||
value:
|
value:
|
||||||
type: string
|
type: string
|
||||||
|
required:
|
||||||
|
- key
|
||||||
|
- value
|
||||||
Principal:
|
Principal:
|
||||||
type: string
|
type: string
|
||||||
Error:
|
Error:
|
||||||
|
|
Reference in a new issue