package handler import ( "encoding/json" "io" "net/http/httptest" "testing" "github.com/gofiber/fiber/v2" "github.com/stretchr/testify/require" ) func TestRPManifestJSONIncludesIAMAndExternalKeyContract(t *testing.T) { app := fiber.New() h := NewRPManifestHandler() app.Get("/.well-known/baron-rp-manifest.json", h.GetJSON) req := httptest.NewRequest("GET", "/.well-known/baron-rp-manifest.json", nil) req.Header.Set("X-Forwarded-Proto", "https") req.Header.Set("X-Forwarded-Host", "sso.hmac.kr") resp, err := app.Test(req) require.NoError(t, err) defer resp.Body.Close() require.Equal(t, fiber.StatusOK, resp.StatusCode) require.Contains(t, resp.Header.Get("Content-Type"), "application/json") var body map[string]any require.NoError(t, json.NewDecoder(resp.Body).Decode(&body)) require.Equal(t, "https://sso.hmac.kr", body["issuer"]) oidc := body["oidc"].(map[string]any) require.Equal(t, "https://sso.hmac.kr/.well-known/openid-configuration", oidc["discovery_url"]) require.Equal(t, "https://sso.hmac.kr/.well-known/jwks.json", oidc["jwks_url"]) iam := body["iam"].(map[string]any) require.Equal(t, "ory-keto", iam["authorization_engine"]) require.Equal(t, "User:", iam["subject_format"]) require.Contains(t, iam["target_object_patterns"].([]any), "RelyingParty:") require.Contains(t, iam["target_object_patterns"].([]any), "Tenant:") require.Contains(t, iam["target_object_patterns"].([]any), "Resource::") identity := body["identity_contract"].(map[string]any) require.Equal(t, "X-Baron-External-Key", identity["external_key_header"]) require.Equal(t, true, identity["external_key_is_opaque"]) require.Equal(t, false, identity["raw_kratos_identity_id_exposed"]) require.Equal(t, "baron", identity["external_key_issuer"]) require.Equal(t, "baron_injected_header", identity["external_key_delivery"]) require.Equal(t, false, identity["rp_supplied_external_key_allowed"]) require.Equal(t, "rp_must_upsert_from_header_value", identity["rp_user_upsert_source"]) headers := body["trusted_headers"].(map[string]any) require.Equal(t, "X-Baron-Subject", headers["subject"]) require.Equal(t, "X-Baron-External-Key", headers["external_key"]) require.Equal(t, "X-Baron-Client-ID", headers["client_id"]) security := body["security_requirements"].(map[string]any) require.Equal(t, true, security["strip_external_identity_headers"]) require.Equal(t, false, security["backend_direct_exposure_allowed"]) audit := body["audit_contract"].(map[string]any) require.Equal(t, "fail_closed_sync", audit["mutating_command_mode"]) require.Equal(t, "reject_mutation", audit["missing_audit_sink_behavior"]) require.Equal(t, "X-Request-Id", audit["correlation_header"]) require.Contains(t, audit["required_detail_fields"].([]any), "obj_id") require.Contains(t, audit["required_detail_fields"].([]any), "client_id") flow := body["object_lookup_flow"].(map[string]any) require.Contains(t, flow["mermaid"].(string), "flowchart TD") require.Contains(t, flow["mermaid"].(string), "obj_id") aliasFlow := body["external_key_flow"].(map[string]any) require.Contains(t, aliasFlow["mermaid"].(string), "Baron resolves internal identity") require.Contains(t, aliasFlow["mermaid"].(string), "Baron injects X-Baron-External-Key") require.Contains(t, aliasFlow["mermaid"].(string), "RP upserts local user") require.NotContains(t, aliasFlow["mermaid"].(string), "RP creates external key") } func TestRPManifestSchemaRequiresLookupAndIdentityContracts(t *testing.T) { app := fiber.New() h := NewRPManifestHandler() app.Get("/.well-known/baron-rp-manifest.schema.json", h.GetSchema) resp, err := app.Test(httptest.NewRequest("GET", "/.well-known/baron-rp-manifest.schema.json", nil)) require.NoError(t, err) defer resp.Body.Close() require.Equal(t, fiber.StatusOK, resp.StatusCode) var body map[string]any require.NoError(t, json.NewDecoder(resp.Body).Decode(&body)) required := body["required"].([]any) require.Contains(t, required, "iam") require.Contains(t, required, "trusted_headers") require.Contains(t, required, "identity_contract") require.Contains(t, required, "object_lookup") require.Contains(t, required, "audit_contract") require.Contains(t, required, "object_lookup_flow") require.Contains(t, required, "external_key_flow") } func TestRPManifestHTMLLinksMachineReadableManifest(t *testing.T) { app := fiber.New() h := NewRPManifestHandler() app.Get("/.well-known/baron-rp-manifest", h.GetHTML) resp, err := app.Test(httptest.NewRequest("GET", "/.well-known/baron-rp-manifest", nil)) require.NoError(t, err) defer resp.Body.Close() require.Equal(t, fiber.StatusOK, resp.StatusCode) require.Contains(t, resp.Header.Get("Content-Type"), "text/html") raw, err := io.ReadAll(resp.Body) require.NoError(t, err) text := string(raw) require.Contains(t, text, "/.well-known/baron-rp-manifest.json") require.Contains(t, text, "X-Baron-External-Key") require.Contains(t, text, "RelyingParty:<client_id>") require.Contains(t, text, "```mermaid") require.Contains(t, text, "audit_contract") require.Contains(t, text, "Baron-issued alias") require.Contains(t, text, "RP upserts local user") }