mirror of
https://github.com/wahyd4/passkey-auth.git
synced 2026-08-09 04:15:55 +10:00
Revert "Merge pull request #9 from wahyd4/traefik-support"
This reverts commit01a625d8fd, reversing changes made to1aba3b3947.
This commit is contained in:
@@ -392,18 +392,17 @@ func (h *Handlers) Logout(w http.ResponseWriter, r *http.Request) {
|
||||
h.writeJSON(w, map[string]string{"status": "success"})
|
||||
}
|
||||
|
||||
// AuthCheck implements auth backend for both nginx auth_request and Traefik ForwardAuth
|
||||
// AuthCheck implements the nginx auth_request protocol
|
||||
func (h *Handlers) AuthCheck(w http.ResponseWriter, r *http.Request) {
|
||||
// Debug logging
|
||||
logrus.Debugf("AuthCheck request from %s", r.RemoteAddr)
|
||||
logrus.Debugf("AuthCheck headers: %+v", r.Header)
|
||||
logrus.Debugf("AuthCheck cookies: %+v", r.Cookies())
|
||||
logrus.Debugf("AuthCheck query params: %+v", r.URL.Query())
|
||||
|
||||
session, err := h.store.Get(r, "auth-session")
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to get auth session: %v", err)
|
||||
h.handleUnauthenticated(w, r)
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -412,8 +411,8 @@ func (h *Handlers) AuthCheck(w http.ResponseWriter, r *http.Request) {
|
||||
logrus.Debugf("Session values: %+v", session.Values)
|
||||
|
||||
if !ok || !authenticated {
|
||||
logrus.Debugf("User not authenticated")
|
||||
h.handleUnauthenticated(w, r)
|
||||
logrus.Debugf("User not authenticated, returning 401")
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -429,41 +428,6 @@ func (h *Handlers) AuthCheck(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
// handleUnauthenticated handles unauthenticated requests for both Nginx and Traefik
|
||||
func (h *Handlers) handleUnauthenticated(w http.ResponseWriter, r *http.Request) {
|
||||
// Check for redirect parameter (Traefik ForwardAuth typically includes this)
|
||||
redirectURL := r.URL.Query().Get("rd")
|
||||
if redirectURL == "" {
|
||||
// Also check for other common redirect parameter names
|
||||
redirectURL = r.URL.Query().Get("redirect")
|
||||
}
|
||||
|
||||
// If redirect parameter is present, return 302 redirect (Traefik ForwardAuth)
|
||||
if redirectURL != "" {
|
||||
logrus.Debugf("Redirect parameter found (%s), returning 302 redirect for Traefik", redirectURL)
|
||||
|
||||
// Construct login URL with redirect parameter
|
||||
loginURL := "/login.html?redirect=" + redirectURL
|
||||
|
||||
// If we have a host header, construct a full URL
|
||||
if host := r.Header.Get("Host"); host != "" {
|
||||
scheme := "http"
|
||||
if r.Header.Get("X-Forwarded-Proto") == "https" || r.TLS != nil {
|
||||
scheme = "https"
|
||||
}
|
||||
loginURL = scheme + "://" + host + loginURL
|
||||
}
|
||||
|
||||
w.Header().Set("Location", loginURL)
|
||||
w.WriteHeader(http.StatusFound) // 302
|
||||
return
|
||||
}
|
||||
|
||||
// No redirect parameter, return 401 (Nginx auth_request)
|
||||
logrus.Debugf("No redirect parameter, returning 401 for Nginx auth_request")
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
}
|
||||
|
||||
// GetAuthStatus returns the current authentication status
|
||||
func (h *Handlers) GetAuthStatus(w http.ResponseWriter, r *http.Request) {
|
||||
session, err := h.store.Get(r, "auth-session")
|
||||
|
||||
@@ -1,195 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"passkey-auth/internal/auth"
|
||||
"passkey-auth/internal/config"
|
||||
"passkey-auth/internal/database"
|
||||
)
|
||||
|
||||
func TestAuthCheck(t *testing.T) {
|
||||
// Setup test config
|
||||
cfg := &config.Config{
|
||||
Auth: config.AuthConfig{
|
||||
SessionSecret: "test-secret",
|
||||
},
|
||||
WebAuthn: config.WebAuthnConfig{
|
||||
RPDisplayName: "Test Passkey Auth",
|
||||
RPID: "localhost",
|
||||
RPOrigins: []string{"http://localhost:8080"},
|
||||
},
|
||||
}
|
||||
|
||||
// Setup test database
|
||||
db, err := database.New(":memory:")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create test database: %v", err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
// Setup test WebAuthn (mock)
|
||||
webAuthn, err := auth.NewWebAuthn(cfg)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create test WebAuthn: %v", err)
|
||||
}
|
||||
|
||||
// Create handlers
|
||||
h := New(db, webAuthn, cfg)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
queryParams string
|
||||
authenticated bool
|
||||
expectedStatus int
|
||||
expectedHeader string
|
||||
}{
|
||||
{
|
||||
name: "Unauthenticated without redirect param (Nginx)",
|
||||
queryParams: "",
|
||||
authenticated: false,
|
||||
expectedStatus: http.StatusUnauthorized,
|
||||
expectedHeader: "",
|
||||
},
|
||||
{
|
||||
name: "Unauthenticated with rd param (Traefik)",
|
||||
queryParams: "rd=https://example.com/protected",
|
||||
authenticated: false,
|
||||
expectedStatus: http.StatusFound,
|
||||
expectedHeader: "/login.html?redirect=https://example.com/protected",
|
||||
},
|
||||
{
|
||||
name: "Unauthenticated with redirect param (Traefik)",
|
||||
queryParams: "redirect=https://example.com/protected",
|
||||
authenticated: false,
|
||||
expectedStatus: http.StatusFound,
|
||||
expectedHeader: "/login.html?redirect=https://example.com/protected",
|
||||
},
|
||||
{
|
||||
name: "Authenticated with redirect param",
|
||||
queryParams: "rd=https://example.com/protected",
|
||||
authenticated: true,
|
||||
expectedStatus: http.StatusOK,
|
||||
expectedHeader: "",
|
||||
},
|
||||
{
|
||||
name: "Authenticated without redirect param",
|
||||
queryParams: "",
|
||||
authenticated: true,
|
||||
expectedStatus: http.StatusOK,
|
||||
expectedHeader: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Create request
|
||||
req, err := http.NewRequest("GET", "/auth?"+tt.queryParams, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create request: %v", err)
|
||||
}
|
||||
|
||||
// Mock session if authenticated
|
||||
if tt.authenticated {
|
||||
// Create a session cookie for testing
|
||||
session, _ := h.store.Get(req, "auth-session")
|
||||
session.Values["authenticated"] = true
|
||||
session.Values["user_id"] = 1
|
||||
session.Values["user_email"] = "test@example.com"
|
||||
|
||||
// Create a response recorder to capture the session cookie
|
||||
w := httptest.NewRecorder()
|
||||
session.Save(req, w)
|
||||
|
||||
// Extract the cookie and add it to the request
|
||||
for _, cookie := range w.Result().Cookies() {
|
||||
if cookie.Name == "auth-session" {
|
||||
req.AddCookie(cookie)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create response recorder
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
// Call the handler
|
||||
h.AuthCheck(w, req)
|
||||
|
||||
// Check status code
|
||||
if w.Code != tt.expectedStatus {
|
||||
t.Errorf("Expected status %d, got %d", tt.expectedStatus, w.Code)
|
||||
}
|
||||
|
||||
// Check Location header for redirects
|
||||
if tt.expectedStatus == http.StatusFound {
|
||||
location := w.Header().Get("Location")
|
||||
if location != tt.expectedHeader {
|
||||
t.Errorf("Expected Location header %s, got %s", tt.expectedHeader, location)
|
||||
}
|
||||
}
|
||||
|
||||
// Check auth headers for authenticated requests
|
||||
if tt.authenticated && tt.expectedStatus == http.StatusOK {
|
||||
userHeader := w.Header().Get("X-Auth-User")
|
||||
if userHeader == "" {
|
||||
t.Error("Expected X-Auth-User header for authenticated request")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthCheckWithHost(t *testing.T) {
|
||||
// Setup test config
|
||||
cfg := &config.Config{
|
||||
Auth: config.AuthConfig{
|
||||
SessionSecret: "test-secret",
|
||||
},
|
||||
WebAuthn: config.WebAuthnConfig{
|
||||
RPDisplayName: "Test Passkey Auth",
|
||||
RPID: "localhost",
|
||||
RPOrigins: []string{"http://localhost:8080"},
|
||||
},
|
||||
}
|
||||
|
||||
// Setup test database
|
||||
db, err := database.New(":memory:")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create test database: %v", err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
// Setup test WebAuthn
|
||||
webAuthn, err := auth.NewWebAuthn(cfg)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create test WebAuthn: %v", err)
|
||||
}
|
||||
|
||||
// Create handlers
|
||||
h := New(db, webAuthn, cfg)
|
||||
|
||||
// Test with Host header
|
||||
req, err := http.NewRequest("GET", "/auth?rd=https://example.com/protected", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create request: %v", err)
|
||||
}
|
||||
req.Header.Set("Host", "auth.example.com")
|
||||
req.Header.Set("X-Forwarded-Proto", "https")
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
h.AuthCheck(w, req)
|
||||
|
||||
// Should return 302 with full URL
|
||||
if w.Code != http.StatusFound {
|
||||
t.Errorf("Expected status %d, got %d", http.StatusFound, w.Code)
|
||||
}
|
||||
|
||||
expectedLocation := "https://auth.example.com/login.html?redirect=https://example.com/protected"
|
||||
location := w.Header().Get("Location")
|
||||
if location != expectedLocation {
|
||||
t.Errorf("Expected Location header %s, got %s", expectedLocation, location)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user