From 47e061a440cd1ef1e97916381785b4c78ddffdae Mon Sep 17 00:00:00 2001 From: Denis Kirillov Date: Mon, 29 Aug 2022 17:16:41 +0300 Subject: [PATCH] [#54] Support keys in eacl Signed-off-by: Denis Kirillov --- cmd/neofs-rest-gw/integration_test.go | 22 ++++++++++++++++------ gen/models/role.go | 5 ++++- gen/models/target.go | 4 ++-- gen/restapi/embedded_spec.go | 14 ++++++++------ internal/util/transformers.go | 10 +++++++++- spec/rest.yaml | 5 +++-- 6 files changed, 42 insertions(+), 18 deletions(-) diff --git a/cmd/neofs-rest-gw/integration_test.go b/cmd/neofs-rest-gw/integration_test.go index f824547..73246f6 100644 --- a/cmd/neofs-rest-gw/integration_test.go +++ b/cmd/neofs-rest-gw/integration_test.go @@ -883,25 +883,26 @@ func restContainerEACLPut(ctx context.Context, t *testing.T, clientPool *pool.Po Filters: []*models.Filter{}, Operation: models.NewOperation(models.OperationDELETE), Targets: []*models.Target{{ - Keys: []string{}, + Keys: []string{"031a6c6fbbdf02ca351745fa86b9ba5a9452d785ac4f7fc2b7548ca2a46c4fcf4a"}, Role: models.NewRole(models.RoleOTHERS), }}, }}, } + invalidBody, err := json.Marshal(&req) + require.NoError(t, err) + + req.Records[0].Targets[0].Role = models.NewRole(models.RoleKEYS) body, err := json.Marshal(&req) require.NoError(t, err) query := make(url.Values) query.Add(walletConnectQuery, strconv.FormatBool(useWalletConnect)) - request, err := http.NewRequest(http.MethodPut, testHost+"/v1/containers/"+cnrID.EncodeToString()+"/eacl?"+query.Encode(), bytes.NewReader(body)) - require.NoError(t, err) - request = request.WithContext(ctx) - prepareCommonHeaders(request.Header, bearerToken) + doSetEACLRequest(ctx, t, httpClient, cnrID, query, bearerToken, invalidBody, http.StatusBadRequest, nil) resp := &models.SuccessResponse{} - doRequest(t, httpClient, request, http.StatusOK, resp) + doSetEACLRequest(ctx, t, httpClient, cnrID, query, bearerToken, body, http.StatusOK, resp) require.True(t, *resp.Success) var prm pool.PrmContainerEACL @@ -917,6 +918,15 @@ func restContainerEACLPut(ctx context.Context, t *testing.T, clientPool *pool.Po require.True(t, eacl.EqualTables(*expectedTable, table)) } +func doSetEACLRequest(ctx context.Context, t *testing.T, httpClient *http.Client, cnrID cid.ID, query url.Values, bearerToken *handlers.BearerToken, body []byte, status int, model interface{}) { + request, err := http.NewRequest(http.MethodPut, testHost+"/v1/containers/"+cnrID.EncodeToString()+"/eacl?"+query.Encode(), bytes.NewReader(body)) + require.NoError(t, err) + request = request.WithContext(ctx) + prepareCommonHeaders(request.Header, bearerToken) + + doRequest(t, httpClient, request, status, model) +} + func restContainerEACLGet(ctx context.Context, t *testing.T, p *pool.Pool, cnrID cid.ID) { var prm pool.PrmContainerEACL prm.SetContainerID(cnrID) diff --git a/gen/models/role.go b/gen/models/role.go index c39ff79..c2b3964 100644 --- a/gen/models/role.go +++ b/gen/models/role.go @@ -38,6 +38,9 @@ const ( // RoleOTHERS captures enum value "OTHERS" RoleOTHERS Role = "OTHERS" + + // RoleKEYS captures enum value "KEYS" + RoleKEYS Role = "KEYS" ) // for schema @@ -45,7 +48,7 @@ var roleEnum []interface{} func init() { var res []Role - if err := json.Unmarshal([]byte(`["USER","SYSTEM","OTHERS"]`), &res); err != nil { + if err := json.Unmarshal([]byte(`["USER","SYSTEM","OTHERS","KEYS"]`), &res); err != nil { panic(err) } for _, v := range res { diff --git a/gen/models/target.go b/gen/models/target.go index f926cc7..ee2b4ee 100644 --- a/gen/models/target.go +++ b/gen/models/target.go @@ -14,8 +14,8 @@ import ( "github.com/go-openapi/validate" ) -// Target Target to apply the ACL rule. Can be a subject's role class or a list of public keys to match. -// Example: {"keys":["021dc56fc6d81d581ae7605a8e00e0e0bab6cbad566a924a527339475a97a8e38e"],"role":"USER"} +// Target Target to apply the ACL rule. Can be a subject's role class or a list of public keys to match (KEYS role). +// Example: {"keys":["021dc56fc6d81d581ae7605a8e00e0e0bab6cbad566a924a527339475a97a8e38e"],"role":"KEYS"} // // swagger:model Target type Target struct { diff --git a/gen/restapi/embedded_spec.go b/gen/restapi/embedded_spec.go index 1d22aa4..5e6df36 100644 --- a/gen/restapi/embedded_spec.go +++ b/gen/restapi/embedded_spec.go @@ -1406,7 +1406,8 @@ func init() { "enum": [ "USER", "SYSTEM", - "OTHERS" + "OTHERS", + "KEYS" ] }, "Rule": { @@ -1508,7 +1509,7 @@ func init() { } }, "Target": { - "description": "Target to apply the ACL rule. Can be a subject's role class or a list of public keys to match.", + "description": "Target to apply the ACL rule. Can be a subject's role class or a list of public keys to match (KEYS role).", "type": "object", "required": [ "role", @@ -1529,7 +1530,7 @@ func init() { "keys": [ "021dc56fc6d81d581ae7605a8e00e0e0bab6cbad566a924a527339475a97a8e38e" ], - "role": "USER" + "role": "KEYS" } }, "TokenResponse": { @@ -3144,7 +3145,8 @@ func init() { "enum": [ "USER", "SYSTEM", - "OTHERS" + "OTHERS", + "KEYS" ] }, "Rule": { @@ -3246,7 +3248,7 @@ func init() { } }, "Target": { - "description": "Target to apply the ACL rule. Can be a subject's role class or a list of public keys to match.", + "description": "Target to apply the ACL rule. Can be a subject's role class or a list of public keys to match (KEYS role).", "type": "object", "required": [ "role", @@ -3267,7 +3269,7 @@ func init() { "keys": [ "021dc56fc6d81d581ae7605a8e00e0e0bab6cbad566a924a527339475a97a8e38e" ], - "role": "USER" + "role": "KEYS" } }, "TokenResponse": { diff --git a/internal/util/transformers.go b/internal/util/transformers.go index b0a6653..c261c2a 100644 --- a/internal/util/transformers.go +++ b/internal/util/transformers.go @@ -163,8 +163,10 @@ func ToNativeRole(r *models.Role) (eacl.Role, error) { return eacl.RoleSystem, nil case models.RoleOTHERS: return eacl.RoleOthers, nil + case models.RoleKEYS: + return eacl.RoleUnknown, nil default: - return eacl.RoleUnknown, fmt.Errorf("unsupported role type: '%s'", *r) + return 0, fmt.Errorf("unsupported role type: '%s'", *r) } } @@ -177,6 +179,8 @@ func FromNativeRole(r eacl.Role) (*models.Role, error) { return models.NewRole(models.RoleSYSTEM), nil case eacl.RoleOthers: return models.NewRole(models.RoleOTHERS), nil + case eacl.RoleUnknown: + return models.NewRole(models.RoleKEYS), nil default: return nil, fmt.Errorf("unsupported role type: '%s'", r) } @@ -315,6 +319,10 @@ func FromNativeRecord(r eacl.Record) (*models.Record, error) { func ToNativeTarget(t *models.Target) (*eacl.Target, error) { var target eacl.Target + if len(t.Keys) > 0 && *t.Role != models.RoleKEYS { + return nil, fmt.Errorf("you cannot set binary keys with role other than '%s'", models.RoleKEYS) + } + role, err := ToNativeRole(t.Role) if err != nil { return nil, err diff --git a/spec/rest.yaml b/spec/rest.yaml index 5bc7bda..5c8fb29 100644 --- a/spec/rest.yaml +++ b/spec/rest.yaml @@ -657,7 +657,7 @@ definitions: - STRING_EQUAL - STRING_NOT_EQUAL Target: - description: Target to apply the ACL rule. Can be a subject's role class or a list of public keys to match. + description: Target to apply the ACL rule. Can be a subject's role class or a list of public keys to match (KEYS role). type: object properties: role: @@ -670,7 +670,7 @@ definitions: - role - keys example: - role: USER + role: KEYS keys: - 021dc56fc6d81d581ae7605a8e00e0e0bab6cbad566a924a527339475a97a8e38e Role: @@ -680,6 +680,7 @@ definitions: - USER - SYSTEM - OTHERS + - KEYS Rule: description: Container session token rule. type: object