Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update authmate #1065

Merged
merged 2 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 13 additions & 14 deletions authmate/authmate.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,11 @@ type (
ContainerID string `json:"container_id"`
}

obtainingResult struct {
BearerToken *bearer.Token `json:"-"`
SecretAccessKey string `json:"secret_access_key"`
// ObtainingResult contains payload for obtainingSecret command.
ObtainingResult struct {
BearerToken *bearer.Token `json:"-"`
SessionTokenForSetEACL *session.Container `json:"-"`
SecretAccessKey string `json:"secret_access_key"`
}
)

Expand Down Expand Up @@ -299,27 +301,24 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr

// ObtainSecret receives an existing secret access key from NeoFS and
// writes to io.Writer the secret access key.
func (a *Agent) ObtainSecret(ctx context.Context, w io.Writer, options *ObtainSecretOptions) error {
func (a *Agent) ObtainSecret(ctx context.Context, options *ObtainSecretOptions) (*ObtainingResult, error) {
bearerCreds := tokens.New(a.neoFS, options.GatePrivateKey, cache.DefaultAccessBoxConfig(a.log))

var addr oid.Address
if err := addr.DecodeString(options.SecretAddress); err != nil {
return fmt.Errorf("failed to parse secret address: %w", err)
return nil, fmt.Errorf("failed to parse secret address: %w", err)
}

box, err := bearerCreds.GetBox(ctx, addr)
if err != nil {
return fmt.Errorf("failed to get tokens: %w", err)
return nil, fmt.Errorf("failed to get tokens: %w", err)
}

or := &obtainingResult{
BearerToken: box.Gate.BearerToken,
SecretAccessKey: box.Gate.AccessKey,
}

enc := json.NewEncoder(w)
enc.SetIndent("", " ")
return enc.Encode(or)
return &ObtainingResult{
BearerToken: box.Gate.BearerToken,
SecretAccessKey: box.Gate.AccessKey,
SessionTokenForSetEACL: box.Gate.SessionTokenForSetEACL(),
}, nil
}

func buildEACLTable(eaclTable []byte) (*eacl.Table, error) {
Expand Down
108 changes: 85 additions & 23 deletions cmd/s3-authmate/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ 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/api/resolver"
"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"
Expand Down Expand Up @@ -54,6 +55,7 @@ var (
walletPathFlag string
accountAddressFlag string
peerAddressFlag string
rpcAddressFlag string
eaclRulesFlag string
gateWalletPathFlag string
gateAccountAddressFlag string
Expand All @@ -70,6 +72,7 @@ var (
awcCliCredFile string
timeoutFlag time.Duration
slicerEnabledFlag bool
applyFlag bool

// pool timeouts flag.
poolDialTimeoutFlag time.Duration
Expand Down Expand Up @@ -573,11 +576,14 @@ func obtainSecret() *cli.Command {
ctx, tcancel = context.WithTimeout(ctx, timeoutFlag)
defer tcancel()

if err = agent.ObtainSecret(ctx, os.Stdout, obtainSecretOptions); err != nil {
or, err := agent.ObtainSecret(ctx, obtainSecretOptions)
if err != nil {
return cli.Exit(fmt.Sprintf("failed to obtain secret: %s", err), 5)
}

return nil
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
return enc.Encode(or)
},
}
return command
Expand Down Expand Up @@ -627,45 +633,68 @@ func resetBucketEACL() *cli.Command {
Usage: "Reset bucket ACL to default state",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "wallet",
Name: "access-key-id",
Usage: "access key id for s3",
Required: true,
Destination: &accessKeyIDFlag,
},
&cli.StringFlag{
Name: "gate-wallet",
Value: "",
Usage: "path to the container owner wallet",
Usage: "path to the gate wallet",
Required: true,
Destination: &walletPathFlag,
Destination: &gateWalletPathFlag,
},
&cli.StringFlag{
Name: "peer",
Value: "",
Usage: "address of neofs peer to connect to",
Usage: "address of neofs peer to connect to. localhost:8080 (without schema)",
Required: true,
Destination: &peerAddressFlag,
},
&cli.StringFlag{
Name: "container-id",
Usage: "neofs container id to update eacl",
Name: "rpc-endpoint",
Value: "",
Usage: "address of neofs RPC endpoint to connect to. https://localhost:30333 (with schema)",
Required: true,
Destination: &rpcAddressFlag,
},
&cli.StringFlag{
Name: "container-name",
Usage: "s3 container name to update eacl",
Required: true,
Destination: &containerIDFlag,
},
&cli.BoolFlag{
Name: "apply",
Usage: "apply EACL changes to container",
Required: false,
Destination: &applyFlag,
},
},
Action: func(_ *cli.Context) error {
ctx, log := prepare()

password := wallet.GetPassword(viper.GetViper(), envWalletPassphrase)
v := viper.New()
v.AutomaticEnv()
v.SetConfigType("env")
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))

password := wallet.GetPassword(v, envWalletGatePassphrase)
if password == nil {
var empty string
password = &empty
}

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

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

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

Expand All @@ -680,19 +709,40 @@ func resetBucketEACL() *cli.Command {
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)
secretAddress := strings.Replace(accessKeyIDFlag, "0", "/", 1)

obtainSecretOptions := &authmate.ObtainSecretOptions{
SecretAddress: secretAddress,
GatePrivateKey: gateCreds,
}

agent := authmate.New(log, neoFS)
or, err := agent.ObtainSecret(ctx, obtainSecretOptions)
if err != nil {
return cli.Exit(fmt.Sprintf("failed to obtain secret: %s", err), 5)
}

containerResolver, err := resolver.NewResolver(ctx, []string{rpcAddressFlag})
if err != nil {
return cli.Exit(fmt.Sprintf("create resolver: %s", err), 5)
}

containerID, err := containerResolver.ResolveCID(ctx, containerIDFlag)
if err != nil {
return cli.Exit(fmt.Sprintf("resolve container: %s", err), 5)
}

if _, err = fmt.Fprintln(os.Stdout, "Resolved CID:", containerID); err != nil {
return cli.Exit(fmt.Sprintf("write resolved CID: %s", err), 5)
}

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

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

for op := eacl.OperationGet; op <= eacl.OperationRangeHash; op++ {
record := eacl.NewRecord()
Expand Down Expand Up @@ -729,12 +779,24 @@ func resetBucketEACL() *cli.Command {
newEACLTable.AddRecord(handler.BucketOwnerPreferredAndRestrictedRecord())
}

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

if err = neoFS.SetContainerEACL(ctx, newEACLTable, or.SessionTokenForSetEACL); err != nil {
return cli.Exit(fmt.Sprintf("failed to setup eacl: %s", err), 1)
}
} else {
_, _ = fmt.Fprintln(os.Stdout, "New EACL table:")

enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
if err = enc.Encode(newEACLTable.Records()); err != nil {
return cli.Exit(fmt.Sprintf("failed to encode new neofs EACL records: %s", err), 1)
}

if err = neoFS.SetContainerEACL(ctx, newEACLTable, nil); err != nil {
return cli.Exit(fmt.Sprintf("failed to setup eacl: %s", err), 1)
_, _ = fmt.Fprintln(os.Stdout, "\nuse --apply flag to apply EACL changes")
}

return nil
Expand Down
Loading