From d48a7b6f666cc554d0719e7aa6ef562f91f13db3 Mon Sep 17 00:00:00 2001 From: Denis Kirillov Date: Thu, 9 Jun 2022 12:59:02 +0300 Subject: [PATCH] [#3] Use owner id to auth Signed-off-by: Denis Kirillov --- Dockerfile | 2 +- cmd/neofs-rest-gw/integration_test.go | 14 +++--- gen/restapi/embedded_spec.go | 10 +++-- gen/restapi/operations/auth_parameters.go | 54 +++++++++++------------ handlers/auth.go | 9 ++-- handlers/containers.go | 2 +- handlers/objects.go | 2 +- spec/rest.yaml | 6 ++- 8 files changed, 55 insertions(+), 44 deletions(-) diff --git a/Dockerfile b/Dockerfile index a483302..d57c6c0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM golang:1.17 as basebuilder RUN set -x \ && apt-get update \ - && apt-get install -y make + && apt-get install -y make jq FROM basebuilder as builder ENV GOGC off diff --git a/cmd/neofs-rest-gw/integration_test.go b/cmd/neofs-rest-gw/integration_test.go index 0f793d3..d4ee7a7 100644 --- a/cmd/neofs-rest-gw/integration_test.go +++ b/cmd/neofs-rest-gw/integration_test.go @@ -25,13 +25,14 @@ import ( "github.com/nspcc-dev/neofs-rest-gw/gen/restapi/operations" "github.com/nspcc-dev/neofs-rest-gw/handlers" "github.com/nspcc-dev/neofs-rest-gw/internal/util" - "github.com/nspcc-dev/neofs-rest-gw/internal/wallet-connect" + walletconnect "github.com/nspcc-dev/neofs-rest-gw/internal/wallet-connect" "github.com/nspcc-dev/neofs-sdk-go/container" cid "github.com/nspcc-dev/neofs-sdk-go/container/id" "github.com/nspcc-dev/neofs-sdk-go/eacl" "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/owner" "github.com/nspcc-dev/neofs-sdk-go/policy" "github.com/nspcc-dev/neofs-sdk-go/pool" "github.com/spf13/viper" @@ -54,11 +55,13 @@ const ( XBearerSignature = "X-Bearer-Signature" // XBearerSignatureKey header contains hex encoded public key that corresponds the signature of the token body. XBearerSignatureKey = "X-Bearer-Signature-Key" + // XBearerOwnerID header contains owner id (wallet address) that corresponds the signature of the token body. + XBearerOwnerID = "X-Bearer-Owner-Id" // XBearerScope header contains operation scope for auth (bearer) token. // It corresponds to 'object' or 'container' services in neofs. XBearerScope = "X-Bearer-Scope" - // configuration tests + // tests configuration. useWalletConnect = false useLocalEnvironment = false ) @@ -86,7 +89,8 @@ func runTestInContainer(rootCtx context.Context, t *testing.T, key *keys.Private //"0.25.1", //"0.26.1", //"0.27.5", - "latest", + "0.27.7", + //"latest", } for _, version := range versions { @@ -682,7 +686,7 @@ func makeAuthTokenRequest(ctx context.Context, t *testing.T, bearer *models.Bear key, err := keys.NewPrivateKeyFromHex(devenvPrivateKey) require.NoError(t, err) - hexPubKey := hex.EncodeToString(key.PublicKey().Bytes()) + ownerID := owner.NewIDFromPublicKey((*ecdsa.PublicKey)(key.PublicKey())) data, err := json.Marshal(bearer) require.NoError(t, err) @@ -692,7 +696,7 @@ func makeAuthTokenRequest(ctx context.Context, t *testing.T, bearer *models.Bear request = request.WithContext(ctx) request.Header.Add("Content-Type", "application/json") request.Header.Add(XBearerScope, string(tokenType)) - request.Header.Add(XBearerSignatureKey, hexPubKey) + request.Header.Add(XBearerOwnerID, ownerID.String()) resp, err := httpClient.Do(request) require.NoError(t, err) diff --git a/gen/restapi/embedded_spec.go b/gen/restapi/embedded_spec.go index 40c9f1d..d5b4c83 100644 --- a/gen/restapi/embedded_spec.go +++ b/gen/restapi/embedded_spec.go @@ -43,7 +43,11 @@ func init() { "operationId": "auth", "parameters": [ { - "$ref": "#/parameters/signatureKeyParam" + "type": "string", + "description": "Owner Id (wallet address) that will sign the token", + "name": "X-Bearer-Owner-Id", + "in": "header", + "required": true }, { "enum": [ @@ -1094,8 +1098,8 @@ func init() { "parameters": [ { "type": "string", - "description": "Hex encoded the public part of the key that signed the bearer token", - "name": "X-Bearer-Signature-Key", + "description": "Owner Id (wallet address) that will sign the token", + "name": "X-Bearer-Owner-Id", "in": "header", "required": true }, diff --git a/gen/restapi/operations/auth_parameters.go b/gen/restapi/operations/auth_parameters.go index eaab093..b5fde96 100644 --- a/gen/restapi/operations/auth_parameters.go +++ b/gen/restapi/operations/auth_parameters.go @@ -49,16 +49,16 @@ type AuthParams struct { Default: 100 */ XBearerLifetime *int64 + /*Owner Id (wallet address) that will sign the token + Required: true + In: header + */ + XBearerOwnerID string /*Supported operation scope for token Required: true In: header */ XBearerScope string - /*Hex encoded the public part of the key that signed the bearer token - Required: true - In: header - */ - XBearerSignatureKey string /*Bearer token Required: true In: body @@ -79,11 +79,11 @@ func (o *AuthParams) BindRequest(r *http.Request, route *middleware.MatchedRoute res = append(res, err) } - if err := o.bindXBearerScope(r.Header[http.CanonicalHeaderKey("X-Bearer-Scope")], true, route.Formats); err != nil { + if err := o.bindXBearerOwnerID(r.Header[http.CanonicalHeaderKey("X-Bearer-Owner-Id")], 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 { + if err := o.bindXBearerScope(r.Header[http.CanonicalHeaderKey("X-Bearer-Scope")], true, route.Formats); err != nil { res = append(res, err) } @@ -143,6 +143,26 @@ func (o *AuthParams) bindXBearerLifetime(rawData []string, hasKey bool, formats return nil } +// bindXBearerOwnerID binds and validates parameter XBearerOwnerID from header. +func (o *AuthParams) bindXBearerOwnerID(rawData []string, hasKey bool, formats strfmt.Registry) error { + if !hasKey { + return errors.Required("X-Bearer-Owner-Id", "header", rawData) + } + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: true + + if err := validate.RequiredString("X-Bearer-Owner-Id", "header", raw); err != nil { + return err + } + o.XBearerOwnerID = raw + + return nil +} + // bindXBearerScope binds and validates parameter XBearerScope from header. func (o *AuthParams) bindXBearerScope(rawData []string, hasKey bool, formats strfmt.Registry) error { if !hasKey { @@ -176,23 +196,3 @@ func (o *AuthParams) validateXBearerScope(formats strfmt.Registry) error { return nil } - -// bindXBearerSignatureKey binds and validates parameter XBearerSignatureKey from header. -func (o *AuthParams) 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 -} diff --git a/handlers/auth.go b/handlers/auth.go index ac9ead8..6afec2a 100644 --- a/handlers/auth.go +++ b/handlers/auth.go @@ -2,7 +2,6 @@ package handlers import ( "context" - "crypto/ecdsa" "encoding/base64" "fmt" @@ -72,9 +71,9 @@ func prepareContainerTokens(params operations.AuthParams, pool *pool.Pool, key * return nil, fmt.Errorf("couldn't get lifetime: %w", err) } - ownerKey, err := keys.NewPublicKeyFromString(params.XBearerSignatureKey) - if err != nil { - return nil, fmt.Errorf("invalid singature key: %w", err) + var ownerID owner.ID + if err = ownerID.Parse(params.XBearerOwnerID); err != nil { + return nil, fmt.Errorf("invalid bearer owner: %w", err) } var resp models.TokenResponse @@ -91,7 +90,7 @@ func prepareContainerTokens(params operations.AuthParams, pool *pool.Pool, key * } stoken.SetID(uid) - stoken.SetOwnerID(owner.NewIDFromPublicKey((*ecdsa.PublicKey)(ownerKey))) + stoken.SetOwnerID(&ownerID) stoken.SetIat(iat) stoken.SetExp(exp) diff --git a/handlers/containers.go b/handlers/containers.go index f4d650a..e7c5b81 100644 --- a/handlers/containers.go +++ b/handlers/containers.go @@ -17,7 +17,7 @@ import ( "github.com/nspcc-dev/neofs-rest-gw/gen/models" "github.com/nspcc-dev/neofs-rest-gw/gen/restapi/operations" "github.com/nspcc-dev/neofs-rest-gw/internal/util" - "github.com/nspcc-dev/neofs-rest-gw/internal/wallet-connect" + walletconnect "github.com/nspcc-dev/neofs-rest-gw/internal/wallet-connect" "github.com/nspcc-dev/neofs-sdk-go/acl" "github.com/nspcc-dev/neofs-sdk-go/container" cid "github.com/nspcc-dev/neofs-sdk-go/container/id" diff --git a/handlers/objects.go b/handlers/objects.go index 85f52c1..91e44c9 100644 --- a/handlers/objects.go +++ b/handlers/objects.go @@ -15,7 +15,7 @@ import ( "github.com/nspcc-dev/neofs-rest-gw/gen/models" "github.com/nspcc-dev/neofs-rest-gw/gen/restapi/operations" "github.com/nspcc-dev/neofs-rest-gw/internal/util" - "github.com/nspcc-dev/neofs-rest-gw/internal/wallet-connect" + walletconnect "github.com/nspcc-dev/neofs-rest-gw/internal/wallet-connect" 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/address" diff --git a/spec/rest.yaml b/spec/rest.yaml index d2a8657..0403176 100644 --- a/spec/rest.yaml +++ b/spec/rest.yaml @@ -59,7 +59,11 @@ paths: summary: Form bearer token to futher requests security: [ ] parameters: - - $ref: '#/parameters/signatureKeyParam' + - in: header + name: X-Bearer-Owner-Id + description: Owner Id (wallet address) that will sign the token + type: string + required: true - in: header description: Supported operation scope for token name: X-Bearer-Scope