mirror of
https://github.com/boringproxy/boringproxy.git
synced 2025-02-25 18:55:29 -06:00
Implement adding users from UI
This commit is contained in:
parent
238b66fb9b
commit
d3b25d5c38
38
database.go
38
database.go
@ -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
33
webui/users.tmpl
Normal 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>
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user