admin page updates
This commit is contained in:
96
internal/rbac/preview_middleware.go
Normal file
96
internal/rbac/preview_middleware.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package rbac
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"git.haelnorr.com/h/golib/hws"
|
||||
"git.haelnorr.com/h/oslstats/internal/contexts"
|
||||
"git.haelnorr.com/h/oslstats/internal/db"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/uptrace/bun"
|
||||
)
|
||||
|
||||
// LoadPreviewRoleMiddleware loads the preview role from the session cookie if present
|
||||
// and adds it to the request context. This must run after authentication but before
|
||||
// the RBAC cache middleware.
|
||||
func LoadPreviewRoleMiddleware(s *hws.Server, conn *bun.DB) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// Check if there's a preview role in the cookie
|
||||
roleID := getPreviewRoleCookie(r)
|
||||
if roleID == 0 {
|
||||
// No preview role, continue normally
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// Load the preview role from the database
|
||||
var previewRole *db.Role
|
||||
if ok := db.WithReadTx(s, w, r, conn, func(ctx context.Context, tx bun.Tx) (bool, error) {
|
||||
var err error
|
||||
previewRole, err = db.GetRoleByID(ctx, tx, roleID)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "db.GetRoleByID")
|
||||
}
|
||||
if previewRole == nil {
|
||||
// Role doesn't exist anymore, clear the cookie
|
||||
ClearPreviewRoleCookie(w)
|
||||
return true, nil
|
||||
}
|
||||
return true, nil
|
||||
}); !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// If role was found, add it to context
|
||||
if previewRole != nil {
|
||||
ctx := contexts.WithPreviewRole(r.Context(), previewRole)
|
||||
r = r.WithContext(ctx)
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// SetPreviewRoleCookie sets the preview role ID in a session cookie
|
||||
func SetPreviewRoleCookie(w http.ResponseWriter, roleID int, ssl bool) {
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: "preview_role",
|
||||
Value: strconv.Itoa(roleID),
|
||||
Path: "/",
|
||||
MaxAge: 0, // Session cookie - expires when browser closes or session times out
|
||||
HttpOnly: true,
|
||||
Secure: ssl,
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
})
|
||||
}
|
||||
|
||||
// getPreviewRoleCookie retrieves the preview role ID from the cookie
|
||||
// Returns 0 if not present or invalid
|
||||
func getPreviewRoleCookie(r *http.Request) int {
|
||||
if r == nil {
|
||||
return 0
|
||||
}
|
||||
cookie, err := r.Cookie("preview_role")
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
roleID, err := strconv.Atoi(cookie.Value)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return roleID
|
||||
}
|
||||
|
||||
// ClearPreviewRoleCookie removes the preview role cookie
|
||||
func ClearPreviewRoleCookie(w http.ResponseWriter) {
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: "preview_role",
|
||||
Value: "",
|
||||
Path: "/",
|
||||
MaxAge: -1,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user