[#54] Support keys in eacl

Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
Denis Kirillov 2022-08-29 17:16:41 +03:00 committed by Alex Vanin
parent 4b9ee3936c
commit 47e061a440
6 changed files with 42 additions and 18 deletions

View file

@ -883,25 +883,26 @@ func restContainerEACLPut(ctx context.Context, t *testing.T, clientPool *pool.Po
Filters: []*models.Filter{}, Filters: []*models.Filter{},
Operation: models.NewOperation(models.OperationDELETE), Operation: models.NewOperation(models.OperationDELETE),
Targets: []*models.Target{{ Targets: []*models.Target{{
Keys: []string{}, Keys: []string{"031a6c6fbbdf02ca351745fa86b9ba5a9452d785ac4f7fc2b7548ca2a46c4fcf4a"},
Role: models.NewRole(models.RoleOTHERS), 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) body, err := json.Marshal(&req)
require.NoError(t, err) require.NoError(t, err)
query := make(url.Values) query := make(url.Values)
query.Add(walletConnectQuery, strconv.FormatBool(useWalletConnect)) query.Add(walletConnectQuery, strconv.FormatBool(useWalletConnect))
request, err := http.NewRequest(http.MethodPut, testHost+"/v1/containers/"+cnrID.EncodeToString()+"/eacl?"+query.Encode(), bytes.NewReader(body)) doSetEACLRequest(ctx, t, httpClient, cnrID, query, bearerToken, invalidBody, http.StatusBadRequest, nil)
require.NoError(t, err)
request = request.WithContext(ctx)
prepareCommonHeaders(request.Header, bearerToken)
resp := &models.SuccessResponse{} 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) require.True(t, *resp.Success)
var prm pool.PrmContainerEACL 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)) 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) { func restContainerEACLGet(ctx context.Context, t *testing.T, p *pool.Pool, cnrID cid.ID) {
var prm pool.PrmContainerEACL var prm pool.PrmContainerEACL
prm.SetContainerID(cnrID) prm.SetContainerID(cnrID)

View file

@ -38,6 +38,9 @@ const (
// RoleOTHERS captures enum value "OTHERS" // RoleOTHERS captures enum value "OTHERS"
RoleOTHERS Role = "OTHERS" RoleOTHERS Role = "OTHERS"
// RoleKEYS captures enum value "KEYS"
RoleKEYS Role = "KEYS"
) )
// for schema // for schema
@ -45,7 +48,7 @@ var roleEnum []interface{}
func init() { func init() {
var res []Role 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) panic(err)
} }
for _, v := range res { for _, v := range res {

View file

@ -14,8 +14,8 @@ import (
"github.com/go-openapi/validate" "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. // 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":"USER"} // Example: {"keys":["021dc56fc6d81d581ae7605a8e00e0e0bab6cbad566a924a527339475a97a8e38e"],"role":"KEYS"}
// //
// swagger:model Target // swagger:model Target
type Target struct { type Target struct {

View file

@ -1406,7 +1406,8 @@ func init() {
"enum": [ "enum": [
"USER", "USER",
"SYSTEM", "SYSTEM",
"OTHERS" "OTHERS",
"KEYS"
] ]
}, },
"Rule": { "Rule": {
@ -1508,7 +1509,7 @@ func init() {
} }
}, },
"Target": { "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", "type": "object",
"required": [ "required": [
"role", "role",
@ -1529,7 +1530,7 @@ func init() {
"keys": [ "keys": [
"021dc56fc6d81d581ae7605a8e00e0e0bab6cbad566a924a527339475a97a8e38e" "021dc56fc6d81d581ae7605a8e00e0e0bab6cbad566a924a527339475a97a8e38e"
], ],
"role": "USER" "role": "KEYS"
} }
}, },
"TokenResponse": { "TokenResponse": {
@ -3144,7 +3145,8 @@ func init() {
"enum": [ "enum": [
"USER", "USER",
"SYSTEM", "SYSTEM",
"OTHERS" "OTHERS",
"KEYS"
] ]
}, },
"Rule": { "Rule": {
@ -3246,7 +3248,7 @@ func init() {
} }
}, },
"Target": { "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", "type": "object",
"required": [ "required": [
"role", "role",
@ -3267,7 +3269,7 @@ func init() {
"keys": [ "keys": [
"021dc56fc6d81d581ae7605a8e00e0e0bab6cbad566a924a527339475a97a8e38e" "021dc56fc6d81d581ae7605a8e00e0e0bab6cbad566a924a527339475a97a8e38e"
], ],
"role": "USER" "role": "KEYS"
} }
}, },
"TokenResponse": { "TokenResponse": {

View file

@ -163,8 +163,10 @@ func ToNativeRole(r *models.Role) (eacl.Role, error) {
return eacl.RoleSystem, nil return eacl.RoleSystem, nil
case models.RoleOTHERS: case models.RoleOTHERS:
return eacl.RoleOthers, nil return eacl.RoleOthers, nil
case models.RoleKEYS:
return eacl.RoleUnknown, nil
default: 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 return models.NewRole(models.RoleSYSTEM), nil
case eacl.RoleOthers: case eacl.RoleOthers:
return models.NewRole(models.RoleOTHERS), nil return models.NewRole(models.RoleOTHERS), nil
case eacl.RoleUnknown:
return models.NewRole(models.RoleKEYS), nil
default: default:
return nil, fmt.Errorf("unsupported role type: '%s'", r) 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) { func ToNativeTarget(t *models.Target) (*eacl.Target, error) {
var target eacl.Target 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) role, err := ToNativeRole(t.Role)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -657,7 +657,7 @@ definitions:
- STRING_EQUAL - STRING_EQUAL
- STRING_NOT_EQUAL - STRING_NOT_EQUAL
Target: 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 type: object
properties: properties:
role: role:
@ -670,7 +670,7 @@ definitions:
- role - role
- keys - keys
example: example:
role: USER role: KEYS
keys: keys:
- 021dc56fc6d81d581ae7605a8e00e0e0bab6cbad566a924a527339475a97a8e38e - 021dc56fc6d81d581ae7605a8e00e0e0bab6cbad566a924a527339475a97a8e38e
Role: Role:
@ -680,6 +680,7 @@ definitions:
- USER - USER
- SYSTEM - SYSTEM
- OTHERS - OTHERS
- KEYS
Rule: Rule:
description: Container session token rule. description: Container session token rule.
type: object type: object