Goit

Simple and lightweight Git web server
git clone http://git.omkov.net/Goit
Log | Tree | Refs | README | Download

Goit/src/admin/users.go (214 lines, 5.6 KiB) -rw-r--r-- file download

c2c5250 Jakob Wakeling 2023-12-12 09:13:37
0
// Copyright (C) 2023, Jakob Wakeling
c2c5250 Jakob Wakeling 2023-12-12 09:13:37
1
// All rights reserved.
c2c5250 Jakob Wakeling 2023-12-12 09:13:37
2
463cf58 Jakob Wakeling 2023-11-22 23:25:37
3
package admin
463cf58 Jakob Wakeling 2023-11-22 23:25:37
4
463cf58 Jakob Wakeling 2023-11-22 23:25:37
5
import (
463cf58 Jakob Wakeling 2023-11-22 23:25:37
6
	"fmt"
b804701 Jakob Wakeling 2023-11-27 23:52:28
7
	"html/template"
463cf58 Jakob Wakeling 2023-11-22 23:25:37
8
	"log"
463cf58 Jakob Wakeling 2023-11-22 23:25:37
9
	"net/http"
463cf58 Jakob Wakeling 2023-11-22 23:25:37
10
	"slices"
463cf58 Jakob Wakeling 2023-11-22 23:25:37
11
	"strconv"
463cf58 Jakob Wakeling 2023-11-22 23:25:37
12
	"strings"
463cf58 Jakob Wakeling 2023-11-22 23:25:37
13
463cf58 Jakob Wakeling 2023-11-22 23:25:37
14
	"github.com/Jamozed/Goit/src/goit"
463cf58 Jakob Wakeling 2023-11-22 23:25:37
15
	"github.com/Jamozed/Goit/src/util"
b804701 Jakob Wakeling 2023-11-27 23:52:28
16
	"github.com/gorilla/csrf"
463cf58 Jakob Wakeling 2023-11-22 23:25:37
17
)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
18
463cf58 Jakob Wakeling 2023-11-22 23:25:37
19
func HandleUsers(w http.ResponseWriter, r *http.Request) {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
20
	auth, user, err := goit.Auth(w, r, true)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
21
	if err != nil {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
22
		log.Println("[admin/users]", err.Error())
463cf58 Jakob Wakeling 2023-11-22 23:25:37
23
		goit.HttpError(w, http.StatusInternalServerError)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
24
		return
463cf58 Jakob Wakeling 2023-11-22 23:25:37
25
	}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
26
463cf58 Jakob Wakeling 2023-11-22 23:25:37
27
	if !auth || !user.IsAdmin {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
28
		goit.HttpError(w, http.StatusNotFound)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
29
		return
463cf58 Jakob Wakeling 2023-11-22 23:25:37
30
	}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
31
463cf58 Jakob Wakeling 2023-11-22 23:25:37
32
	type row struct{ Id, Name, FullName, IsAdmin string }
463cf58 Jakob Wakeling 2023-11-22 23:25:37
33
	data := struct {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
34
		Title string
463cf58 Jakob Wakeling 2023-11-22 23:25:37
35
		Users []row
463cf58 Jakob Wakeling 2023-11-22 23:25:37
36
	}{Title: "Admin - Users"}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
37
463cf58 Jakob Wakeling 2023-11-22 23:25:37
38
	users, err := goit.GetUsers()
463cf58 Jakob Wakeling 2023-11-22 23:25:37
39
	if err != nil {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
40
		log.Println("[admin/users]", err.Error())
463cf58 Jakob Wakeling 2023-11-22 23:25:37
41
		goit.HttpError(w, http.StatusInternalServerError)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
42
		return
463cf58 Jakob Wakeling 2023-11-22 23:25:37
43
	}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
44
463cf58 Jakob Wakeling 2023-11-22 23:25:37
45
	for _, u := range users {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
46
		data.Users = append(data.Users, row{
463cf58 Jakob Wakeling 2023-11-22 23:25:37
47
			fmt.Sprint(u.Id), u.Name, u.FullName, util.If(u.IsAdmin, "true", "false"),
463cf58 Jakob Wakeling 2023-11-22 23:25:37
48
		})
463cf58 Jakob Wakeling 2023-11-22 23:25:37
49
	}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
50
463cf58 Jakob Wakeling 2023-11-22 23:25:37
51
	if err := goit.Tmpl.ExecuteTemplate(w, "admin/users", data); err != nil {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
52
		log.Println("[/admin/users]", err.Error())
463cf58 Jakob Wakeling 2023-11-22 23:25:37
53
	}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
54
}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
55
463cf58 Jakob Wakeling 2023-11-22 23:25:37
56
func HandleUserCreate(w http.ResponseWriter, r *http.Request) {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
57
	auth, user, err := goit.Auth(w, r, true)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
58
	if err != nil {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
59
		log.Println("[admin/users]", err.Error())
463cf58 Jakob Wakeling 2023-11-22 23:25:37
60
		goit.HttpError(w, http.StatusInternalServerError)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
61
		return
463cf58 Jakob Wakeling 2023-11-22 23:25:37
62
	}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
63
463cf58 Jakob Wakeling 2023-11-22 23:25:37
64
	if !auth || !user.IsAdmin {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
65
		goit.HttpError(w, http.StatusNotFound)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
66
		return
463cf58 Jakob Wakeling 2023-11-22 23:25:37
67
	}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
68
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
69
	data := struct {
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
70
		Title, Message string
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
71
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
72
		Form struct {
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
73
			Name, FullName string
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
74
			IsAdmin        bool
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
75
		}
b804701 Jakob Wakeling 2023-11-27 23:52:28
76
b804701 Jakob Wakeling 2023-11-27 23:52:28
77
		CsrfField template.HTML
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
78
	}{
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
79
		Title: "Admin - Create User",
b804701 Jakob Wakeling 2023-11-27 23:52:28
80
b804701 Jakob Wakeling 2023-11-27 23:52:28
81
		CsrfField: csrf.TemplateField(r),
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
82
	}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
83
463cf58 Jakob Wakeling 2023-11-22 23:25:37
84
	if r.Method == http.MethodPost {
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
85
		data.Form.Name = strings.ToLower(r.FormValue("username"))
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
86
		data.Form.FullName = r.FormValue("fullname")
463cf58 Jakob Wakeling 2023-11-22 23:25:37
87
		password := r.FormValue("password")
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
88
		data.Form.IsAdmin = r.FormValue("admin") == "true"
463cf58 Jakob Wakeling 2023-11-22 23:25:37
89
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
90
		if data.Form.Name == "" {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
91
			data.Message = "Username cannot be empty"
efb68c3 Jakob Wakeling 2023-12-06 20:37:06
92
		} else if slices.Contains(goit.Reserved, data.Form.Name) || !goit.IsLegal(data.Form.Name) {
efb68c3 Jakob Wakeling 2023-12-06 20:37:06
93
			data.Message = "Username \"" + data.Form.Name + "\" is illegal"
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
94
		} else if exists, err := goit.UserExists(data.Form.Name); err != nil {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
95
			log.Println("[/admin/user/create]", err.Error())
463cf58 Jakob Wakeling 2023-11-22 23:25:37
96
			goit.HttpError(w, http.StatusInternalServerError)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
97
			return
463cf58 Jakob Wakeling 2023-11-22 23:25:37
98
		} else if exists {
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
99
			data.Message = "Username \"" + data.Form.Name + "\" is taken"
463cf58 Jakob Wakeling 2023-11-22 23:25:37
100
		} else if salt, err := goit.Salt(); err != nil {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
101
			log.Println("[/admin/user/create]", err.Error())
463cf58 Jakob Wakeling 2023-11-22 23:25:37
102
			goit.HttpError(w, http.StatusInternalServerError)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
103
			return
463cf58 Jakob Wakeling 2023-11-22 23:25:37
104
		} else if err := goit.CreateUser(goit.User{
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
105
			Name: data.Form.Name, FullName: data.Form.FullName, Pass: goit.Hash(password, salt), PassAlgo: "argon2",
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
106
			Salt: salt, IsAdmin: data.Form.IsAdmin,
463cf58 Jakob Wakeling 2023-11-22 23:25:37
107
		}); err != nil {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
108
			log.Println("[/admin/user/create]", err.Error())
463cf58 Jakob Wakeling 2023-11-22 23:25:37
109
			goit.HttpError(w, http.StatusInternalServerError)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
110
			return
463cf58 Jakob Wakeling 2023-11-22 23:25:37
111
		} else {
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
112
			// data.Message = "User \"" + data.Form.Name + "\" created successfully"
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
113
			http.Redirect(w, r, "/admin/users", http.StatusFound)
e3bf6a7 Jakob Wakeling 2023-11-22 23:38:17
114
			return
463cf58 Jakob Wakeling 2023-11-22 23:25:37
115
		}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
116
	}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
117
463cf58 Jakob Wakeling 2023-11-22 23:25:37
118
	if err := goit.Tmpl.ExecuteTemplate(w, "admin/user/create", data); err != nil {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
119
		log.Println("[/admin/user/create]", err.Error())
463cf58 Jakob Wakeling 2023-11-22 23:25:37
120
	}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
121
}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
122
463cf58 Jakob Wakeling 2023-11-22 23:25:37
123
func HandleUserEdit(w http.ResponseWriter, r *http.Request) {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
124
	auth, user, err := goit.Auth(w, r, true)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
125
	if err != nil {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
126
		log.Println("[admin/users]", err.Error())
463cf58 Jakob Wakeling 2023-11-22 23:25:37
127
		goit.HttpError(w, http.StatusInternalServerError)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
128
		return
463cf58 Jakob Wakeling 2023-11-22 23:25:37
129
	}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
130
463cf58 Jakob Wakeling 2023-11-22 23:25:37
131
	if !auth || !user.IsAdmin {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
132
		goit.HttpError(w, http.StatusNotFound)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
133
		return
463cf58 Jakob Wakeling 2023-11-22 23:25:37
134
	}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
135
463cf58 Jakob Wakeling 2023-11-22 23:25:37
136
	uid, err := strconv.ParseInt(r.URL.Query().Get("user"), 10, 64)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
137
	if err != nil {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
138
		goit.HttpError(w, http.StatusNotFound)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
139
		return
463cf58 Jakob Wakeling 2023-11-22 23:25:37
140
	}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
141
463cf58 Jakob Wakeling 2023-11-22 23:25:37
142
	u, err := goit.GetUser(uid)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
143
	if err != nil {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
144
		log.Println("[/admin/user/edit]", err.Error())
463cf58 Jakob Wakeling 2023-11-22 23:25:37
145
		goit.HttpError(w, http.StatusInternalServerError)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
146
		return
463cf58 Jakob Wakeling 2023-11-22 23:25:37
147
	} else if u == nil {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
148
		goit.HttpError(w, http.StatusNotFound)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
149
		return
463cf58 Jakob Wakeling 2023-11-22 23:25:37
150
	}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
151
463cf58 Jakob Wakeling 2023-11-22 23:25:37
152
	data := struct {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
153
		Title, Message string
463cf58 Jakob Wakeling 2023-11-22 23:25:37
154
463cf58 Jakob Wakeling 2023-11-22 23:25:37
155
		Form struct {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
156
			Id, Name, FullName string
463cf58 Jakob Wakeling 2023-11-22 23:25:37
157
			IsAdmin            bool
463cf58 Jakob Wakeling 2023-11-22 23:25:37
158
		}
b804701 Jakob Wakeling 2023-11-27 23:52:28
159
b804701 Jakob Wakeling 2023-11-27 23:52:28
160
		CsrfField template.HTML
463cf58 Jakob Wakeling 2023-11-22 23:25:37
161
	}{
463cf58 Jakob Wakeling 2023-11-22 23:25:37
162
		Title: "Admin - Edit User",
b804701 Jakob Wakeling 2023-11-27 23:52:28
163
b804701 Jakob Wakeling 2023-11-27 23:52:28
164
		CsrfField: csrf.TemplateField(r),
463cf58 Jakob Wakeling 2023-11-22 23:25:37
165
	}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
166
463cf58 Jakob Wakeling 2023-11-22 23:25:37
167
	data.Form.Id = fmt.Sprint(u.Id)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
168
	data.Form.Name = u.Name
463cf58 Jakob Wakeling 2023-11-22 23:25:37
169
	data.Form.FullName = u.FullName
463cf58 Jakob Wakeling 2023-11-22 23:25:37
170
	data.Form.IsAdmin = u.IsAdmin
463cf58 Jakob Wakeling 2023-11-22 23:25:37
171
463cf58 Jakob Wakeling 2023-11-22 23:25:37
172
	if r.Method == http.MethodPost {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
173
		data.Form.Name = strings.ToLower(r.FormValue("username"))
463cf58 Jakob Wakeling 2023-11-22 23:25:37
174
		data.Form.FullName = r.FormValue("fullname")
463cf58 Jakob Wakeling 2023-11-22 23:25:37
175
		password := r.FormValue("password")
463cf58 Jakob Wakeling 2023-11-22 23:25:37
176
		data.Form.IsAdmin = r.FormValue("admin") == "true"
463cf58 Jakob Wakeling 2023-11-22 23:25:37
177
463cf58 Jakob Wakeling 2023-11-22 23:25:37
178
		if data.Form.Name == "" {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
179
			data.Message = "Username cannot be empty"
efb68c3 Jakob Wakeling 2023-12-06 20:37:06
180
		} else if slices.Contains(goit.Reserved, data.Form.Name) && user.Id != 0 || !goit.IsLegal(data.Form.Name) {
efb68c3 Jakob Wakeling 2023-12-06 20:37:06
181
			data.Message = "Username \"" + data.Form.Name + "\" is illegal"
463cf58 Jakob Wakeling 2023-11-22 23:25:37
182
		} else if exists, err := goit.UserExists(data.Form.Name); err != nil {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
183
			log.Println("[/admin/user/edit]", err.Error())
463cf58 Jakob Wakeling 2023-11-22 23:25:37
184
			goit.HttpError(w, http.StatusInternalServerError)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
185
			return
463cf58 Jakob Wakeling 2023-11-22 23:25:37
186
		} else if exists && data.Form.Name != u.Name {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
187
			data.Message = "Username \"" + data.Form.Name + "\" is taken"
463cf58 Jakob Wakeling 2023-11-22 23:25:37
188
		} else {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
189
			if err := goit.UpdateUser(u.Id, goit.User{
463cf58 Jakob Wakeling 2023-11-22 23:25:37
190
				Name: data.Form.Name, FullName: data.Form.FullName, IsAdmin: data.Form.IsAdmin,
463cf58 Jakob Wakeling 2023-11-22 23:25:37
191
			}); err != nil {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
192
				log.Println("[/admin/user/edit]", err.Error())
463cf58 Jakob Wakeling 2023-11-22 23:25:37
193
				goit.HttpError(w, http.StatusInternalServerError)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
194
				return
463cf58 Jakob Wakeling 2023-11-22 23:25:37
195
			}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
196
463cf58 Jakob Wakeling 2023-11-22 23:25:37
197
			if password != "" {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
198
				if err := goit.UpdatePassword(u.Id, password); err != nil {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
199
					log.Println("[/admin/user/edit]", err.Error())
463cf58 Jakob Wakeling 2023-11-22 23:25:37
200
					goit.HttpError(w, http.StatusInternalServerError)
463cf58 Jakob Wakeling 2023-11-22 23:25:37
201
					return
463cf58 Jakob Wakeling 2023-11-22 23:25:37
202
				}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
203
			}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
204
463cf58 Jakob Wakeling 2023-11-22 23:25:37
205
			data.Message = "User \"" + u.Name + "\" updated successfully"
463cf58 Jakob Wakeling 2023-11-22 23:25:37
206
		}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
207
	}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
208
463cf58 Jakob Wakeling 2023-11-22 23:25:37
209
	if err := goit.Tmpl.ExecuteTemplate(w, "admin/user/edit", data); err != nil {
463cf58 Jakob Wakeling 2023-11-22 23:25:37
210
		log.Println("[/admin/user/edit]", err.Error())
463cf58 Jakob Wakeling 2023-11-22 23:25:37
211
	}
463cf58 Jakob Wakeling 2023-11-22 23:25:37
212
}
213