From 41a07df933390b4a33f5bda07c94eaf2422d1298 Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Thu, 10 Aug 2023 15:42:45 +0400 Subject: [PATCH] cli: add container ownership check The eACL table can only be set by the container owner or his authorized representative. Similar to `container delete`, it makes sense to add an ownership check to `container set-eacl`. Precede the ACL extensibility check with an owner check: if the `--no-precheck` flag is set, then the caller must be the owner of the container or provide a session token signed by them. Refs #2436. Signed-off-by: Ekaterina Pavlova --- CHANGELOG.md | 1 + cmd/neofs-cli/internal/client/client.go | 15 ---------- cmd/neofs-cli/modules/container/set_eacl.go | 33 +++++++++++++++++++-- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38fbe909bb4..356f554328b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ Changelog for NeoFS Node - CLI `--timeout` flag configures whole execution timeout from now (#2124) - CLI default timeout for commands with `--await` flag increased to 1m (#2124) - BlobStor tries to store object in any sub-storage with free space (#2450) +- CLI `neofs-cli container set-eacl` checks container's ownership (#2436) ### Updated - `neofs-sdk-go` to `v1.0.0-rc.10` diff --git a/cmd/neofs-cli/internal/client/client.go b/cmd/neofs-cli/internal/client/client.go index b3ac01e0900..59629937fca 100644 --- a/cmd/neofs-cli/internal/client/client.go +++ b/cmd/neofs-cli/internal/client/client.go @@ -148,21 +148,6 @@ func GetContainer(ctx context.Context, prm GetContainerPrm) (res GetContainerRes return } -// IsACLExtendable checks if ACL of the container referenced by the given identifier -// can be extended. Client connection MUST BE correctly established in advance. -func IsACLExtendable(ctx context.Context, c *client.Client, cnr cid.ID) (bool, error) { - var prm GetContainerPrm - prm.SetClient(c) - prm.SetContainer(cnr) - - res, err := GetContainer(ctx, prm) - if err != nil { - return false, fmt.Errorf("get container from the NeoFS: %w", err) - } - - return res.Container().BasicACL().Extendable(), nil -} - // DeleteContainerPrm groups parameters of DeleteContainerPrm operation. type DeleteContainerPrm struct { commonPrm diff --git a/cmd/neofs-cli/modules/container/set_eacl.go b/cmd/neofs-cli/modules/container/set_eacl.go index e0126fe4ecf..8aa5b42b54e 100644 --- a/cmd/neofs-cli/modules/container/set_eacl.go +++ b/cmd/neofs-cli/modules/container/set_eacl.go @@ -10,6 +10,7 @@ import ( "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key" + "github.com/nspcc-dev/neofs-sdk-go/user" "github.com/spf13/cobra" ) @@ -40,9 +41,37 @@ Container ID in EACL table will be substituted with ID from the CLI.`, if !flagVarsSetEACL.noPreCheck { cmd.Println("Checking the ability to modify access rights in the container...") + common.PrintVerbose(cmd, "Reading the container to check ownership...") - extendable, err := internalclient.IsACLExtendable(ctx, cli, id) - common.ExitOnErr(cmd, "Extensibility check failure: %w", err) + var getPrm internalclient.GetContainerPrm + getPrm.SetClient(cli) + getPrm.SetContainer(id) + + resGet, err := internalclient.GetContainer(ctx, getPrm) + common.ExitOnErr(cmd, "can't get the container: %w", err) + + cnr := resGet.Container() + owner := cnr.Owner() + + if tok != nil { + common.PrintVerbose(cmd, "Checking session issuer...") + + if !tok.Issuer().Equals(owner) { + common.ExitOnErr(cmd, "", fmt.Errorf("session issuer differs with the container owner: expected %s, has %s", owner, tok.Issuer())) + } + } else { + common.PrintVerbose(cmd, "Checking provided account...") + + acc := user.ResolveFromECDSAPublicKey(pk.PublicKey) + + if !acc.Equals(owner) { + common.ExitOnErr(cmd, "", fmt.Errorf("provided account differs with the container owner: expected %s, has %s", owner, acc)) + } + } + + common.PrintVerbose(cmd, "Account matches the container owner.") + + extendable := cnr.BasicACL().Extendable() if !extendable { common.ExitOnErr(cmd, "", errors.New("container ACL is immutable"))