Skip to content

Commit ee5a98e

Browse files
committed
use bootstrap; rework handlers to improve maintainability
1 parent e607a6f commit ee5a98e

16 files changed

Lines changed: 319 additions & 278 deletions

internal/assets/static/css/bootstrap.min.css.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/assets/static/js/bootstrap.min.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/handler/admin.go

Lines changed: 92 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,36 @@ import (
88
"github.com/KaiserWerk/CertMaker/internal/global"
99
"github.com/KaiserWerk/CertMaker/internal/security"
1010
"github.com/KaiserWerk/CertMaker/internal/templates"
11+
1112
"github.com/gorilla/mux"
1213
)
1314

1415
// AdminSettingsHandler takes care of checking and write system-wide settings
1516
// to the database
1617
func (bh *BaseHandler) AdminSettingsHandler(w http.ResponseWriter, r *http.Request) {
1718
var (
18-
err error
19-
logger = bh.ContextLogger("admin")
19+
template = "admin/settings.gohtml"
20+
logger = bh.ContextLogger("admin")
2021
)
2122

23+
data := struct {
24+
Error string
25+
Success string
26+
User *entity.User
27+
AdminSettings map[string]string
28+
}{
29+
Error: templates.GetErrorMessage(w, r),
30+
Success: templates.GetSuccessMessage(w, r),
31+
}
32+
33+
user, ok := r.Context().Value("user").(*entity.User)
34+
if !ok || user == nil {
35+
http.Redirect(w, r, "/login", http.StatusSeeOther)
36+
return
37+
}
38+
data.User = user
39+
40+
var err error
2241
if r.Method == http.MethodPost {
2342

2443
var errors uint8 = 0
@@ -130,35 +149,44 @@ func (bh *BaseHandler) AdminSettingsHandler(w http.ResponseWriter, r *http.Reque
130149
if err != nil {
131150
logger.Error("could not get all settings: " + err.Error())
132151
}
152+
data.AdminSettings = allSettings
133153

134-
data := struct {
135-
AdminSettings map[string]string
136-
}{
137-
AdminSettings: allSettings,
138-
}
139-
140-
if err := templates.ExecuteTemplate(bh.Inj(), w, "admin/settings.gohtml", data); err != nil {
141-
w.WriteHeader(http.StatusNotFound)
154+
if err := templates.ExecuteTemplate(bh.Inj(), w, template, data); err != nil {
155+
logger.Errorf("could not execute template '%s': %s", template, err)
142156
}
143157
}
144158

145159
// AdminUserListHandler lists all existing user
146-
func (bh *BaseHandler) AdminUserListHandler(w http.ResponseWriter, _ *http.Request) {
160+
func (bh *BaseHandler) AdminUserListHandler(w http.ResponseWriter, r *http.Request) {
147161
var (
148-
logger = bh.ContextLogger("admin")
162+
template = "admin/user_list.gohtml"
163+
logger = bh.ContextLogger("admin")
149164
)
165+
166+
data := struct {
167+
Error string
168+
Success string
169+
User *entity.User
170+
AllUsers []entity.User
171+
}{
172+
Error: templates.GetErrorMessage(w, r),
173+
Success: templates.GetSuccessMessage(w, r),
174+
}
175+
176+
user, ok := r.Context().Value("user").(*entity.User)
177+
if !ok || user == nil {
178+
http.Redirect(w, r, "/login", http.StatusSeeOther)
179+
return
180+
}
181+
data.User = user
182+
150183
allUsers, err := bh.DBSvc.GetAllUsers()
151184
if err != nil {
152185
logger.Error("could not get all users: " + err.Error())
153186
w.WriteHeader(http.StatusInternalServerError)
154187
return
155188
}
156-
157-
data := struct {
158-
AllUsers []entity.User
159-
}{
160-
AllUsers: allUsers,
161-
}
189+
data.AllUsers = allUsers
162190

163191
if err := templates.ExecuteTemplate(bh.Inj(), w, "admin/user_list.gohtml", data); err != nil {
164192
w.WriteHeader(http.StatusNotFound)
@@ -168,24 +196,36 @@ func (bh *BaseHandler) AdminUserListHandler(w http.ResponseWriter, _ *http.Reque
168196
// AdminUserAddHandler takes form values and creates a new user account
169197
func (bh *BaseHandler) AdminUserAddHandler(w http.ResponseWriter, r *http.Request) {
170198
var (
171-
err error
172-
logger = bh.ContextLogger("admin")
199+
err error
200+
template = "admin/user_add.gohtml"
201+
logger = bh.ContextLogger("admin")
173202
)
203+
204+
data := struct {
205+
Error string
206+
Success string
207+
Edit bool
208+
User *entity.User
209+
}{
210+
Error: templates.GetErrorMessage(w, r),
211+
Success: templates.GetSuccessMessage(w, r),
212+
}
213+
214+
user, ok := r.Context().Value("user").(*entity.User)
215+
if !ok || user == nil {
216+
http.Redirect(w, r, "/login", http.StatusSeeOther)
217+
return
218+
}
219+
data.User = user
220+
174221
if r.Method == http.MethodPost {
175222

176223
username := r.FormValue("username")
177224
email := r.FormValue("email")
178225
password := r.FormValue("password")
179-
password2 := r.FormValue("password2")
180-
181-
if username == "" || password == "" || password2 == "" {
182-
logger.Debug("username and passwords required")
183-
http.Redirect(w, r, "/admin/user/add", http.StatusSeeOther)
184-
return
185-
}
186226

187-
if password != password2 {
188-
logger.Debug("passwords don not match")
227+
if username == "" || password == "" {
228+
logger.Debug("username and password required")
189229
http.Redirect(w, r, "/admin/user/add", http.StatusSeeOther)
190230
return
191231
}
@@ -256,8 +296,8 @@ func (bh *BaseHandler) AdminUserAddHandler(w http.ResponseWriter, r *http.Reques
256296

257297
}
258298

259-
if err := templates.ExecuteTemplate(bh.Inj(), w, "admin/user_add.gohtml", nil); err != nil {
260-
w.WriteHeader(http.StatusNotFound)
299+
if err := templates.ExecuteTemplate(bh.Inj(), w, template, data); err != nil {
300+
logger.Errorf("could not execute template '%s': %s", template, err)
261301
}
262302
}
263303

@@ -268,15 +308,35 @@ func (bh *BaseHandler) AdminUserEditHandler(w http.ResponseWriter, r *http.Reque
268308
err error
269309
logger = bh.ContextLogger("admin")
270310
changes uint8 = 0
271-
message string
272311
)
273312

313+
data := struct {
314+
Error string
315+
Success string
316+
Edit bool
317+
User *entity.User
318+
UserToEdit *entity.User
319+
Message string
320+
}{
321+
Error: templates.GetErrorMessage(w, r),
322+
Success: templates.GetSuccessMessage(w, r),
323+
Edit: true,
324+
}
325+
326+
user, ok := r.Context().Value("user").(*entity.User)
327+
if !ok || user == nil {
328+
http.Redirect(w, r, "/login", http.StatusSeeOther)
329+
return
330+
}
331+
data.User = user
332+
274333
userToEdit, err := bh.DBSvc.FindUser("id = ?", vars["id"])
275334
if err != nil {
276335
logger.Debugf("could not find user with ID '%s': %s", vars["id"], err.Error())
277336
http.Redirect(w, r, "/admin/user/list", http.StatusSeeOther)
278337
return
279338
}
339+
data.UserToEdit = &userToEdit
280340

281341
if r.Method == http.MethodPost {
282342
username := r.FormValue("username")
@@ -357,14 +417,6 @@ func (bh *BaseHandler) AdminUserEditHandler(w http.ResponseWriter, r *http.Reque
357417
}
358418
}
359419

360-
data := struct {
361-
User entity.User
362-
Message string
363-
}{
364-
User: userToEdit,
365-
Message: message,
366-
}
367-
368420
if err := templates.ExecuteTemplate(bh.Inj(), w, "admin/user_edit.gohtml", data); err != nil {
369421
w.WriteHeader(http.StatusNotFound)
370422
}

internal/handler/auth.go

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ package handler
22

33
import (
44
"fmt"
5+
"net/http"
6+
"time"
7+
58
"github.com/KaiserWerk/CertMaker/internal/entity"
69
"github.com/KaiserWerk/CertMaker/internal/global"
710
"github.com/KaiserWerk/CertMaker/internal/security"
811
"github.com/KaiserWerk/CertMaker/internal/templates"
9-
"html/template"
10-
"net/http"
11-
"time"
1212
)
1313

1414
// LoginHandler authenticates the user against the database, created
@@ -19,7 +19,7 @@ func (bh *BaseHandler) LoginHandler(w http.ResponseWriter, r *http.Request) {
1919

2020
if val := bh.DBSvc.GetSetting("authprovider_userpw"); val != "true" {
2121
logger.Debug("authprovider userpw not enabled; redirecting")
22-
templates.SetMessage(r, templates.MsgInfo, "AuthProvider 'userpw' not enabled; redirecting...")
22+
//templates.SetMessage(r, templates.MsgInfo, "AuthProvider 'userpw' not enabled; redirecting...")
2323
http.Redirect(w, r, "/", http.StatusSeeOther)
2424
return
2525
}
@@ -30,37 +30,37 @@ func (bh *BaseHandler) LoginHandler(w http.ResponseWriter, r *http.Request) {
3030

3131
if username == "" || password == "" {
3232
logger.Debug("username and password are required")
33-
templates.SetMessage(r, templates.MsgInfo, "Please enter username and password!")
33+
//templates.SetMessage(r, templates.MsgInfo, "Please enter username and password!")
3434
http.Redirect(w, r, "/auth/login", http.StatusSeeOther)
3535
return
3636
}
3737

3838
user, err := bh.DBSvc.FindUser("username = ?", username)
3939
if err != nil {
4040
logger.Debug("could not find user: " + err.Error())
41-
templates.SetMessage(r, templates.MsgError, "Incorrect credentials!")
41+
//templates.SetMessage(r, templates.MsgError, "Incorrect credentials!")
4242
http.Redirect(w, r, "/auth/login", http.StatusSeeOther)
4343
return
4444
}
4545

4646
if !security.DoesHashMatch(password, user.Password) {
4747
logger.Debug("password did not match")
48-
templates.SetMessage(r, templates.MsgError, "Incorrect credentials!")
48+
//templates.SetMessage(r, templates.MsgError, "Incorrect credentials!")
4949
http.Redirect(w, r, "/auth/login", http.StatusSeeOther)
5050
return
5151
}
5252

5353
if user.NoLogin {
5454
logger.Info("user logged in correctly, but was cancelled due to nologin setting")
55-
templates.SetMessage(r, templates.MsgError, "No login possible due to 'nologin' setting!")
55+
//templates.SetMessage(r, templates.MsgError, "No login possible due to 'nologin' setting!")
5656
http.Redirect(w, r, "/auth/login", http.StatusSeeOther)
5757
return
5858
}
5959

6060
sess, err := bh.SessMgr.CreateSession(time.Now().AddDate(0, 0, 7))
6161
if err != nil {
6262
logger.Error("could not create session: " + err.Error())
63-
templates.SetMessage(r, templates.MsgError, "Session could not be created!")
63+
//templates.SetMessage(r, templates.MsgError, "Session could not be created!")
6464
http.Redirect(w, r, "/auth/login", http.StatusSeeOther)
6565
return
6666
}
@@ -69,7 +69,7 @@ func (bh *BaseHandler) LoginHandler(w http.ResponseWriter, r *http.Request) {
6969
err = bh.SessMgr.SetCookie(w, sess.Id)
7070
if err != nil {
7171
logger.Error("could not set cookie: " + err.Error())
72-
templates.SetMessage(r, templates.MsgError, "Cookie could not be set!")
72+
//templates.SetMessage(r, templates.MsgError, "Cookie could not be set!")
7373
http.Redirect(w, r, "/auth/login", http.StatusSeeOther)
7474
return
7575
}
@@ -78,15 +78,9 @@ func (bh *BaseHandler) LoginHandler(w http.ResponseWriter, r *http.Request) {
7878
return
7979
}
8080

81-
msg := templates.GetMessage(r, templates.MsgError, "ERROR!!!")
82-
logger.Trace("Message: ", msg)
83-
data := struct {
84-
Message template.HTML
85-
}{
86-
Message: msg,
87-
}
81+
//msg := templates.GetMessage(r, templates.MsgError, "ERROR!!!")
8882

89-
if err := templates.ExecuteTemplate(bh.Inj(), w, "auth/login.gohtml", data); err != nil {
83+
if err := templates.ExecuteTemplate(bh.Inj(), w, "auth/login.gohtml", nil); err != nil {
9084
w.WriteHeader(http.StatusNotFound)
9185
}
9286
}

internal/templates/alert.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package templates
2+
3+
import (
4+
"encoding/base64"
5+
"net/http"
6+
"time"
7+
)
8+
9+
func GetSuccessMessage(w http.ResponseWriter, r *http.Request) string {
10+
return getMessageFromCookie(w, r, global.SuccessCookieName)
11+
}
12+
13+
func SetSuccessMessage(w http.ResponseWriter, message string) {
14+
c := &http.Cookie{
15+
Name: global.SuccessCookieName,
16+
Value: base64.RawURLEncoding.EncodeToString([]byte(message)),
17+
HttpOnly: true,
18+
Expires: time.Now().Add(24 * time.Hour),
19+
Path: "/",
20+
}
21+
http.SetCookie(w, c)
22+
}
23+
24+
func GetErrorMessage(w http.ResponseWriter, r *http.Request) string {
25+
return getMessageFromCookie(w, r, global.ErrorCookieName)
26+
}
27+
28+
func SetErrorMessage(w http.ResponseWriter, message string) {
29+
c := &http.Cookie{
30+
Name: global.ErrorCookieName,
31+
Value: base64.RawURLEncoding.EncodeToString([]byte(message)),
32+
HttpOnly: true,
33+
Expires: time.Now().Add(24 * time.Hour),
34+
Path: "/",
35+
}
36+
http.SetCookie(w, c)
37+
}
38+
39+
func getMessageFromCookie(w http.ResponseWriter, r *http.Request, cookieName string) string {
40+
c, err := r.Cookie(cookieName)
41+
if err != nil {
42+
return ""
43+
}
44+
if c == nil {
45+
return ""
46+
}
47+
if c.Value == "" {
48+
removeCookie(w, cookieName)
49+
return ""
50+
}
51+
// Clear the cookie after reading it
52+
removeCookie(w, cookieName)
53+
v, _ := base64.RawURLEncoding.DecodeString(c.Value)
54+
return string(v)
55+
}
56+
57+
func removeCookie(w http.ResponseWriter, cookieName string) {
58+
c2 := &http.Cookie{
59+
Name: cookieName,
60+
Value: "",
61+
Path: "/",
62+
Expires: time.Unix(0, 0),
63+
HttpOnly: true,
64+
}
65+
http.SetCookie(w, c2)
66+
}

0 commit comments

Comments
 (0)