mirror of
https://github.com/boringproxy/boringproxy.git
synced 2025-02-25 18:55:29 -06:00
Implement managing clients through web UI
This commit is contained in:
parent
5ae2b81882
commit
53aa3735a9
31
templates/clients.tmpl
Normal file
31
templates/clients.tmpl
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{{ template "header.tmpl" . }}
|
||||||
|
<div class='list'>
|
||||||
|
{{range $username, $user := .Users}}
|
||||||
|
{{range $clientName, $client := $user.Clients}}
|
||||||
|
|
||||||
|
<div class='list-item'>
|
||||||
|
<span class='client'>{{$clientName}} ({{$username}})</span>
|
||||||
|
<a href="/confirm-delete-client?owner={{$username}}&client-name={{$clientName}}">
|
||||||
|
<button class='button'>Delete</button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='client-adder'>
|
||||||
|
<form action="/clients" method="POST">
|
||||||
|
<label for="client-owner">Owner:</label>
|
||||||
|
<select id="client-owner" name="owner">
|
||||||
|
{{range $username, $user := .Users}}
|
||||||
|
<option value="{{$username}}">{{$username}}</option>
|
||||||
|
{{end}}
|
||||||
|
</select>
|
||||||
|
<label for="client-name">Client Name:</label>
|
||||||
|
<input type="text" name="client-name" required></input>
|
||||||
|
<button class='button' type="submit">Add Client</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ template "footer.tmpl" . }}
|
@ -26,6 +26,7 @@
|
|||||||
<a class='menu-item' href='/tunnels'>Tunnels</a>
|
<a class='menu-item' href='/tunnels'>Tunnels</a>
|
||||||
<a class='menu-item' href='/edit-tunnel'>Add Tunnel</a>
|
<a class='menu-item' href='/edit-tunnel'>Add Tunnel</a>
|
||||||
<a class='menu-item' href='/tokens'>Tokens</a>
|
<a class='menu-item' href='/tokens'>Tokens</a>
|
||||||
|
<a class='menu-item' href='/clients'>Clients</a>
|
||||||
{{ if $.User.IsAdmin }}
|
{{ if $.User.IsAdmin }}
|
||||||
<a class='menu-item' href='/users'>Users</a>
|
<a class='menu-item' href='/users'>Users</a>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
105
ui_handler.go
105
ui_handler.go
@ -235,10 +235,16 @@ func (h *WebUiHandler) handleWebUiRequest(w http.ResponseWriter, r *http.Request
|
|||||||
}
|
}
|
||||||
case "/tokens":
|
case "/tokens":
|
||||||
h.handleTokens(w, r, user, tokenData)
|
h.handleTokens(w, r, user, tokenData)
|
||||||
|
case "/clients":
|
||||||
|
h.handleClients(w, r, user, tokenData)
|
||||||
case "/confirm-delete-token":
|
case "/confirm-delete-token":
|
||||||
h.confirmDeleteToken(w, r)
|
h.confirmDeleteToken(w, r)
|
||||||
case "/delete-token":
|
case "/delete-token":
|
||||||
h.deleteToken(w, r, tokenData)
|
h.deleteToken(w, r, tokenData)
|
||||||
|
case "/confirm-delete-client":
|
||||||
|
h.confirmDeleteClient(w, r)
|
||||||
|
case "/delete-client":
|
||||||
|
h.deleteClient(w, r, tokenData)
|
||||||
case "/confirm-logout":
|
case "/confirm-logout":
|
||||||
|
|
||||||
data := &ConfirmData{
|
data := &ConfirmData{
|
||||||
@ -402,6 +408,66 @@ func (h *WebUiHandler) handleTokens(w http.ResponseWriter, r *http.Request, user
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *WebUiHandler) handleClients(w http.ResponseWriter, r *http.Request, user User, tokenData TokenData) {
|
||||||
|
|
||||||
|
r.ParseForm()
|
||||||
|
|
||||||
|
switch r.Method {
|
||||||
|
case "GET":
|
||||||
|
var users map[string]User
|
||||||
|
|
||||||
|
// TODO: handle security checks in api
|
||||||
|
if user.IsAdmin {
|
||||||
|
users = h.db.GetUsers()
|
||||||
|
} else {
|
||||||
|
user, _ := h.db.GetUser(tokenData.Owner)
|
||||||
|
users = make(map[string]User)
|
||||||
|
users[tokenData.Owner] = user
|
||||||
|
}
|
||||||
|
|
||||||
|
clients := make(map[string]DbClient)
|
||||||
|
|
||||||
|
for _, user := range users {
|
||||||
|
for clientName, client := range user.Clients {
|
||||||
|
clients[clientName] = client
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
templateData := struct {
|
||||||
|
User User
|
||||||
|
Users map[string]User
|
||||||
|
Clients map[string]DbClient
|
||||||
|
}{
|
||||||
|
User: user,
|
||||||
|
Users: users,
|
||||||
|
Clients: clients,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := h.tmpl.ExecuteTemplate(w, "clients.tmpl", templateData)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(500)
|
||||||
|
io.WriteString(w, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case "POST":
|
||||||
|
|
||||||
|
owner := r.Form.Get("owner")
|
||||||
|
clientName := r.Form.Get("client-name")
|
||||||
|
|
||||||
|
err := h.api.SetClient(tokenData, r.Form, owner, clientName)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(500)
|
||||||
|
h.alertDialog(w, r, err.Error(), "/clients")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
http.Redirect(w, r, "/clients", 303)
|
||||||
|
default:
|
||||||
|
w.WriteHeader(405)
|
||||||
|
h.alertDialog(w, r, "Invalid method for tokens", "/tokens")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
func (h *WebUiHandler) handleLogin(w http.ResponseWriter, r *http.Request) {
|
func (h *WebUiHandler) handleLogin(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
if r.Method != "GET" {
|
if r.Method != "GET" {
|
||||||
@ -646,7 +712,6 @@ func (h *WebUiHandler) confirmDeleteToken(w http.ResponseWriter, r *http.Request
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *WebUiHandler) deleteToken(w http.ResponseWriter, r *http.Request, tokenData TokenData) {
|
func (h *WebUiHandler) deleteToken(w http.ResponseWriter, r *http.Request, tokenData TokenData) {
|
||||||
|
|
||||||
r.ParseForm()
|
r.ParseForm()
|
||||||
@ -660,6 +725,44 @@ func (h *WebUiHandler) deleteToken(w http.ResponseWriter, r *http.Request, token
|
|||||||
http.Redirect(w, r, "/tokens", 303)
|
http.Redirect(w, r, "/tokens", 303)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *WebUiHandler) confirmDeleteClient(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
r.ParseForm()
|
||||||
|
|
||||||
|
owner := r.Form.Get("owner")
|
||||||
|
clientName := r.Form.Get("client-name")
|
||||||
|
|
||||||
|
data := &ConfirmData{
|
||||||
|
Head: h.headHtml,
|
||||||
|
Message: fmt.Sprintf("Are you sure you want to delete client %s for user %s?", clientName, owner),
|
||||||
|
ConfirmUrl: fmt.Sprintf("/delete-client?owner=%s&client-name=%s", owner, clientName),
|
||||||
|
CancelUrl: "/clients",
|
||||||
|
}
|
||||||
|
|
||||||
|
err := h.tmpl.ExecuteTemplate(w, "confirm.tmpl", data)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(500)
|
||||||
|
h.alertDialog(w, r, err.Error(), "/clients")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (h *WebUiHandler) deleteClient(w http.ResponseWriter, r *http.Request, tokenData TokenData) {
|
||||||
|
|
||||||
|
r.ParseForm()
|
||||||
|
|
||||||
|
owner := r.Form.Get("owner")
|
||||||
|
clientName := r.Form.Get("client-name")
|
||||||
|
|
||||||
|
err := h.api.DeleteClient(tokenData, owner, clientName)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(500)
|
||||||
|
h.alertDialog(w, r, err.Error(), "/clients")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
http.Redirect(w, r, "/clients", 303)
|
||||||
|
}
|
||||||
|
|
||||||
func (h *WebUiHandler) alertDialog(w http.ResponseWriter, r *http.Request, message, redirectUrl string) error {
|
func (h *WebUiHandler) alertDialog(w http.ResponseWriter, r *http.Request, message, redirectUrl string) error {
|
||||||
err := h.tmpl.ExecuteTemplate(w, "alert.tmpl", &AlertData{
|
err := h.tmpl.ExecuteTemplate(w, "alert.tmpl", &AlertData{
|
||||||
Head: h.headHtml,
|
Head: h.headHtml,
|
||||||
|
Loading…
Reference in New Issue
Block a user