117 lines
3.0 KiB
Go
117 lines
3.0 KiB
Go
package server
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"warpbox/lib/config"
|
|
)
|
|
|
|
const adminSessionCookie = "warpbox_admin_session"
|
|
const adminSessionMarker = "1"
|
|
|
|
func (app *App) adminLoginEnabled() bool {
|
|
return app.config.AdminLoginEnabled(app.config.AdminPassword != "")
|
|
}
|
|
|
|
func (app *App) adminAuthMiddleware(ctx *gin.Context) {
|
|
if !app.adminLoginEnabled() {
|
|
ctx.Redirect(http.StatusSeeOther, "/")
|
|
ctx.Abort()
|
|
return
|
|
}
|
|
|
|
token, err := ctx.Cookie(adminSessionCookie)
|
|
if err != nil || token != app.adminSessionToken() {
|
|
ctx.Redirect(http.StatusSeeOther, "/admin/login")
|
|
ctx.Abort()
|
|
return
|
|
}
|
|
|
|
ctx.Next()
|
|
}
|
|
|
|
func (app *App) adminSessionToken() string {
|
|
// A simple deterministic token derived from the admin credentials.
|
|
// This will improve when proper user/session storage is added.
|
|
return app.config.AdminUsername + ":" + app.config.AdminPassword
|
|
}
|
|
|
|
func (app *App) handleAdminLogin(ctx *gin.Context) {
|
|
if !app.adminLoginEnabled() {
|
|
ctx.Redirect(http.StatusSeeOther, "/")
|
|
return
|
|
}
|
|
|
|
// Already logged in.
|
|
if token, err := ctx.Cookie(adminSessionCookie); err == nil && token == app.adminSessionToken() {
|
|
ctx.Redirect(http.StatusSeeOther, "/admin/dashboard")
|
|
return
|
|
}
|
|
|
|
ctx.HTML(http.StatusOK, "admin/login.html", gin.H{})
|
|
}
|
|
|
|
func (app *App) handleAdminLoginPost(ctx *gin.Context) {
|
|
if !app.adminLoginEnabled() {
|
|
ctx.Redirect(http.StatusSeeOther, "/")
|
|
return
|
|
}
|
|
|
|
username := strings.TrimSpace(ctx.PostForm("username"))
|
|
password := ctx.PostForm("password")
|
|
|
|
if username != app.config.AdminUsername || password != app.config.AdminPassword {
|
|
ctx.HTML(http.StatusUnauthorized, "admin/login.html", gin.H{
|
|
"ErrorMessage": "Invalid username or password.",
|
|
})
|
|
return
|
|
}
|
|
|
|
secure := app.config.AdminCookieSecure
|
|
maxAge := int(app.config.SessionTTLSeconds)
|
|
|
|
ctx.SetCookie(adminSessionCookie, app.adminSessionToken(), maxAge, "/admin", "", secure, true)
|
|
ctx.Redirect(http.StatusSeeOther, "/admin/dashboard")
|
|
}
|
|
|
|
func (app *App) handleAdminLogout(ctx *gin.Context) {
|
|
secure := app.config.AdminCookieSecure
|
|
ctx.SetCookie(adminSessionCookie, "", -1, "/admin", "", secure, true)
|
|
ctx.Redirect(http.StatusSeeOther, "/admin/login")
|
|
}
|
|
|
|
func (app *App) handleAdminDashboard(ctx *gin.Context) {
|
|
if !app.adminLoginEnabled() {
|
|
ctx.Redirect(http.StatusSeeOther, "/")
|
|
return
|
|
}
|
|
|
|
dashboardEnabled := config.AdminEnabledTrue
|
|
if cfgVal := app.config.AdminEnabled; cfgVal == config.AdminEnabledAuto || cfgVal == config.AdminEnabledTrue {
|
|
dashboardEnabled = cfgVal
|
|
}
|
|
|
|
ctx.HTML(http.StatusOK, "admin/dashboard.html", gin.H{
|
|
"AdminUsername": app.config.AdminUsername,
|
|
"AdminEmail": app.config.AdminEmail,
|
|
"ActivePage": "dashboard",
|
|
"DashboardEnabled": string(dashboardEnabled),
|
|
})
|
|
}
|
|
|
|
func (app *App) handleAdminAlerts(ctx *gin.Context) {
|
|
if !app.adminLoginEnabled() {
|
|
ctx.Redirect(http.StatusSeeOther, "/")
|
|
return
|
|
}
|
|
|
|
ctx.HTML(http.StatusOK, "admin/alerts.html", gin.H{
|
|
"AdminUsername": app.config.AdminUsername,
|
|
"AdminEmail": app.config.AdminEmail,
|
|
"ActivePage": "alerts",
|
|
})
|
|
}
|