Something went wrong. Try again.
Caddy module to require at-proto authentication and restrict routes to DIDs
Something went wrong. Try again.
caddy-atproto-auth integration_test.go
3.0 kB · 126 lines
Go
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127package caddyatprotoauth
import ( "net/http" "strings" "testing" "time"
"github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile" _ "github.com/caddyserver/caddy/v2/modules/standard")
func TestCaddyIntegration(t *testing.T) { // Setup Caddyfile // Try: Change the allow list on the gate to include a nonexistent handle. // You should see a warning log that Caddy was unable to resolve it. input := ` { admin off atproto { storage_path :memory: } }
:8080 { route /auth/* { uri strip_prefix /auth atproto_portal { name "Test Portal" } }
route /protected/* { atproto_gate { allow @tangled.org portal_url http://localhost:8080/auth } respond "Authorized Content" } } `
// Parse and Load Config adapter := caddyfile.Adapter{ ServerType: httpcaddyfile.ServerType{}, }
jsonConfig, warnings, err := adapter.Adapt([]byte(input), nil) if err != nil { t.Fatalf("Failed to adapt config: %v", err) } if len(warnings) > 0 { t.Logf("Warnings: %v", warnings) }
err = caddy.Load(jsonConfig, true) if err != nil { t.Fatalf("Failed to load caddy: %v", err) } defer caddy.Stop()
// Wait a moment for server start time.Sleep(100 * time.Millisecond)
baseURL := "http://localhost:8080" client := &http.Client{ CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse // Don't follow redirects }, }
t.Run("Unauthorized Access Redirects to Portal", func(t *testing.T) { resp, err := client.Get(baseURL + "/protected/resource") if err != nil { t.Fatalf("Request failed: %v", err) } defer resp.Body.Close()
if resp.StatusCode != http.StatusFound { t.Errorf("Expected status 302, got %d", resp.StatusCode) }
location := resp.Header.Get("Location") if !strings.Contains(location, "/auth/login") { t.Errorf("Expected redirect to portal login, got %s", location) } })
t.Run("Portal Serves Login Page", func(t *testing.T) { resp, err := client.Get(baseURL + "/auth/login") if err != nil { t.Fatalf("Request failed: %v", err) } defer resp.Body.Close()
if resp.StatusCode != http.StatusOK { t.Errorf("Expected status 200, got %d", resp.StatusCode) }
// Verify content type (HTML) ct := resp.Header.Get("Content-Type") if !strings.Contains(ct, "text/html") { t.Errorf("Expected HTML content, got %s", ct) } })
t.Run("Portal Serves Metadata", func(t *testing.T) { resp, err := client.Get(baseURL + "/auth/.well-known/oauth-client-metadata.json") if err != nil { t.Fatalf("Request failed: %v", err) } defer resp.Body.Close()
if resp.StatusCode != http.StatusOK { t.Errorf("Expected status 200, got %d", resp.StatusCode) }
// Verify content type (JSON) ct := resp.Header.Get("Content-Type") if !strings.Contains(ct, "application/json") { t.Errorf("Expected JSON content, got %s", ct) } })}