Skip to content

Commit

Permalink
support keys by standard input
Browse files Browse the repository at this point in the history
Based on work by @sinhaashish in minio#2785
  • Loading branch information
h0tw1r3 committed Feb 16, 2020
1 parent 2f2aecb commit b6285e7
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 24 deletions.
61 changes: 56 additions & 5 deletions cmd/admin-user-add.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@
package cmd

import (
"bufio"
"fmt"
"os"
"strings"

"github.com/fatih/color"
"github.com/minio/cli"
json "github.com/minio/mc/pkg/colorjson"
"github.com/minio/mc/pkg/probe"
"github.com/minio/minio/pkg/console"
"golang.org/x/crypto/ssh/terminal"
)

var adminUserAddCmd = cli.Command{
Expand Down Expand Up @@ -53,13 +56,23 @@ EXAMPLES:
{{.DisableHistory}}
{{.Prompt}} {{.HelpName}} myminio foobar foo12345
{{.EnableHistory}}
2. Add a new user 'foobar' to MinIO server, prompting for keys.
{{.Prompt}} {{.HelpName}} myminio
Enter Access Key: foobar
Enter Secret Key: foobar12345
3. Add a new user 'foobar' to MinIO server using piped keys.
{{.DisableHistory}}
{{.Prompt}} echo "foobar\nfoobar12345" | {{.HelpName}} myminio
{{.EnableHistory}}
`,
}

// checkAdminUserAddSyntax - validate all the passed arguments
func checkAdminUserAddSyntax(ctx *cli.Context) {
if len(ctx.Args()) != 3 {
cli.ShowCommandHelpAndExit(ctx, "add", 1) // last argument is exit code
argsNr := len(ctx.Args())
if argsNr > 3 || argsNr < 1 {
fatalIf(errInvalidArgument().Trace(ctx.Args().Tail()...),
"Incorrect number of arguments for user add command.")
}
}

Expand Down Expand Up @@ -115,6 +128,43 @@ func (u userMessage) JSON() string {
return string(jsonMessageBytes)
}

// fetchUserKeys - returns the access and secret key
func fetchUserKeys(args cli.Args) (string, string) {
accessKey := ""
secretKey := ""
console.SetColor(cred, color.New(color.FgYellow, color.Italic))
isTerminal := terminal.IsTerminal(int(os.Stdin.Fd()))
reader := bufio.NewReader(os.Stdin)

argCount := len(args)

if argCount == 1 {
if isTerminal {
fmt.Printf("%s", console.Colorize(cred, "Enter Access Key: "))
}
value, _, _ := reader.ReadLine()
accessKey = string(value)
} else {
accessKey = args.Get(1)
}

if argCount >= 1 && argCount <= 2 {
if isTerminal {
fmt.Printf("%s", console.Colorize(cred, "Enter Secret Key: "))
bytePassword, _ := terminal.ReadPassword(int(os.Stdin.Fd()))
fmt.Printf("\n")
secretKey = string(bytePassword)
} else {
value, _, _ := reader.ReadLine()
secretKey = string(value)
}
} else {
secretKey = args.Get(2)
}

return accessKey, secretKey
}

// mainAdminUserAdd is the handle for "mc admin user add" command.
func mainAdminUserAdd(ctx *cli.Context) error {
checkAdminUserAddSyntax(ctx)
Expand All @@ -124,17 +174,18 @@ func mainAdminUserAdd(ctx *cli.Context) error {
// Get the alias parameter from cli
args := ctx.Args()
aliasedURL := args.Get(0)
accessKey, secretKey := fetchUserKeys(args)

// Create a new MinIO Admin Client
client, err := newAdminClient(aliasedURL)
fatalIf(err, "Unable to initialize admin connection.")

fatalIf(probe.NewError(client.AddUser(args.Get(1), args.Get(2))).Trace(args...), "Cannot add new user")
fatalIf(probe.NewError(client.AddUser(accessKey, secretKey)).Trace(args...), "Cannot add new user")

printMsg(userMessage{
op: "add",
AccessKey: args.Get(1),
SecretKey: args.Get(2),
AccessKey: accessKey,
SecretKey: secretKey,
UserStatus: "enabled",
})

Expand Down
76 changes: 63 additions & 13 deletions cmd/config-host-add.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,21 @@
package cmd

import (
"bufio"
"fmt"
"math/rand"
"os"
"time"

"github.com/fatih/color"
"github.com/minio/cli"
"github.com/minio/mc/pkg/probe"
"github.com/minio/minio/pkg/console"
"golang.org/x/crypto/ssh/terminal"
)

const cred = "YellowItalics"

var hostAddFlags = []cli.Flag{
cli.StringFlag{
Name: "lookup",
Expand Down Expand Up @@ -71,24 +77,32 @@ EXAMPLES:
{{.Prompt}} {{.HelpName}} mys3 https://s3.amazonaws.com \
BKIKJAA5BMMU2RHO6IBB V8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
{{.EnableHistory}}
4. Add Amazon S3 storage service under "mys3" alias, prompting for keys.
{{.Prompt}} {{.HelpName}} mys3 https://s3.amazonaws.com --api "s3v4" --lookup "dns"
Enter Access Key: BKIKJAA5BMMU2RHO6IBB
Enter Secret Key: V8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
5. Add Amazon S3 storage service under "mys3" alias using piped keys.
{{.DisableHistory}}
{{.Prompt}} echo "BKIKJAA5BMMU2RHO6IBB\nV8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12" | \
{{.HelpName}} mys3 https://s3.amazonaws.com --api "s3v4" --lookup "dns"
{{.EnableHistory}}
`,
}

