From 684281f3f622e193dd08a5efc4d187ceea87b197 Mon Sep 17 00:00:00 2001
From: Lukas Braun <lukas.braun@fau.de>
Date: Wed, 19 Apr 2017 16:34:42 +0200
Subject: [PATCH] Use subcommands instead of flags for actions

---
 goatherd.go          | 90 ++++++++++++++++++++++----------------------
 test_pam_goatherd.sh | 10 ++---
 2 files changed, 49 insertions(+), 51 deletions(-)

diff --git a/goatherd.go b/goatherd.go
index ae61e42..f67b793 100644
--- a/goatherd.go
+++ b/goatherd.go
@@ -481,17 +481,6 @@ func serve() {
 
 func main() {
     flag_config := flag.String("config", "/etc/goatherd.conf", "Path to config file")
-    flag_init_db := flag.Bool("init-db", false, "Initialize the database.")
-    flag_from_file := flag.String("from-file", "", "Read list of users and secrets from a file.")
-    flag_add_user := flag.String("add-user", "", "Add new user to the database. If '-' read name from stdin.")
-    flag_secret := flag.String("secret", "-", "Secret for the new user. If '-' read from stdin.")
-    flag_serve := flag.Bool("serve", false, "Start daemon.")
-    flag_dump_config := flag.Bool("dump-config", false, "Dump the effective config to stdout.")
-    flag_listen := flag.String("listen", "", "Address to listen on. (default 127.0.0.1:9999)")
-    flag_tls_key := flag.String("tls-key", "", "Use TLS.")
-    flag_tls_cert := flag.String("tls-cert", "", "Use TLS.")
-
-    // also settable in config file
     flag.StringVar(&cfg.Db_url, "db-url", "", "URL used to connect to the database.")
     flag.Uint64Var(&cfg.Lookahead, "lookahead", 10, "Counter range to check for matching OTPs.")
     flag.BoolVar(&cfg.Debug, "debug", false, "Enable debug output.")
@@ -513,41 +502,50 @@ func main() {
     db, err = sql.Open("postgres", cfg.Db_url)
     err_fatal(err)
 
-    // default action is to serve, but not if one of the other actions is given
-    serve_default := true
-
-    // copy -listen option to config
-    if *flag_listen != "" {
-        cfg.Listen = make(map[string]tls_cfg)
-        cfg.Listen[*flag_listen] = tls_cfg{ Key: *flag_tls_key, Cert: *flag_tls_cert }
-    } else if cfg.Listen == nil {
-        cfg.Listen = make(map[string]tls_cfg)
-        cfg.Listen["127.0.0.1:9999"] = tls_cfg{}
-    }
-
-    if *flag_dump_config {
-        serve_default = false
-        enc := json.NewEncoder(os.Stdout)
-        enc.SetIndent("", "\t")
-        err_fatal(enc.Encode(cfg))
-    }
-
-    if *flag_init_db {
-        serve_default = false
-        init_db()
-    }
-
-    if *flag_from_file != "" {
-        serve_default = false
-        read_users_from_file(*flag_from_file)
-    }
-
-    if *flag_add_user != "" {
-        serve_default = false
-        create_user(*flag_add_user, *flag_secret)
-    }
-
-    if serve_default || *flag_serve {
+    if len(flag.Args()) < 1 {
         serve()
+    } else {
+        op := flag.Arg(0)
+        args := flag.Args()[1:]
+
+        switch op {
+        case "dump-config":
+            enc := json.NewEncoder(os.Stdout)
+            enc.SetIndent("", "\t")
+            err_fatal(enc.Encode(cfg))
+        case "init-db":
+            init_db()
+        case "sync-users":
+            if len(args) != 1 {
+                log.Fatalf("sync-users: Invalid number of arguments: %v (expecting <path>)\n", len(args))
+            }
+            read_users_from_file(args[0])
+        case "add-user":
+            if len(args) != 2 {
+                log.Fatalf("add-user: Invalid number of arguments: %v (expecting <username> <secret>)\n", len(args))
+            }
+            user := args[0]
+            secret := args[1]
+            create_user(user, secret)
+        case "serve":
+            fs := flag.NewFlagSet("serve", flag.ExitOnError)
+            flag_addr := fs.String("addr", "", "Address to listen on. (default 127.0.0.1:9999)")
+            flag_tls_key := fs.String("tls-key", "", "Use TLS.")
+            flag_tls_cert := fs.String("tls-cert", "", "Use TLS.")
+            fs.Parse(args)
+
+            // copy -addr option to config
+            if *flag_addr != "" {
+                cfg.Listen = make(map[string]tls_cfg)
+                cfg.Listen[*flag_addr] = tls_cfg{ Key: *flag_tls_key, Cert: *flag_tls_cert }
+            } else if cfg.Listen == nil {
+                cfg.Listen = make(map[string]tls_cfg)
+                cfg.Listen["127.0.0.1:9999"] = tls_cfg{}
+            }
+
+            serve()
+        default:
+            log.Fatalf("Unkown subcommand: %v", op)
+        }
     }
 }
diff --git a/test_pam_goatherd.sh b/test_pam_goatherd.sh
index be29b31..a634ffc 100644
--- a/test_pam_goatherd.sh
+++ b/test_pam_goatherd.sh
@@ -32,7 +32,7 @@ die() {
 
 for i in $(seq 1 3); do
     createdb "goatherd_test_$i"
-    ghdb $i -init-db
+    ghdb $i init-db
 done
 
 
@@ -48,7 +48,7 @@ else
     echo "(failure expected)"
 fi
 
-ghdb 1 -listen 127.0.0.1:9999 -tls-key test.key -tls-cert test.crt &
+ghdb 1 serve -addr 127.0.0.1:9999 -tls-key test.key -tls-cert test.crt &
 
 echo blub | if pw pamtester single_server someuser authenticate; then
     die "FAIL: Auth succeeded but user is not valid"
@@ -57,7 +57,7 @@ else
 fi
 
 secret=12345678901234567890
-ghdb 1 -add-user someuser -secret $(echo -n $secret | base64)
+ghdb 1 add-user someuser $(echo -n $secret | base64)
 
 echo blub | if pw pamtester single_server someuser authenticate; then
     die "FAIL: Auth succeeded but OTP is not valid"
@@ -83,7 +83,7 @@ else
     echo "(failure expected)"
 fi
 
-ghdb 2 -listen 127.0.0.1:9998 -tls-key test.key -tls-cert test.crt &
+ghdb 2 serve -addr 127.0.0.1:9998 -tls-key test.key -tls-cert test.crt &
 
 oathtool -d 8 -c 2 $(echo -n $secret | xxd -p) | \
     if pw pamtester three_servers someuser authenticate; then
@@ -92,7 +92,7 @@ else
     echo "(failure expected)"
 fi
 
-ghdb 2 -add-user someuser -secret $(echo -n $secret | base64)
+ghdb 2 add-user someuser $(echo -n $secret | base64)
 
 oathtool -d 8 -c 3 $(echo -n $secret | xxd -p) | \
     if ! pw pamtester three_servers someuser authenticate; then
-- 
GitLab