arimelody.me/admin/http.go

91 lines
2.8 KiB
Go
Raw Normal View History

package admin
import (
"fmt"
"net/http"
"os"
"path/filepath"
"arimelody-web/admin/account"
"arimelody-web/admin/auth"
"arimelody-web/admin/core"
"arimelody-web/admin/logs"
"arimelody-web/admin/music"
"arimelody-web/admin/templates"
"arimelody-web/controller"
"arimelody-web/model"
)
func Handler(app *model.AppState) http.Handler {
mux := http.NewServeMux()
mux.Handle("/register", auth.RegisterAccountHandler(app))
mux.Handle("/login", auth.LoginHandler(app))
mux.Handle("/totp", auth.LoginTOTPHandler(app))
mux.Handle("/logout", core.RequireAccount(auth.LogoutHandler(app)))
mux.Handle("/music/", core.RequireAccount(http.StripPrefix("/music", music.Handler(app))))
mux.Handle("/logs", core.RequireAccount(logs.Handler(app)))
mux.Handle("/account/", core.RequireAccount(http.StripPrefix("/account", account.Handler(app))))
mux.Handle("/static/", http.StripPrefix("/static", staticHandler()))
mux.Handle("/", core.RequireAccount(AdminIndexHandler(app)))
// response wrapper to make sure a session cookie exists
return core.EnforceSession(app, mux)
}
func AdminIndexHandler(app *model.AppState) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
session := r.Context().Value("session").(*model.Session)
latestRelease, err := controller.GetLatestRelease(app.DB)
if err != nil {
fmt.Fprintf(os.Stderr, "WARN: Failed to pull latest release: %s\n", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
2024-09-03 08:07:45 +01:00
type IndexData struct {
Session *model.Session
LatestRelease *model.Release
}
err = templates.IndexTemplate.Execute(w, IndexData{
Session: session,
LatestRelease: latestRelease,
})
if err != nil {
fmt.Fprintf(os.Stderr, "WARN: Failed to render admin index: %s\n", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
})
}
func staticHandler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
info, err := os.Stat(filepath.Join("admin", "static", filepath.Clean(r.URL.Path)))
// does the file exist?
if err != nil {
if os.IsNotExist(err) {
http.NotFound(w, r)
return
}
}
// is thjs a directory? (forbidden)
if info.IsDir() {
http.NotFound(w, r)
return
}
http.FileServer(http.Dir(filepath.Join("admin", "static"))).ServeHTTP(w, r)
})
}