Skip to content

Commit

Permalink
authmate: Add command to reset container EACL to default state
Browse files Browse the repository at this point in the history
We assume container is private.

Signed-off-by: Evgenii Baidakov <[email protected]>
  • Loading branch information
smallhive committed Jan 24, 2025
1 parent c674acc commit 8b3d943
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 0 deletions.
6 changes: 6 additions & 0 deletions authmate/authmate.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ type NeoFS interface {
//
// It returns any error encountered which prevented computing epochs.
TimeToEpoch(context.Context, time.Time) (uint64, uint64, error)

// SetContainerEACL updates container EACL.
SetContainerEACL(ctx context.Context, table eacl.Table, sessionToken *session.Container) error

// ContainerEACL gets container EACL.
ContainerEACL(ctx context.Context, containerID cid.ID) (*eacl.Table, error)
}

// Agent contains client communicating with NeoFS and logger.
Expand Down
126 changes: 126 additions & 0 deletions cmd/s3-authmate/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ import (

"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neofs-s3-gw/api"
"github.com/nspcc-dev/neofs-s3-gw/api/handler"
"github.com/nspcc-dev/neofs-s3-gw/authmate"
"github.com/nspcc-dev/neofs-s3-gw/internal/neofs"
"github.com/nspcc-dev/neofs-s3-gw/internal/version"
"github.com/nspcc-dev/neofs-s3-gw/internal/wallet"
"github.com/nspcc-dev/neofs-sdk-go/client"
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/pool"
"github.com/nspcc-dev/neofs-sdk-go/user"
"github.com/spf13/viper"
Expand Down Expand Up @@ -166,6 +168,7 @@ func appCommands() []*cli.Command {
return []*cli.Command{
issueSecret(),
obtainSecret(),
resetBucketEACL(),
}
}

Expand Down Expand Up @@ -617,3 +620,126 @@ func createNeoFS(ctx context.Context, log *zap.Logger, cfg PoolConfig, anonSigne

return neofs.NewAuthmateNeoFS(neoFS), nil
}

func resetBucketEACL() *cli.Command {
command := &cli.Command{
Name: "reset-bucket-acl",
Usage: "Reset bucket ACL to default state",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "wallet",
Value: "",
Usage: "path to the container owner wallet",
Required: true,
Destination: &walletPathFlag,
},
&cli.StringFlag{
Name: "peer",
Value: "",
Usage: "address of neofs peer to connect to",
Required: true,
Destination: &peerAddressFlag,
},
&cli.StringFlag{
Name: "container-id",
Usage: "neofs container id to update eacl",
Required: true,
Destination: &containerIDFlag,
},
},
Action: func(_ *cli.Context) error {
ctx, log := prepare()

password := wallet.GetPassword(viper.GetViper(), envWalletPassphrase)
if password == nil {
var empty string
password = &empty
}

key, err := wallet.GetKeyFromPath(walletPathFlag, accountAddressFlag, password)
if err != nil {
return cli.Exit(fmt.Sprintf("failed to load neofs private key: %s", err), 1)
}

ctx, cancel := context.WithCancel(ctx)
defer cancel()

poolCfg := PoolConfig{
Key: &key.PrivateKey,
Address: peerAddressFlag,
}

anonKey, err := keys.NewPrivateKey()
if err != nil {
log.Fatal("obtainSecret: couldn't generate random key", zap.Error(err))
}
anonSigner := user.NewAutoIDSignerRFC6979(anonKey.PrivateKey)

neoFS, err := createNeoFS(ctx, log, poolCfg, anonSigner, slicerEnabledFlag)
if err != nil {
return cli.Exit(fmt.Sprintf("failed to create NeoFS component: %s", err), 1)
}

var containerID cid.ID
if err = containerID.DecodeString(containerIDFlag); err != nil {
return cli.Exit(fmt.Sprintf("failed to parse auth container id: %s", err), 1)
}

var (
newEACLTable eacl.Table
ownerID = user.NewFromScriptHash(key.GetScriptHash())
targetOwner eacl.Target
)

newEACLTable.SetCID(containerID)
targetOwner.SetAccounts([]user.ID{ownerID})

for op := eacl.OperationGet; op <= eacl.OperationRangeHash; op++ {
record := eacl.NewRecord()
record.SetOperation(op)
record.SetAction(eacl.ActionAllow)
record.SetTargets(targetOwner)

newEACLTable.AddRecord(record)
}

for op := eacl.OperationGet; op <= eacl.OperationRangeHash; op++ {
record := eacl.NewRecord()
record.SetOperation(op)
record.SetAction(eacl.ActionDeny)
eacl.AddFormedTarget(record, eacl.RoleOthers)

newEACLTable.AddRecord(record)
}

oldEacl, err := neoFS.ContainerEACL(ctx, containerID)
if err != nil {
return cli.Exit(fmt.Sprintf("failed to obtain old neofs EACL: %s", err), 1)
}

if handler.IsBucketOwnerForced(oldEacl) {
newEACLTable.AddRecord(handler.BucketOwnerEnforcedRecord())
}

if handler.IsBucketOwnerPreferred(oldEacl) {
newEACLTable.AddRecord(handler.BucketOwnerPreferredRecord())
}

if handler.IsBucketOwnerPreferredAndRestricted(oldEacl) {
newEACLTable.AddRecord(handler.BucketOwnerPreferredAndRestrictedRecord())
}

var tcancel context.CancelFunc
ctx, tcancel = context.WithTimeout(ctx, timeoutFlag)
defer tcancel()

if err = neoFS.SetContainerEACL(ctx, newEACLTable, nil); err != nil {
return cli.Exit(fmt.Sprintf("failed to setup eacl: %s", err), 1)
}

return nil
},
}

return command
}
10 changes: 10 additions & 0 deletions internal/neofs/neofs.go
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,16 @@ func (x *AuthmateNeoFS) CreateObject(ctx context.Context, prm tokens.PrmObjectCr
})
}

// SetContainerEACL implements authmate.NeoFS interface method.
func (x *AuthmateNeoFS) SetContainerEACL(ctx context.Context, table eacl.Table, sessionToken *session.Container) error {
return x.neoFS.SetContainerEACL(ctx, table, sessionToken)
}

// ContainerEACL implements authmate.NeoFS interface method.
func (x *AuthmateNeoFS) ContainerEACL(ctx context.Context, containerID cid.ID) (*eacl.Table, error) {
return x.neoFS.ContainerEACL(ctx, containerID)
}

// PoolStatistic is a mediator which implements authmate.NeoFS through pool.Pool.
type PoolStatistic struct {
poolStat *stat.PoolStat
Expand Down

0 comments on commit 8b3d943

Please sign in to comment.