mirror of
https://blitiri.com.ar/repos/chasquid
synced 2025-12-17 14:37:02 +00:00
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.
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
# The binaries.
|
# The binaries.
|
||||||
chasquid
|
chasquid
|
||||||
chasquid-userdb
|
cmd/chasquid-util/chasquid-util
|
||||||
|
|
||||||
# Exclude any .pem files, to prevent accidentally including test keys and
|
# Exclude any .pem files, to prevent accidentally including test keys and
|
||||||
# certificates.
|
# certificates.
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
"blitiri.com.ar/go/chasquid/internal/aliases"
|
"blitiri.com.ar/go/chasquid/internal/aliases"
|
||||||
"blitiri.com.ar/go/chasquid/internal/config"
|
"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/normalize"
|
||||||
"blitiri.com.ar/go/chasquid/internal/userdb"
|
"blitiri.com.ar/go/chasquid/internal/userdb"
|
||||||
|
|
||||||
@@ -22,23 +23,36 @@ import (
|
|||||||
// Usage, which doubles as parameter definitions thanks to docopt.
|
// Usage, which doubles as parameter definitions thanks to docopt.
|
||||||
const usage = `
|
const usage = `
|
||||||
Usage:
|
Usage:
|
||||||
chasquid-util adduser <db> <username> [--password=<password>]
|
chasquid-util [options] user-add <username> [--password=<password>]
|
||||||
chasquid-util removeuser <db> <username>
|
chasquid-util [options] user-remove <username>
|
||||||
chasquid-util authenticate <db> <username> [--password=<password>]
|
chasquid-util [options] authenticate <username> [--password=<password>]
|
||||||
chasquid-util check-userdb <db>
|
chasquid-util [options] check-userdb <domain>
|
||||||
chasquid-util aliases-resolve <configdir> <address>
|
chasquid-util [options] aliases-resolve <address>
|
||||||
chasquid-util print-config <configdir>
|
chasquid-util [options] print-config
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-C --configdir=<path> Configuration directory
|
||||||
`
|
`
|
||||||
|
|
||||||
// Command-line arguments.
|
// Command-line arguments.
|
||||||
var args map[string]interface{}
|
var args map[string]interface{}
|
||||||
|
|
||||||
|
// Globals, loaded from top-level options.
|
||||||
|
var (
|
||||||
|
configDir = "/etc/chasquid"
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
args, _ = docopt.Parse(usage, nil, true, "", false)
|
args, _ = docopt.Parse(usage, nil, true, "", false)
|
||||||
|
|
||||||
|
// Load globals.
|
||||||
|
if d, ok := args["--configdir"].(string); ok {
|
||||||
|
configDir = d
|
||||||
|
}
|
||||||
|
|
||||||
commands := map[string]func(){
|
commands := map[string]func(){
|
||||||
"adduser": AddUser,
|
"user-add": UserAdd,
|
||||||
"removeuser": RemoveUser,
|
"user-remove": UserRemove,
|
||||||
"authenticate": Authenticate,
|
"authenticate": Authenticate,
|
||||||
"check-userdb": CheckUserDB,
|
"check-userdb": CheckUserDB,
|
||||||
"aliases-resolve": AliasesResolve,
|
"aliases-resolve": AliasesResolve,
|
||||||
@@ -57,9 +71,37 @@ func Fatalf(s string, arg ...interface{}) {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// chasquid-util check-userdb <db>
|
func userDBForDomain(domain string) string {
|
||||||
|
if domain == "" {
|
||||||
|
domain = args["<domain>"].(string)
|
||||||
|
}
|
||||||
|
return configDir + "/domains/" + domain + "/users"
|
||||||
|
}
|
||||||
|
|
||||||
|
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 create && os.IsNotExist(err) {
|
||||||
|
fmt.Println("Creating database")
|
||||||
|
} else {
|
||||||
|
Fatalf("Error loading database: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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() {
|
func CheckUserDB() {
|
||||||
_, err := userdb.Load(args["<db>"].(string))
|
_, err := userdb.Load(userDBForDomain(""))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("Error loading database: %v", err)
|
Fatalf("Error loading database: %v", err)
|
||||||
}
|
}
|
||||||
@@ -67,25 +109,12 @@ func CheckUserDB() {
|
|||||||
fmt.Println("Database loaded")
|
fmt.Println("Database loaded")
|
||||||
}
|
}
|
||||||
|
|
||||||
// chasquid-util adduser <db> <username> [--password=<password>]
|
// chasquid-util user-add <username> [--password=<password>]
|
||||||
func AddUser() {
|
func UserAdd() {
|
||||||
db, err := userdb.Load(args["<db>"].(string))
|
user, _, db := userDBFromArgs(true)
|
||||||
if err != nil {
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
fmt.Println("Creating database")
|
|
||||||
} else {
|
|
||||||
Fatalf("Error loading database: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
user, err := normalize.User(args["<username>"].(string))
|
|
||||||
if err != nil {
|
|
||||||
Fatalf("Error normalizing user: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
password := getPassword()
|
password := getPassword()
|
||||||
|
|
||||||
err = db.AddUser(user, password)
|
err := db.AddUser(user, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("Error adding user: %v", err)
|
Fatalf("Error adding user: %v", err)
|
||||||
}
|
}
|
||||||
@@ -98,15 +127,12 @@ func AddUser() {
|
|||||||
fmt.Println("Added user")
|
fmt.Println("Added user")
|
||||||
}
|
}
|
||||||
|
|
||||||
// chasquid-util authenticate <db> <username> [--password=<password>]
|
// chasquid-util authenticate <username> [--password=<password>]
|
||||||
func Authenticate() {
|
func Authenticate() {
|
||||||
db, err := userdb.Load(args["<db>"].(string))
|
user, _, db := userDBFromArgs(false)
|
||||||
if err != nil {
|
|
||||||
Fatalf("Error loading database: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
password := getPassword()
|
password := getPassword()
|
||||||
ok := db.Authenticate(args["<username>"].(string), password)
|
ok := db.Authenticate(user, password)
|
||||||
if ok {
|
if ok {
|
||||||
fmt.Println("Authentication succeeded")
|
fmt.Println("Authentication succeeded")
|
||||||
} else {
|
} else {
|
||||||
@@ -141,19 +167,16 @@ func getPassword() string {
|
|||||||
return string(p1)
|
return string(p1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// chasquid-util removeuser <db> <username>
|
// chasquid-util user-remove <username>
|
||||||
func RemoveUser() {
|
func UserRemove() {
|
||||||
db, err := userdb.Load(args["<db>"].(string))
|
user, _, db := userDBFromArgs(false)
|
||||||
if err != nil {
|
|
||||||
Fatalf("Error loading database: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
present := db.RemoveUser(args["<username>"].(string))
|
present := db.RemoveUser(user)
|
||||||
if !present {
|
if !present {
|
||||||
Fatalf("Unknown user")
|
Fatalf("Unknown user")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = db.Write()
|
err := db.Write()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("Error writing database: %v", err)
|
Fatalf("Error writing database: %v", err)
|
||||||
}
|
}
|
||||||
@@ -161,9 +184,8 @@ func RemoveUser() {
|
|||||||
fmt.Println("Removed user")
|
fmt.Println("Removed user")
|
||||||
}
|
}
|
||||||
|
|
||||||
// chasquid-util aliases-resolve <configdir> <address>
|
// chasquid-util aliases-resolve <address>
|
||||||
func AliasesResolve() {
|
func AliasesResolve() {
|
||||||
configDir := args["<configdir>"].(string)
|
|
||||||
conf, err := config.Load(configDir + "/chasquid.conf")
|
conf, err := config.Load(configDir + "/chasquid.conf")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("Error reading config")
|
Fatalf("Error reading config")
|
||||||
@@ -206,9 +228,8 @@ func AliasesResolve() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// chasquid-util print-config <configdir>
|
// chasquid-util print-config
|
||||||
func PrintConfig() {
|
func PrintConfig() {
|
||||||
configDir := args["<configdir>"].(string)
|
|
||||||
conf, err := config.Load(configDir + "/chasquid.conf")
|
conf, err := config.Load(configDir + "/chasquid.conf")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("Error reading config")
|
Fatalf("Error reading config")
|
||||||
|
|||||||
72
cmd/chasquid-util/test.sh
Executable file
72
cmd/chasquid-util/test.sh
Executable file
@@ -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
|
||||||
@@ -42,7 +42,8 @@ function add_user() {
|
|||||||
CONFDIR="${CONFDIR:-config}"
|
CONFDIR="${CONFDIR:-config}"
|
||||||
mkdir -p "${CONFDIR}/domains/${1}/"
|
mkdir -p "${CONFDIR}/domains/${1}/"
|
||||||
go run ${TBASE}/../../cmd/chasquid-util/chasquid-util.go \
|
go run ${TBASE}/../../cmd/chasquid-util/chasquid-util.go \
|
||||||
adduser "${CONFDIR}/domains/${1}/users" "${2}" \
|
-C "${CONFDIR}" \
|
||||||
|
user-add "$2@$1" \
|
||||||
--password "${3}" \
|
--password "${3}" \
|
||||||
>> .add_user_logs
|
>> .add_user_logs
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user