fix(webui): display user accounts menu entry to admin even on error pages
This commit is contained in:
parent
15e0a12f61
commit
ef565022d8
10 changed files with 33 additions and 33 deletions
|
@ -20,7 +20,7 @@ func handleAccountsGET(db *database.DB) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
accounts, err := db.LoadAccounts()
|
accounts, err := db.LoadAccounts()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorResponse(w, http.StatusInternalServerError, err)
|
errorResponse(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
render(w, accountsTemplates, http.StatusOK, AccountsPage{
|
render(w, accountsTemplates, http.StatusOK, AccountsPage{
|
||||||
|
|
|
@ -19,7 +19,7 @@ func adminMiddleware(db *database.DB, requireLogin func(http.Handler) http.Handl
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !account.(*model.Account).IsAdmin {
|
if !account.(*model.Account).IsAdmin {
|
||||||
errorResponse(w, http.StatusForbidden, fmt.Errorf("Only administrators can perform this request."))
|
errorResponse(w, r, http.StatusForbidden, fmt.Errorf("Only administrators can perform this request."))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
next.ServeHTTP(w, r)
|
next.ServeHTTP(w, r)
|
||||||
|
|
|
@ -7,15 +7,15 @@ import (
|
||||||
|
|
||||||
var errorTemplates = template.Must(template.ParseFS(htmlFS, "html/base.html", "html/error.html"))
|
var errorTemplates = template.Must(template.ParseFS(htmlFS, "html/base.html", "html/error.html"))
|
||||||
|
|
||||||
func errorResponse(w http.ResponseWriter, status int, err error) {
|
func errorResponse(w http.ResponseWriter, r *http.Request, status int, err error) {
|
||||||
type ErrorData struct {
|
type ErrorData struct {
|
||||||
Page
|
Page *Page
|
||||||
Err error
|
Err error
|
||||||
Status int
|
Status int
|
||||||
StatusText string
|
StatusText string
|
||||||
}
|
}
|
||||||
render(w, errorTemplates, status, &ErrorData{
|
render(w, errorTemplates, status, &ErrorData{
|
||||||
Page: Page{Title: "Error", Section: "error"},
|
Page: makePage(r, &Page{Title: "Error", Section: "error"}),
|
||||||
Err: err,
|
Err: err,
|
||||||
Status: status,
|
Status: status,
|
||||||
StatusText: http.StatusText(status),
|
StatusText: http.StatusText(status),
|
||||||
|
|
|
@ -28,7 +28,7 @@ func handleIndexGET() http.Handler {
|
||||||
if r.URL.Path == "/" {
|
if r.URL.Path == "/" {
|
||||||
http.Redirect(w, r, "/states", http.StatusFound)
|
http.Redirect(w, r, "/states", http.StatusFound)
|
||||||
} else {
|
} else {
|
||||||
errorResponse(w, http.StatusNotFound, fmt.Errorf("Page not found"))
|
errorResponse(w, r, http.StatusNotFound, fmt.Errorf("Page not found"))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,14 +48,14 @@ func handleLoginPOST(db *database.DB) http.Handler {
|
||||||
}
|
}
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
if err := r.ParseForm(); err != nil {
|
if err := r.ParseForm(); err != nil {
|
||||||
errorResponse(w, http.StatusBadRequest, err)
|
errorResponse(w, r, http.StatusBadRequest, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
username := r.FormValue("username")
|
username := r.FormValue("username")
|
||||||
password := r.FormValue("password")
|
password := r.FormValue("password")
|
||||||
|
|
||||||
if username == "" || password == "" { // the webui cannot issue this
|
if username == "" || password == "" { // the webui cannot issue this
|
||||||
errorResponse(w, http.StatusBadRequest, fmt.Errorf("Forbidden"))
|
errorResponse(w, r, http.StatusBadRequest, fmt.Errorf("Forbidden"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ok := validUsername.MatchString(username); !ok {
|
if ok := validUsername.MatchString(username); !ok {
|
||||||
|
@ -64,7 +64,7 @@ func handleLoginPOST(db *database.DB) http.Handler {
|
||||||
}
|
}
|
||||||
account, err := db.LoadAccountByUsername(username)
|
account, err := db.LoadAccountByUsername(username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorResponse(w, http.StatusInternalServerError, err)
|
errorResponse(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if account == nil || !account.CheckPassword(password) {
|
if account == nil || !account.CheckPassword(password) {
|
||||||
|
@ -72,12 +72,12 @@ func handleLoginPOST(db *database.DB) http.Handler {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := db.TouchAccount(account); err != nil {
|
if err := db.TouchAccount(account); err != nil {
|
||||||
errorResponse(w, http.StatusInternalServerError, err)
|
errorResponse(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sessionId, err := db.CreateSession(account)
|
sessionId, err := db.CreateSession(account)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorResponse(w, http.StatusInternalServerError, err)
|
errorResponse(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
http.SetCookie(w, &http.Cookie{
|
http.SetCookie(w, &http.Cookie{
|
||||||
|
@ -105,7 +105,7 @@ func loginMiddleware(db *database.DB, requireSession func(http.Handler) http.Han
|
||||||
}
|
}
|
||||||
account, err := db.LoadAccountById(session.(*model.Session).AccountId)
|
account, err := db.LoadAccountById(session.(*model.Session).AccountId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorResponse(w, http.StatusInternalServerError, err)
|
errorResponse(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if account == nil {
|
if account == nil {
|
||||||
|
|
|
@ -18,7 +18,7 @@ func handleLogoutGET(db *database.DB) http.Handler {
|
||||||
session := r.Context().Value(model.SessionContextKey{})
|
session := r.Context().Value(model.SessionContextKey{})
|
||||||
err := db.DeleteSession(session.(*model.Session))
|
err := db.DeleteSession(session.(*model.Session))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorResponse(w, http.StatusInternalServerError, err)
|
errorResponse(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
unsetSesssionCookie(w)
|
unsetSesssionCookie(w)
|
||||||
|
|
|
@ -17,7 +17,7 @@ func sessionsMiddleware(db *database.DB) func(http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
cookie, err := r.Cookie(cookieName)
|
cookie, err := r.Cookie(cookieName)
|
||||||
if err != nil && !errors.Is(err, http.ErrNoCookie) {
|
if err != nil && !errors.Is(err, http.ErrNoCookie) {
|
||||||
errorResponse(w, http.StatusInternalServerError, fmt.Errorf("failed to get request cookie \"%s\": %w", cookieName, err))
|
errorResponse(w, r, http.StatusInternalServerError, fmt.Errorf("failed to get request cookie \"%s\": %w", cookieName, err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -26,14 +26,14 @@ func sessionsMiddleware(db *database.DB) func(http.Handler) http.Handler {
|
||||||
} else {
|
} else {
|
||||||
session, err := db.LoadSessionById(cookie.Value)
|
session, err := db.LoadSessionById(cookie.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorResponse(w, http.StatusInternalServerError, err)
|
errorResponse(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if session == nil {
|
if session == nil {
|
||||||
unsetSesssionCookie(w)
|
unsetSesssionCookie(w)
|
||||||
} else if !session.IsExpired() {
|
} else if !session.IsExpired() {
|
||||||
if err := db.TouchSession(cookie.Value); err != nil {
|
if err := db.TouchSession(cookie.Value); err != nil {
|
||||||
errorResponse(w, http.StatusInternalServerError, err)
|
errorResponse(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx := context.WithValue(r.Context(), model.SessionContextKey{}, session)
|
ctx := context.WithValue(r.Context(), model.SessionContextKey{}, session)
|
||||||
|
|
|
@ -28,7 +28,7 @@ func handleSettingsGET(db *database.DB) http.Handler {
|
||||||
func handleSettingsPOST(db *database.DB) http.Handler {
|
func handleSettingsPOST(db *database.DB) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
if err := r.ParseForm(); err != nil {
|
if err := r.ParseForm(); err != nil {
|
||||||
errorResponse(w, http.StatusBadRequest, err)
|
errorResponse(w, r, http.StatusBadRequest, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
darkMode := r.FormValue("dark-mode")
|
darkMode := r.FormValue("dark-mode")
|
||||||
|
@ -38,7 +38,7 @@ func handleSettingsPOST(db *database.DB) http.Handler {
|
||||||
account := r.Context().Value(model.AccountContextKey{}).(*model.Account)
|
account := r.Context().Value(model.AccountContextKey{}).(*model.Account)
|
||||||
err := db.SaveAccountSettings(account, &settings)
|
err := db.SaveAccountSettings(account, &settings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorResponse(w, http.StatusInternalServerError, err)
|
errorResponse(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
render(w, settingsTemplates, http.StatusOK, SettingsPage{
|
render(w, settingsTemplates, http.StatusOK, SettingsPage{
|
||||||
|
|
|
@ -29,7 +29,7 @@ func handleStatesGET(db *database.DB) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
states, err := db.LoadStates()
|
states, err := db.LoadStates()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorResponse(w, http.StatusInternalServerError, err)
|
errorResponse(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
render(w, statesTemplates, http.StatusOK, StatesPage{
|
render(w, statesTemplates, http.StatusOK, StatesPage{
|
||||||
|
@ -43,12 +43,12 @@ func handleStatesPOST(db *database.DB) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
// file upload limit of 20MB
|
// file upload limit of 20MB
|
||||||
if err := r.ParseMultipartForm(20 << 20); err != nil {
|
if err := r.ParseMultipartForm(20 << 20); err != nil {
|
||||||
errorResponse(w, http.StatusBadRequest, err)
|
errorResponse(w, r, http.StatusBadRequest, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
file, _, err := r.FormFile("file")
|
file, _, err := r.FormFile("file")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorResponse(w, http.StatusBadRequest, err)
|
errorResponse(w, r, http.StatusBadRequest, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
@ -65,18 +65,18 @@ func handleStatesPOST(db *database.DB) http.Handler {
|
||||||
}
|
}
|
||||||
data, err := io.ReadAll(file)
|
data, err := io.ReadAll(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorResponse(w, http.StatusBadRequest, fmt.Errorf("failed to read uploaded file: %w", err))
|
errorResponse(w, r, http.StatusBadRequest, fmt.Errorf("failed to read uploaded file: %w", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fileType := http.DetectContentType(data)
|
fileType := http.DetectContentType(data)
|
||||||
if fileType != "text/plain; charset=utf-8" {
|
if fileType != "text/plain; charset=utf-8" {
|
||||||
errorResponse(w, http.StatusBadRequest, fmt.Errorf("invalid file type: expected \"text/plain; charset=utf-8\" but got \"%s\"", fileType))
|
errorResponse(w, r, http.StatusBadRequest, fmt.Errorf("invalid file type: expected \"text/plain; charset=utf-8\" but got \"%s\"", fileType))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
account := r.Context().Value(model.AccountContextKey{}).(*model.Account)
|
account := r.Context().Value(model.AccountContextKey{}).(*model.Account)
|
||||||
version, err := db.CreateState(statePath, account.Id, data)
|
version, err := db.CreateState(statePath, account.Id, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorResponse(w, http.StatusInternalServerError, err)
|
errorResponse(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if version == nil {
|
if version == nil {
|
||||||
|
@ -103,22 +103,22 @@ func handleStatesIdGET(db *database.DB) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
var stateId uuid.UUID
|
var stateId uuid.UUID
|
||||||
if err := stateId.Parse(r.PathValue("id")); err != nil {
|
if err := stateId.Parse(r.PathValue("id")); err != nil {
|
||||||
errorResponse(w, http.StatusBadRequest, err)
|
errorResponse(w, r, http.StatusBadRequest, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
state, err := db.LoadStateById(stateId)
|
state, err := db.LoadStateById(stateId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorResponse(w, http.StatusInternalServerError, err)
|
errorResponse(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
versions, err := db.LoadVersionsByState(state)
|
versions, err := db.LoadVersionsByState(state)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorResponse(w, http.StatusInternalServerError, err)
|
errorResponse(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
usernames, err := db.LoadAccountUsernames()
|
usernames, err := db.LoadAccountUsernames()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorResponse(w, http.StatusInternalServerError, err)
|
errorResponse(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
render(w, statesIdTemplate, http.StatusOK, StatesData{
|
render(w, statesIdTemplate, http.StatusOK, StatesData{
|
||||||
|
|
|
@ -23,26 +23,26 @@ func handleVersionsGET(db *database.DB) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
var versionId uuid.UUID
|
var versionId uuid.UUID
|
||||||
if err := versionId.Parse(r.PathValue("id")); err != nil {
|
if err := versionId.Parse(r.PathValue("id")); err != nil {
|
||||||
errorResponse(w, http.StatusBadRequest, err)
|
errorResponse(w, r, http.StatusBadRequest, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
version, err := db.LoadVersionById(versionId)
|
version, err := db.LoadVersionById(versionId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorResponse(w, http.StatusInternalServerError, err)
|
errorResponse(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if version == nil {
|
if version == nil {
|
||||||
errorResponse(w, http.StatusNotFound, err)
|
errorResponse(w, r, http.StatusNotFound, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
state, err := db.LoadStateById(version.StateId)
|
state, err := db.LoadStateById(version.StateId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorResponse(w, http.StatusInternalServerError, err)
|
errorResponse(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
account, err := db.LoadAccountById(version.AccountId)
|
account, err := db.LoadAccountById(version.AccountId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorResponse(w, http.StatusInternalServerError, err)
|
errorResponse(w, r, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
versionData := string(version.Data[:])
|
versionData := string(version.Data[:])
|
||||||
|
|
Loading…
Add table
Reference in a new issue