forked from baron/baron-sso
124 lines
5.1 KiB
Go
124 lines
5.1 KiB
Go
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:<baron_identity_id>", iam["subject_format"])
|
|
require.Contains(t, iam["target_object_patterns"].([]any), "RelyingParty:<client_id>")
|
|
require.Contains(t, iam["target_object_patterns"].([]any), "Tenant:<tenant_id>")
|
|
require.Contains(t, iam["target_object_patterns"].([]any), "Resource:<resource_type>:<resource_id>")
|
|
|
|
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")
|
|
}
|