refactor: clean up nidusctl CLI
This commit is contained in:
+40
-53
@@ -8,7 +8,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -23,18 +22,12 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func run(args []string) int {
|
func run(args []string) int {
|
||||||
fs := flag.NewFlagSet("nidusctl", flag.ContinueOnError)
|
if len(args) < 1 {
|
||||||
cfgPath := fs.String("config", "config.yaml", "path to configuration file")
|
|
||||||
if err := fs.Parse(args); err != nil {
|
|
||||||
return 2
|
|
||||||
}
|
|
||||||
rest := fs.Args()
|
|
||||||
if len(rest) < 1 {
|
|
||||||
usage()
|
usage()
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg, err := config.Load(*cfgPath)
|
cfg, err := config.Load()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "error loading config: %v\n", err)
|
fmt.Fprintf(os.Stderr, "error loading config: %v\n", err)
|
||||||
return 1
|
return 1
|
||||||
@@ -54,20 +47,20 @@ func run(args []string) int {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
switch rest[0] {
|
switch args[0] {
|
||||||
case "user":
|
case "user":
|
||||||
return runUser(dbase, rest[1:])
|
return runUser(dbase, args[1:])
|
||||||
case "calendar", "cal":
|
case "calendar", "cal":
|
||||||
return runCalendar(dbase, st, rest[1:])
|
return runCalendar(dbase, st, args[1:])
|
||||||
case "addressbook", "card":
|
case "addressbook", "card":
|
||||||
return runAddressBook(dbase, st, rest[1:])
|
return runAddressBook(dbase, st, args[1:])
|
||||||
case "migrate":
|
case "migrate":
|
||||||
return runMigrate(st, rest[1:])
|
return runMigrate(st, args[1:])
|
||||||
case "help", "-h", "--help":
|
case "help", "-h", "--help":
|
||||||
usage()
|
usage()
|
||||||
return 0
|
return 0
|
||||||
default:
|
default:
|
||||||
fmt.Fprintf(os.Stderr, "unknown command %q\n\n", rest[0])
|
fmt.Fprintf(os.Stderr, "unknown command: %s\n", args[0])
|
||||||
usage()
|
usage()
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
@@ -77,27 +70,32 @@ func usage() {
|
|||||||
fmt.Fprint(os.Stderr, `nidusctl - manage nidus DAV server users, resources, and sharing grants
|
fmt.Fprint(os.Stderr, `nidusctl - manage nidus DAV server users, resources, and sharing grants
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
nidusctl [-config config.yaml] user create <username> [--display-name NAME] [--email EMAIL] [--password PW]
|
nidusctl user create <username> [--display-name NAME] [--email EMAIL] [--password PW]
|
||||||
nidusctl [-config config.yaml] user delete <username>
|
nidusctl user delete <username>
|
||||||
nidusctl [-config config.yaml] user list
|
nidusctl user list
|
||||||
nidusctl [-config config.yaml] user passwd <username> [--password PW]
|
nidusctl user passwd <username> [--password PW]
|
||||||
|
|
||||||
nidusctl [-config config.yaml] calendar create <owner> <calendar> [--color '#RRGGBB']
|
nidusctl calendar create <owner> <calendar> [--color '#RRGGBB']
|
||||||
nidusctl [-config config.yaml] calendar color <owner> <calendar> <hex-color>
|
nidusctl calendar color <owner> <calendar> <hex-color>
|
||||||
nidusctl [-config config.yaml] calendar delete <owner> <calendar>
|
nidusctl calendar delete <owner> <calendar>
|
||||||
nidusctl [-config config.yaml] calendar list <owner>
|
nidusctl calendar list <owner>
|
||||||
nidusctl [-config config.yaml] calendar share <owner> <calendar> <user> <read|write>
|
nidusctl calendar share <owner> <calendar> <user> <read|write>
|
||||||
nidusctl [-config config.yaml] calendar unshare <owner> <calendar> <user>
|
nidusctl calendar unshare <owner> <calendar> <user>
|
||||||
nidusctl [-config config.yaml] calendar shares <owner> <calendar>
|
nidusctl calendar shares <owner> <calendar>
|
||||||
|
|
||||||
nidusctl [-config config.yaml] addressbook create <owner> <book>
|
nidusctl addressbook create <owner> <book>
|
||||||
nidusctl [-config config.yaml] addressbook delete <owner> <book>
|
nidusctl addressbook delete <owner> <book>
|
||||||
nidusctl [-config config.yaml] addressbook list <owner>
|
nidusctl addressbook list <owner>
|
||||||
nidusctl [-config config.yaml] addressbook share <owner> <book> <user> <read|write>
|
nidusctl addressbook share <owner> <book> <user> <read|write>
|
||||||
nidusctl [-config config.yaml] addressbook unshare <owner> <book> <user>
|
nidusctl addressbook unshare <owner> <book> <user>
|
||||||
nidusctl [-config config.yaml] addressbook shares <owner> <book>
|
nidusctl addressbook shares <owner> <book>
|
||||||
|
|
||||||
nidusctl [-config config.yaml] migrate [--verbose]
|
nidusctl migrate [--verbose]
|
||||||
|
|
||||||
|
nidusctl help
|
||||||
|
|
||||||
|
Configuration is done via environment variables:
|
||||||
|
NIDUS_DATA_DIR - data directory (default: ./data)
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
nidusctl user create alice --display-name "Alice Smith" --email alice@example.com
|
nidusctl user create alice --display-name "Alice Smith" --email alice@example.com
|
||||||
@@ -106,14 +104,7 @@ Examples:
|
|||||||
nidusctl calendar shares alice work
|
nidusctl calendar shares alice work
|
||||||
nidusctl calendar unshare alice work bob
|
nidusctl calendar unshare alice work bob
|
||||||
nidusctl migrate
|
nidusctl migrate
|
||||||
`)
|
`)
|
||||||
}
|
|
||||||
|
|
||||||
// newFlagSet creates a flag.FlagSet configured for subcommand parsing
|
|
||||||
// (flags may appear before or after positional args, since callers parse
|
|
||||||
// flags first with fs.Parse then read fs.Args() for the rest).
|
|
||||||
func newFlagSet(name string) *flag.FlagSet {
|
|
||||||
return flag.NewFlagSet(name, flag.ContinueOnError)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func runCalendar(dbase *db.DB, st *store.Store, args []string) int {
|
func runCalendar(dbase *db.DB, st *store.Store, args []string) int {
|
||||||
@@ -123,17 +114,17 @@ func runCalendar(dbase *db.DB, st *store.Store, args []string) int {
|
|||||||
}
|
}
|
||||||
switch args[0] {
|
switch args[0] {
|
||||||
case "create":
|
case "create":
|
||||||
fs := newFlagSet("calendar create")
|
color := ""
|
||||||
color := fs.String("color", "", "hex color like #3b82f6 (optional)")
|
if len(args) > 2 && args[1] == "--color" {
|
||||||
if err := fs.Parse(args[1:]); err != nil {
|
color = args[2]
|
||||||
return 2
|
args = args[:1]
|
||||||
}
|
}
|
||||||
if fs.NArg() != 2 {
|
if len(args) != 3 {
|
||||||
fmt.Fprintln(os.Stderr, "usage: nidusctl calendar create <owner> <calendar> [--color '#RRGGBB']")
|
fmt.Fprintln(os.Stderr, "usage: nidusctl calendar create <owner> <calendar> [--color '#RRGGBB']")
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
owner, calName := fs.Arg(0), fs.Arg(1)
|
owner, calName := args[1], args[2]
|
||||||
if err := dbase.CreateCalendarWithColor(owner, calName, *color); err != nil {
|
if err := dbase.CreateCalendarWithColor(owner, calName, color); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
@@ -365,11 +356,7 @@ func runAddressBook(dbase *db.DB, st *store.Store, args []string) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runMigrate(st *store.Store, args []string) int {
|
func runMigrate(st *store.Store, args []string) int {
|
||||||
fs := newFlagSet("migrate")
|
// Ignore args for now (could add --verbose flag in future if needed)
|
||||||
if err := fs.Parse(args); err != nil {
|
|
||||||
return 2
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := st.Migrate(); err != nil {
|
if err := st.Migrate(); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "migration failed: %v\n", err)
|
fmt.Fprintf(os.Stderr, "migration failed: %v\n", err)
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
+18
-38
@@ -12,25 +12,6 @@ import (
|
|||||||
"git.arnef.de/arnef/nidus/internal/db"
|
"git.arnef.de/arnef/nidus/internal/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
// writeTestConfig creates a minimal config.yaml in dir and returns its path.
|
|
||||||
func writeTestConfig(t *testing.T, dir string) string {
|
|
||||||
t.Helper()
|
|
||||||
cfgPath := filepath.Join(dir, "config.yaml")
|
|
||||||
dataDir := filepath.Join(dir, "data")
|
|
||||||
content := "storage:\n data_dir: " + dataDir + "\n" +
|
|
||||||
"users:\n" +
|
|
||||||
" alice:\n" +
|
|
||||||
" password: \"$2a$10$9.WEs0uz5TaNJLQbSTLrX.Te.BIe8XTTykVRzZbSHQMEkyFb8Sq/O\"\n" +
|
|
||||||
" bob:\n" +
|
|
||||||
" password: \"$2a$10$9.WEs0uz5TaNJLQbSTLrX.Te.BIe8XTTykVRzZbSHQMEkyFb8Sq/O\"\n"
|
|
||||||
if err := os.WriteFile(cfgPath, []byte(content), 0o644); err != nil {
|
|
||||||
t.Fatalf("writing test config: %v", err)
|
|
||||||
}
|
|
||||||
return cfgPath
|
|
||||||
}
|
|
||||||
|
|
||||||
// runCLI runs the CLI's run() function, capturing stdout/stderr, and
|
|
||||||
// returns (exit code, combined stdout+stderr).
|
|
||||||
func runCLI(t *testing.T, args ...string) (int, string) {
|
func runCLI(t *testing.T, args ...string) (int, string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
@@ -56,9 +37,9 @@ func runCLI(t *testing.T, args ...string) (int, string) {
|
|||||||
|
|
||||||
func TestCalendarShareUnshareLifecycle(t *testing.T) {
|
func TestCalendarShareUnshareLifecycle(t *testing.T) {
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
cfgPath := writeTestConfig(t, dir)
|
t.Setenv("NIDUS_DATA_DIR", filepath.Join(dir, "data"))
|
||||||
|
|
||||||
code, out := runCLI(t, "-config", cfgPath, "calendar", "share", "alice", "work", "bob", "write")
|
code, out := runCLI(t, "calendar", "share", "alice", "work", "bob", "write")
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
t.Fatalf("share exit code = %d, output: %s", code, out)
|
t.Fatalf("share exit code = %d, output: %s", code, out)
|
||||||
}
|
}
|
||||||
@@ -66,7 +47,7 @@ func TestCalendarShareUnshareLifecycle(t *testing.T) {
|
|||||||
t.Errorf("output = %q, want to contain 'shared'", out)
|
t.Errorf("output = %q, want to contain 'shared'", out)
|
||||||
}
|
}
|
||||||
|
|
||||||
code, out = runCLI(t, "-config", cfgPath, "calendar", "shares", "alice", "work")
|
code, out = runCLI(t, "calendar", "shares", "alice", "work")
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
t.Fatalf("shares exit code = %d, output: %s", code, out)
|
t.Fatalf("shares exit code = %d, output: %s", code, out)
|
||||||
}
|
}
|
||||||
@@ -74,12 +55,12 @@ func TestCalendarShareUnshareLifecycle(t *testing.T) {
|
|||||||
t.Errorf("output = %q, want to contain bob/write", out)
|
t.Errorf("output = %q, want to contain bob/write", out)
|
||||||
}
|
}
|
||||||
|
|
||||||
code, out = runCLI(t, "-config", cfgPath, "calendar", "unshare", "alice", "work", "bob")
|
code, out = runCLI(t, "calendar", "unshare", "alice", "work", "bob")
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
t.Fatalf("unshare exit code = %d, output: %s", code, out)
|
t.Fatalf("unshare exit code = %d, output: %s", code, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
code, out = runCLI(t, "-config", cfgPath, "calendar", "shares", "alice", "work")
|
code, out = runCLI(t, "calendar", "shares", "alice", "work")
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
t.Fatalf("shares (after unshare) exit code = %d, output: %s", code, out)
|
t.Fatalf("shares (after unshare) exit code = %d, output: %s", code, out)
|
||||||
}
|
}
|
||||||
@@ -90,9 +71,9 @@ func TestCalendarShareUnshareLifecycle(t *testing.T) {
|
|||||||
|
|
||||||
func TestCalendarShareInvalidPermission(t *testing.T) {
|
func TestCalendarShareInvalidPermission(t *testing.T) {
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
cfgPath := writeTestConfig(t, dir)
|
t.Setenv("NIDUS_DATA_DIR", filepath.Join(dir, "data"))
|
||||||
|
|
||||||
code, out := runCLI(t, "-config", cfgPath, "calendar", "share", "alice", "work", "bob", "admin")
|
code, out := runCLI(t, "calendar", "share", "alice", "work", "bob", "admin")
|
||||||
if code != 2 {
|
if code != 2 {
|
||||||
t.Errorf("exit code = %d, want 2; output: %s", code, out)
|
t.Errorf("exit code = %d, want 2; output: %s", code, out)
|
||||||
}
|
}
|
||||||
@@ -103,9 +84,9 @@ func TestCalendarShareInvalidPermission(t *testing.T) {
|
|||||||
|
|
||||||
func TestCalendarUnshareNotFound(t *testing.T) {
|
func TestCalendarUnshareNotFound(t *testing.T) {
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
cfgPath := writeTestConfig(t, dir)
|
t.Setenv("NIDUS_DATA_DIR", filepath.Join(dir, "data"))
|
||||||
|
|
||||||
code, out := runCLI(t, "-config", cfgPath, "calendar", "unshare", "alice", "ghost", "bob")
|
code, out := runCLI(t, "calendar", "unshare", "alice", "ghost", "bob")
|
||||||
if code != 1 {
|
if code != 1 {
|
||||||
t.Errorf("exit code = %d, want 1; output: %s", code, out)
|
t.Errorf("exit code = %d, want 1; output: %s", code, out)
|
||||||
}
|
}
|
||||||
@@ -116,14 +97,14 @@ func TestCalendarUnshareNotFound(t *testing.T) {
|
|||||||
|
|
||||||
func TestAddressBookShareUnshareLifecycle(t *testing.T) {
|
func TestAddressBookShareUnshareLifecycle(t *testing.T) {
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
cfgPath := writeTestConfig(t, dir)
|
t.Setenv("NIDUS_DATA_DIR", filepath.Join(dir, "data"))
|
||||||
|
|
||||||
code, out := runCLI(t, "-config", cfgPath, "addressbook", "share", "alice", "contacts", "bob", "read")
|
code, out := runCLI(t, "addressbook", "share", "alice", "contacts", "bob", "read")
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
t.Fatalf("share exit code = %d, output: %s", code, out)
|
t.Fatalf("share exit code = %d, output: %s", code, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
code, out = runCLI(t, "-config", cfgPath, "addressbook", "shares", "alice", "contacts")
|
code, out = runCLI(t, "addressbook", "shares", "alice", "contacts")
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
t.Fatalf("shares exit code = %d, output: %s", code, out)
|
t.Fatalf("shares exit code = %d, output: %s", code, out)
|
||||||
}
|
}
|
||||||
@@ -131,7 +112,7 @@ func TestAddressBookShareUnshareLifecycle(t *testing.T) {
|
|||||||
t.Errorf("output = %q, want to contain bob/read", out)
|
t.Errorf("output = %q, want to contain bob/read", out)
|
||||||
}
|
}
|
||||||
|
|
||||||
code, out = runCLI(t, "-config", cfgPath, "addressbook", "unshare", "alice", "contacts", "bob")
|
code, out = runCLI(t, "addressbook", "unshare", "alice", "contacts", "bob")
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
t.Fatalf("unshare exit code = %d, output: %s", code, out)
|
t.Fatalf("unshare exit code = %d, output: %s", code, out)
|
||||||
}
|
}
|
||||||
@@ -139,9 +120,9 @@ func TestAddressBookShareUnshareLifecycle(t *testing.T) {
|
|||||||
|
|
||||||
func TestUnknownUserWarningDoesNotBlockShare(t *testing.T) {
|
func TestUnknownUserWarningDoesNotBlockShare(t *testing.T) {
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
cfgPath := writeTestConfig(t, dir)
|
t.Setenv("NIDUS_DATA_DIR", filepath.Join(dir, "data"))
|
||||||
|
|
||||||
code, out := runCLI(t, "-config", cfgPath, "calendar", "share", "alice", "work", "carol", "read")
|
code, out := runCLI(t, "calendar", "share", "alice", "work", "carol", "read")
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
t.Fatalf("exit code = %d, output: %s", code, out)
|
t.Fatalf("exit code = %d, output: %s", code, out)
|
||||||
}
|
}
|
||||||
@@ -154,10 +135,9 @@ func TestUnknownUserWarningDoesNotBlockShare(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestNoArgsShowsUsage(t *testing.T) {
|
func TestNoArgsShowsUsage(t *testing.T) {
|
||||||
dir := t.TempDir()
|
|
||||||
// No config needed since usage() is printed before config.Load for
|
// No config needed since usage() is printed before config.Load for
|
||||||
// missing subcommands.
|
// missing subcommands.
|
||||||
code, out := runCLI(t, "-config", filepath.Join(dir, "missing.yaml"))
|
code, out := runCLI(t)
|
||||||
if code != 2 {
|
if code != 2 {
|
||||||
t.Errorf("exit code = %d, want 2", code)
|
t.Errorf("exit code = %d, want 2", code)
|
||||||
}
|
}
|
||||||
@@ -168,9 +148,9 @@ func TestNoArgsShowsUsage(t *testing.T) {
|
|||||||
|
|
||||||
func TestUnknownCommand(t *testing.T) {
|
func TestUnknownCommand(t *testing.T) {
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
cfgPath := writeTestConfig(t, dir)
|
t.Setenv("NIDUS_DATA_DIR", filepath.Join(dir, "data"))
|
||||||
|
|
||||||
code, out := runCLI(t, "-config", cfgPath, "bogus")
|
code, out := runCLI(t, "bogus")
|
||||||
if code != 2 {
|
if code != 2 {
|
||||||
t.Errorf("exit code = %d, want 2", code)
|
t.Errorf("exit code = %d, want 2", code)
|
||||||
}
|
}
|
||||||
|
|||||||
+44
-20
@@ -31,31 +31,47 @@ func runUser(dbase *db.DB, args []string) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func userCreate(dbase *db.DB, args []string) int {
|
func userCreate(dbase *db.DB, args []string) int {
|
||||||
fs := newFlagSet("nidusctl user create")
|
var displayName, email, password string
|
||||||
displayName := fs.String("display-name", "", "display name shown in DAV clients")
|
var rest []string
|
||||||
email := fs.String("email", "", "email address")
|
|
||||||
password := fs.String("password", "", "password (omit to be prompted, recommended)")
|
for i := 0; i < len(args); i++ {
|
||||||
if err := fs.Parse(args); err != nil {
|
switch args[i] {
|
||||||
return 2
|
case "--display-name":
|
||||||
|
if i+1 < len(args) {
|
||||||
|
displayName = args[i+1]
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
rest := fs.Args()
|
case "--email":
|
||||||
|
if i+1 < len(args) {
|
||||||
|
email = args[i+1]
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
case "--password":
|
||||||
|
if i+1 < len(args) {
|
||||||
|
password = args[i+1]
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
rest = append(rest, args[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(rest) != 1 {
|
if len(rest) != 1 {
|
||||||
fmt.Fprintln(os.Stderr, "usage: nidusctl user create <username> [--display-name NAME] [--email EMAIL] [--password PASSWORD]")
|
fmt.Fprintln(os.Stderr, "usage: nidusctl user create <username> [--display-name NAME] [--email EMAIL] [--password PASSWORD]")
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
username := rest[0]
|
username := rest[0]
|
||||||
|
|
||||||
pw := *password
|
if password == "" {
|
||||||
if pw == "" {
|
|
||||||
var err error
|
var err error
|
||||||
pw, err = promptPassword(username)
|
password, err = promptPassword(username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "error reading password: %v\n", err)
|
fmt.Fprintf(os.Stderr, "error reading password: %v\n", err)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := dbase.CreateUser(username, pw, *displayName, *email); err != nil {
|
if err := dbase.CreateUser(username, password, displayName, email); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
@@ -98,29 +114,37 @@ func userList(dbase *db.DB, args []string) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func userPasswd(dbase *db.DB, args []string) int {
|
func userPasswd(dbase *db.DB, args []string) int {
|
||||||
fs := newFlagSet("nidusctl user passwd")
|
var password string
|
||||||
password := fs.String("password", "", "new password (omit to be prompted, recommended)")
|
var rest []string
|
||||||
if err := fs.Parse(args); err != nil {
|
|
||||||
return 2
|
for i := 0; i < len(args); i++ {
|
||||||
|
switch args[i] {
|
||||||
|
case "--password":
|
||||||
|
if i+1 < len(args) {
|
||||||
|
password = args[i+1]
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
rest := fs.Args()
|
default:
|
||||||
|
rest = append(rest, args[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(rest) != 1 {
|
if len(rest) != 1 {
|
||||||
fmt.Fprintln(os.Stderr, "usage: nidusctl user passwd <username> [--password PASSWORD]")
|
fmt.Fprintln(os.Stderr, "usage: nidusctl user passwd <username> [--password PASSWORD]")
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
username := rest[0]
|
username := rest[0]
|
||||||
|
|
||||||
pw := *password
|
if password == "" {
|
||||||
if pw == "" {
|
|
||||||
var err error
|
var err error
|
||||||
pw, err = promptPassword(username)
|
password, err = promptPassword(username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "error reading password: %v\n", err)
|
fmt.Fprintf(os.Stderr, "error reading password: %v\n", err)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := dbase.SetPassword(username, pw); err != nil {
|
if err := dbase.SetPassword(username, password); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user