git » chasquid » commit f38ae47

chasquid-util: Make the commands more user-friendly

author Alberto Bertogli
2016-10-17 00:01:23 UTC
committer Alberto Bertogli
2016-10-21 21:20:49 UTC
parent febe96697a82431c3ce8e577595b95b0b5185357

chasquid-util: Make the commands more user-friendly

This patch changes chasquid-util's subcommands and parameters to
(hopefully) make them more user friendly and intuitive by default.

The changes include defaulting the configuration to /etc/chasquid, and
using full addresses as usernames.

It also adds some shell tests to cover most of the functionality.

.gitignore +1 -1
cmd/chasquid-util/chasquid-util.go +60 -39
cmd/chasquid-util/test.sh +72 -0
test/util/lib.sh +2 -1

diff --git a/.gitignore b/.gitignore
index b6643a6..79a0a55 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,7 +9,7 @@
 
 # The binaries.
 chasquid
-chasquid-userdb
+cmd/chasquid-util/chasquid-util
 
 # Exclude any .pem files, to prevent accidentally including test keys and
 # certificates.
diff --git a/cmd/chasquid-util/chasquid-util.go b/cmd/chasquid-util/chasquid-util.go
index eca4aaf..9ec05e4 100644
--- a/cmd/chasquid-util/chasquid-util.go
+++ b/cmd/chasquid-util/chasquid-util.go
@@ -11,6 +11,7 @@ import (
 
 	"blitiri.com.ar/go/chasquid/internal/aliases"
 	"blitiri.com.ar/go/chasquid/internal/config"
+	"blitiri.com.ar/go/chasquid/internal/envelope"
 	"blitiri.com.ar/go/chasquid/internal/normalize"
 	"blitiri.com.ar/go/chasquid/internal/userdb"
 
@@ -22,23 +23,36 @@ import (
 // Usage, which doubles as parameter definitions thanks to docopt.
 const usage = `
 Usage:
-  chasquid-util adduser <db> <username> [--password=<password>]
-  chasquid-util removeuser <db> <username>
-  chasquid-util authenticate <db> <username> [--password=<password>]
-  chasquid-util check-userdb <db>
-  chasquid-util aliases-resolve <configdir> <address>
-  chasquid-util print-config <configdir>
+  chasquid-util [options] user-add <username> [--password=<password>]
+  chasquid-util [options] user-remove <username>
+  chasquid-util [options] authenticate <username> [--password=<password>]
+  chasquid-util [options] check-userdb <domain>
+  chasquid-util [options] aliases-resolve <address>
+  chasquid-util [options] print-config
+
+Options:
+  -C --configdir=<path>  Configuration directory
 `
 
 // Command-line arguments.
 var args map[string]interface{}
 
+// Globals, loaded from top-level options.
+var (
+	configDir = "/etc/chasquid"
+)
+
 func main() {
 	args, _ = docopt.Parse(usage, nil, true, "", false)
 
+	// Load globals.
+	if d, ok := args["--configdir"].(string); ok {
+		configDir = d
+	}
+
 	commands := map[string]func(){
-		"adduser":         AddUser,
-		"removeuser":      RemoveUser,
+		"user-add":        UserAdd,
+		"user-remove":     UserRemove,
 		"authenticate":    Authenticate,
 		"check-userdb":    CheckUserDB,
 		"aliases-resolve": AliasesResolve,
@@ -57,35 +71,50 @@ func Fatalf(s string, arg ...interface{}) {
 	os.Exit(1)
 }
 
-// chasquid-util check-userdb <db>
-func CheckUserDB() {
-	_, err := userdb.Load(args["<db>"].(string))
-	if err != nil {
-		Fatalf("Error loading database: %v", err)
+func userDBForDomain(domain string) string {
+	if domain == "" {
+		domain = args["<domain>"].(string)
 	}
-
-	fmt.Println("Database loaded")
+	return configDir + "/domains/" + domain + "/users"
 }
 
-// chasquid-util adduser <db> <username> [--password=<password>]
-func AddUser() {
-	db, err := userdb.Load(args["<db>"].(string))
+func userDBFromArgs(create bool) (string, string, *userdb.DB) {
+	username := args["<username>"].(string)
+	user, domain := envelope.Split(username)
+
+	db, err := userdb.Load(userDBForDomain(domain))
 	if err != nil {
-		if os.IsNotExist(err) {
+		if create && os.IsNotExist(err) {
 			fmt.Println("Creating database")
 		} else {
 			Fatalf("Error loading database: %v", err)
 		}
 	}
 
-	user, err := normalize.User(args["<username>"].(string))
+	user, err = normalize.User(user)
 	if err != nil {
 		Fatalf("Error normalizing user: %v", err)
 	}
 
+	return user, domain, db
+}
+
+// chasquid-util check-userdb <domain>
+func CheckUserDB() {
+	_, err := userdb.Load(userDBForDomain(""))
+	if err != nil {
+		Fatalf("Error loading database: %v", err)
+	}
+
+	fmt.Println("Database loaded")
+}
+
+// chasquid-util user-add <username> [--password=<password>]
+func UserAdd() {
+	user, _, db := userDBFromArgs(true)
 	password := getPassword()
 
-	err = db.AddUser(user, password)
+	err := db.AddUser(user, password)
 	if err != nil {
 		Fatalf("Error adding user: %v", err)
 	}
@@ -98,15 +127,12 @@ func AddUser() {
 	fmt.Println("Added user")
 }
 
-// chasquid-util authenticate <db> <username> [--password=<password>]
+// chasquid-util authenticate <username> [--password=<password>]
 func Authenticate() {
-	db, err := userdb.Load(args["<db>"].(string))
-	if err != nil {
-		Fatalf("Error loading database: %v", err)
-	}
+	user, _, db := userDBFromArgs(false)
 
 	password := getPassword()
-	ok := db.Authenticate(args["<username>"].(string), password)
+	ok := db.Authenticate(user, password)
 	if ok {
 		fmt.Println("Authentication succeeded")
 	} else {
@@ -141,19 +167,16 @@ func getPassword() string {
 	return string(p1)
 }
 
-// chasquid-util removeuser <db> <username>
-func RemoveUser() {
-	db, err := userdb.Load(args["<db>"].(string))
-	if err != nil {
-		Fatalf("Error loading database: %v", err)
-	}
+// chasquid-util user-remove <username>
+func UserRemove() {
+	user, _, db := userDBFromArgs(false)
 
-	present := db.RemoveUser(args["<username>"].(string))
+	present := db.RemoveUser(user)
 	if !present {
 		Fatalf("Unknown user")
 	}
 
-	err = db.Write()
+	err := db.Write()
 	if err != nil {
 		Fatalf("Error writing database: %v", err)
 	}
@@ -161,9 +184,8 @@ func RemoveUser() {
 	fmt.Println("Removed user")
 }
 
-// chasquid-util aliases-resolve <configdir> <address>
+// chasquid-util aliases-resolve <address>
 func AliasesResolve() {
-	configDir := args["<configdir>"].(string)
 	conf, err := config.Load(configDir + "/chasquid.conf")
 	if err != nil {
 		Fatalf("Error reading config")
@@ -206,9 +228,8 @@ func AliasesResolve() {
 
 }
 
-// chasquid-util print-config <configdir>
+// chasquid-util print-config
 func PrintConfig() {
-	configDir := args["<configdir>"].(string)
 	conf, err := config.Load(configDir + "/chasquid.conf")
 	if err != nil {
 		Fatalf("Error reading config")
diff --git a/cmd/chasquid-util/test.sh b/cmd/chasquid-util/test.sh
new file mode 100755
index 0000000..812c8e1
--- /dev/null
+++ b/cmd/chasquid-util/test.sh
@@ -0,0 +1,72 @@
+#!/bin/bash
+
+set -e
+. $(dirname ${0})/../../test/util/lib.sh
+
+init
+
+go build || exit 1
+
+function r() {
+	./chasquid-util -C .config "$@"
+}
+
+function check_userdb() {
+	if ! r check-userdb domain > /dev/null; then
+		echo check-userdb failed
+		exit 1
+	fi
+}
+
+
+mkdir -p .config/domains/domain
+touch .config/chasquid.conf
+
+if ! r print-config > /dev/null; then
+	echo print-config failed
+	exit 1
+fi
+
+if ! r user-add user@domain --password=passwd > /dev/null; then
+	echo user-add failed
+	exit 1
+fi
+check_userdb
+
+if ! r authenticate user@domain --password=passwd > /dev/null; then
+	echo authenticate failed
+	exit 1
+fi
+
+if r authenticate user@domain --password=abcd > /dev/null; then
+	echo authenticate with bad password worked
+	exit 1
+fi
+
+if ! r user-remove user@domain > /dev/null; then
+	echo user-remove failed
+	exit 1
+fi
+check_userdb
+
+if r authenticate user@domain --password=passwd > /dev/null; then
+	echo authenticate for removed user worked
+	exit 1
+fi
+
+echo "alias: user@somewhere" > .config/domains/domain/aliases
+A=$(r aliases-resolve alias@domain | grep somewhere)
+if [ "$A" != "(email)  user@somewhere" ]; then
+	echo aliases-resolve failed
+	echo output: "$A"
+	exit 1
+fi
+
+C=$(r print-config | grep hostname)
+if [ "$C" != "hostname: \"$HOSTNAME\"" ]; then
+	echo print-config failed
+	echo output: "$C"
+	exit 1
+fi
+
+success
diff --git a/test/util/lib.sh b/test/util/lib.sh
index 6c2924b..53b47dc 100644
--- a/test/util/lib.sh
+++ b/test/util/lib.sh
@@ -42,7 +42,8 @@ function add_user() {
 	CONFDIR="${CONFDIR:-config}"
 	mkdir -p "${CONFDIR}/domains/${1}/"
 	go run ${TBASE}/../../cmd/chasquid-util/chasquid-util.go \
-		adduser "${CONFDIR}/domains/${1}/users" "${2}" \
+		-C "${CONFDIR}" \
+		user-add "$2@$1" \
 		--password "${3}" \
 		>> .add_user_logs
 }