mirror of
https://github.com/boringproxy/boringproxy.git
synced 2025-02-25 18:55:29 -06:00
Implement managing domains
This commit is contained in:
parent
1832e99e22
commit
4d8b9aeaae
57
api.go
57
api.go
@ -580,3 +580,60 @@ func (a *Api) DeleteClient(tokenData TokenData, ownerId, clientId string) error
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Api) GetDomains(tokenData TokenData) map[string]Domain {
|
||||
|
||||
user, _ := a.db.GetUser(tokenData.Owner)
|
||||
|
||||
var domains map[string]Domain
|
||||
|
||||
if user.IsAdmin {
|
||||
domains = a.db.GetDomains()
|
||||
} else {
|
||||
domains = make(map[string]Domain)
|
||||
|
||||
for name, domain := range a.db.GetDomains() {
|
||||
if tokenData.Owner == domain.Owner {
|
||||
domains[name] = domain
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return domains
|
||||
}
|
||||
func (a *Api) SetDomain(tokenData TokenData, params url.Values, domain, ownerId string) error {
|
||||
|
||||
if tokenData.Owner != ownerId {
|
||||
user, _ := a.db.GetUser(tokenData.Owner)
|
||||
if !user.IsAdmin {
|
||||
return errors.New("Unauthorized")
|
||||
}
|
||||
}
|
||||
|
||||
err := a.db.AddDomain(domain, ownerId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func (a *Api) DeleteDomain(tokenData TokenData, domainName string) error {
|
||||
|
||||
domains := a.db.GetDomains()
|
||||
|
||||
domain, exists := domains[domainName]
|
||||
if !exists {
|
||||
return errors.New("No such domain")
|
||||
}
|
||||
|
||||
if tokenData.Owner != domain.Owner {
|
||||
user, _ := a.db.GetUser(tokenData.Owner)
|
||||
if !user.IsAdmin {
|
||||
return errors.New("Unauthorized")
|
||||
}
|
||||
}
|
||||
|
||||
a.db.DeleteDomain(domainName)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
50
database.go
50
database.go
@ -18,6 +18,7 @@ type Database struct {
|
||||
Tokens map[string]TokenData `json:"tokens"`
|
||||
Tunnels map[string]Tunnel `json:"tunnels"`
|
||||
Users map[string]User `json:"users"`
|
||||
Domains map[string]Domain `json:"domains"`
|
||||
dnsRequests map[string]namedrop.DNSRequest `json:"dns_requests"`
|
||||
Waygates map[string]waygate.Waygate `json:"waygates"`
|
||||
WaygateTokens map[string]waygate.TokenData `json:"waygate_tokens"`
|
||||
@ -35,6 +36,10 @@ type User struct {
|
||||
Clients map[string]DbClient `json:"clients"`
|
||||
}
|
||||
|
||||
type Domain struct {
|
||||
Owner string `json:"owner"`
|
||||
}
|
||||
|
||||
type DbClient struct {
|
||||
}
|
||||
|
||||
@ -336,6 +341,51 @@ func (d *Database) DeleteUser(username string) {
|
||||
d.persist()
|
||||
}
|
||||
|
||||
func (d *Database) GetDomains() map[string]Domain {
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
|
||||
domains := make(map[string]Domain)
|
||||
|
||||
for k, v := range d.Domains {
|
||||
domains[k] = v
|
||||
}
|
||||
|
||||
return domains
|
||||
}
|
||||
|
||||
func (d *Database) AddDomain(domain, owner string) error {
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
|
||||
_, exists := d.Domains[domain]
|
||||
|
||||
if exists {
|
||||
return errors.New("Domain already taken")
|
||||
}
|
||||
|
||||
_, exists = d.Users[owner]
|
||||
if !exists {
|
||||
return errors.New("No such user")
|
||||
}
|
||||
|
||||
d.Domains[domain] = Domain{
|
||||
Owner: owner,
|
||||
}
|
||||
|
||||
d.persist()
|
||||
|
||||
return nil
|
||||
}
|
||||
func (d *Database) DeleteDomain(domain string) {
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
|
||||
delete(d.Domains, domain)
|
||||
|
||||
d.persist()
|
||||
}
|
||||
|
||||
func (d *Database) AddWaygateTunnel(domains []string) (string, error) {
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
|
29
templates/domains.tmpl
Normal file
29
templates/domains.tmpl
Normal file
@ -0,0 +1,29 @@
|
||||
{{ template "header.tmpl" . }}
|
||||
<div class='list'>
|
||||
{{range $name, $domain := $.Domains}}
|
||||
|
||||
<div class='list-item'>
|
||||
<span class='domain'>{{$name}} (Owner: {{$domain.Owner}})</span>
|
||||
<a href="/confirm-delete-domain?owner={{$domain.Owner}}&domain={{$name}}">
|
||||
<button class='button'>Delete</button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<div class='domain-adder'>
|
||||
<form action="/domains" method="POST">
|
||||
<label for="owner">Owner:</label>
|
||||
<select id="owner" name="owner">
|
||||
{{range $username, $user := $.Users}}
|
||||
<option value="{{$username}}">{{$username}}</option>
|
||||
{{end}}
|
||||
</select>
|
||||
<label for="domain">Domain:</label>
|
||||
<input type="text" name="domain" required></input>
|
||||
<button class='button' type="submit">Add Domain</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{{ template "footer.tmpl" . }}
|
@ -27,6 +27,7 @@
|
||||
<a class='menu-item' href='/edit-tunnel'>Add Tunnel</a>
|
||||
<a class='menu-item' href='/tokens'>Tokens</a>
|
||||
<a class='menu-item' href='/clients'>Clients</a>
|
||||
<a class='menu-item' href='/domains'>Domains</a>
|
||||
{{ if $.User.IsAdmin }}
|
||||
<a class='menu-item' href='/users'>Users</a>
|
||||
{{ end }}
|
||||
|
@ -352,6 +352,8 @@ func (h *WebUiHandler) handleWebUiRequest(w http.ResponseWriter, r *http.Request
|
||||
h.handleTokens(w, r, user, tokenData)
|
||||
case "/clients":
|
||||
h.handleClients(w, r, user, tokenData)
|
||||
case "/domains":
|
||||
h.handleDomains(w, r, user, tokenData)
|
||||
case "/confirm-delete-token":
|
||||
h.confirmDeleteToken(w, r)
|
||||
case "/delete-token":
|
||||
@ -360,6 +362,10 @@ func (h *WebUiHandler) handleWebUiRequest(w http.ResponseWriter, r *http.Request
|
||||
h.confirmDeleteClient(w, r)
|
||||
case "/delete-client":
|
||||
h.deleteClient(w, r, tokenData)
|
||||
case "/confirm-delete-domain":
|
||||
h.confirmDeleteDomain(w, r)
|
||||
case "/delete-domain":
|
||||
h.deleteDomain(w, r, tokenData)
|
||||
case "/confirm-logout":
|
||||
|
||||
data := &ConfirmData{
|
||||
@ -583,6 +589,62 @@ func (h *WebUiHandler) handleClients(w http.ResponseWriter, r *http.Request, use
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (h *WebUiHandler) handleDomains(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
|
||||
}
|
||||
|
||||
domains := h.api.GetDomains(tokenData)
|
||||
|
||||
templateData := struct {
|
||||
User User
|
||||
Users map[string]User
|
||||
Domains map[string]Domain
|
||||
}{
|
||||
User: user,
|
||||
Users: users,
|
||||
Domains: domains,
|
||||
}
|
||||
|
||||
err := h.tmpl.ExecuteTemplate(w, "domains.tmpl", templateData)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
io.WriteString(w, err.Error())
|
||||
return
|
||||
}
|
||||
case "POST":
|
||||
|
||||
owner := r.Form.Get("owner")
|
||||
domain := r.Form.Get("domain")
|
||||
|
||||
err := h.api.SetDomain(tokenData, r.Form, domain, owner)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
h.alertDialog(w, r, err.Error(), "/domains")
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/domains", 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) {
|
||||
|
||||
if r.Method != "GET" {
|
||||
@ -878,6 +940,42 @@ func (h *WebUiHandler) deleteClient(w http.ResponseWriter, r *http.Request, toke
|
||||
http.Redirect(w, r, "/clients", 303)
|
||||
}
|
||||
|
||||
func (h *WebUiHandler) confirmDeleteDomain(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
r.ParseForm()
|
||||
|
||||
domain := r.Form.Get("domain")
|
||||
|
||||
data := &ConfirmData{
|
||||
Head: h.headHtml,
|
||||
Message: fmt.Sprintf("Are you sure you want to delete domain %s?", domain),
|
||||
ConfirmUrl: fmt.Sprintf("/delete-domain?domain=%s", domain),
|
||||
CancelUrl: "/domains",
|
||||
}
|
||||
|
||||
err := h.tmpl.ExecuteTemplate(w, "confirm.tmpl", data)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
h.alertDialog(w, r, err.Error(), "/domains")
|
||||
return
|
||||
}
|
||||
}
|
||||
func (h *WebUiHandler) deleteDomain(w http.ResponseWriter, r *http.Request, tokenData TokenData) {
|
||||
|
||||
r.ParseForm()
|
||||
|
||||
domain := r.Form.Get("domain")
|
||||
|
||||
err := h.api.DeleteDomain(tokenData, domain)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
h.alertDialog(w, r, err.Error(), "/domains")
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/domains", 303)
|
||||
}
|
||||
|
||||
func (h *WebUiHandler) alertDialog(w http.ResponseWriter, r *http.Request, message, redirectUrl string) error {
|
||||
err := h.tmpl.ExecuteTemplate(w, "alert.tmpl", &AlertData{
|
||||
Head: h.headHtml,
|
||||
|
Loading…
Reference in New Issue
Block a user