[#1] Add route to delete object

Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
Denis Kirillov 2022-04-14 11:53:13 +03:00 committed by Alex Vanin
parent 26f0ae93f4
commit f5eab95f95
17 changed files with 624 additions and 212 deletions

View file

@ -45,13 +45,13 @@ const (
testNode = "localhost:8080" testNode = "localhost:8080"
containerName = "test-container" containerName = "test-container"
// XNeofsTokenSignature header contains base64 encoded signature of the token body. // XBearerSignature header contains base64 encoded signature of the token body.
XNeofsTokenSignature = "X-Neofs-Token-Signature" XBearerSignature = "X-Bearer-Signature"
// XNeofsTokenSignatureKey header contains hex encoded public key that corresponds the signature of the token body. // XBearerSignatureKey header contains hex encoded public key that corresponds the signature of the token body.
XNeofsTokenSignatureKey = "X-Neofs-Token-Signature-Key" XBearerSignatureKey = "X-Bearer-Signature-Key"
// XNeofsTokenScope header contains operation scope for auth (bearer) token. // XBearerScope header contains operation scope for auth (bearer) token.
// It corresponds to 'object' or 'container' services in neofs. // It corresponds to 'object' or 'container' services in neofs.
XNeofsTokenScope = "X-Neofs-Token-Scope" XBearerScope = "X-Bearer-Scope"
) )
func TestIntegration(t *testing.T) { func TestIntegration(t *testing.T) {
@ -74,15 +74,17 @@ func TestIntegration(t *testing.T) {
cancel := runServer(ctx, t) cancel := runServer(ctx, t)
clientPool := getPool(ctx, t, key) clientPool := getPool(ctx, t, key)
cnrID := createContainer(ctx, t, clientPool, containerName) cnrID := createContainer(ctx, t, clientPool, containerName)
restrictByEACL(ctx, t, clientPool, cnrID)
t.Run("rest put object "+version, func(t *testing.T) { restObjectPut(ctx, t, clientPool, cnrID) }) t.Run("rest put object "+version, func(t *testing.T) { restObjectPut(ctx, t, clientPool, cnrID) })
t.Run("rest get object "+version, func(t *testing.T) { restObjectGet(ctx, t, clientPool, cnrID) }) t.Run("rest get object "+version, func(t *testing.T) { restObjectGet(ctx, t, clientPool, cnrID) })
t.Run("rest delete object "+version, func(t *testing.T) { restObjectDelete(ctx, t, clientPool, cnrID) })
t.Run("rest put container"+version, func(t *testing.T) { restContainerPut(ctx, t, clientPool) }) t.Run("rest put container"+version, func(t *testing.T) { restContainerPut(ctx, t, clientPool) })
t.Run("rest get container"+version, func(t *testing.T) { restContainerGet(ctx, t, clientPool, cnrID) }) t.Run("rest get container"+version, func(t *testing.T) { restContainerGet(ctx, t, clientPool, cnrID) })
t.Run("rest delete container"+version, func(t *testing.T) { restContainerDelete(ctx, t, clientPool) }) t.Run("rest delete container"+version, func(t *testing.T) { restContainerDelete(ctx, t, clientPool) })
t.Run("rest put container eacl "+version, func(t *testing.T) { restContainerEACLPut(ctx, t, clientPool) }) t.Run("rest put container eacl "+version, func(t *testing.T) { restContainerEACLPut(ctx, t, clientPool) })
t.Run("rest get container eacl "+version, func(t *testing.T) { restContainerEACLGet(ctx, t, clientPool) }) t.Run("rest get container eacl "+version, func(t *testing.T) { restContainerEACLGet(ctx, t, clientPool, cnrID) })
t.Run("rest list containers "+version, func(t *testing.T) { restContainerList(ctx, t, clientPool, cnrID) }) t.Run("rest list containers "+version, func(t *testing.T) { restContainerList(ctx, t, clientPool, cnrID) })
cancel() cancel()
@ -170,8 +172,6 @@ func getPool(ctx context.Context, t *testing.T, key *keys.PrivateKey) *pool.Pool
} }
func restObjectPut(ctx context.Context, t *testing.T, clientPool *pool.Pool, cnrID *cid.ID) { func restObjectPut(ctx context.Context, t *testing.T, clientPool *pool.Pool, cnrID *cid.ID) {
restrictByEACL(ctx, t, clientPool, cnrID)
bearer := &models.Bearer{ bearer := &models.Bearer{
Object: []*models.Record{{ Object: []*models.Record{{
Operation: models.NewOperation(models.OperationPUT), Operation: models.NewOperation(models.OperationPUT),
@ -238,8 +238,6 @@ func restObjectPut(ctx context.Context, t *testing.T, clientPool *pool.Pool, cnr
} }
func restObjectGet(ctx context.Context, t *testing.T, p *pool.Pool, cnrID *cid.ID) { func restObjectGet(ctx context.Context, t *testing.T, p *pool.Pool, cnrID *cid.ID) {
restrictByEACL(ctx, t, p, cnrID)
attributes := map[string]string{ attributes := map[string]string{
object.AttributeFileName: "get-obj-name", object.AttributeFileName: "get-obj-name",
"user-attribute": "user value", "user-attribute": "user value",
@ -279,6 +277,41 @@ func restObjectGet(ctx context.Context, t *testing.T, p *pool.Pool, cnrID *cid.I
} }
} }
func restObjectDelete(ctx context.Context, t *testing.T, p *pool.Pool, cnrID *cid.ID) {
objID := createObject(ctx, t, p, cnrID, nil, []byte("some content"))
bearer := &models.Bearer{
Object: []*models.Record{{
Operation: models.NewOperation(models.OperationDELETE),
Action: models.NewAction(models.ActionALLOW),
Filters: []*models.Filter{},
Targets: []*models.Target{{
Role: models.NewRole(models.RoleOTHERS),
Keys: []string{},
}},
}},
}
httpClient := defaultHTTPClient()
bearerToken := makeAuthObjectTokenRequest(ctx, t, bearer, httpClient)
request, err := http.NewRequest(http.MethodDelete, testHost+"/v1/objects/"+cnrID.String()+"/"+objID.String(), nil)
require.NoError(t, err)
prepareCommonHeaders(request.Header, bearerToken)
doRequest(t, httpClient, request, http.StatusNoContent, nil)
var addr address.Address
addr.SetContainerID(cnrID)
addr.SetObjectID(objID)
var prm pool.PrmObjectHead
prm.SetAddress(addr)
_, err = p.HeadObject(ctx, prm)
require.Error(t, err)
}
func doRequest(t *testing.T, httpClient *http.Client, request *http.Request, expectedCode int, model interface{}) { func doRequest(t *testing.T, httpClient *http.Client, request *http.Request, expectedCode int, model interface{}) {
resp, err := httpClient.Do(request) resp, err := httpClient.Do(request)
require.NoError(t, err) require.NoError(t, err)
@ -387,9 +420,11 @@ func restContainerEACLPut(ctx context.Context, t *testing.T, clientPool *pool.Po
require.True(t, eacl.EqualTables(*expectedTable, *table)) require.True(t, eacl.EqualTables(*expectedTable, *table))
} }
func restContainerEACLGet(ctx context.Context, t *testing.T, clientPool *pool.Pool) { func restContainerEACLGet(ctx context.Context, t *testing.T, p *pool.Pool, cnrID *cid.ID) {
cnrID := createContainer(ctx, t, clientPool, "for-eacl-get") var prm pool.PrmContainerEACL
expectedTable := restrictByEACL(ctx, t, clientPool, cnrID) prm.SetContainerID(*cnrID)
expectedTable, err := p.GetEACL(ctx, prm)
require.NoError(t, err)
httpClient := &http.Client{Timeout: 60 * time.Second} httpClient := &http.Client{Timeout: 60 * time.Second}
@ -459,8 +494,8 @@ func makeAuthTokenRequest(ctx context.Context, t *testing.T, bearer *models.Bear
require.NoError(t, err) require.NoError(t, err)
request = request.WithContext(ctx) request = request.WithContext(ctx)
request.Header.Add("Content-Type", "application/json") request.Header.Add("Content-Type", "application/json")
request.Header.Add(XNeofsTokenScope, string(tokenType)) request.Header.Add(XBearerScope, string(tokenType))
request.Header.Add(XNeofsTokenSignatureKey, hexPubKey) request.Header.Add(XBearerSignatureKey, hexPubKey)
resp, err := httpClient.Do(request) resp, err := httpClient.Do(request)
require.NoError(t, err) require.NoError(t, err)
@ -564,9 +599,9 @@ func restContainerPut(ctx context.Context, t *testing.T, clientPool *pool.Pool)
func prepareCommonHeaders(header http.Header, bearerToken *handlers.BearerToken) { func prepareCommonHeaders(header http.Header, bearerToken *handlers.BearerToken) {
header.Add("Content-Type", "application/json") header.Add("Content-Type", "application/json")
header.Add(XNeofsTokenSignature, bearerToken.Signature) header.Add(XBearerSignature, bearerToken.Signature)
header.Add("Authorization", "Bearer "+bearerToken.Token) header.Add("Authorization", "Bearer "+bearerToken.Token)
header.Add(XNeofsTokenSignatureKey, bearerToken.Key) header.Add(XBearerSignatureKey, bearerToken.Key)
} }
func createContainer(ctx context.Context, t *testing.T, clientPool *pool.Pool, name string) *cid.ID { func createContainer(ctx context.Context, t *testing.T, clientPool *pool.Pool, name string) *cid.ID {

View file

@ -42,6 +42,9 @@ func init() {
"summary": "Form bearer token to futher requests", "summary": "Form bearer token to futher requests",
"operationId": "auth", "operationId": "auth",
"parameters": [ "parameters": [
{
"$ref": "#/parameters/signatureKeyParam"
},
{ {
"enum": [ "enum": [
"object", "object",
@ -49,14 +52,7 @@ func init() {
], ],
"type": "string", "type": "string",
"description": "Supported operation scope for token", "description": "Supported operation scope for token",
"name": "X-Neofs-Token-Scope", "name": "X-Bearer-Scope",
"in": "header",
"required": true
},
{
"type": "string",
"description": "Public key of user",
"name": "X-Neofs-Token-Signature-Key",
"in": "header", "in": "header",
"required": true "required": true
}, },
@ -64,7 +60,7 @@ func init() {
"type": "integer", "type": "integer",
"default": 100, "default": 100,
"description": "Token lifetime in epoch", "description": "Token lifetime in epoch",
"name": "X-Neofs-Token-Lifetime", "name": "X-Bearer-Lifetime",
"in": "header" "in": "header"
}, },
{ {
@ -418,6 +414,21 @@ func init() {
} }
} }
}, },
"delete": {
"summary": "Remove object from NeoFS",
"operationId": "deleteObject",
"responses": {
"204": {
"description": "Successful deletion"
},
"400": {
"description": "Bad request",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
},
"parameters": [ "parameters": [
{ {
"$ref": "#/parameters/signatureParam" "$ref": "#/parameters/signatureParam"
@ -429,11 +440,7 @@ func init() {
"$ref": "#/parameters/containerId" "$ref": "#/parameters/containerId"
}, },
{ {
"type": "string", "$ref": "#/parameters/objectId"
"description": "Base58 encoded object id",
"name": "objectId",
"in": "path",
"required": true
} }
] ]
} }
@ -814,7 +821,7 @@ func init() {
"in": "path", "in": "path",
"required": true "required": true
}, },
"ojectId": { "objectId": {
"type": "string", "type": "string",
"description": "Base58 encoded object id", "description": "Base58 encoded object id",
"name": "objectId", "name": "objectId",
@ -824,14 +831,14 @@ func init() {
"signatureKeyParam": { "signatureKeyParam": {
"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-Bearer-Signature-Key",
"in": "header", "in": "header",
"required": true "required": true
}, },
"signatureParam": { "signatureParam": {
"type": "string", "type": "string",
"description": "Base64 encoded signature for bearer token", "description": "Base64 encoded signature for bearer token",
"name": "X-Neofs-Token-Signature", "name": "X-Bearer-Signature",
"in": "header", "in": "header",
"required": true "required": true
} }
@ -875,6 +882,13 @@ func init() {
"summary": "Form bearer token to futher requests", "summary": "Form bearer token to futher requests",
"operationId": "auth", "operationId": "auth",
"parameters": [ "parameters": [
{
"type": "string",
"description": "Hex encoded the public part of the key that signed the bearer token",
"name": "X-Bearer-Signature-Key",
"in": "header",
"required": true
},
{ {
"enum": [ "enum": [
"object", "object",
@ -882,14 +896,7 @@ func init() {
], ],
"type": "string", "type": "string",
"description": "Supported operation scope for token", "description": "Supported operation scope for token",
"name": "X-Neofs-Token-Scope", "name": "X-Bearer-Scope",
"in": "header",
"required": true
},
{
"type": "string",
"description": "Public key of user",
"name": "X-Neofs-Token-Signature-Key",
"in": "header", "in": "header",
"required": true "required": true
}, },
@ -897,7 +904,7 @@ func init() {
"type": "integer", "type": "integer",
"default": 100, "default": 100,
"description": "Token lifetime in epoch", "description": "Token lifetime in epoch",
"name": "X-Neofs-Token-Lifetime", "name": "X-Bearer-Lifetime",
"in": "header" "in": "header"
}, },
{ {
@ -979,14 +986,14 @@ func init() {
{ {
"type": "string", "type": "string",
"description": "Base64 encoded signature for bearer token", "description": "Base64 encoded signature for bearer token",
"name": "X-Neofs-Token-Signature", "name": "X-Bearer-Signature",
"in": "header", "in": "header",
"required": true "required": true
}, },
{ {
"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-Bearer-Signature-Key",
"in": "header", "in": "header",
"required": true "required": true
}, },
@ -1080,14 +1087,14 @@ func init() {
{ {
"type": "string", "type": "string",
"description": "Base64 encoded signature for bearer token", "description": "Base64 encoded signature for bearer token",
"name": "X-Neofs-Token-Signature", "name": "X-Bearer-Signature",
"in": "header", "in": "header",
"required": true "required": true
}, },
{ {
"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-Bearer-Signature-Key",
"in": "header", "in": "header",
"required": true "required": true
} }
@ -1141,14 +1148,14 @@ func init() {
{ {
"type": "string", "type": "string",
"description": "Base64 encoded signature for bearer token", "description": "Base64 encoded signature for bearer token",
"name": "X-Neofs-Token-Signature", "name": "X-Bearer-Signature",
"in": "header", "in": "header",
"required": true "required": true
}, },
{ {
"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-Bearer-Signature-Key",
"in": "header", "in": "header",
"required": true "required": true
}, },
@ -1260,14 +1267,14 @@ func init() {
{ {
"type": "string", "type": "string",
"description": "Base64 encoded signature for bearer token", "description": "Base64 encoded signature for bearer token",
"name": "X-Neofs-Token-Signature", "name": "X-Bearer-Signature",
"in": "header", "in": "header",
"required": true "required": true
}, },
{ {
"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-Bearer-Signature-Key",
"in": "header", "in": "header",
"required": true "required": true
} }
@ -1292,18 +1299,33 @@ func init() {
} }
} }
}, },
"delete": {
"summary": "Remove object from NeoFS",
"operationId": "deleteObject",
"responses": {
"204": {
"description": "Successful deletion"
},
"400": {
"description": "Bad request",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
},
"parameters": [ "parameters": [
{ {
"type": "string", "type": "string",
"description": "Base64 encoded signature for bearer token", "description": "Base64 encoded signature for bearer token",
"name": "X-Neofs-Token-Signature", "name": "X-Bearer-Signature",
"in": "header", "in": "header",
"required": true "required": true
}, },
{ {
"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-Bearer-Signature-Key",
"in": "header", "in": "header",
"required": true "required": true
}, },
@ -1700,7 +1722,7 @@ func init() {
"in": "path", "in": "path",
"required": true "required": true
}, },
"ojectId": { "objectId": {
"type": "string", "type": "string",
"description": "Base58 encoded object id", "description": "Base58 encoded object id",
"name": "objectId", "name": "objectId",
@ -1710,14 +1732,14 @@ func init() {
"signatureKeyParam": { "signatureKeyParam": {
"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-Bearer-Signature-Key",
"in": "header", "in": "header",
"required": true "required": true
}, },
"signatureParam": { "signatureParam": {
"type": "string", "type": "string",
"description": "Base64 encoded signature for bearer token", "description": "Base64 encoded signature for bearer token",
"name": "X-Neofs-Token-Signature", "name": "X-Bearer-Signature",
"in": "header", "in": "header",
"required": true "required": true
} }

View file

@ -27,11 +27,11 @@ func NewAuthParams() AuthParams {
var ( var (
// initialize parameters with default values // initialize parameters with default values
xNeofsTokenLifetimeDefault = int64(100) xBearerLifetimeDefault = int64(100)
) )
return AuthParams{ return AuthParams{
XNeofsTokenLifetime: &xNeofsTokenLifetimeDefault, XBearerLifetime: &xBearerLifetimeDefault,
} }
} }
@ -48,17 +48,17 @@ type AuthParams struct {
In: header In: header
Default: 100 Default: 100
*/ */
XNeofsTokenLifetime *int64 XBearerLifetime *int64
/*Supported operation scope for token /*Supported operation scope for token
Required: true Required: true
In: header In: header
*/ */
XNeofsTokenScope string XBearerScope string
/*Public key of user /*Hex encoded the public part of the key that signed the bearer token
Required: true Required: true
In: header In: header
*/ */
XNeofsTokenSignatureKey string XBearerSignatureKey string
/*Bearer token /*Bearer token
Required: true Required: true
In: body In: body
@ -75,15 +75,15 @@ func (o *AuthParams) BindRequest(r *http.Request, route *middleware.MatchedRoute
o.HTTPRequest = r o.HTTPRequest = r
if err := o.bindXNeofsTokenLifetime(r.Header[http.CanonicalHeaderKey("X-Neofs-Token-Lifetime")], true, route.Formats); err != nil { if err := o.bindXBearerLifetime(r.Header[http.CanonicalHeaderKey("X-Bearer-Lifetime")], true, route.Formats); err != nil {
res = append(res, err) res = append(res, err)
} }
if err := o.bindXNeofsTokenScope(r.Header[http.CanonicalHeaderKey("X-Neofs-Token-Scope")], true, route.Formats); err != nil { if err := o.bindXBearerScope(r.Header[http.CanonicalHeaderKey("X-Bearer-Scope")], true, route.Formats); err != nil {
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.bindXBearerSignatureKey(r.Header[http.CanonicalHeaderKey("X-Bearer-Signature-Key")], true, route.Formats); err != nil {
res = append(res, err) res = append(res, err)
} }
@ -120,8 +120,8 @@ func (o *AuthParams) BindRequest(r *http.Request, route *middleware.MatchedRoute
return nil return nil
} }
// bindXNeofsTokenLifetime binds and validates parameter XNeofsTokenLifetime from header. // bindXBearerLifetime binds and validates parameter XBearerLifetime from header.
func (o *AuthParams) bindXNeofsTokenLifetime(rawData []string, hasKey bool, formats strfmt.Registry) error { func (o *AuthParams) bindXBearerLifetime(rawData []string, hasKey bool, formats strfmt.Registry) error {
var raw string var raw string
if len(rawData) > 0 { if len(rawData) > 0 {
raw = rawData[len(rawData)-1] raw = rawData[len(rawData)-1]
@ -136,17 +136,17 @@ func (o *AuthParams) bindXNeofsTokenLifetime(rawData []string, hasKey bool, form
value, err := swag.ConvertInt64(raw) value, err := swag.ConvertInt64(raw)
if err != nil { if err != nil {
return errors.InvalidType("X-Neofs-Token-Lifetime", "header", "int64", raw) return errors.InvalidType("X-Bearer-Lifetime", "header", "int64", raw)
} }
o.XNeofsTokenLifetime = &value o.XBearerLifetime = &value
return nil return nil
} }
// bindXNeofsTokenScope binds and validates parameter XNeofsTokenScope from header. // bindXBearerScope binds and validates parameter XBearerScope from header.
func (o *AuthParams) bindXNeofsTokenScope(rawData []string, hasKey bool, formats strfmt.Registry) error { func (o *AuthParams) bindXBearerScope(rawData []string, hasKey bool, formats strfmt.Registry) error {
if !hasKey { if !hasKey {
return errors.Required("X-Neofs-Token-Scope", "header", rawData) return errors.Required("X-Bearer-Scope", "header", rawData)
} }
var raw string var raw string
if len(rawData) > 0 { if len(rawData) > 0 {
@ -155,32 +155,32 @@ func (o *AuthParams) bindXNeofsTokenScope(rawData []string, hasKey bool, formats
// Required: true // Required: true
if err := validate.RequiredString("X-Neofs-Token-Scope", "header", raw); err != nil { if err := validate.RequiredString("X-Bearer-Scope", "header", raw); err != nil {
return err return err
} }
o.XNeofsTokenScope = raw o.XBearerScope = raw
if err := o.validateXNeofsTokenScope(formats); err != nil { if err := o.validateXBearerScope(formats); err != nil {
return err return err
} }
return nil return nil
} }
// validateXNeofsTokenScope carries on validations for parameter XNeofsTokenScope // validateXBearerScope carries on validations for parameter XBearerScope
func (o *AuthParams) validateXNeofsTokenScope(formats strfmt.Registry) error { func (o *AuthParams) validateXBearerScope(formats strfmt.Registry) error {
if err := validate.EnumCase("X-Neofs-Token-Scope", "header", o.XNeofsTokenScope, []interface{}{"object", "container"}, true); err != nil { if err := validate.EnumCase("X-Bearer-Scope", "header", o.XBearerScope, []interface{}{"object", "container"}, true); err != nil {
return err return err
} }
return nil return nil
} }
// bindXNeofsTokenSignatureKey binds and validates parameter XNeofsTokenSignatureKey from header. // bindXBearerSignatureKey binds and validates parameter XBearerSignatureKey from header.
func (o *AuthParams) bindXNeofsTokenSignatureKey(rawData []string, hasKey bool, formats strfmt.Registry) error { func (o *AuthParams) bindXBearerSignatureKey(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-Bearer-Signature-Key", "header", rawData)
} }
var raw string var raw string
if len(rawData) > 0 { if len(rawData) > 0 {
@ -189,10 +189,10 @@ func (o *AuthParams) bindXNeofsTokenSignatureKey(rawData []string, hasKey bool,
// Required: true // Required: true
if err := validate.RequiredString("X-Neofs-Token-Signature-Key", "header", raw); err != nil { if err := validate.RequiredString("X-Bearer-Signature-Key", "header", raw); err != nil {
return err return err
} }
o.XNeofsTokenSignatureKey = raw o.XBearerSignatureKey = raw
return nil return nil
} }

View file

@ -35,12 +35,12 @@ type DeleteContainerParams struct {
Required: true Required: true
In: header In: header
*/ */
XNeofsTokenSignature string XBearerSignature string
/*Hex encoded the public part of the key that signed the bearer token /*Hex encoded the public part of the key that signed the bearer token
Required: true Required: true
In: header In: header
*/ */
XNeofsTokenSignatureKey string XBearerSignatureKey string
/*Base58 encoded container id /*Base58 encoded container id
Required: true Required: true
In: path In: path
@ -57,11 +57,11 @@ func (o *DeleteContainerParams) BindRequest(r *http.Request, route *middleware.M
o.HTTPRequest = r o.HTTPRequest = r
if err := o.bindXNeofsTokenSignature(r.Header[http.CanonicalHeaderKey("X-Neofs-Token-Signature")], true, route.Formats); err != nil { if err := o.bindXBearerSignature(r.Header[http.CanonicalHeaderKey("X-Bearer-Signature")], true, route.Formats); err != nil {
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.bindXBearerSignatureKey(r.Header[http.CanonicalHeaderKey("X-Bearer-Signature-Key")], true, route.Formats); err != nil {
res = append(res, err) res = append(res, err)
} }
@ -75,10 +75,10 @@ func (o *DeleteContainerParams) BindRequest(r *http.Request, route *middleware.M
return nil return nil
} }
// bindXNeofsTokenSignature binds and validates parameter XNeofsTokenSignature from header. // bindXBearerSignature binds and validates parameter XBearerSignature from header.
func (o *DeleteContainerParams) bindXNeofsTokenSignature(rawData []string, hasKey bool, formats strfmt.Registry) error { func (o *DeleteContainerParams) bindXBearerSignature(rawData []string, hasKey bool, formats strfmt.Registry) error {
if !hasKey { if !hasKey {
return errors.Required("X-Neofs-Token-Signature", "header", rawData) return errors.Required("X-Bearer-Signature", "header", rawData)
} }
var raw string var raw string
if len(rawData) > 0 { if len(rawData) > 0 {
@ -87,18 +87,18 @@ func (o *DeleteContainerParams) bindXNeofsTokenSignature(rawData []string, hasKe
// Required: true // Required: true
if err := validate.RequiredString("X-Neofs-Token-Signature", "header", raw); err != nil { if err := validate.RequiredString("X-Bearer-Signature", "header", raw); err != nil {
return err return err
} }
o.XNeofsTokenSignature = raw o.XBearerSignature = raw
return nil return nil
} }
// bindXNeofsTokenSignatureKey binds and validates parameter XNeofsTokenSignatureKey from header. // bindXBearerSignatureKey binds and validates parameter XBearerSignatureKey from header.
func (o *DeleteContainerParams) bindXNeofsTokenSignatureKey(rawData []string, hasKey bool, formats strfmt.Registry) error { func (o *DeleteContainerParams) bindXBearerSignatureKey(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-Bearer-Signature-Key", "header", rawData)
} }
var raw string var raw string
if len(rawData) > 0 { if len(rawData) > 0 {
@ -107,10 +107,10 @@ func (o *DeleteContainerParams) bindXNeofsTokenSignatureKey(rawData []string, ha
// Required: true // Required: true
if err := validate.RequiredString("X-Neofs-Token-Signature-Key", "header", raw); err != nil { if err := validate.RequiredString("X-Bearer-Signature-Key", "header", raw); err != nil {
return err return err
} }
o.XNeofsTokenSignatureKey = raw o.XBearerSignatureKey = raw
return nil return nil
} }

View 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"
)
// DeleteObjectHandlerFunc turns a function with the right signature into a delete object handler
type DeleteObjectHandlerFunc func(DeleteObjectParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn DeleteObjectHandlerFunc) Handle(params DeleteObjectParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// DeleteObjectHandler interface for that can handle valid delete object params
type DeleteObjectHandler interface {
Handle(DeleteObjectParams, *models.Principal) middleware.Responder
}
// NewDeleteObject creates a new http.Handler for the delete object operation
func NewDeleteObject(ctx *middleware.Context, handler DeleteObjectHandler) *DeleteObject {
return &DeleteObject{Context: ctx, Handler: handler}
}
/* DeleteObject swagger:route DELETE /objects/{containerId}/{objectId} deleteObject
Remove object from NeoFS
*/
type DeleteObject struct {
Context *middleware.Context
Handler DeleteObjectHandler
}
func (o *DeleteObject) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewDeleteObjectParams()
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)
}

View 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"
)
// NewDeleteObjectParams creates a new DeleteObjectParams object
//
// There are no default values defined in the spec.
func NewDeleteObjectParams() DeleteObjectParams {
return DeleteObjectParams{}
}
// DeleteObjectParams contains all the bound params for the delete object operation
// typically these are obtained from a http.Request
//
// swagger:parameters deleteObject
type DeleteObjectParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
/*Base64 encoded signature for bearer token
Required: true
In: header
*/
XBearerSignature string
/*Hex encoded the public part of the key that signed the bearer token
Required: true
In: header
*/
XBearerSignatureKey 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 NewDeleteObjectParams() beforehand.
func (o *DeleteObjectParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
if err := o.bindXBearerSignature(r.Header[http.CanonicalHeaderKey("X-Bearer-Signature")], true, route.Formats); err != nil {
res = append(res, err)
}
if err := o.bindXBearerSignatureKey(r.Header[http.CanonicalHeaderKey("X-Bearer-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
}
// bindXBearerSignature binds and validates parameter XBearerSignature from header.
func (o *DeleteObjectParams) bindXBearerSignature(rawData []string, hasKey bool, formats strfmt.Registry) error {
if !hasKey {
return errors.Required("X-Bearer-Signature", "header", rawData)
}
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: true
if err := validate.RequiredString("X-Bearer-Signature", "header", raw); err != nil {
return err
}
o.XBearerSignature = raw
return nil
}
// bindXBearerSignatureKey binds and validates parameter XBearerSignatureKey from header.
func (o *DeleteObjectParams) bindXBearerSignatureKey(rawData []string, hasKey bool, formats strfmt.Registry) error {
if !hasKey {
return errors.Required("X-Bearer-Signature-Key", "header", rawData)
}
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: true
if err := validate.RequiredString("X-Bearer-Signature-Key", "header", raw); err != nil {
return err
}
o.XBearerSignatureKey = raw
return nil
}
// bindContainerID binds and validates parameter ContainerID from path.
func (o *DeleteObjectParams) 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 *DeleteObjectParams) 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
}

View file

@ -0,0 +1,80 @@
// 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"
)
// DeleteObjectNoContentCode is the HTTP code returned for type DeleteObjectNoContent
const DeleteObjectNoContentCode int = 204
/*DeleteObjectNoContent Successful deletion
swagger:response deleteObjectNoContent
*/
type DeleteObjectNoContent struct {
}
// NewDeleteObjectNoContent creates DeleteObjectNoContent with default headers values
func NewDeleteObjectNoContent() *DeleteObjectNoContent {
return &DeleteObjectNoContent{}
}
// WriteResponse to the client
func (o *DeleteObjectNoContent) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
rw.WriteHeader(204)
}
// DeleteObjectBadRequestCode is the HTTP code returned for type DeleteObjectBadRequest
const DeleteObjectBadRequestCode int = 400
/*DeleteObjectBadRequest Bad request
swagger:response deleteObjectBadRequest
*/
type DeleteObjectBadRequest struct {
/*
In: Body
*/
Payload models.Error `json:"body,omitempty"`
}
// NewDeleteObjectBadRequest creates DeleteObjectBadRequest with default headers values
func NewDeleteObjectBadRequest() *DeleteObjectBadRequest {
return &DeleteObjectBadRequest{}
}
// WithPayload adds the payload to the delete object bad request response
func (o *DeleteObjectBadRequest) WithPayload(payload models.Error) *DeleteObjectBadRequest {
o.Payload = payload
return o
}
// SetPayload sets the payload to the delete object bad request response
func (o *DeleteObjectBadRequest) SetPayload(payload models.Error) {
o.Payload = payload
}
// WriteResponse to the client
func (o *DeleteObjectBadRequest) 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
}
}

View file

@ -35,12 +35,12 @@ type GetObjectInfoParams struct {
Required: true Required: true
In: header In: header
*/ */
XNeofsTokenSignature string XBearerSignature string
/*Hex encoded the public part of the key that signed the bearer token /*Hex encoded the public part of the key that signed the bearer token
Required: true Required: true
In: header In: header
*/ */
XNeofsTokenSignatureKey string XBearerSignatureKey string
/*Base58 encoded container id /*Base58 encoded container id
Required: true Required: true
In: path In: path
@ -62,11 +62,11 @@ func (o *GetObjectInfoParams) BindRequest(r *http.Request, route *middleware.Mat
o.HTTPRequest = r o.HTTPRequest = r
if err := o.bindXNeofsTokenSignature(r.Header[http.CanonicalHeaderKey("X-Neofs-Token-Signature")], true, route.Formats); err != nil { if err := o.bindXBearerSignature(r.Header[http.CanonicalHeaderKey("X-Bearer-Signature")], true, route.Formats); err != nil {
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.bindXBearerSignatureKey(r.Header[http.CanonicalHeaderKey("X-Bearer-Signature-Key")], true, route.Formats); err != nil {
res = append(res, err) res = append(res, err)
} }
@ -85,10 +85,10 @@ func (o *GetObjectInfoParams) BindRequest(r *http.Request, route *middleware.Mat
return nil return nil
} }
// bindXNeofsTokenSignature binds and validates parameter XNeofsTokenSignature from header. // bindXBearerSignature binds and validates parameter XBearerSignature from header.
func (o *GetObjectInfoParams) bindXNeofsTokenSignature(rawData []string, hasKey bool, formats strfmt.Registry) error { func (o *GetObjectInfoParams) bindXBearerSignature(rawData []string, hasKey bool, formats strfmt.Registry) error {
if !hasKey { if !hasKey {
return errors.Required("X-Neofs-Token-Signature", "header", rawData) return errors.Required("X-Bearer-Signature", "header", rawData)
} }
var raw string var raw string
if len(rawData) > 0 { if len(rawData) > 0 {
@ -97,18 +97,18 @@ func (o *GetObjectInfoParams) bindXNeofsTokenSignature(rawData []string, hasKey
// Required: true // Required: true
if err := validate.RequiredString("X-Neofs-Token-Signature", "header", raw); err != nil { if err := validate.RequiredString("X-Bearer-Signature", "header", raw); err != nil {
return err return err
} }
o.XNeofsTokenSignature = raw o.XBearerSignature = raw
return nil return nil
} }
// bindXNeofsTokenSignatureKey binds and validates parameter XNeofsTokenSignatureKey from header. // bindXBearerSignatureKey binds and validates parameter XBearerSignatureKey from header.
func (o *GetObjectInfoParams) bindXNeofsTokenSignatureKey(rawData []string, hasKey bool, formats strfmt.Registry) error { func (o *GetObjectInfoParams) bindXBearerSignatureKey(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-Bearer-Signature-Key", "header", rawData)
} }
var raw string var raw string
if len(rawData) > 0 { if len(rawData) > 0 {
@ -117,10 +117,10 @@ func (o *GetObjectInfoParams) bindXNeofsTokenSignatureKey(rawData []string, hasK
// Required: true // Required: true
if err := validate.RequiredString("X-Neofs-Token-Signature-Key", "header", raw); err != nil { if err := validate.RequiredString("X-Bearer-Signature-Key", "header", raw); err != nil {
return err return err
} }
o.XNeofsTokenSignatureKey = raw o.XBearerSignatureKey = raw
return nil return nil
} }

View file

@ -50,6 +50,9 @@ func NewNeofsRestGwAPI(spec *loads.Document) *NeofsRestGwAPI {
DeleteContainerHandler: DeleteContainerHandlerFunc(func(params DeleteContainerParams, principal *models.Principal) middleware.Responder { DeleteContainerHandler: DeleteContainerHandlerFunc(func(params DeleteContainerParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation DeleteContainer has not yet been implemented") return middleware.NotImplemented("operation DeleteContainer has not yet been implemented")
}), }),
DeleteObjectHandler: DeleteObjectHandlerFunc(func(params DeleteObjectParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation DeleteObject has not yet been implemented")
}),
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")
}), }),
@ -125,6 +128,8 @@ type NeofsRestGwAPI struct {
AuthHandler AuthHandler AuthHandler AuthHandler
// DeleteContainerHandler sets the operation handler for the delete container operation // DeleteContainerHandler sets the operation handler for the delete container operation
DeleteContainerHandler DeleteContainerHandler DeleteContainerHandler DeleteContainerHandler
// DeleteObjectHandler sets the operation handler for the delete object operation
DeleteObjectHandler DeleteObjectHandler
// GetContainerHandler sets the operation handler for the get container operation // GetContainerHandler sets the operation handler for the get container operation
GetContainerHandler GetContainerHandler GetContainerHandler GetContainerHandler
// GetContainerEACLHandler sets the operation handler for the get container e ACL operation // GetContainerEACLHandler sets the operation handler for the get container e ACL operation
@ -226,6 +231,9 @@ func (o *NeofsRestGwAPI) Validate() error {
if o.DeleteContainerHandler == nil { if o.DeleteContainerHandler == nil {
unregistered = append(unregistered, "DeleteContainerHandler") unregistered = append(unregistered, "DeleteContainerHandler")
} }
if o.DeleteObjectHandler == nil {
unregistered = append(unregistered, "DeleteObjectHandler")
}
if o.GetContainerHandler == nil { if o.GetContainerHandler == nil {
unregistered = append(unregistered, "GetContainerHandler") unregistered = append(unregistered, "GetContainerHandler")
} }
@ -354,6 +362,10 @@ func (o *NeofsRestGwAPI) initHandlerCache() {
o.handlers["DELETE"] = make(map[string]http.Handler) o.handlers["DELETE"] = make(map[string]http.Handler)
} }
o.handlers["DELETE"]["/containers/{containerId}"] = NewDeleteContainer(o.context, o.DeleteContainerHandler) o.handlers["DELETE"]["/containers/{containerId}"] = NewDeleteContainer(o.context, o.DeleteContainerHandler)
if o.handlers["DELETE"] == nil {
o.handlers["DELETE"] = make(map[string]http.Handler)
}
o.handlers["DELETE"]["/objects/{containerId}/{objectId}"] = NewDeleteObject(o.context, o.DeleteObjectHandler)
if o.handlers["GET"] == nil { if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler) o.handlers["GET"] = make(map[string]http.Handler)
} }

View file

@ -40,12 +40,12 @@ type PutContainerEACLParams struct {
Required: true Required: true
In: header In: header
*/ */
XNeofsTokenSignature string XBearerSignature string
/*Hex encoded the public part of the key that signed the bearer token /*Hex encoded the public part of the key that signed the bearer token
Required: true Required: true
In: header In: header
*/ */
XNeofsTokenSignatureKey string XBearerSignatureKey string
/*Base58 encoded container id /*Base58 encoded container id
Required: true Required: true
In: path In: path
@ -67,11 +67,11 @@ func (o *PutContainerEACLParams) BindRequest(r *http.Request, route *middleware.
o.HTTPRequest = r o.HTTPRequest = r
if err := o.bindXNeofsTokenSignature(r.Header[http.CanonicalHeaderKey("X-Neofs-Token-Signature")], true, route.Formats); err != nil { if err := o.bindXBearerSignature(r.Header[http.CanonicalHeaderKey("X-Bearer-Signature")], true, route.Formats); err != nil {
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.bindXBearerSignatureKey(r.Header[http.CanonicalHeaderKey("X-Bearer-Signature-Key")], true, route.Formats); err != nil {
res = append(res, err) res = append(res, err)
} }
@ -113,10 +113,10 @@ func (o *PutContainerEACLParams) BindRequest(r *http.Request, route *middleware.
return nil return nil
} }
// bindXNeofsTokenSignature binds and validates parameter XNeofsTokenSignature from header. // bindXBearerSignature binds and validates parameter XBearerSignature from header.
func (o *PutContainerEACLParams) bindXNeofsTokenSignature(rawData []string, hasKey bool, formats strfmt.Registry) error { func (o *PutContainerEACLParams) bindXBearerSignature(rawData []string, hasKey bool, formats strfmt.Registry) error {
if !hasKey { if !hasKey {
return errors.Required("X-Neofs-Token-Signature", "header", rawData) return errors.Required("X-Bearer-Signature", "header", rawData)
} }
var raw string var raw string
if len(rawData) > 0 { if len(rawData) > 0 {
@ -125,18 +125,18 @@ func (o *PutContainerEACLParams) bindXNeofsTokenSignature(rawData []string, hasK
// Required: true // Required: true
if err := validate.RequiredString("X-Neofs-Token-Signature", "header", raw); err != nil { if err := validate.RequiredString("X-Bearer-Signature", "header", raw); err != nil {
return err return err
} }
o.XNeofsTokenSignature = raw o.XBearerSignature = raw
return nil return nil
} }
// bindXNeofsTokenSignatureKey binds and validates parameter XNeofsTokenSignatureKey from header. // bindXBearerSignatureKey binds and validates parameter XBearerSignatureKey from header.
func (o *PutContainerEACLParams) bindXNeofsTokenSignatureKey(rawData []string, hasKey bool, formats strfmt.Registry) error { func (o *PutContainerEACLParams) bindXBearerSignatureKey(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-Bearer-Signature-Key", "header", rawData)
} }
var raw string var raw string
if len(rawData) > 0 { if len(rawData) > 0 {
@ -145,10 +145,10 @@ func (o *PutContainerEACLParams) bindXNeofsTokenSignatureKey(rawData []string, h
// Required: true // Required: true
if err := validate.RequiredString("X-Neofs-Token-Signature-Key", "header", raw); err != nil { if err := validate.RequiredString("X-Bearer-Signature-Key", "header", raw); err != nil {
return err return err
} }
o.XNeofsTokenSignatureKey = raw o.XBearerSignatureKey = raw
return nil return nil
} }

View file

@ -46,12 +46,12 @@ type PutContainerParams struct {
Required: true Required: true
In: header In: header
*/ */
XNeofsTokenSignature string XBearerSignature string
/*Hex encoded the public part of the key that signed the bearer token /*Hex encoded the public part of the key that signed the bearer token
Required: true Required: true
In: header In: header
*/ */
XNeofsTokenSignatureKey string XBearerSignatureKey string
/*Container info /*Container info
Required: true Required: true
In: body In: body
@ -75,11 +75,11 @@ func (o *PutContainerParams) BindRequest(r *http.Request, route *middleware.Matc
qs := runtime.Values(r.URL.Query()) qs := runtime.Values(r.URL.Query())
if err := o.bindXNeofsTokenSignature(r.Header[http.CanonicalHeaderKey("X-Neofs-Token-Signature")], true, route.Formats); err != nil { if err := o.bindXBearerSignature(r.Header[http.CanonicalHeaderKey("X-Bearer-Signature")], true, route.Formats); err != nil {
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.bindXBearerSignatureKey(r.Header[http.CanonicalHeaderKey("X-Bearer-Signature-Key")], true, route.Formats); err != nil {
res = append(res, err) res = append(res, err)
} }
@ -121,10 +121,10 @@ func (o *PutContainerParams) BindRequest(r *http.Request, route *middleware.Matc
return nil return nil
} }
// bindXNeofsTokenSignature binds and validates parameter XNeofsTokenSignature from header. // bindXBearerSignature binds and validates parameter XBearerSignature from header.
func (o *PutContainerParams) bindXNeofsTokenSignature(rawData []string, hasKey bool, formats strfmt.Registry) error { func (o *PutContainerParams) bindXBearerSignature(rawData []string, hasKey bool, formats strfmt.Registry) error {
if !hasKey { if !hasKey {
return errors.Required("X-Neofs-Token-Signature", "header", rawData) return errors.Required("X-Bearer-Signature", "header", rawData)
} }
var raw string var raw string
if len(rawData) > 0 { if len(rawData) > 0 {
@ -133,18 +133,18 @@ func (o *PutContainerParams) bindXNeofsTokenSignature(rawData []string, hasKey b
// Required: true // Required: true
if err := validate.RequiredString("X-Neofs-Token-Signature", "header", raw); err != nil { if err := validate.RequiredString("X-Bearer-Signature", "header", raw); err != nil {
return err return err
} }
o.XNeofsTokenSignature = raw o.XBearerSignature = raw
return nil return nil
} }
// bindXNeofsTokenSignatureKey binds and validates parameter XNeofsTokenSignatureKey from header. // bindXBearerSignatureKey binds and validates parameter XBearerSignatureKey from header.
func (o *PutContainerParams) bindXNeofsTokenSignatureKey(rawData []string, hasKey bool, formats strfmt.Registry) error { func (o *PutContainerParams) bindXBearerSignatureKey(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-Bearer-Signature-Key", "header", rawData)
} }
var raw string var raw string
if len(rawData) > 0 { if len(rawData) > 0 {
@ -153,10 +153,10 @@ 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-Bearer-Signature-Key", "header", raw); err != nil {
return err return err
} }
o.XNeofsTokenSignatureKey = raw o.XBearerSignatureKey = raw
return nil return nil
} }

View file

@ -38,12 +38,12 @@ type PutObjectParams struct {
Required: true Required: true
In: header In: header
*/ */
XNeofsTokenSignature string XBearerSignature string
/*Hex encoded the public part of the key that signed the bearer token /*Hex encoded the public part of the key that signed the bearer token
Required: true Required: true
In: header In: header
*/ */
XNeofsTokenSignatureKey string XBearerSignatureKey string
/*Object info to upload /*Object info to upload
Required: true Required: true
In: body In: body
@ -60,11 +60,11 @@ func (o *PutObjectParams) BindRequest(r *http.Request, route *middleware.Matched
o.HTTPRequest = r o.HTTPRequest = r
if err := o.bindXNeofsTokenSignature(r.Header[http.CanonicalHeaderKey("X-Neofs-Token-Signature")], true, route.Formats); err != nil { if err := o.bindXBearerSignature(r.Header[http.CanonicalHeaderKey("X-Bearer-Signature")], true, route.Formats); err != nil {
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.bindXBearerSignatureKey(r.Header[http.CanonicalHeaderKey("X-Bearer-Signature-Key")], true, route.Formats); err != nil {
res = append(res, err) res = append(res, err)
} }
@ -101,10 +101,10 @@ func (o *PutObjectParams) BindRequest(r *http.Request, route *middleware.Matched
return nil return nil
} }
// bindXNeofsTokenSignature binds and validates parameter XNeofsTokenSignature from header. // bindXBearerSignature binds and validates parameter XBearerSignature from header.
func (o *PutObjectParams) bindXNeofsTokenSignature(rawData []string, hasKey bool, formats strfmt.Registry) error { func (o *PutObjectParams) bindXBearerSignature(rawData []string, hasKey bool, formats strfmt.Registry) error {
if !hasKey { if !hasKey {
return errors.Required("X-Neofs-Token-Signature", "header", rawData) return errors.Required("X-Bearer-Signature", "header", rawData)
} }
var raw string var raw string
if len(rawData) > 0 { if len(rawData) > 0 {
@ -113,18 +113,18 @@ func (o *PutObjectParams) bindXNeofsTokenSignature(rawData []string, hasKey bool
// Required: true // Required: true
if err := validate.RequiredString("X-Neofs-Token-Signature", "header", raw); err != nil { if err := validate.RequiredString("X-Bearer-Signature", "header", raw); err != nil {
return err return err
} }
o.XNeofsTokenSignature = raw o.XBearerSignature = raw
return nil return nil
} }
// bindXNeofsTokenSignatureKey binds and validates parameter XNeofsTokenSignatureKey from header. // bindXBearerSignatureKey binds and validates parameter XBearerSignatureKey from header.
func (o *PutObjectParams) bindXNeofsTokenSignatureKey(rawData []string, hasKey bool, formats strfmt.Registry) error { func (o *PutObjectParams) bindXBearerSignatureKey(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-Bearer-Signature-Key", "header", rawData)
} }
var raw string var raw string
if len(rawData) > 0 { if len(rawData) > 0 {
@ -133,10 +133,10 @@ func (o *PutObjectParams) bindXNeofsTokenSignatureKey(rawData []string, hasKey b
// Required: true // Required: true
if err := validate.RequiredString("X-Neofs-Token-Signature-Key", "header", raw); err != nil { if err := validate.RequiredString("X-Bearer-Signature-Key", "header", raw); err != nil {
return err return err
} }
o.XNeofsTokenSignatureKey = raw o.XBearerSignatureKey = raw
return nil return nil
} }

View file

@ -65,6 +65,7 @@ func (a *API) Configure(api *operations.NeofsRestGwAPI) http.Handler {
api.PutObjectHandler = operations.PutObjectHandlerFunc(a.PutObjects) api.PutObjectHandler = operations.PutObjectHandlerFunc(a.PutObjects)
api.GetObjectInfoHandler = operations.GetObjectInfoHandlerFunc(a.GetObjectInfo) api.GetObjectInfoHandler = operations.GetObjectInfoHandlerFunc(a.GetObjectInfo)
api.DeleteObjectHandler = operations.DeleteObjectHandlerFunc(a.DeleteObject)
api.PutContainerHandler = operations.PutContainerHandlerFunc(a.PutContainers) api.PutContainerHandler = operations.PutContainerHandlerFunc(a.PutContainers)
api.GetContainerHandler = operations.GetContainerHandlerFunc(a.GetContainer) api.GetContainerHandler = operations.GetContainerHandlerFunc(a.GetContainer)

View file

@ -24,7 +24,7 @@ func (a *API) PostAuth(params operations.AuthParams) middleware.Responder {
resp *models.TokenResponse resp *models.TokenResponse
) )
if params.XNeofsTokenScope == "object" { if params.XBearerScope == "object" {
resp, err = prepareObjectToken(params, a.pool) resp, err = prepareObjectToken(params, a.pool)
} else { } else {
resp, err = prepareContainerTokens(params, a.pool, a.key.PublicKey()) resp, err = prepareContainerTokens(params, a.pool, a.key.PublicKey())
@ -45,7 +45,7 @@ func prepareObjectToken(params operations.AuthParams, pool *pool.Pool) (*models.
} }
btoken.SetOwner(pool.OwnerID()) btoken.SetOwner(pool.OwnerID())
iat, exp, err := getTokenLifetime(ctx, pool, params.XNeofsTokenLifetime) iat, exp, err := getTokenLifetime(ctx, pool, params.XBearerLifetime)
if err != nil { if err != nil {
return nil, fmt.Errorf("couldn't get lifetime: %w", err) return nil, fmt.Errorf("couldn't get lifetime: %w", err)
} }
@ -66,12 +66,12 @@ func prepareObjectToken(params operations.AuthParams, pool *pool.Pool) (*models.
func prepareContainerTokens(params operations.AuthParams, pool *pool.Pool, key *keys.PublicKey) (*models.TokenResponse, error) { func prepareContainerTokens(params operations.AuthParams, pool *pool.Pool, key *keys.PublicKey) (*models.TokenResponse, error) {
ctx := params.HTTPRequest.Context() ctx := params.HTTPRequest.Context()
iat, exp, err := getTokenLifetime(ctx, pool, params.XNeofsTokenLifetime) iat, exp, err := getTokenLifetime(ctx, pool, params.XBearerLifetime)
if err != nil { if err != nil {
return nil, fmt.Errorf("couldn't get lifetime: %w", err) return nil, fmt.Errorf("couldn't get lifetime: %w", err)
} }
ownerKey, err := keys.NewPublicKeyFromString(params.XNeofsTokenSignatureKey) ownerKey, err := keys.NewPublicKeyFromString(params.XBearerSignatureKey)
if err != nil { if err != nil {
return nil, fmt.Errorf("invalid singature key: %w", err) return nil, fmt.Errorf("invalid singature key: %w", err)
} }

View file

@ -4,7 +4,6 @@ import (
"context" "context"
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"github.com/nspcc-dev/neofs-sdk-go/owner"
"net/http" "net/http"
"strconv" "strconv"
"strings" "strings"
@ -19,6 +18,7 @@ import (
"github.com/nspcc-dev/neofs-sdk-go/acl" "github.com/nspcc-dev/neofs-sdk-go/acl"
"github.com/nspcc-dev/neofs-sdk-go/container" "github.com/nspcc-dev/neofs-sdk-go/container"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id" cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
"github.com/nspcc-dev/neofs-sdk-go/owner"
"github.com/nspcc-dev/neofs-sdk-go/policy" "github.com/nspcc-dev/neofs-sdk-go/policy"
"github.com/nspcc-dev/neofs-sdk-go/pool" "github.com/nspcc-dev/neofs-sdk-go/pool"
"github.com/nspcc-dev/neofs-sdk-go/session" "github.com/nspcc-dev/neofs-sdk-go/session"
@ -34,8 +34,8 @@ const (
func (a *API) PutContainers(params operations.PutContainerParams, principal *models.Principal) middleware.Responder { func (a *API) PutContainers(params operations.PutContainerParams, principal *models.Principal) middleware.Responder {
bt := &BearerToken{ bt := &BearerToken{
Token: string(*principal), Token: string(*principal),
Signature: params.XNeofsTokenSignature, Signature: params.XBearerSignature,
Key: params.XNeofsTokenSignatureKey, Key: params.XBearerSignatureKey,
} }
stoken, err := prepareSessionToken(bt) stoken, err := prepareSessionToken(bt)
if err != nil { if err != nil {
@ -92,8 +92,8 @@ func (a *API) PutContainerEACL(params operations.PutContainerEACLParams, princip
bt := &BearerToken{ bt := &BearerToken{
Token: string(*principal), Token: string(*principal),
Signature: params.XNeofsTokenSignature, Signature: params.XBearerSignature,
Key: params.XNeofsTokenSignatureKey, Key: params.XBearerSignatureKey,
} }
stoken, err := prepareSessionToken(bt) stoken, err := prepareSessionToken(bt)
if err != nil { if err != nil {
@ -180,8 +180,8 @@ func (a *API) ListContainer(params operations.ListContainersParams) middleware.R
func (a *API) DeleteContainer(params operations.DeleteContainerParams, principal *models.Principal) middleware.Responder { func (a *API) DeleteContainer(params operations.DeleteContainerParams, principal *models.Principal) middleware.Responder {
bt := &BearerToken{ bt := &BearerToken{
Token: string(*principal), Token: string(*principal),
Signature: params.XNeofsTokenSignature, Signature: params.XBearerSignature,
Key: params.XNeofsTokenSignatureKey, Key: params.XBearerSignatureKey,
} }
stoken, err := prepareSessionToken(bt) stoken, err := prepareSessionToken(bt)
if err != nil { if err != nil {

View file

@ -4,10 +4,6 @@ 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"
@ -16,8 +12,11 @@ import (
"github.com/nspcc-dev/neofs-rest-gw/gen/restapi/operations" "github.com/nspcc-dev/neofs-rest-gw/gen/restapi/operations"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id" cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
"github.com/nspcc-dev/neofs-sdk-go/object" "github.com/nspcc-dev/neofs-sdk-go/object"
"github.com/nspcc-dev/neofs-sdk-go/object/address"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
"github.com/nspcc-dev/neofs-sdk-go/pool" "github.com/nspcc-dev/neofs-sdk-go/pool"
"github.com/nspcc-dev/neofs-sdk-go/token" "github.com/nspcc-dev/neofs-sdk-go/token"
"go.uber.org/zap"
) )
// PutObjects handler that uploads object to NeoFS. // PutObjects handler that uploads object to NeoFS.
@ -25,13 +24,7 @@ func (a *API) PutObjects(params operations.PutObjectParams, principal *models.Pr
errorResponse := operations.NewPutObjectBadRequest() errorResponse := operations.NewPutObjectBadRequest()
ctx := params.HTTPRequest.Context() ctx := params.HTTPRequest.Context()
bt := &BearerToken{ btoken, err := getBearerToken(principal, params.XBearerSignature, params.XBearerSignatureKey)
Token: string(*principal),
Signature: params.XNeofsTokenSignature,
Key: params.XNeofsTokenSignatureKey,
}
btoken, err := prepareBearerToken(bt)
if err != nil { if err != nil {
return errorResponse.WithPayload(models.Error(err.Error())) return errorResponse.WithPayload(models.Error(err.Error()))
} }
@ -83,32 +76,18 @@ func (a *API) GetObjectInfo(params operations.GetObjectInfoParams, principal *mo
errorResponse := operations.NewGetObjectInfoBadRequest() errorResponse := operations.NewGetObjectInfoBadRequest()
ctx := params.HTTPRequest.Context() ctx := params.HTTPRequest.Context()
var cnrID cid.ID addr, err := parseAddress(params.ContainerID, params.ObjectID)
if err := cnrID.Parse(params.ContainerID); err != nil { if err != nil {
a.log.Error("invalid container id", zap.Error(err)) a.log.Error("invalid address", zap.Error(err))
return errorResponse.WithPayload("invalid container id") return errorResponse.WithPayload("invalid address")
}
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{ btoken, err := getBearerToken(principal, params.XBearerSignature, params.XBearerSignatureKey)
Token: string(*principal),
Signature: params.XNeofsTokenSignature,
Key: params.XNeofsTokenSignatureKey,
}
btoken, err := prepareBearerToken(bt)
if err != nil { if err != nil {
return errorResponse.WithPayload(NewError(err)) return errorResponse.WithPayload(NewError(err))
} }
var prm pool.PrmObjectHead var prm pool.PrmObjectHead
addr := address.NewAddress()
addr.SetContainerID(&cnrID)
addr.SetObjectID(&objID)
prm.SetAddress(*addr) prm.SetAddress(*addr)
prm.UseBearer(btoken) prm.UseBearer(btoken)
@ -133,8 +112,64 @@ func (a *API) GetObjectInfo(params operations.GetObjectInfoParams, principal *mo
return operations.NewGetObjectInfoOK().WithPayload(&resp) return operations.NewGetObjectInfoOK().WithPayload(&resp)
} }
// DeleteObject handler that removes object from NeoFS.
func (a *API) DeleteObject(params operations.DeleteObjectParams, principal *models.Principal) middleware.Responder {
errorResponse := operations.NewDeleteObjectBadRequest()
ctx := params.HTTPRequest.Context()
addr, err := parseAddress(params.ContainerID, params.ObjectID)
if err != nil {
a.log.Error("invalid address", zap.Error(err))
return errorResponse.WithPayload("invalid address")
}
btoken, err := getBearerToken(principal, params.XBearerSignature, params.XBearerSignatureKey)
if err != nil {
a.log.Error("failed to get bearer token", zap.Error(err))
return errorResponse.WithPayload(NewError(err))
}
var prm pool.PrmObjectDelete
prm.SetAddress(*addr)
prm.UseBearer(btoken)
if err = a.pool.DeleteObject(ctx, prm); err != nil {
a.log.Error("failed to delete object", zap.Error(err))
return errorResponse.WithPayload(NewError(err))
}
return operations.NewDeleteObjectNoContent()
}
func parseAddress(containerID, objectID string) (*address.Address, error) {
var cnrID cid.ID
if err := cnrID.Parse(containerID); err != nil {
return nil, fmt.Errorf("invalid container id: %w", err)
}
var objID oid.ID
if err := objID.Parse(objectID); err != nil {
return nil, fmt.Errorf("invalid object id: %w", err)
}
addr := address.NewAddress()
addr.SetContainerID(&cnrID)
addr.SetObjectID(&objID)
return addr, nil
}
func getBearerToken(token *models.Principal, signature, key string) (*token.BearerToken, error) {
bt := &BearerToken{
Token: string(*token),
Signature: signature,
Key: key,
}
return prepareBearerToken(bt)
}
func prepareBearerToken(bt *BearerToken) (*token.BearerToken, error) { func prepareBearerToken(bt *BearerToken) (*token.BearerToken, error) {
btoken, err := getBearerToken(bt.Token) btoken, err := parseBearerToken(bt.Token)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not fetch bearer token: %w", err) return nil, fmt.Errorf("could not fetch bearer token: %w", err)
} }
@ -158,7 +193,7 @@ func prepareBearerToken(bt *BearerToken) (*token.BearerToken, error) {
return btoken, btoken.VerifySignature() return btoken, btoken.VerifySignature()
} }
func getBearerToken(auth string) (*token.BearerToken, error) { func parseBearerToken(auth string) (*token.BearerToken, error) {
data, err := base64.StdEncoding.DecodeString(auth) data, err := base64.StdEncoding.DecodeString(auth)
if err != nil { if err != nil {
return nil, fmt.Errorf("can't base64-decode bearer token: %w", err) return nil, fmt.Errorf("can't base64-decode bearer token: %w", err)

View file

@ -23,13 +23,13 @@ security:
parameters: parameters:
signatureParam: signatureParam:
in: header in: header
name: X-Neofs-Token-Signature name: X-Bearer-Signature
description: Base64 encoded signature for bearer token description: Base64 encoded signature for bearer token
type: string type: string
required: true required: true
signatureKeyParam: signatureKeyParam:
in: header in: header
name: X-Neofs-Token-Signature-Key name: X-Bearer-Signature-Key
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
type: string type: string
required: true required: true
@ -39,7 +39,7 @@ parameters:
type: string type: string
required: true required: true
description: Base58 encoded container id description: Base58 encoded container id
ojectId: objectId:
in: path in: path
name: objectId name: objectId
type: string type: string
@ -53,22 +53,18 @@ paths:
summary: Form bearer token to futher requests summary: Form bearer token to futher requests
security: [ ] security: [ ]
parameters: parameters:
- $ref: '#/parameters/signatureKeyParam'
- in: header - in: header
description: Supported operation scope for token description: Supported operation scope for token
name: X-Neofs-Token-Scope name: X-Bearer-Scope
type: string type: string
enum: enum:
- object - object
- container - container
required: true required: true
- in: header
description: Public key of user
name: X-Neofs-Token-Signature-Key
type: string
required: true
- in: header - in: header
description: Token lifetime in epoch description: Token lifetime in epoch
name: X-Neofs-Token-Lifetime name: X-Bearer-Lifetime
type: integer type: integer
default: 100 default: 100
- in: body - in: body
@ -149,11 +145,7 @@ paths:
- $ref: '#/parameters/signatureParam' - $ref: '#/parameters/signatureParam'
- $ref: '#/parameters/signatureKeyParam' - $ref: '#/parameters/signatureKeyParam'
- $ref: '#/parameters/containerId' - $ref: '#/parameters/containerId'
- in: path - $ref: '#/parameters/objectId'
name: objectId
type: string
required: true
description: Base58 encoded object id
get: get:
operationId: getObjectInfo operationId: getObjectInfo
summary: Get object info by address and summary: Get object info by address and
@ -166,6 +158,16 @@ paths:
description: Bad request description: Bad request
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/Error'
delete:
operationId: deleteObject
summary: Remove object from NeoFS
responses:
204:
description: Successful deletion
400:
description: Bad request
schema:
$ref: '#/definitions/Error'
/containers: /containers:
put: put: