-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathadmin.go
127 lines (113 loc) · 2.8 KB
/
admin.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package main
import (
"errors"
"net/http"
"net/url"
"strings"
)
type userData struct {
indexData
Users *[]string
}
func (u *userData) AddError(err string) {
u.Errors = append(u.Errors, err)
}
// Handler for GET and POST /admin
func (app *App) adminHandler(w http.ResponseWriter, r *http.Request) {
if authDisabled {
http.Error(w, "Admin interface not available when authentication is disabled.", http.StatusNotImplemented)
return
}
var user User
session, err := store.Get(r, "user")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if _, ok := session.Values["user"]; !ok {
data := indexData{URI: r.RequestURI}
if flash := session.Flashes("unauth_flash"); len(flash) > 0 {
data.NotAuth = flash[0].(string)
w.WriteHeader(http.StatusUnauthorized)
session.Save(r, w)
}
tmpl.ExecuteTemplate(w, "index", data)
return
}
v := session.Values["user"]
switch v := v.(type) {
case string:
user.Email = v
case User:
user = v
}
users, err := app.db.LoadUsers()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
data := userData{
indexData: indexData{Authenticated: true, User: user},
Users: &users,
}
// Handle deleting and adding users
if r.Method == "POST" {
err := r.ParseForm()
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
f := r.Form
err = app.adminFormProcess(f, user, users)
switch {
case err == errUserExists:
data.AddError(userExists)
w.WriteHeader(http.StatusBadRequest)
case err == errSelfDeletion:
data.AddError(selfDeletion)
w.WriteHeader(http.StatusBadRequest)
case err != nil:
http.Error(w, err.Error(), http.StatusInternalServerError)
return
case err == nil:
// Reload the list of users
users, err = app.db.LoadUsers()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
}
tmpl.ExecuteTemplate(w, "admin", data)
}
var (
userExists = "User already exists"
selfDeletion = "You can't delete yourself"
errUserExists = errors.New(strings.ToLower(userExists))
errSelfDeletion = errors.New(strings.ToLower(selfDeletion))
)
func (app *App) adminFormProcess(f url.Values, user User, users []string) error {
if add := f.Get("add_email"); add != "" {
// Check if the address already exists as a user
for _, u := range users {
if u == add {
return errUserExists
}
}
if err := app.db.SaveUser(add); err != nil {
return err
}
app.audit(user.Email, "add_user", add)
}
if delete := f.Get("delete_email"); delete != "" {
// Ensure the user isn't trying to delete themselves
if user.Email == delete {
return errSelfDeletion
}
if err := app.db.DeleteUser(delete); err != nil {
return err
}
app.audit(user.Email, "delete_user", delete)
}
return nil
}