cli.go

  1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
  2//
  3// SPDX-License-Identifier: Apache-2.0
  4
  5package main
  6
  7import (
  8	"database/sql"
  9	"fmt"
 10	"os"
 11	"syscall"
 12
 13	"git.sr.ht/~amolith/willow/users"
 14	"github.com/microcosm-cc/bluemonday"
 15	"golang.org/x/term"
 16)
 17
 18var bmStrict = bluemonday.StrictPolicy()
 19
 20// createUser is a CLI that creates a new user with the specified username.
 21func createUser(dbConn *sql.DB, username string) {
 22	fmt.Println("Creating user", username)
 23
 24	fmt.Print("Enter password: ")
 25	password, err := term.ReadPassword(syscall.Stdin)
 26	if err != nil {
 27		fmt.Println("Error reading password:", err)
 28		os.Exit(1)
 29	}
 30	fmt.Println()
 31
 32	fmt.Print("Confirm password: ")
 33	passwordConfirmation, err := term.ReadPassword(syscall.Stdin)
 34	if err != nil {
 35		fmt.Println("Error reading password confirmation:", err)
 36		os.Exit(1)
 37	}
 38	fmt.Println()
 39
 40	if string(password) != string(passwordConfirmation) {
 41		fmt.Println("Passwords do not match")
 42		os.Exit(1)
 43	}
 44
 45	// Both frontend and backend need to sanitise the
 46	// password the same way. This feel like a code
 47	// smell; user creation should all be in the user
 48	// package and the cli and frontend and API and
 49	// everything should use that.
 50	//
 51	// TODO: Abstract this
 52	sanitisedPassword := bmStrict.Sanitize(string(password))
 53	err = users.Register(dbConn, username, sanitisedPassword)
 54	if err != nil {
 55		fmt.Println("Error creating user:", err)
 56		os.Exit(1)
 57	}
 58
 59	fmt.Println("\nUser", username, "created successfully")
 60	os.Exit(0)
 61}
 62
 63// deleteUser is a CLI that deletes a user with the specified username.
 64func deleteUser(dbConn *sql.DB, username string) {
 65	fmt.Println("Deleting user", username)
 66	err := users.Delete(dbConn, username)
 67	if err != nil {
 68		fmt.Println("Error deleting user:", err)
 69		os.Exit(1)
 70	}
 71
 72	fmt.Printf("User %s deleted successfully\n", username)
 73	os.Exit(0)
 74}
 75
 76// listUsers is a CLI that lists all users in the database.
 77func listUsers(dbConn *sql.DB) {
 78	fmt.Println("Listing all users")
 79
 80	dbUsers, err := users.GetUsers(dbConn)
 81	if err != nil {
 82		fmt.Println("Error retrieving users from the database:", err)
 83		os.Exit(1)
 84	}
 85
 86	if len(dbUsers) == 0 {
 87		fmt.Println("- No users found")
 88	} else {
 89		for _, u := range dbUsers {
 90			fmt.Println("-", u)
 91		}
 92	}
 93	os.Exit(0)
 94}
 95
 96// checkAuthorised is a CLI that checks whether the provided user/password
 97// combo is authorised.
 98func checkAuthorised(dbConn *sql.DB, username string) {
 99	fmt.Printf("Checking whether password for user %s is correct\n", username)
100
101	fmt.Print("Enter password: ")
102	password, err := term.ReadPassword(syscall.Stdin)
103	if err != nil {
104		fmt.Println("Error reading password:", err)
105		os.Exit(1)
106	}
107	fmt.Println()
108
109	// TODO: Abstract this, refer to note in createUser()
110	sanitisedPassword := bmStrict.Sanitize(string(password))
111	authorised, err := users.UserAuthorised(dbConn, username, sanitisedPassword)
112	if err != nil {
113		fmt.Println("Error checking authorisation:", err)
114		os.Exit(1)
115	}
116
117	if authorised {
118		fmt.Println("User is authorised")
119	} else {
120		fmt.Println("User is not authorised")
121	}
122	os.Exit(0)
123}