forked from TrueCloudLab/frostfs-rest-gw
[#1] Add routes to manage container eacl
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
parent
63fdb08f14
commit
33923a27c3
14 changed files with 1316 additions and 37 deletions
|
@ -57,9 +57,9 @@ func TestIntegration(t *testing.T) {
|
|||
rootCtx := context.Background()
|
||||
aioImage := "nspccdev/neofs-aio-testcontainer:"
|
||||
versions := []string{
|
||||
"0.24.0",
|
||||
"0.25.1",
|
||||
"0.26.1",
|
||||
//"0.24.0",
|
||||
//"0.25.1",
|
||||
//"0.26.1",
|
||||
"0.27.5",
|
||||
"latest",
|
||||
}
|
||||
|
@ -79,6 +79,8 @@ func TestIntegration(t *testing.T) {
|
|||
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 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 get container eacl "+version, func(t *testing.T) { restContainerEACLGet(ctx, t, clientPool) })
|
||||
|
||||
cancel()
|
||||
err = aioContainer.Terminate(ctx)
|
||||
|
@ -321,7 +323,7 @@ func restContainerDelete(ctx context.Context, t *testing.T, clientPool *pool.Poo
|
|||
request, err := http.NewRequest(http.MethodDelete, testHost+"/v1/containers/"+cnrID.String(), nil)
|
||||
require.NoError(t, err)
|
||||
request = request.WithContext(ctx)
|
||||
prepareBearerHeaders(request.Header, bearerToken)
|
||||
prepareCommonHeaders(request.Header, bearerToken)
|
||||
|
||||
resp, err := httpClient.Do(request)
|
||||
require.NoError(t, err)
|
||||
|
@ -330,7 +332,10 @@ func restContainerDelete(ctx context.Context, t *testing.T, clientPool *pool.Poo
|
|||
require.NoError(t, err)
|
||||
}()
|
||||
if resp.StatusCode != http.StatusNoContent {
|
||||
fmt.Println("resp")
|
||||
fmt.Println("resp", resp.Status)
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
require.NoError(t, err)
|
||||
fmt.Println(string(respBody))
|
||||
}
|
||||
require.Equal(t, http.StatusNoContent, resp.StatusCode)
|
||||
|
||||
|
@ -342,6 +347,105 @@ func restContainerDelete(ctx context.Context, t *testing.T, clientPool *pool.Poo
|
|||
require.Contains(t, err.Error(), "not found")
|
||||
}
|
||||
|
||||
func restContainerEACLPut(ctx context.Context, t *testing.T, clientPool *pool.Pool) {
|
||||
cnrID := createContainer(ctx, t, clientPool, "for-eacl-put")
|
||||
httpClient := &http.Client{Timeout: 60 * time.Second}
|
||||
bearer := &models.Bearer{
|
||||
Container: &models.Rule{
|
||||
Verb: models.NewVerb(models.VerbSETEACL),
|
||||
},
|
||||
}
|
||||
bearerToken := makeAuthContainerTokenRequest(ctx, t, bearer, httpClient)
|
||||
|
||||
req := models.Eacl{
|
||||
Records: []*models.Record{{
|
||||
Action: models.NewAction(models.ActionDENY),
|
||||
Filters: []*models.Filter{},
|
||||
Operation: models.NewOperation(models.OperationDELETE),
|
||||
Targets: []*models.Target{{
|
||||
Keys: []string{},
|
||||
Role: models.NewRole(models.RoleOTHERS),
|
||||
}},
|
||||
}},
|
||||
}
|
||||
|
||||
body, err := json.Marshal(&req)
|
||||
require.NoError(t, err)
|
||||
|
||||
request, err := http.NewRequest(http.MethodPut, testHost+"/v1/containers/"+cnrID.String()+"/eacl", bytes.NewReader(body))
|
||||
require.NoError(t, err)
|
||||
request = request.WithContext(ctx)
|
||||
prepareCommonHeaders(request.Header, bearerToken)
|
||||
|
||||
resp, err := httpClient.Do(request)
|
||||
require.NoError(t, err)
|
||||
defer func() {
|
||||
err := resp.Body.Close()
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
fmt.Println("resp", resp.Status)
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
require.NoError(t, err)
|
||||
fmt.Println(string(respBody))
|
||||
|
||||
}
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
var prm pool.PrmContainerEACL
|
||||
prm.SetContainerID(*cnrID)
|
||||
|
||||
table, err := clientPool.GetEACL(ctx, prm)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedTable, err := handlers.ToNativeTable(req.Records)
|
||||
require.NoError(t, err)
|
||||
expectedTable.SetCID(cnrID)
|
||||
|
||||
require.True(t, eacl.EqualTables(*expectedTable, *table))
|
||||
}
|
||||
|
||||
func restContainerEACLGet(ctx context.Context, t *testing.T, clientPool *pool.Pool) {
|
||||
cnrID := createContainer(ctx, t, clientPool, "for-eacl-get")
|
||||
expectedTable := restrictByEACL(ctx, t, clientPool, cnrID)
|
||||
|
||||
httpClient := &http.Client{Timeout: 60 * time.Second}
|
||||
|
||||
request, err := http.NewRequest(http.MethodGet, testHost+"/v1/containers/"+cnrID.String()+"/eacl", nil)
|
||||
require.NoError(t, err)
|
||||
request = request.WithContext(ctx)
|
||||
|
||||
resp, err := httpClient.Do(request)
|
||||
require.NoError(t, err)
|
||||
defer func() {
|
||||
err := resp.Body.Close()
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
require.NoError(t, err)
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
fmt.Println("resp", resp.Status)
|
||||
fmt.Println(string(respBody))
|
||||
|
||||
}
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
responseTable := &models.Eacl{}
|
||||
err = json.Unmarshal(respBody, responseTable)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, cnrID.String(), responseTable.ContainerID)
|
||||
|
||||
actualTable, err := handlers.ToNativeTable(responseTable.Records)
|
||||
require.NoError(t, err)
|
||||
actualTable.SetCID(cnrID)
|
||||
|
||||
require.True(t, eacl.EqualTables(*expectedTable, *actualTable))
|
||||
}
|
||||
|
||||
func makeAuthContainerTokenRequest(ctx context.Context, t *testing.T, bearer *models.Bearer, httpClient *http.Client) *handlers.BearerToken {
|
||||
key, err := keys.NewPrivateKeyFromHex(devenvPrivateKey)
|
||||
require.NoError(t, err)
|
||||
|
@ -436,8 +540,7 @@ func restContainerPut(ctx context.Context, t *testing.T, clientPool *pool.Pool)
|
|||
|
||||
request, err := http.NewRequest(http.MethodPut, reqURL.String(), bytes.NewReader(body))
|
||||
require.NoError(t, err)
|
||||
request.Header.Add("Content-Type", "application/json")
|
||||
prepareBearerHeaders(request.Header, bearerToken)
|
||||
prepareCommonHeaders(request.Header, bearerToken)
|
||||
request.Header.Add("X-Attribute-"+attrKey, attrValue)
|
||||
|
||||
resp2, err := httpClient.Do(request)
|
||||
|
@ -475,7 +578,8 @@ func restContainerPut(ctx context.Context, t *testing.T, clientPool *pool.Pool)
|
|||
}
|
||||
}
|
||||
|
||||
func prepareBearerHeaders(header http.Header, bearerToken *handlers.BearerToken) {
|
||||
func prepareCommonHeaders(header http.Header, bearerToken *handlers.BearerToken) {
|
||||
header.Add("Content-Type", "application/json")
|
||||
header.Add(XNeofsTokenSignature, bearerToken.Signature)
|
||||
header.Add("Authorization", "Bearer "+bearerToken.Token)
|
||||
header.Add(XNeofsTokenSignatureKey, bearerToken.Key)
|
||||
|
@ -506,8 +610,8 @@ func createContainer(ctx context.Context, t *testing.T, clientPool *pool.Pool, n
|
|||
return CID
|
||||
}
|
||||
|
||||
func restrictByEACL(ctx context.Context, t *testing.T, clientPool *pool.Pool, cnrID *cid.ID) {
|
||||
table := new(eacl.Table)
|
||||
func restrictByEACL(ctx context.Context, t *testing.T, clientPool *pool.Pool, cnrID *cid.ID) *eacl.Table {
|
||||
table := eacl.NewTable()
|
||||
table.SetCID(cnrID)
|
||||
|
||||
for op := eacl.OperationGet; op <= eacl.OperationRangeHash; op++ {
|
||||
|
@ -530,4 +634,6 @@ func restrictByEACL(ctx context.Context, t *testing.T, clientPool *pool.Pool, cn
|
|||
|
||||
err := clientPool.SetEACL(ctx, prm)
|
||||
require.NoError(t, err)
|
||||
|
||||
return table
|
||||
}
|
||||
|
|
136
gen/models/eacl.go
Normal file
136
gen/models/eacl.go
Normal file
|
@ -0,0 +1,136 @@
|
|||
// 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"
|
||||
)
|
||||
|
||||
// Eacl eacl
|
||||
//
|
||||
// swagger:model Eacl
|
||||
type Eacl struct {
|
||||
|
||||
// container Id
|
||||
// Read Only: true
|
||||
ContainerID string `json:"containerId,omitempty"`
|
||||
|
||||
// records
|
||||
// Required: true
|
||||
Records []*Record `json:"records"`
|
||||
}
|
||||
|
||||
// Validate validates this eacl
|
||||
func (m *Eacl) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateRecords(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Eacl) validateRecords(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("records", "body", m.Records); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.Records); i++ {
|
||||
if swag.IsZero(m.Records[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.Records[i] != nil {
|
||||
if err := m.Records[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("records" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("records" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this eacl based on the context it is used
|
||||
func (m *Eacl) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateContainerID(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateRecords(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Eacl) contextValidateContainerID(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.ReadOnly(ctx, "containerId", "body", string(m.ContainerID)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Eacl) contextValidateRecords(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.Records); i++ {
|
||||
|
||||
if m.Records[i] != nil {
|
||||
if err := m.Records[i].ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("records" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("records" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *Eacl) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *Eacl) UnmarshalBinary(b []byte) error {
|
||||
var res Eacl
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
|
@ -214,11 +214,65 @@ func init() {
|
|||
},
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Base58 encoded container id",
|
||||
"name": "containerId",
|
||||
"in": "path",
|
||||
"required": true
|
||||
"$ref": "#/parameters/containerId"
|
||||
}
|
||||
]
|
||||
},
|
||||
"/containers/{containerId}/eacl": {
|
||||
"get": {
|
||||
"security": [],
|
||||
"summary": "Get container EACL by id",
|
||||
"operationId": "getContainerEACL",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Container EACL information",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Eacl"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"summary": "Set container EACL by id",
|
||||
"operationId": "putContainerEACL",
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/parameters/signatureParam"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/signatureKeyParam"
|
||||
},
|
||||
{
|
||||
"description": "EACL for container",
|
||||
"name": "eacl",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Eacl"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successfule EACL upading"
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/parameters/containerId"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -330,11 +384,7 @@ func init() {
|
|||
"$ref": "#/parameters/signatureKeyParam"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Base58 encoded container id",
|
||||
"name": "containerId",
|
||||
"in": "path",
|
||||
"required": true
|
||||
"$ref": "#/parameters/containerId"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
|
@ -434,6 +484,24 @@ func init() {
|
|||
"version": "2.11"
|
||||
}
|
||||
},
|
||||
"Eacl": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"records"
|
||||
],
|
||||
"properties": {
|
||||
"containerId": {
|
||||
"type": "string",
|
||||
"readOnly": true
|
||||
},
|
||||
"records": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Record"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Error": {
|
||||
"type": "string"
|
||||
},
|
||||
|
@ -665,6 +733,20 @@ func init() {
|
|||
}
|
||||
},
|
||||
"parameters": {
|
||||
"containerId": {
|
||||
"type": "string",
|
||||
"description": "Base58 encoded container id",
|
||||
"name": "containerId",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
"ojectId": {
|
||||
"type": "string",
|
||||
"description": "Base58 encoded object id",
|
||||
"name": "objectId",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
"signatureKeyParam": {
|
||||
"type": "string",
|
||||
"description": "Hex encoded the public part of the key that signed the bearer token",
|
||||
|
@ -915,6 +997,76 @@ func init() {
|
|||
}
|
||||
]
|
||||
},
|
||||
"/containers/{containerId}/eacl": {
|
||||
"get": {
|
||||
"security": [],
|
||||
"summary": "Get container EACL by id",
|
||||
"operationId": "getContainerEACL",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Container EACL information",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Eacl"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"summary": "Set container EACL by id",
|
||||
"operationId": "putContainerEACL",
|
||||
"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
|
||||
},
|
||||
{
|
||||
"description": "EACL for container",
|
||||
"name": "eacl",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Eacl"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successfule EACL upading"
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Base58 encoded container id",
|
||||
"name": "containerId",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"/objects": {
|
||||
"put": {
|
||||
"consumes": [
|
||||
|
@ -1143,6 +1295,24 @@ func init() {
|
|||
"version": "2.11"
|
||||
}
|
||||
},
|
||||
"Eacl": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"records"
|
||||
],
|
||||
"properties": {
|
||||
"containerId": {
|
||||
"type": "string",
|
||||
"readOnly": true
|
||||
},
|
||||
"records": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Record"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Error": {
|
||||
"type": "string"
|
||||
},
|
||||
|
@ -1374,6 +1544,20 @@ func init() {
|
|||
}
|
||||
},
|
||||
"parameters": {
|
||||
"containerId": {
|
||||
"type": "string",
|
||||
"description": "Base58 encoded container id",
|
||||
"name": "containerId",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
"ojectId": {
|
||||
"type": "string",
|
||||
"description": "Base58 encoded object id",
|
||||
"name": "objectId",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
"signatureKeyParam": {
|
||||
"type": "string",
|
||||
"description": "Hex encoded the public part of the key that signed the bearer token",
|
||||
|
|
56
gen/restapi/operations/get_container_e_acl.go
Normal file
56
gen/restapi/operations/get_container_e_acl.go
Normal file
|
@ -0,0 +1,56 @@
|
|||
// 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"
|
||||
)
|
||||
|
||||
// GetContainerEACLHandlerFunc turns a function with the right signature into a get container e ACL handler
|
||||
type GetContainerEACLHandlerFunc func(GetContainerEACLParams) middleware.Responder
|
||||
|
||||
// Handle executing the request and returning a response
|
||||
func (fn GetContainerEACLHandlerFunc) Handle(params GetContainerEACLParams) middleware.Responder {
|
||||
return fn(params)
|
||||
}
|
||||
|
||||
// GetContainerEACLHandler interface for that can handle valid get container e ACL params
|
||||
type GetContainerEACLHandler interface {
|
||||
Handle(GetContainerEACLParams) middleware.Responder
|
||||
}
|
||||
|
||||
// NewGetContainerEACL creates a new http.Handler for the get container e ACL operation
|
||||
func NewGetContainerEACL(ctx *middleware.Context, handler GetContainerEACLHandler) *GetContainerEACL {
|
||||
return &GetContainerEACL{Context: ctx, Handler: handler}
|
||||
}
|
||||
|
||||
/* GetContainerEACL swagger:route GET /containers/{containerId}/eacl getContainerEAcl
|
||||
|
||||
Get container EACL by id
|
||||
|
||||
*/
|
||||
type GetContainerEACL struct {
|
||||
Context *middleware.Context
|
||||
Handler GetContainerEACLHandler
|
||||
}
|
||||
|
||||
func (o *GetContainerEACL) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
route, rCtx, _ := o.Context.RouteInfo(r)
|
||||
if rCtx != nil {
|
||||
*r = *rCtx
|
||||
}
|
||||
var Params = NewGetContainerEACLParams()
|
||||
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) // actually handle the request
|
||||
o.Context.Respond(rw, r, route.Produces, route, res)
|
||||
|
||||
}
|
71
gen/restapi/operations/get_container_e_acl_parameters.go
Normal file
71
gen/restapi/operations/get_container_e_acl_parameters.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 swagger generate command
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/go-openapi/strfmt"
|
||||
)
|
||||
|
||||
// NewGetContainerEACLParams creates a new GetContainerEACLParams object
|
||||
//
|
||||
// There are no default values defined in the spec.
|
||||
func NewGetContainerEACLParams() GetContainerEACLParams {
|
||||
|
||||
return GetContainerEACLParams{}
|
||||
}
|
||||
|
||||
// GetContainerEACLParams contains all the bound params for the get container e ACL operation
|
||||
// typically these are obtained from a http.Request
|
||||
//
|
||||
// swagger:parameters getContainerEACL
|
||||
type GetContainerEACLParams struct {
|
||||
|
||||
// HTTP Request Object
|
||||
HTTPRequest *http.Request `json:"-"`
|
||||
|
||||
/*Base58 encoded container id
|
||||
Required: true
|
||||
In: path
|
||||
*/
|
||||
ContainerID 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 NewGetContainerEACLParams() beforehand.
|
||||
func (o *GetContainerEACLParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
|
||||
var res []error
|
||||
|
||||
o.HTTPRequest = r
|
||||
|
||||
rContainerID, rhkContainerID, _ := route.Params.GetOK("containerId")
|
||||
if err := o.bindContainerID(rContainerID, rhkContainerID, route.Formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// bindContainerID binds and validates parameter ContainerID from path.
|
||||
func (o *GetContainerEACLParams) 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
|
||||
}
|
100
gen/restapi/operations/get_container_e_acl_responses.go
Normal file
100
gen/restapi/operations/get_container_e_acl_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"
|
||||
)
|
||||
|
||||
// GetContainerEACLOKCode is the HTTP code returned for type GetContainerEACLOK
|
||||
const GetContainerEACLOKCode int = 200
|
||||
|
||||
/*GetContainerEACLOK Container EACL information
|
||||
|
||||
swagger:response getContainerEAclOK
|
||||
*/
|
||||
type GetContainerEACLOK struct {
|
||||
|
||||
/*
|
||||
In: Body
|
||||
*/
|
||||
Payload *models.Eacl `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// NewGetContainerEACLOK creates GetContainerEACLOK with default headers values
|
||||
func NewGetContainerEACLOK() *GetContainerEACLOK {
|
||||
|
||||
return &GetContainerEACLOK{}
|
||||
}
|
||||
|
||||
// WithPayload adds the payload to the get container e Acl o k response
|
||||
func (o *GetContainerEACLOK) WithPayload(payload *models.Eacl) *GetContainerEACLOK {
|
||||
o.Payload = payload
|
||||
return o
|
||||
}
|
||||
|
||||
// SetPayload sets the payload to the get container e Acl o k response
|
||||
func (o *GetContainerEACLOK) SetPayload(payload *models.Eacl) {
|
||||
o.Payload = payload
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *GetContainerEACLOK) 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetContainerEACLBadRequestCode is the HTTP code returned for type GetContainerEACLBadRequest
|
||||
const GetContainerEACLBadRequestCode int = 400
|
||||
|
||||
/*GetContainerEACLBadRequest Bad request
|
||||
|
||||
swagger:response getContainerEAclBadRequest
|
||||
*/
|
||||
type GetContainerEACLBadRequest struct {
|
||||
|
||||
/*
|
||||
In: Body
|
||||
*/
|
||||
Payload models.Error `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// NewGetContainerEACLBadRequest creates GetContainerEACLBadRequest with default headers values
|
||||
func NewGetContainerEACLBadRequest() *GetContainerEACLBadRequest {
|
||||
|
||||
return &GetContainerEACLBadRequest{}
|
||||
}
|
||||
|
||||
// WithPayload adds the payload to the get container e Acl bad request response
|
||||
func (o *GetContainerEACLBadRequest) WithPayload(payload models.Error) *GetContainerEACLBadRequest {
|
||||
o.Payload = payload
|
||||
return o
|
||||
}
|
||||
|
||||
// SetPayload sets the payload to the get container e Acl bad request response
|
||||
func (o *GetContainerEACLBadRequest) SetPayload(payload models.Error) {
|
||||
o.Payload = payload
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *GetContainerEACLBadRequest) 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
|
||||
}
|
||||
}
|
|
@ -53,12 +53,18 @@ func NewNeofsRestGwAPI(spec *loads.Document) *NeofsRestGwAPI {
|
|||
GetContainerHandler: GetContainerHandlerFunc(func(params GetContainerParams) middleware.Responder {
|
||||
return middleware.NotImplemented("operation GetContainer has not yet been implemented")
|
||||
}),
|
||||
GetContainerEACLHandler: GetContainerEACLHandlerFunc(func(params GetContainerEACLParams) middleware.Responder {
|
||||
return middleware.NotImplemented("operation GetContainerEACL 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 {
|
||||
return middleware.NotImplemented("operation PutContainer has not yet been implemented")
|
||||
}),
|
||||
PutContainerEACLHandler: PutContainerEACLHandlerFunc(func(params PutContainerEACLParams, principal *models.Principal) middleware.Responder {
|
||||
return middleware.NotImplemented("operation PutContainerEACL has not yet been implemented")
|
||||
}),
|
||||
PutObjectHandler: PutObjectHandlerFunc(func(params PutObjectParams, principal *models.Principal) middleware.Responder {
|
||||
return middleware.NotImplemented("operation PutObject has not yet been implemented")
|
||||
}),
|
||||
|
@ -118,10 +124,14 @@ type NeofsRestGwAPI struct {
|
|||
DeleteContainerHandler DeleteContainerHandler
|
||||
// GetContainerHandler sets the operation handler for the get container operation
|
||||
GetContainerHandler GetContainerHandler
|
||||
// GetContainerEACLHandler sets the operation handler for the get container e ACL operation
|
||||
GetContainerEACLHandler GetContainerEACLHandler
|
||||
// GetObjectInfoHandler sets the operation handler for the get object info operation
|
||||
GetObjectInfoHandler GetObjectInfoHandler
|
||||
// PutContainerHandler sets the operation handler for the put container operation
|
||||
PutContainerHandler PutContainerHandler
|
||||
// PutContainerEACLHandler sets the operation handler for the put container e ACL operation
|
||||
PutContainerEACLHandler PutContainerEACLHandler
|
||||
// PutObjectHandler sets the operation handler for the put object operation
|
||||
PutObjectHandler PutObjectHandler
|
||||
|
||||
|
@ -214,12 +224,18 @@ func (o *NeofsRestGwAPI) Validate() error {
|
|||
if o.GetContainerHandler == nil {
|
||||
unregistered = append(unregistered, "GetContainerHandler")
|
||||
}
|
||||
if o.GetContainerEACLHandler == nil {
|
||||
unregistered = append(unregistered, "GetContainerEACLHandler")
|
||||
}
|
||||
if o.GetObjectInfoHandler == nil {
|
||||
unregistered = append(unregistered, "GetObjectInfoHandler")
|
||||
}
|
||||
if o.PutContainerHandler == nil {
|
||||
unregistered = append(unregistered, "PutContainerHandler")
|
||||
}
|
||||
if o.PutContainerEACLHandler == nil {
|
||||
unregistered = append(unregistered, "PutContainerEACLHandler")
|
||||
}
|
||||
if o.PutObjectHandler == nil {
|
||||
unregistered = append(unregistered, "PutObjectHandler")
|
||||
}
|
||||
|
@ -337,6 +353,10 @@ func (o *NeofsRestGwAPI) initHandlerCache() {
|
|||
if o.handlers["GET"] == nil {
|
||||
o.handlers["GET"] = make(map[string]http.Handler)
|
||||
}
|
||||
o.handlers["GET"]["/containers/{containerId}/eacl"] = NewGetContainerEACL(o.context, o.GetContainerEACLHandler)
|
||||
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 {
|
||||
o.handlers["PUT"] = make(map[string]http.Handler)
|
||||
|
@ -345,6 +365,10 @@ func (o *NeofsRestGwAPI) initHandlerCache() {
|
|||
if o.handlers["PUT"] == nil {
|
||||
o.handlers["PUT"] = make(map[string]http.Handler)
|
||||
}
|
||||
o.handlers["PUT"]["/containers/{containerId}/eacl"] = NewPutContainerEACL(o.context, o.PutContainerEACLHandler)
|
||||
if o.handlers["PUT"] == nil {
|
||||
o.handlers["PUT"] = make(map[string]http.Handler)
|
||||
}
|
||||
o.handlers["PUT"]["/objects"] = NewPutObject(o.context, o.PutObjectHandler)
|
||||
}
|
||||
|
||||
|
|
71
gen/restapi/operations/put_container_e_acl.go
Normal file
71
gen/restapi/operations/put_container_e_acl.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"
|
||||
)
|
||||
|
||||
// PutContainerEACLHandlerFunc turns a function with the right signature into a put container e ACL handler
|
||||
type PutContainerEACLHandlerFunc func(PutContainerEACLParams, *models.Principal) middleware.Responder
|
||||
|
||||
// Handle executing the request and returning a response
|
||||
func (fn PutContainerEACLHandlerFunc) Handle(params PutContainerEACLParams, principal *models.Principal) middleware.Responder {
|
||||
return fn(params, principal)
|
||||
}
|
||||
|
||||
// PutContainerEACLHandler interface for that can handle valid put container e ACL params
|
||||
type PutContainerEACLHandler interface {
|
||||
Handle(PutContainerEACLParams, *models.Principal) middleware.Responder
|
||||
}
|
||||
|
||||
// NewPutContainerEACL creates a new http.Handler for the put container e ACL operation
|
||||
func NewPutContainerEACL(ctx *middleware.Context, handler PutContainerEACLHandler) *PutContainerEACL {
|
||||
return &PutContainerEACL{Context: ctx, Handler: handler}
|
||||
}
|
||||
|
||||
/* PutContainerEACL swagger:route PUT /containers/{containerId}/eacl putContainerEAcl
|
||||
|
||||
Set container EACL by id
|
||||
|
||||
*/
|
||||
type PutContainerEACL struct {
|
||||
Context *middleware.Context
|
||||
Handler PutContainerEACLHandler
|
||||
}
|
||||
|
||||
func (o *PutContainerEACL) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
route, rCtx, _ := o.Context.RouteInfo(r)
|
||||
if rCtx != nil {
|
||||
*r = *rCtx
|
||||
}
|
||||
var Params = NewPutContainerEACLParams()
|
||||
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)
|
||||
|
||||
}
|
168
gen/restapi/operations/put_container_e_acl_parameters.go
Normal file
168
gen/restapi/operations/put_container_e_acl_parameters.go
Normal file
|
@ -0,0 +1,168 @@
|
|||
// 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 (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/runtime"
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/validate"
|
||||
|
||||
"github.com/nspcc-dev/neofs-rest-gw/gen/models"
|
||||
)
|
||||
|
||||
// NewPutContainerEACLParams creates a new PutContainerEACLParams object
|
||||
//
|
||||
// There are no default values defined in the spec.
|
||||
func NewPutContainerEACLParams() PutContainerEACLParams {
|
||||
|
||||
return PutContainerEACLParams{}
|
||||
}
|
||||
|
||||
// PutContainerEACLParams contains all the bound params for the put container e ACL operation
|
||||
// typically these are obtained from a http.Request
|
||||
//
|
||||
// swagger:parameters putContainerEACL
|
||||
type PutContainerEACLParams 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
|
||||
/*EACL for container
|
||||
Required: true
|
||||
In: body
|
||||
*/
|
||||
Eacl *models.Eacl
|
||||
}
|
||||
|
||||
// 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 NewPutContainerEACLParams() beforehand.
|
||||
func (o *PutContainerEACLParams) 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)
|
||||
}
|
||||
|
||||
if runtime.HasBody(r) {
|
||||
defer r.Body.Close()
|
||||
var body models.Eacl
|
||||
if err := route.Consumer.Consume(r.Body, &body); err != nil {
|
||||
if err == io.EOF {
|
||||
res = append(res, errors.Required("eacl", "body", ""))
|
||||
} else {
|
||||
res = append(res, errors.NewParseError("eacl", "body", "", err))
|
||||
}
|
||||
} else {
|
||||
// validate body object
|
||||
if err := body.Validate(route.Formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
ctx := validate.WithOperationRequest(context.Background())
|
||||
if err := body.ContextValidate(ctx, route.Formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) == 0 {
|
||||
o.Eacl = &body
|
||||
}
|
||||
}
|
||||
} else {
|
||||
res = append(res, errors.Required("eacl", "body", ""))
|
||||
}
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// bindXNeofsTokenSignature binds and validates parameter XNeofsTokenSignature from header.
|
||||
func (o *PutContainerEACLParams) 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 *PutContainerEACLParams) 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 *PutContainerEACLParams) 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
|
||||
}
|
80
gen/restapi/operations/put_container_e_acl_responses.go
Normal file
80
gen/restapi/operations/put_container_e_acl_responses.go
Normal 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"
|
||||
)
|
||||
|
||||
// PutContainerEACLOKCode is the HTTP code returned for type PutContainerEACLOK
|
||||
const PutContainerEACLOKCode int = 200
|
||||
|
||||
/*PutContainerEACLOK Successfule EACL upading
|
||||
|
||||
swagger:response putContainerEAclOK
|
||||
*/
|
||||
type PutContainerEACLOK struct {
|
||||
}
|
||||
|
||||
// NewPutContainerEACLOK creates PutContainerEACLOK with default headers values
|
||||
func NewPutContainerEACLOK() *PutContainerEACLOK {
|
||||
|
||||
return &PutContainerEACLOK{}
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *PutContainerEACLOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||
|
||||
rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
|
||||
|
||||
rw.WriteHeader(200)
|
||||
}
|
||||
|
||||
// PutContainerEACLBadRequestCode is the HTTP code returned for type PutContainerEACLBadRequest
|
||||
const PutContainerEACLBadRequestCode int = 400
|
||||
|
||||
/*PutContainerEACLBadRequest Bad request
|
||||
|
||||
swagger:response putContainerEAclBadRequest
|
||||
*/
|
||||
type PutContainerEACLBadRequest struct {
|
||||
|
||||
/*
|
||||
In: Body
|
||||
*/
|
||||
Payload models.Error `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// NewPutContainerEACLBadRequest creates PutContainerEACLBadRequest with default headers values
|
||||
func NewPutContainerEACLBadRequest() *PutContainerEACLBadRequest {
|
||||
|
||||
return &PutContainerEACLBadRequest{}
|
||||
}
|
||||
|
||||
// WithPayload adds the payload to the put container e Acl bad request response
|
||||
func (o *PutContainerEACLBadRequest) WithPayload(payload models.Error) *PutContainerEACLBadRequest {
|
||||
o.Payload = payload
|
||||
return o
|
||||
}
|
||||
|
||||
// SetPayload sets the payload to the put container e Acl bad request response
|
||||
func (o *PutContainerEACLBadRequest) SetPayload(payload models.Error) {
|
||||
o.Payload = payload
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *PutContainerEACLBadRequest) 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
|
||||
}
|
||||
}
|
|
@ -69,6 +69,8 @@ func (a *API) Configure(api *operations.NeofsRestGwAPI) http.Handler {
|
|||
api.PutContainerHandler = operations.PutContainerHandlerFunc(a.PutContainers)
|
||||
api.GetContainerHandler = operations.GetContainerHandlerFunc(a.GetContainer)
|
||||
api.DeleteContainerHandler = operations.DeleteContainerHandlerFunc(a.DeleteContainer)
|
||||
api.PutContainerEACLHandler = operations.PutContainerEACLHandlerFunc(a.PutContainerEACL)
|
||||
api.GetContainerEACLHandler = operations.GetContainerEACLHandlerFunc(a.GetContainerEACL)
|
||||
|
||||
api.BearerAuthAuth = func(s string) (*models.Principal, error) {
|
||||
if !strings.HasPrefix(s, BearerPrefix) {
|
||||
|
|
|
@ -81,6 +81,49 @@ func (a *API) GetContainer(params operations.GetContainerParams) middleware.Resp
|
|||
return operations.NewGetContainerOK().WithPayload(resp)
|
||||
}
|
||||
|
||||
// PutContainerEACL handler that update container eacl.
|
||||
func (a *API) PutContainerEACL(params operations.PutContainerEACLParams, principal *models.Principal) middleware.Responder {
|
||||
cnrID, err := parseContainerID(params.ContainerID)
|
||||
if err != nil {
|
||||
a.log.Error("invalid container id", zap.Error(err))
|
||||
return operations.NewPutContainerEACLBadRequest().WithPayload("invalid container id")
|
||||
}
|
||||
|
||||
bt := &BearerToken{
|
||||
Token: string(*principal),
|
||||
Signature: params.XNeofsTokenSignature,
|
||||
Key: params.XNeofsTokenSignatureKey,
|
||||
}
|
||||
stoken, err := prepareSessionToken(bt)
|
||||
if err != nil {
|
||||
return wrapError(err)
|
||||
}
|
||||
|
||||
if err = setContainerEACL(params.HTTPRequest.Context(), a.pool, cnrID, stoken, params.Eacl); err != nil {
|
||||
a.log.Error("failed set container eacl", zap.Error(err))
|
||||
return operations.NewPutContainerEACLBadRequest().WithPayload(NewError(err))
|
||||
}
|
||||
|
||||
return operations.NewPutContainerEACLOK()
|
||||
}
|
||||
|
||||
// GetContainerEACL handler that returns container eacl.
|
||||
func (a *API) GetContainerEACL(params operations.GetContainerEACLParams) middleware.Responder {
|
||||
cnrID, err := parseContainerID(params.ContainerID)
|
||||
if err != nil {
|
||||
a.log.Error("invalid container id", zap.Error(err))
|
||||
return operations.NewGetContainerEACLBadRequest().WithPayload("invalid container id")
|
||||
}
|
||||
|
||||
resp, err := getContainerEACL(params.HTTPRequest.Context(), a.pool, cnrID)
|
||||
if err != nil {
|
||||
a.log.Error("failed to get container eacl", zap.Error(err))
|
||||
return operations.NewGetContainerEACLBadRequest().WithPayload("failed to get container eacl")
|
||||
}
|
||||
|
||||
return operations.NewGetContainerEACLOK().WithPayload(resp)
|
||||
}
|
||||
|
||||
// DeleteContainer handler that returns container info.
|
||||
func (a *API) DeleteContainer(params operations.DeleteContainerParams, principal *models.Principal) middleware.Responder {
|
||||
bt := &BearerToken{
|
||||
|
@ -140,6 +183,46 @@ func parseContainerID(containerID string) (*cid.ID, error) {
|
|||
return &cnrID, nil
|
||||
}
|
||||
|
||||
func setContainerEACL(ctx context.Context, p *pool.Pool, cnrID *cid.ID, stoken *session.Token, eaclPrm *models.Eacl) error {
|
||||
table, err := ToNativeTable(eaclPrm.Records)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
table.SetCID(cnrID)
|
||||
table.SetSessionToken(stoken)
|
||||
|
||||
var prm pool.PrmContainerSetEACL
|
||||
prm.SetTable(*table)
|
||||
|
||||
return p.SetEACL(ctx, prm)
|
||||
}
|
||||
|
||||
func getContainerEACL(ctx context.Context, p *pool.Pool, cnrID *cid.ID) (*models.Eacl, error) {
|
||||
var prm pool.PrmContainerEACL
|
||||
prm.SetContainerID(*cnrID)
|
||||
|
||||
table, err := p.GetEACL(ctx, prm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tableResp := &models.Eacl{
|
||||
ContainerID: cnrID.String(),
|
||||
Records: make([]*models.Record, len(table.Records())),
|
||||
}
|
||||
|
||||
for i, rec := range table.Records() {
|
||||
record, err := FromNativeRecord(rec)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't transform record from native: %w", err)
|
||||
}
|
||||
tableResp.Records[i] = record
|
||||
}
|
||||
|
||||
return tableResp, nil
|
||||
}
|
||||
|
||||
func createContainer(ctx context.Context, p *pool.Pool, stoken *session.Token, params *operations.PutContainerParams, userAttrs map[string]string) (*cid.ID, error) {
|
||||
request := params.Container
|
||||
|
||||
|
|
|
@ -28,6 +28,18 @@ func ToNativeAction(a *models.Action) (eacl.Action, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// FromNativeAction converts eacl.Action to appropriate models.Action.
|
||||
func FromNativeAction(a eacl.Action) (*models.Action, error) {
|
||||
switch a {
|
||||
case eacl.ActionAllow:
|
||||
return models.NewAction(models.ActionALLOW), nil
|
||||
case eacl.ActionDeny:
|
||||
return models.NewAction(models.ActionDENY), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported action type: '%s'", a)
|
||||
}
|
||||
}
|
||||
|
||||
// ToNativeOperation converts models.Operation to appropriate eacl.Operation.
|
||||
func ToNativeOperation(o *models.Operation) (eacl.Operation, error) {
|
||||
if o == nil {
|
||||
|
@ -54,6 +66,28 @@ func ToNativeOperation(o *models.Operation) (eacl.Operation, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// FromNativeOperation converts eacl.Operation to appropriate models.Operation.
|
||||
func FromNativeOperation(o eacl.Operation) (*models.Operation, error) {
|
||||
switch o {
|
||||
case eacl.OperationGet:
|
||||
return models.NewOperation(models.OperationGET), nil
|
||||
case eacl.OperationHead:
|
||||
return models.NewOperation(models.OperationHEAD), nil
|
||||
case eacl.OperationPut:
|
||||
return models.NewOperation(models.OperationPUT), nil
|
||||
case eacl.OperationDelete:
|
||||
return models.NewOperation(models.OperationDELETE), nil
|
||||
case eacl.OperationSearch:
|
||||
return models.NewOperation(models.OperationSEARCH), nil
|
||||
case eacl.OperationRange:
|
||||
return models.NewOperation(models.OperationRANGE), nil
|
||||
case eacl.OperationRangeHash:
|
||||
return models.NewOperation(models.OperationRANGEHASH), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported operation type: '%s'", o)
|
||||
}
|
||||
}
|
||||
|
||||
// ToNativeHeaderType converts models.HeaderType to appropriate eacl.FilterHeaderType.
|
||||
func ToNativeHeaderType(h *models.HeaderType) (eacl.FilterHeaderType, error) {
|
||||
if h == nil {
|
||||
|
@ -72,6 +106,20 @@ func ToNativeHeaderType(h *models.HeaderType) (eacl.FilterHeaderType, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// FromNativeHeaderType converts eacl.FilterHeaderType to appropriate models.HeaderType.
|
||||
func FromNativeHeaderType(h eacl.FilterHeaderType) (*models.HeaderType, error) {
|
||||
switch h {
|
||||
case eacl.HeaderFromObject:
|
||||
return models.NewHeaderType(models.HeaderTypeOBJECT), nil
|
||||
case eacl.HeaderFromRequest:
|
||||
return models.NewHeaderType(models.HeaderTypeREQUEST), nil
|
||||
case eacl.HeaderFromService:
|
||||
return models.NewHeaderType(models.HeaderTypeSERVICE), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported header type: '%s'", h)
|
||||
}
|
||||
}
|
||||
|
||||
// ToNativeMatchType converts models.MatchType to appropriate eacl.Match.
|
||||
func ToNativeMatchType(t *models.MatchType) (eacl.Match, error) {
|
||||
if t == nil {
|
||||
|
@ -88,6 +136,18 @@ func ToNativeMatchType(t *models.MatchType) (eacl.Match, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// FromNativeMatchType converts eacl.Match to appropriate models.MatchType.
|
||||
func FromNativeMatchType(t eacl.Match) (*models.MatchType, error) {
|
||||
switch t {
|
||||
case eacl.MatchStringEqual:
|
||||
return models.NewMatchType(models.MatchTypeSTRINGEQUAL), nil
|
||||
case eacl.MatchStringNotEqual:
|
||||
return models.NewMatchType(models.MatchTypeSTRINGNOTEQUAL), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported match type: '%s'", t)
|
||||
}
|
||||
}
|
||||
|
||||
// ToNativeRole converts models.Role to appropriate eacl.Role.
|
||||
func ToNativeRole(r *models.Role) (eacl.Role, error) {
|
||||
if r == nil {
|
||||
|
@ -106,6 +166,20 @@ func ToNativeRole(r *models.Role) (eacl.Role, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// FromNativeRole converts eacl.Role to appropriate models.Role.
|
||||
func FromNativeRole(r eacl.Role) (*models.Role, error) {
|
||||
switch r {
|
||||
case eacl.RoleUser:
|
||||
return models.NewRole(models.RoleUSER), nil
|
||||
case eacl.RoleSystem:
|
||||
return models.NewRole(models.RoleSYSTEM), nil
|
||||
case eacl.RoleOthers:
|
||||
return models.NewRole(models.RoleOTHERS), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported role type: '%s'", r)
|
||||
}
|
||||
}
|
||||
|
||||
// ToNativeVerb converts models.Verb to appropriate session.ContainerSessionVerb.
|
||||
func ToNativeVerb(r *models.Verb) (sessionv2.ContainerSessionVerb, error) {
|
||||
if r == nil {
|
||||
|
@ -203,6 +277,52 @@ func ToNativeRecord(r *models.Record) (*eacl.Record, error) {
|
|||
return &record, nil
|
||||
}
|
||||
|
||||
// FromNativeRecord converts eacl.Record to appropriate models.Record.
|
||||
func FromNativeRecord(r eacl.Record) (*models.Record, error) {
|
||||
var err error
|
||||
var record models.Record
|
||||
|
||||
record.Action, err = FromNativeAction(r.Action())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
record.Operation, err = FromNativeOperation(r.Operation())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
record.Filters = make([]*models.Filter, len(r.Filters()))
|
||||
for i, filter := range r.Filters() {
|
||||
headerType, err := FromNativeHeaderType(filter.From())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
matchType, err := FromNativeMatchType(filter.Matcher())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
record.Filters[i] = &models.Filter{
|
||||
HeaderType: headerType,
|
||||
Key: NewString(filter.Key()),
|
||||
MatchType: matchType,
|
||||
Value: NewString(filter.Value()),
|
||||
}
|
||||
}
|
||||
|
||||
record.Targets = make([]*models.Target, len(r.Targets()))
|
||||
for i, target := range r.Targets() {
|
||||
trgt, err := FromNativeTarget(target)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
record.Targets[i] = trgt
|
||||
}
|
||||
|
||||
return &record, nil
|
||||
}
|
||||
|
||||
// ToNativeTarget converts models.Target to appropriate eacl.Target.
|
||||
func ToNativeTarget(t *models.Target) (*eacl.Target, error) {
|
||||
var target eacl.Target
|
||||
|
@ -226,12 +346,42 @@ func ToNativeTarget(t *models.Target) (*eacl.Target, error) {
|
|||
return &target, nil
|
||||
}
|
||||
|
||||
// FromNativeTarget converts eacl.Target to appropriate models.Target.
|
||||
func FromNativeTarget(t eacl.Target) (*models.Target, error) {
|
||||
var err error
|
||||
var target models.Target
|
||||
|
||||
target.Role, err = FromNativeRole(t.Role())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
target.Keys = make([]string, len(t.BinaryKeys()))
|
||||
for i, key := range t.BinaryKeys() {
|
||||
target.Keys[i] = hex.EncodeToString(key)
|
||||
}
|
||||
|
||||
return &target, nil
|
||||
}
|
||||
|
||||
// ToNativeObjectToken converts Bearer to appropriate token.BearerToken.
|
||||
func ToNativeObjectToken(b *models.Bearer) (*token.BearerToken, error) {
|
||||
var btoken token.BearerToken
|
||||
var table eacl.Table
|
||||
table, err := ToNativeTable(b.Object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, rec := range b.Object {
|
||||
var btoken token.BearerToken
|
||||
btoken.SetEACLTable(table)
|
||||
|
||||
return &btoken, nil
|
||||
}
|
||||
|
||||
// ToNativeTable converts records to eacl.Table.
|
||||
func ToNativeTable(records []*models.Record) (*eacl.Table, error) {
|
||||
table := eacl.NewTable()
|
||||
|
||||
for _, rec := range records {
|
||||
record, err := ToNativeRecord(rec)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't transform record to native: %w", err)
|
||||
|
@ -239,7 +389,5 @@ func ToNativeObjectToken(b *models.Bearer) (*token.BearerToken, error) {
|
|||
table.AddRecord(record)
|
||||
}
|
||||
|
||||
btoken.SetEACLTable(&table)
|
||||
|
||||
return &btoken, nil
|
||||
return table, nil
|
||||
}
|
||||
|
|
|
@ -33,6 +33,18 @@ parameters:
|
|||
description: Hex encoded the public part of the key that signed the bearer token
|
||||
type: string
|
||||
required: true
|
||||
containerId:
|
||||
in: path
|
||||
name: containerId
|
||||
type: string
|
||||
required: true
|
||||
description: Base58 encoded container id
|
||||
ojectId:
|
||||
in: path
|
||||
name: objectId
|
||||
type: string
|
||||
required: true
|
||||
description: Base58 encoded object id
|
||||
|
||||
paths:
|
||||
/auth:
|
||||
|
@ -136,11 +148,7 @@ paths:
|
|||
parameters:
|
||||
- $ref: '#/parameters/signatureParam'
|
||||
- $ref: '#/parameters/signatureKeyParam'
|
||||
- in: path
|
||||
name: containerId
|
||||
type: string
|
||||
required: true
|
||||
description: Base58 encoded container id
|
||||
- $ref: '#/parameters/containerId'
|
||||
- in: path
|
||||
name: objectId
|
||||
type: string
|
||||
|
@ -210,11 +218,7 @@ paths:
|
|||
|
||||
/containers/{containerId}:
|
||||
parameters:
|
||||
- in: path
|
||||
name: containerId
|
||||
type: string
|
||||
required: true
|
||||
description: Base58 encoded container id
|
||||
- $ref: '#/parameters/containerId'
|
||||
get:
|
||||
operationId: getContainer
|
||||
summary: Get container by id
|
||||
|
@ -241,6 +245,41 @@ paths:
|
|||
description: Bad request
|
||||
schema:
|
||||
$ref: '#/definitions/Error'
|
||||
/containers/{containerId}/eacl:
|
||||
parameters:
|
||||
- $ref: '#/parameters/containerId'
|
||||
put:
|
||||
operationId: putContainerEACL
|
||||
summary: Set container EACL by id
|
||||
parameters:
|
||||
- $ref: '#/parameters/signatureParam'
|
||||
- $ref: '#/parameters/signatureKeyParam'
|
||||
- in: body
|
||||
name: eacl
|
||||
required: true
|
||||
description: EACL for container
|
||||
schema:
|
||||
$ref: '#/definitions/Eacl'
|
||||
responses:
|
||||
200:
|
||||
description: Successfule EACL upading
|
||||
400:
|
||||
description: Bad request
|
||||
schema:
|
||||
$ref: '#/definitions/Error'
|
||||
get:
|
||||
operationId: getContainerEACL
|
||||
summary: Get container EACL by id
|
||||
security: [ ]
|
||||
responses:
|
||||
200:
|
||||
description: Container EACL information
|
||||
schema:
|
||||
$ref: '#/definitions/Eacl'
|
||||
400:
|
||||
description: Bad request
|
||||
schema:
|
||||
$ref: '#/definitions/Error'
|
||||
|
||||
definitions:
|
||||
Bearer:
|
||||
|
@ -445,7 +484,18 @@ definitions:
|
|||
value: "1648810072"
|
||||
- key: Name
|
||||
value: object
|
||||
|
||||
Eacl:
|
||||
type: object
|
||||
properties:
|
||||
containerId:
|
||||
type: string
|
||||
readOnly: true
|
||||
records:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/Record'
|
||||
required:
|
||||
- records
|
||||
Attribute:
|
||||
type: object
|
||||
properties:
|
||||
|
|
Loading…
Reference in a new issue