Merge pull request #408 from koic/dcr_application_type
Set OIDC `application_type` on Dynamic Client Registration per SEP-837
This commit is contained in:
commit
aac41cdff8
2 changed files with 140 additions and 1 deletions
|
|
@ -158,6 +158,39 @@ module MCP
|
|||
)
|
||||
end
|
||||
|
||||
def test_infer_application_type_returns_native_for_loopback_http_redirect_uris
|
||||
uris = ["http://localhost:0/callback", "http://127.0.0.1:8080/cb", "http://[::1]/cb"]
|
||||
|
||||
assert_equal("native", Discovery.infer_application_type(uris))
|
||||
end
|
||||
|
||||
def test_infer_application_type_returns_native_for_custom_scheme_redirect_uris
|
||||
assert_equal("native", Discovery.infer_application_type(["com.example.app:/oauth/callback"]))
|
||||
end
|
||||
|
||||
def test_infer_application_type_returns_web_for_https_redirect_uris
|
||||
assert_equal("web", Discovery.infer_application_type(["https://app.example.com/callback"]))
|
||||
end
|
||||
|
||||
def test_infer_application_type_returns_web_when_any_redirect_uri_is_not_native
|
||||
uris = ["http://localhost:0/callback", "https://app.example.com/callback"]
|
||||
|
||||
assert_equal("web", Discovery.infer_application_type(uris))
|
||||
end
|
||||
|
||||
def test_infer_application_type_returns_web_for_localhost_lookalike_host
|
||||
assert_equal("web", Discovery.infer_application_type(["http://localhost.example.com/cb"]))
|
||||
end
|
||||
|
||||
def test_infer_application_type_returns_web_for_nil_or_empty_redirect_uris
|
||||
assert_equal("web", Discovery.infer_application_type(nil))
|
||||
assert_equal("web", Discovery.infer_application_type([]))
|
||||
end
|
||||
|
||||
def test_infer_application_type_returns_web_for_unparseable_redirect_uri
|
||||
assert_equal("web", Discovery.infer_application_type(["http://[invalid"]))
|
||||
end
|
||||
|
||||
def test_canonicalize_url_normalizes_scheme_host_port_and_path
|
||||
assert_equal(
|
||||
"https://srv.example.com/mcp",
|
||||
|
|
|
|||
|
|
@ -200,6 +200,62 @@ module MCP
|
|||
end
|
||||
end
|
||||
|
||||
# Runs the full authorization flow with a minimal provider so tests can assert on
|
||||
# the Dynamic Client Registration request body. The default loopback redirect URI
|
||||
# exercises SEP-837's `"native"` inference; passing an HTTPS `redirect_uri` exercises
|
||||
# the `"web"` inference.
|
||||
def run_authorization_flow(redirect_uri: "http://localhost:0/callback", client_metadata_extra: {})
|
||||
state_holder = {}
|
||||
provider = Provider.new(
|
||||
client_metadata: {
|
||||
redirect_uris: [redirect_uri],
|
||||
grant_types: ["authorization_code"],
|
||||
response_types: ["code"],
|
||||
token_endpoint_auth_method: "none",
|
||||
}.merge(client_metadata_extra),
|
||||
redirect_uri: redirect_uri,
|
||||
redirect_handler: ->(url) { state_holder[:state] = URI.decode_www_form(url.query).to_h.fetch("state") },
|
||||
callback_handler: -> { ["test-auth-code", state_holder[:state]] },
|
||||
)
|
||||
|
||||
Flow.new(provider: provider).run!(server_url: @server_url, resource_metadata_url: @prm_url)
|
||||
end
|
||||
|
||||
def test_run_registers_native_application_type_for_loopback_redirect_uri
|
||||
run_authorization_flow
|
||||
|
||||
assert_requested(:post, "#{@auth_base}/register") do |req|
|
||||
JSON.parse(req.body)["application_type"] == "native"
|
||||
end
|
||||
end
|
||||
|
||||
def test_run_registers_web_application_type_for_https_redirect_uri
|
||||
run_authorization_flow(redirect_uri: "https://app.example.com/callback")
|
||||
|
||||
assert_requested(:post, "#{@auth_base}/register") do |req|
|
||||
JSON.parse(req.body)["application_type"] == "web"
|
||||
end
|
||||
end
|
||||
|
||||
def test_run_does_not_override_explicit_application_type
|
||||
run_authorization_flow(client_metadata_extra: { application_type: "web" })
|
||||
|
||||
assert_requested(:post, "#{@auth_base}/register") do |req|
|
||||
JSON.parse(req.body)["application_type"] == "web"
|
||||
end
|
||||
end
|
||||
|
||||
def test_run_does_not_override_explicit_string_keyed_application_type
|
||||
run_authorization_flow(
|
||||
redirect_uri: "https://app.example.com/callback",
|
||||
client_metadata_extra: { "application_type" => "native" },
|
||||
)
|
||||
|
||||
assert_requested(:post, "#{@auth_base}/register") do |req|
|
||||
JSON.parse(req.body)["application_type"] == "native"
|
||||
end
|
||||
end
|
||||
|
||||
def test_run_completes_full_authorization_flow
|
||||
captured_authorization_url = nil
|
||||
state_value = nil
|
||||
|
|
|
|||
Loading…
Reference in a new issue