cmd/jouncectl: new command

Allows to create users.
This commit is contained in:
Simon Ser 2020-03-11 19:01:03 +01:00
parent 2a1db4cb8d
commit a572b24702
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
4 changed files with 112 additions and 0 deletions

81
cmd/jouncectl/main.go Normal file
View File

@ -0,0 +1,81 @@
package main
import (
"flag"
"fmt"
"log"
"os"
"git.sr.ht/~emersion/jounce"
"git.sr.ht/~emersion/jounce/config"
"golang.org/x/crypto/bcrypt"
"golang.org/x/crypto/ssh/terminal"
)
const usage = `usage: jouncectl [-config path] <action> [options...]
create-user <username> Create a new user
help Show this help message
`
func init() {
flag.Usage = func() {
fmt.Fprintf(flag.CommandLine.Output(), usage)
}
}
func main() {
var configPath string
flag.StringVar(&configPath, "config", "", "path to configuration file")
flag.Parse()
var cfg *config.Server
if configPath != "" {
var err error
cfg, err = config.Load(configPath)
if err != nil {
log.Fatalf("failed to load config file: %v", err)
}
} else {
cfg = config.Defaults()
}
db, err := jounce.OpenSQLDB(cfg.SQLDriver, cfg.SQLSource)
if err != nil {
log.Fatalf("failed to open database: %v", err)
}
switch cmd := flag.Arg(0); cmd {
case "create-user":
username := flag.Arg(1)
if username == "" {
flag.Usage()
os.Exit(1)
}
fmt.Printf("Password: ")
password, err := terminal.ReadPassword(int(os.Stdin.Fd()))
if err != nil {
log.Fatalf("failed to read password: %v", err)
}
fmt.Printf("\n")
hashed, err := bcrypt.GenerateFromPassword(password, bcrypt.DefaultCost)
if err != nil {
log.Fatalf("failed to hash password: %v", err)
}
user := jounce.User{
Username: username,
Password: string(hashed),
}
if err := db.CreateUser(&user); err != nil {
log.Fatalf("failed to create user: %v", err)
}
default:
flag.Usage()
if cmd != "help" {
os.Exit(1)
}
}
}

22
db.go
View File

@ -73,6 +73,28 @@ func (db *DB) ListUsers() ([]User, error) {
return users, nil
}
func (db *DB) CreateUser(user *User) error {
db.lock.Lock()
defer db.lock.Unlock()
tx, err := db.db.Begin()
if err != nil {
return err
}
defer tx.Rollback()
var password *string
if user.Password != "" {
password = &user.Password
}
_, err = tx.Exec("INSERT INTO User(username, password) VALUES (?, ?)", user.Username, password)
if err != nil {
return err
}
return tx.Commit()
}
func (db *DB) ListNetworks(username string) ([]Network, error) {
db.lock.RLock()
defer db.lock.RUnlock()

1
go.mod
View File

@ -4,5 +4,6 @@ go 1.13
require (
github.com/mattn/go-sqlite3 v2.0.3+incompatible
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4
gopkg.in/irc.v3 v3.1.0
)

8
go.sum
View File

@ -1,5 +1,13 @@
github.com/mattn/go-sqlite3 v1.13.0 h1:LnJI81JidiW9r7pS/hXe6cFeO5EXNq7KbfvoJLRI69c=
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4 h1:QmwruyY+bKbDDL0BaglrbZABEali68eoMFhTZpCjYVA=
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/irc.v3 v3.1.0 h1:AeDaEhQ/78gHfpbj/3mSi8FfiNIsFiVrWEgLzOwHWnU=
gopkg.in/irc.v3 v3.1.0/go.mod h1:qE0DWv0j8Z8wCbFhA9783JBO0bufi3rttcV1Sjin8io=