all repos — flounder @ 137c6301b83699c6bdee329a8d85ca825317e4fe

A small site builder for the Gemini protocol

admin.go (view raw)

  1package main
  2
  3// Commands for administering your instance
  4// reset user password -> generate link
  5// delete user
  6
  7// Run some scripts to setup your instance
  8
  9import (
 10	"flag"
 11	"fmt"
 12	"io/ioutil"
 13	"log"
 14	"os"
 15	"path"
 16	"path/filepath"
 17)
 18
 19// TODO improve cli
 20func runAdminCommand() {
 21	args := flag.Args() // again?
 22	if len(args) < 3 {
 23		fmt.Println("Expected subcommand with parameter activate-user|delete-user|make-admin|rename-user")
 24		os.Exit(1)
 25	}
 26	var err error
 27	switch args[1] {
 28	case "activate-user":
 29		username := args[2]
 30		err = activateUser(username)
 31	case "delete-user":
 32		username := args[2]
 33		// TODO add confirmation
 34		err = deleteUser(username)
 35	case "make-admin":
 36		username := args[2]
 37		err = makeAdmin(username)
 38	case "rename-user":
 39		username := args[2]
 40		newUsername := args[3]
 41		err = renameUser(username, newUsername)
 42		// case "set-password":
 43	}
 44	if err != nil {
 45		log.Fatal(err)
 46	}
 47	// reset password
 48
 49}
 50
 51func makeAdmin(username string) error {
 52	_, err := DB.Exec("UPDATE user SET admin = true WHERE username = $1", username)
 53	if err != nil {
 54		return err
 55	}
 56	log.Println("Made admin user", username)
 57	return nil
 58}
 59
 60func setPassword(username string, newPass string) error {
 61	return nil
 62}
 63
 64func activateUser(username string) error {
 65	_, err := DB.Exec("UPDATE user SET active = true WHERE username = ?", username)
 66	if err != nil {
 67		// TODO verify 1 row updated
 68		return err
 69	}
 70	log.Println("Activated user", username)
 71	baseIndex := `# Welcome to Flounder!
 72## About
 73Welcome to an ultra-lightweight platform for making and sharing small websites. You can get started by editing this page -- remove this content and replace it with whatever you like! It will be live at <your-name>.flounder.online. You can go there right now to see what this page currently looks like. Here is a link to a page which will give you more information about using flounder:
 74=> //admin.flounder.online
 75
 76And here's a guide to the text format that Flounder uses to create pages, Gemini. These pages are converted into HTML so they can be displayed in a web browser.
 77=> //admin.flounder.online/gemini_text_guide.gmi
 78
 79Have fun!`
 80	// Redundant filepath.Clean call just in case.
 81	username = filepath.Clean(username)
 82	os.Mkdir(path.Join(c.FilesDirectory, username), os.ModePerm)
 83	ioutil.WriteFile(path.Join(c.FilesDirectory, username, "index.gmi"), []byte(baseIndex), 0644)
 84	os.Mkdir(path.Join(c.FilesDirectory, username), os.ModePerm)
 85	return nil
 86}
 87
 88func renameUser(oldUsername string, newUsername string) error {
 89	err := isOkUsername(newUsername)
 90	if err != nil {
 91		return err
 92	}
 93	res, err := DB.Exec("UPDATE user set username = ? WHERE username = ?", newUsername, oldUsername)
 94	if err != nil {
 95		return err
 96	}
 97	rowsAffected, err := res.RowsAffected()
 98	if rowsAffected != 1 {
 99		return fmt.Errorf("No User updated %s %s", oldUsername, newUsername)
100	} else if err != nil {
101		return err
102	}
103	userFolder := path.Join(c.FilesDirectory, oldUsername)
104	newUserFolder := path.Join(c.FilesDirectory, newUsername)
105	err = os.Rename(userFolder, newUserFolder)
106	if err != nil {
107		// This would be bad. User in broken, insecure state.
108		// TODO some sort of better handling?
109		return err
110	}
111	log.Printf("Changed username from %s to %s", oldUsername, newUsername)
112	return nil
113}
114
115func deleteUser(username string) error {
116	_, err := DB.Exec("DELETE FROM user WHERE username = $1", username)
117	if err != nil {
118		return err
119	}
120	username = filepath.Clean(username)
121	err = os.RemoveAll(path.Join(c.FilesDirectory, username))
122	if err != nil {
123		// bad state
124		return err
125	}
126	log.Println("Deleted user", username)
127	return nil
128}