Implement adding users from UI

This commit is contained in:
Anders Pitman 2020-10-12 19:51:13 -06:00
parent 238b66fb9b
commit d3b25d5c38
3 changed files with 126 additions and 0 deletions

View File

@ -2,6 +2,7 @@ package main
import (
"encoding/json"
"errors"
"io/ioutil"
"log"
"sync"
@ -10,6 +11,7 @@ import (
type Database struct {
Tokens map[string]TokenData `json:"tokens"`
Tunnels map[string]Tunnel `json:"tunnels"`
Users map[string]User `json:"users"`
mutex *sync.Mutex
}
@ -56,6 +58,10 @@ func NewDatabase() (*Database, error) {
db.Tunnels = make(map[string]Tunnel)
}
if db.Users == nil {
db.Users = make(map[string]User)
}
db.mutex = &sync.Mutex{}
db.mutex.Lock()
@ -129,6 +135,38 @@ func (d *Database) DeleteTunnel(domain string) {
d.persist()
}
func (d *Database) GetUsers() map[string]User {
d.mutex.Lock()
defer d.mutex.Unlock()
users := make(map[string]User)
for k, v := range d.Users {
users[k] = v
}
return users
}
func (d *Database) AddUser(username string, isAdmin bool) error {
d.mutex.Lock()
defer d.mutex.Unlock()
_, exists := d.Users[username]
if exists {
return errors.New("User exists")
}
d.Users[username] = User{
isAdmin,
}
d.persist()
return nil
}
func (d *Database) persist() {
saveJson(d, "boringproxy_db.json")
}

33
webui/users.tmpl Normal file
View File

@ -0,0 +1,33 @@
<!doctype html>
<html>
<head>
{{.Head}}
</head>
<body>
<main>
<label id='menu-label' for='menu-toggle'>Menu</label>
<input type='checkbox' id='menu-toggle'/>
<div class='menu'>
<a class='menu-item' href='/'>Tunnels</a>
<a class='menu-item' href='/users'>Users</a>
</div>
<div class='list'>
{{range $username, $user := .Users}}
<div class='list-item'>
{{$username}}
</div>
{{end}}
</div>
<div class='user-adder'>
<form action="/users" method="POST">
<label for="username">Username:</label>
<input type="text" id="username" name="username">
<label for="is-admin">Is Admin:</label>
<input type="checkbox" id="is-admin" name="is-admin">
<button class='button green-button' type="submit">Add User</button>
</form>
</div>
</main>
</body>
</html>

View File

@ -1,6 +1,7 @@
package main
import (
"errors"
"fmt"
"github.com/GeertJohan/go.rice"
"html/template"
@ -40,6 +41,11 @@ type HeadData struct {
Styles template.CSS
}
type UsersData struct {
Head template.HTML
Users map[string]User
}
func NewWebUiHandler(config *BoringProxyConfig, db *Database, auth *Auth, tunMan *TunnelManager) *WebUiHandler {
return &WebUiHandler{
config: config,
@ -303,4 +309,53 @@ func (h *WebUiHandler) sendLoginPage(w http.ResponseWriter, r *http.Request, cod
}
func (h *WebUiHandler) users(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
r.ParseForm()
if len(r.Form["username"]) != 1 {
w.WriteHeader(400)
w.Write([]byte("Invalid username parameter"))
return
}
username := r.Form["username"][0]
isAdmin := len(r.Form["is-admin"]) == 1 && r.Form["is-admin"][0] == "on"
err := h.db.AddUser(username, isAdmin)
if err != nil {
w.WriteHeader(500)
io.WriteString(w, err.Error())
return
}
http.Redirect(w, r, "/users", 303)
}
tmpl, err := h.loadTemplate("users.tmpl")
if err != nil {
w.WriteHeader(500)
io.WriteString(w, err.Error())
return
}
tmpl.Execute(w, UsersData{
Head: h.headHtml,
Users: h.db.GetUsers(),
})
}
func (h *WebUiHandler) loadTemplate(name string) (*template.Template, error) {
tmplStr, err := h.box.String(name)
if err != nil {
return nil, errors.New("Error reading template " + name)
}
tmpl, err := template.New(name).Parse(tmplStr)
if err != nil {
return nil, errors.New("Error compiling template " + name)
}
return tmpl, nil
}