welcome working end to end
parent
92807f9b6b
commit
57115b1c11
|
@ -7,3 +7,4 @@ cmd/signup/signup
|
||||||
cmd/review/review
|
cmd/review/review
|
||||||
cmd/welcome/welcome
|
cmd/welcome/welcome
|
||||||
cmd/createkeyfile/createkeyfile
|
cmd/createkeyfile/createkeyfile
|
||||||
|
cmd/registeruser/registeruser
|
||||||
|
|
|
@ -26,36 +26,36 @@ import (
|
||||||
|
|
||||||
const keyfileName = "authorized_keys2"
|
const keyfileName = "authorized_keys2"
|
||||||
|
|
||||||
func quit(msg string) {
|
func quit(msg string, code int) {
|
||||||
fmt.Println(msg)
|
fmt.Println(msg)
|
||||||
os.Exit(1)
|
os.Exit(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
username := os.Args[1]
|
username := os.Args[1]
|
||||||
if username == "" {
|
if username == "" {
|
||||||
quit("expected username as argument")
|
quit("expected username as argument", 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
u, err := user.Current()
|
u, err := user.Current()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
quit(err.Error())
|
quit(err.Error(), 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
if u.Username != username {
|
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")
|
sshPath := path.Join("/home", u.Username, ".ssh")
|
||||||
keyfilePath := path.Join(sshPath, keyfileName)
|
keyfilePath := path.Join(sshPath, keyfileName)
|
||||||
|
|
||||||
if err = os.Mkdir(sshPath, os.FileMode(0700)); err != nil {
|
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)
|
f, err := os.OpenFile(keyfilePath, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0600)
|
||||||
if err != nil {
|
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()
|
defer f.Close()
|
||||||
|
@ -64,23 +64,23 @@ func main() {
|
||||||
|
|
||||||
n, err := os.Stdin.Read(stdin)
|
n, err := os.Stdin.Read(stdin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
quit(err.Error())
|
quit(err.Error(), 6)
|
||||||
} else if n == 0 {
|
} else if n == 0 {
|
||||||
quit("nothing passed on STDIN")
|
quit("nothing passed on STDIN", 7)
|
||||||
}
|
}
|
||||||
|
|
||||||
stdin = stdin[0:n]
|
stdin = stdin[0:n]
|
||||||
|
|
||||||
if !strings.HasPrefix(string(stdin), "########## GREETINGS! ##########") {
|
if !strings.HasPrefix(string(stdin), "########## GREETINGS! ##########") {
|
||||||
// TODO further validation?
|
// 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)
|
n, err = f.Write(stdin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
quit(err.Error())
|
quit(err.Error(), 9)
|
||||||
} else if n == 0 {
|
} else if n == 0 {
|
||||||
quit("wrote nothing to keyfile")
|
quit("wrote nothing to keyfile", 10)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
_ "github.com/mattn/go-sqlite3"
|
// _ "github.com/mattn/go-sqlite3"
|
||||||
|
|
||||||
"git.tilde.town/tildetown/town/towndb"
|
"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
|
// 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
|
// 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 == "" {
|
if userData.Username == "" {
|
||||||
return errors.New("no 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 errors.New("bad state")
|
||||||
}
|
}
|
||||||
|
|
||||||
return userData.Insert(tdb)
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseInput(stdin *os.File) (u towndb.TownUser, err error) {
|
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)
|
err = json.Unmarshal(input[0:n], &u)
|
||||||
return
|
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 = exec.Command("sudo", "--user", data.Username, "/town/bin/createkeyfile", data.Username)
|
||||||
cmd.Stdin = bytes.NewBufferString(keyfileText(data))
|
cmd.Stdin = bytes.NewBufferString(keyfileText(data))
|
||||||
|
stdoutBuff := bytes.NewBuffer([]byte{})
|
||||||
|
cmd.Stdout = stdoutBuff
|
||||||
if err = cmd.Run(); err != nil {
|
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)
|
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.
|
// TODO log this. no reason to bail out.
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = exec.Command("sudo", "/town/bin/registeruser")
|
|
||||||
tu := towndb.TownUser{
|
tu := towndb.TownUser{
|
||||||
Username: data.Username,
|
Username: data.Username,
|
||||||
Emails: []string{
|
Emails: []string{
|
||||||
|
@ -174,9 +175,12 @@ func createUser(data newUserData) (err error) {
|
||||||
if out, err = json.Marshal(tu); err != nil {
|
if out, err = json.Marshal(tu); err != nil {
|
||||||
return fmt.Errorf("could not serialize user data: %w", err)
|
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)
|
cmd.Stdin = bytes.NewBuffer(out)
|
||||||
if err = cmd.Run(); err != nil {
|
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
|
return nil
|
||||||
|
|
|
@ -2,11 +2,8 @@ CREATE TABLE IF NOT EXISTS users (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
created TEXT DEFAULT (strftime('%Y-%m-%dT%H:%M', 'now', 'localtime')),
|
created TEXT DEFAULT (strftime('%Y-%m-%dT%H:%M', 'now', 'localtime')),
|
||||||
username TEXT UNIQUE,
|
username TEXT UNIQUE,
|
||||||
signupid INTEGER,
|
|
||||||
state TEXT,
|
state TEXT,
|
||||||
admin INTEGER DEFAULT FALSE,
|
admin INTEGER DEFAULT 0
|
||||||
|
|
||||||
FOREIGN KEY (signupid) REFERENCES signups(signupid)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 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
|
-- 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,
|
content TEXT,
|
||||||
created TEXT DEFAULT (strftime('%Y-%m-%dT%H:%M', 'now', 'localtime')),
|
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()
|
u.Created = time.Now()
|
||||||
if stmt, err = tx.Prepare(`
|
if stmt, err = tx.Prepare(`
|
||||||
INSERT INTO notes (created, username, state, admin)
|
INSERT INTO users (created, username, state)
|
||||||
VALUES ( ?, ?, ?, ?)`); err != nil {
|
VALUES (?, ?, ?)`); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if result, err = stmt.Exec(
|
if result, err = stmt.Exec(
|
||||||
u.Created.Unix(),
|
u.Created.Unix(),
|
||||||
u.Username,
|
u.Username,
|
||||||
u.State,
|
u.State); err != nil {
|
||||||
u.IsAdmin); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,9 +120,7 @@ func (u *TownUser) Insert(db *sql.DB) (err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tx.Commit()
|
return tx.Commit()
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConnectDB() (*sql.DB, error) {
|
func ConnectDB() (*sql.DB, error) {
|
||||||
|
|
Loading…
Reference in New Issue