Start implementing middleware for logging and authentication in member-console application

This commit is contained in:
2025-02-21 11:22:45 -06:00
parent f0fc18ab7f
commit 0b4cc932b6
2 changed files with 67 additions and 12 deletions

View File

@ -3,7 +3,9 @@ package cmd
import ( import (
"log" "log"
"net/http" "net/http"
"time"
"git.coopcloud.tech/wiki-cafe/member-console/internal/middleware"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@ -12,7 +14,7 @@ var startCmd = &cobra.Command{
Use: "start", Use: "start",
Short: "Start serving the member-console web application", Short: "Start serving the member-console web application",
Long: `The start command starts an HTTP server that serves the member-console web Long: `The start command starts an HTTP server that serves the member-console web
application. application from the components directory in the current directory.
The server listens on port 8080 by default, unless a different port is specified using the --port flag.`, The server listens on port 8080 by default, unless a different port is specified using the --port flag.`,
Args: cobra.NoArgs, Args: cobra.NoArgs,
@ -20,20 +22,27 @@ var startCmd = &cobra.Command{
// Retrieve the port value from Viper // Retrieve the port value from Viper
port := viper.GetString("port") port := viper.GetString("port")
// Define the directory containing the static HTML files // Create a new HTTP request router
dir := http.Dir("./components")
fileServer := http.FileServer(dir)
// Use a ServeMux to handle requests
httpRequestRouter := http.NewServeMux() httpRequestRouter := http.NewServeMux()
httpRequestRouter.Handle("/", fileServer)
// Start the HTTP server // Create a middleware stack
log.Printf("Starting server on :%s...\n", port) stack := middleware.CreateStack(
err := http.ListenAndServe(":"+port, httpRequestRouter) loggingMiddleware,
if err != nil { authMiddleware,
log.Fatal(err) )
server := http.Server{
Addr: ":" + port,
Handler: stack(httpRequestRouter),
} }
// Register the login page handler
httpRequestRouter.HandleFunc("/login", serveLoginPage)
// Serve the components directory
httpRequestRouter.Handle("/", http.FileServer(http.Dir("./components")))
log.Println("Starting server on port", port)
log.Fatal(server.ListenAndServe())
}, },
} }
@ -50,3 +59,32 @@ func init() {
// Add the command to the root command // Add the command to the root command
rootCmd.AddCommand(startCmd) rootCmd.AddCommand(startCmd)
} }
// authMiddleware is a simple middleware function that checks for a valid session cookie
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Check for the session cookie
cookie, err := r.Cookie("session")
if err != nil || cookie.Value != "authenticated" {
http.Redirect(w, r, "/login", http.StatusSeeOther)
return
}
// Call the next handler
next.ServeHTTP(w, r)
})
}
// loggerMiddleware is a simple middleware function that logs the request method and URL
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
next.ServeHTTP(w, r)
log.Println(r.Method, r.URL.Path, time.Since(start))
})
}
// serveLoginPage is a simple handler function that serves the login page
func serveLoginPage(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "./components/login.html")
}

View File

@ -0,0 +1,17 @@
package middleware
import "net/http"
type Middleware func(http.Handler) http.Handler
// CreateStack creates a stack of middleware handlers
func CreateStack(middlewares ...Middleware) Middleware {
return func(nextMiddleware http.Handler) http.Handler {
for i := len(middlewares) - 1; i >= 0; i-- {
currentMiddleware := middlewares[i]
nextMiddleware = currentMiddleware(nextMiddleware)
}
return nextMiddleware
}
}