welcome working end to end
parent
92807f9b6b
commit
57115b1c11
|
@ -7,3 +7,4 @@ cmd/signup/signup
|
|||
cmd/review/review
|
||||
cmd/welcome/welcome
|
||||
cmd/createkeyfile/createkeyfile
|
||||
cmd/registeruser/registeruser
|
||||
|
|
|
@ -26,36 +26,36 @@ import (
|
|||
|
||||
const keyfileName = "authorized_keys2"
|
||||
|
||||
func quit(msg string) {
|
||||
func quit(msg string, code int) {
|
||||
fmt.Println(msg)
|
||||
os.Exit(1)
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
func main() {
|
||||
username := os.Args[1]
|
||||
if username == "" {
|
||||
quit("expected username as argument")
|
||||
quit("expected username as argument", 1)
|
||||
}
|
||||
|
||||
u, err := user.Current()
|
||||
if err != nil {
|
||||
quit(err.Error())
|
||||
quit(err.Error(), 2)
|
||||
}
|
||||
|
||||
if u.Username != username {
|
||||
quit("that's my purse; I don't know you")
|
||||
quit("that's my purse; I don't know you", 3)
|
||||
}
|
||||
|
||||
sshPath := path.Join("/home", u.Username, ".ssh")
|
||||
keyfilePath := path.Join(sshPath, keyfileName)
|
||||
|
||||
if err = os.Mkdir(sshPath, os.FileMode(0700)); err != nil {
|
||||
quit(err.Error())
|
||||
quit(err.Error(), 4)
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(keyfilePath, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0600)
|
||||
if err != nil {
|
||||
quit(fmt.Sprintf("failed to open %s: %s", keyfilePath, err.Error()))
|
||||
quit(fmt.Sprintf("failed to open %s: %s", keyfilePath, err.Error()), 5)
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
@ -64,23 +64,23 @@ func main() {
|
|||
|
||||
n, err := os.Stdin.Read(stdin)
|
||||
if err != nil {
|
||||
quit(err.Error())
|
||||
quit(err.Error(), 6)
|
||||
} else if n == 0 {
|
||||
quit("nothing passed on STDIN")
|
||||
quit("nothing passed on STDIN", 7)
|
||||
}
|
||||
|
||||
stdin = stdin[0:n]
|
||||
|
||||
if !strings.HasPrefix(string(stdin), "########## GREETINGS! ##########") {
|
||||
// TODO further validation?
|
||||
quit(fmt.Sprintf("file contents look wrong: %s", string(stdin)))
|
||||
quit(fmt.Sprintf("file contents look wrong: %s", string(stdin)), 8)
|
||||
}
|
||||
|
||||
n, err = f.Write(stdin)
|
||||
if err != nil {
|
||||
quit(err.Error())
|
||||
quit(err.Error(), 9)
|
||||
} else if n == 0 {
|
||||
quit("wrote nothing to keyfile")
|
||||
quit("wrote nothing to keyfile", 10)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
// _ "github.com/mattn/go-sqlite3"
|
||||
|
||||
"git.tilde.town/tildetown/town/towndb"
|
||||
)
|
||||
|
@ -15,7 +14,31 @@ import (
|
|||
// this command adds a new user to /town/var/town.db. it's meant to be invoked
|
||||
// by the welcome binary upon successfully creating a new user account
|
||||
|
||||
func _main(tdb *sql.DB, userData towndb.TownUser) error {
|
||||
func main() {
|
||||
tdb, err := towndb.ConnectDB()
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
userData, err := parseInput(os.Stdin)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
if err = validateInput(userData); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err.Error())
|
||||
os.Exit(3)
|
||||
}
|
||||
|
||||
if err = userData.Insert(tdb); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err.Error())
|
||||
os.Exit(4)
|
||||
}
|
||||
}
|
||||
|
||||
func validateInput(userData towndb.TownUser) error {
|
||||
if userData.Username == "" {
|
||||
return errors.New("no username")
|
||||
}
|
||||
|
@ -38,7 +61,7 @@ func _main(tdb *sql.DB, userData towndb.TownUser) error {
|
|||
return errors.New("bad state")
|
||||
}
|
||||
|
||||
return userData.Insert(tdb)
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseInput(stdin *os.File) (u towndb.TownUser, err error) {
|
||||
|
@ -54,22 +77,3 @@ func parseInput(stdin *os.File) (u towndb.TownUser, err error) {
|
|||
err = json.Unmarshal(input[0:n], &u)
|
||||
return
|
||||
}
|
||||
|
||||
func main() {
|
||||
tdb, err := towndb.ConnectDB()
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
userData, err := parseInput(os.Stdin)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
if err = _main(tdb, userData); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(3)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,8 +153,10 @@ func createUser(data newUserData) (err error) {
|
|||
|
||||
cmd = exec.Command("sudo", "--user", data.Username, "/town/bin/createkeyfile", data.Username)
|
||||
cmd.Stdin = bytes.NewBufferString(keyfileText(data))
|
||||
stdoutBuff := bytes.NewBuffer([]byte{})
|
||||
cmd.Stdout = stdoutBuff
|
||||
if err = cmd.Run(); err != nil {
|
||||
return fmt.Errorf("createkeyfile failed: %w", err)
|
||||
return fmt.Errorf("createkeyfile failed with '%s': %w", string(stdoutBuff.Bytes()), err)
|
||||
}
|
||||
|
||||
cmd = exec.Command("sudo", "/town/bin/generate_welcome_present.sh", data.Username)
|
||||
|
@ -162,7 +164,6 @@ func createUser(data newUserData) (err error) {
|
|||
// TODO log this. no reason to bail out.
|
||||
}
|
||||
|
||||
cmd = exec.Command("sudo", "/town/bin/registeruser")
|
||||
tu := towndb.TownUser{
|
||||
Username: data.Username,
|
||||
Emails: []string{
|
||||
|
@ -174,9 +175,12 @@ func createUser(data newUserData) (err error) {
|
|||
if out, err = json.Marshal(tu); err != nil {
|
||||
return fmt.Errorf("could not serialize user data: %w", err)
|
||||
}
|
||||
cmd = exec.Command("sudo", "/town/bin/registeruser")
|
||||
stderrBuff := bytes.NewBuffer([]byte{})
|
||||
cmd.Stderr = stderrBuff
|
||||
cmd.Stdin = bytes.NewBuffer(out)
|
||||
if err = cmd.Run(); err != nil {
|
||||
return fmt.Errorf("register user failed: %w", err)
|
||||
return fmt.Errorf("register user failed with '%s': %w", string(stderrBuff.Bytes()), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -2,11 +2,8 @@ CREATE TABLE IF NOT EXISTS users (
|
|||
id INTEGER PRIMARY KEY,
|
||||
created TEXT DEFAULT (strftime('%Y-%m-%dT%H:%M', 'now', 'localtime')),
|
||||
username TEXT UNIQUE,
|
||||
signupid INTEGER,
|
||||
state TEXT,
|
||||
admin INTEGER DEFAULT FALSE,
|
||||
|
||||
FOREIGN KEY (signupid) REFERENCES signups(signupid)
|
||||
admin INTEGER DEFAULT 0
|
||||
);
|
||||
|
||||
-- TODO address /should/ be unique but leaving it duplicable for now since i can think of some cases where there might be >1 account for the same human
|
||||
|
@ -33,5 +30,5 @@ CREATE TABLE IF NOT EXISTS notes (
|
|||
content TEXT,
|
||||
created TEXT DEFAULT (strftime('%Y-%m-%dT%H:%M', 'now', 'localtime')),
|
||||
|
||||
FOREIGN KEY (adminid) REFERENCES users(adminid)
|
||||
FOREIGN KEY (author) REFERENCES users(author)
|
||||
);
|
||||
|
|
|
@ -83,18 +83,21 @@ func (u *TownUser) Insert(db *sql.DB) (err error) {
|
|||
}
|
||||
}()
|
||||
|
||||
// TODO this does not set the admin flag intentionally as rn this code is
|
||||
// just meant to be called by the welcome binary; other stuff for now is just
|
||||
// expected to be done via sql
|
||||
|
||||
u.Created = time.Now()
|
||||
if stmt, err = tx.Prepare(`
|
||||
INSERT INTO notes (created, username, state, admin)
|
||||
VALUES ( ?, ?, ?, ?)`); err != nil {
|
||||
INSERT INTO users (created, username, state)
|
||||
VALUES (?, ?, ?)`); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if result, err = stmt.Exec(
|
||||
u.Created.Unix(),
|
||||
u.Username,
|
||||
u.State,
|
||||
u.IsAdmin); err != nil {
|
||||
u.State); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -117,9 +120,7 @@ func (u *TownUser) Insert(db *sql.DB) (err error) {
|
|||
}
|
||||
}
|
||||
|
||||
tx.Commit()
|
||||
|
||||
return nil
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func ConnectDB() (*sql.DB, error) {
|
||||
|
|
Loading…
Reference in New Issue