Initial commit with server startup infrastructure
Core infrastructure: - Uber fx dependency injection - Chi router with middleware stack - SQLite database with embedded migrations - Embedded templates and static assets - Structured logging with slog Features implemented: - Authentication (login, logout, session management, argon2id hashing) - App management (create, edit, delete, list) - Deployment pipeline (clone, build, deploy, health check) - Webhook processing for Gitea - Notifications (ntfy, Slack) - Environment variables, labels, volumes per app - SSH key generation for deploy keys Server startup: - Server.Run() starts HTTP server on configured port - Server.Shutdown() for graceful shutdown - SetupRoutes() wires all handlers with chi router
This commit is contained in:
82
internal/handlers/auth.go
Normal file
82
internal/handlers/auth.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"git.eeqj.de/sneak/upaas/templates"
|
||||
)
|
||||
|
||||
// HandleLoginGET returns the login page handler.
|
||||
func (h *Handlers) HandleLoginGET() http.HandlerFunc {
|
||||
tmpl := templates.GetParsed()
|
||||
|
||||
return func(writer http.ResponseWriter, _ *http.Request) {
|
||||
data := map[string]any{}
|
||||
|
||||
err := tmpl.ExecuteTemplate(writer, "login.html", data)
|
||||
if err != nil {
|
||||
h.log.Error("template execution failed", "error", err)
|
||||
http.Error(writer, "Internal Server Error", http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HandleLoginPOST handles the login form submission.
|
||||
func (h *Handlers) HandleLoginPOST() http.HandlerFunc {
|
||||
tmpl := templates.GetParsed()
|
||||
|
||||
return func(writer http.ResponseWriter, request *http.Request) {
|
||||
parseErr := request.ParseForm()
|
||||
if parseErr != nil {
|
||||
http.Error(writer, "Bad Request", http.StatusBadRequest)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
username := request.FormValue("username")
|
||||
password := request.FormValue("password")
|
||||
|
||||
data := map[string]any{
|
||||
"Username": username,
|
||||
}
|
||||
|
||||
if username == "" || password == "" {
|
||||
data["Error"] = "Username and password are required"
|
||||
_ = tmpl.ExecuteTemplate(writer, "login.html", data)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
user, authErr := h.auth.Authenticate(request.Context(), username, password)
|
||||
if authErr != nil {
|
||||
data["Error"] = "Invalid username or password"
|
||||
_ = tmpl.ExecuteTemplate(writer, "login.html", data)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
sessionErr := h.auth.CreateSession(writer, request, user)
|
||||
if sessionErr != nil {
|
||||
h.log.Error("failed to create session", "error", sessionErr)
|
||||
|
||||
data["Error"] = "Failed to create session"
|
||||
_ = tmpl.ExecuteTemplate(writer, "login.html", data)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(writer, request, "/", http.StatusSeeOther)
|
||||
}
|
||||
}
|
||||
|
||||
// HandleLogout handles logout requests.
|
||||
func (h *Handlers) HandleLogout() http.HandlerFunc {
|
||||
return func(writer http.ResponseWriter, request *http.Request) {
|
||||
destroyErr := h.auth.DestroySession(writer, request)
|
||||
if destroyErr != nil {
|
||||
h.log.Error("failed to destroy session", "error", destroyErr)
|
||||
}
|
||||
|
||||
http.Redirect(writer, request, "/login", http.StatusSeeOther)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user