// checkConfigHostAddSyntax - verifies input arguments to 'config host add'.
func checkConfigHostAddSyntax(ctx *cli.Context) {
func checkConfigHostAddSyntax(ctx *cli.Context, accessKey, secretKey, api, bucketLookup string) {
args := ctx.Args()
argsNr := len(args)
if argsNr < 4 || argsNr > 5 {
if argsNr > 4 || argsNr < 2 {
fatalIf(errInvalidArgument().Trace(ctx.Args().Tail()...),
"Incorrect number of arguments for host add command.")
}

alias := args.Get(0)
url := args.Get(1)
accessKey := args.Get(2)
secretKey := args.Get(3)
api := ctx.String("api")
bucketLookup := ctx.String("lookup")

if !isValidAlias(alias) {
fatalIf(errInvalidAlias(alias), "Invalid alias.")
}
Expand Down Expand Up @@ -213,18 +227,54 @@ func buildS3Config(url, accessKey, secretKey, api, lookup string) (*Config, *pro
return s3Config, nil
}

// fetchHostKeys - returns the user accessKey and secretKey
func fetchHostKeys(args cli.Args) (string, string) {
accessKey := ""
secretKey := ""
console.SetColor(cred, color.New(color.FgYellow, color.Italic))
isTerminal := terminal.IsTerminal(int(os.Stdin.Fd()))
reader := bufio.NewReader(os.Stdin)

argsNr := len(args)

if argsNr == 2 {
if isTerminal {
fmt.Printf("%s", console.Colorize(cred, "Enter Access Key: "))
}
value, _, _ := reader.ReadLine()
accessKey = string(value)
} else {
accessKey = args.Get(2)
}

if argsNr >= 2 && argsNr <= 3 {
if isTerminal {
fmt.Printf("%s", console.Colorize(cred, "Enter Secret Key: "))
bytePassword, _ := terminal.ReadPassword(int(os.Stdin.Fd()))
fmt.Printf("\n")
secretKey = string(bytePassword)
} else {
value, _, _ := reader.ReadLine()
secretKey = string(value)
}
} else {
secretKey = args.Get(3)
}

return accessKey, secretKey
}

func mainConfigHostAdd(ctx *cli.Context) error {
checkConfigHostAddSyntax(ctx)

console.SetColor("HostMessage", color.New(color.FgGreen))
var (
args = ctx.Args()
url = trimTrailingSeparator(args.Get(1))
accessKey = args.Get(2)
secretKey = args.Get(3)
api = ctx.String("api")
lookup = ctx.String("lookup")
args = ctx.Args()
url = trimTrailingSeparator(args.Get(1))
api = ctx.String("api")
lookup = ctx.String("lookup")
)
accessKey, secretKey := fetchHostKeys(args)
checkConfigHostAddSyntax(ctx, accessKey, secretKey, api, lookup)

s3Config, err := buildS3Config(url, accessKey, secretKey, api, lookup)
fatalIf(err.Trace(ctx.Args()...), "Unable to initialize new config from the provided credentials.")
Expand Down
37 changes: 33 additions & 4 deletions docs/minio-admin-complete-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,35 @@ MinIO server displays URL, access and secret keys.
#### Usage

```
mc config host add <ALIAS> <YOUR-MINIO-ENDPOINT> <YOUR-ACCESS-KEY> <YOUR-SECRET-KEY>
mc config host add <ALIAS> <YOUR-MINIO-ENDPOINT> [YOUR-ACCESS-KEY] [YOUR-SECRET-KEY]
```

Keys must be supplied by argument or standard input.

Alias is simply a short name to your MinIO service. MinIO end-point, access and secret keys are supplied by your MinIO service. Admin API uses "S3v4" signature and cannot be changed.

```
mc config host add minio http://192.168.1.51:9000 BKIKJAA5BMMU2RHO6IBB V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
```
### Examples

1. Keys by argument

```
mc config host add minio http://192.168.1.51:9000 BKIKJAA5BMMU2RHO6IBB V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
```

2. Keys by prompt

```
mc config host add minio http://192.168.1.51:9000
Enter Access Key: BKIKJAA5BMMU2RHO6IBB
Enter Secret Key: V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
```

2. Keys by pipe

```
echo "BKIKJAA5BMMU2RHO6IBB\nV7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12" | \
mc config host add minio http://192.168.1.51:9000
```

## 4. Test Your Setup

Expand Down Expand Up @@ -430,6 +451,14 @@ COMMANDS:
mc admin user add myminio/ newuser newuser123
```

*Example: Add a new user 'newuser' on MinIO, using standard input.*

```
mc admin user add myminio/
Enter Access Key: newuser
Enter Secret Key: newuser123
```

*Example: Disable a user 'newuser' on MinIO.*

```
Expand Down
21 changes: 20 additions & 1 deletion docs/minio-client-complete-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,11 @@ To add one or more Amazon S3 compatible hosts, please follow the instructions be
#### Usage

```
mc config host add <ALIAS> <YOUR-S3-ENDPOINT> <YOUR-ACCESS-KEY> <YOUR-SECRET-KEY> <API-SIGNATURE>
mc config host add <ALIAS> <YOUR-S3-ENDPOINT> [YOUR-ACCESS-KEY] [YOUR-SECRET-KEY] <API-SIGNATURE>
```

Keys must be supplied by argument or standard input.

Alias is simply a short name to your cloud storage service. S3 end-point, access and secret keys are supplied by your cloud storage provider. API signature is an optional argument. By default, it is set to "S3v4".

### Example - MinIO Cloud Storage
Expand All @@ -146,6 +148,23 @@ Get your AccessKeyID and SecretAccessKey by following [Google Credentials Guide]
mc config host add gcs https://storage.googleapis.com BKIKJAA5BMMU2RHO6IBB V8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
```

### Example - Specify keys using standard input

1. Prompt

```
mc config host add minio http://192.168.1.51 --api S3v4
Enter Access Key: BKIKJAA5BMMU2RHO6IBB
Enter Secret Key: V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
```

2. Pipe

```
echo "BKIKJAA5BMMU2RHO6IBB\nV7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12" | \
mc config host add minio http://192.168.1.51 --api S3v4
```

### Specify host configuration through environment variable
```
export MC_HOST_<alias>=https://<Access Key>:<Secret Key>@<YOUR-S3-ENDPOINT>
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ require (
github.com/rjeczalik/notify v0.9.2
github.com/ugorji/go v1.1.7 // indirect
go.uber.org/zap v1.11.0 // indirect
golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6 // indirect
golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6
golang.org/x/net v0.0.0-20200202094626-16171245cfb2
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 // indirect
golang.org/x/text v0.3.2
Expand Down

0 comments on commit b6285e7

Please sign in to comment.