diff --git a/docs/lola-discovery.md b/docs/lola-discovery.md index 3dd431e..0618e95 100644 --- a/docs/lola-discovery.md +++ b/docs/lola-discovery.md @@ -79,13 +79,8 @@ def oauth_authorization_server_metadata(request): "scopes_supported": ["activitypub_account_portability"], "response_types_supported": ["code"], "grant_types_supported": ["authorization_code"], - # LOLA-specific parameter for account portability endpoint discovery - "activitypub_account_portability": { - "supported": True, - "authorization_endpoint": authorization_endpoint, - "scopes": ["activitypub_account_portability"] - } + "activitypub_account_portability": authorization_endpoint, } response = JsonResponse(metadata) @@ -129,22 +124,18 @@ The `activitypub_account_portability` scope is included in `scopes_supported`: ### LOLA Endpoint Parameter -A custom parameter provides structured metadata about LOLA account portability support: +Per LOLA spec section 4.1, the `activitypub_account_portability` parameter is the **URL string** of the portability authorization endpoint: ```json { - "activitypub_account_portability": { - "supported": true, - "authorization_endpoint": "https://server.example/oauth/authorize/", - "scopes": ["activitypub_account_portability"] - } + "activitypub_account_portability": "https://server.example/oauth/authorize/" } ``` -This structured format enables destination servers to: -- Detect LOLA support via the `supported` flag -- Discover the authorization endpoint for portability flows -- Identify required scopes for account migration +This enables destination servers to: +- Detect LOLA support via the presence of the `activitypub_account_portability` parameter +- Discover the authorization endpoint for portability flows by reading the parameter value directly +- Identify the required scope via the standard `scopes_supported` array (which includes `activitypub_account_portability`) ## Discovery Flow @@ -168,11 +159,7 @@ curl https://source.example/.well-known/oauth-authorization-server ], "response_types_supported": ["code"], "grant_types_supported": ["authorization_code"], - "activitypub_account_portability": { - "supported": true, - "authorization_endpoint": "https://source.example/oauth/authorize/", - "scopes": ["activitypub_account_portability"] - } + "activitypub_account_portability": "https://source.example/oauth/authorize/" } ``` diff --git a/testbed/core/tests/test_lola_compliance.py b/testbed/core/tests/test_lola_compliance.py index 63a8053..c1d6acd 100644 --- a/testbed/core/tests/test_lola_compliance.py +++ b/testbed/core/tests/test_lola_compliance.py @@ -33,9 +33,9 @@ def test_rfc8414_returns_valid_metadata(): # Verify LOLA-specific parameters are included for account portability discovery def test_rfc8414_includes_lola_parameters(): - + client = APIClient() - + response = client.get('/.well-known/oauth-authorization-server') data = response.json() @@ -46,27 +46,15 @@ def test_rfc8414_includes_lola_parameters(): # LOLA endpoint parameter should be present (LOLA extension to RFC8414) assert 'activitypub_account_portability' in data, \ "LOLA parameter 'activitypub_account_portability' must be present" - - lola_metadata = data['activitypub_account_portability'] - - assert 'supported' in lola_metadata, \ - "LOLA metadata 'supported' flag must be present" - - assert lola_metadata['supported'] is True, \ - "LOLA metadata 'supported' flag must be True" - - assert 'authorization_endpoint' in lola_metadata, \ - "LOLA metadata 'authorization_endpoint' must be present" - - assert lola_metadata['authorization_endpoint'].endswith('/oauth/authorize/'), \ - "LOLA authorization endpoint should point to OAuth authorization endpoint" - - assert 'scopes' in lola_metadata, \ - "LOLA metadata 'scopes' must be present" - - assert 'activitypub_account_portability' in lola_metadata['scopes'], \ - "LOLA scopes array must include 'activitypub_account_portability'" - + + lola_endpoint = data['activitypub_account_portability'] + + assert isinstance(lola_endpoint, str), \ + "LOLA parameter 'activitypub_account_portability' must be a URL string" + + assert lola_endpoint.endswith('/oauth/authorize/'), \ + "LOLA portability endpoint should point to the OAuth authorization endpoint" + # Ensure all URLs in discovery response are absolute for federation compatibility def test_rfc8414_urls_are_absolute(): @@ -87,11 +75,11 @@ def test_rfc8414_urls_are_absolute(): url = data[field] assert url.startswith('http'), \ f"{field} should be absolute URL starting with http/https: {url}" - - lola_metadata = data['activitypub_account_portability'] - lola_auth_endpoint = lola_metadata['authorization_endpoint'] - assert lola_auth_endpoint.startswith('http'), \ - f"LOLA authorization_endpoint should be absolute URL: {lola_auth_endpoint}" + + # The LOLA portability parameter is itself an absolute URL string + lola_endpoint = data['activitypub_account_portability'] + assert lola_endpoint.startswith('http'), \ + f"LOLA portability endpoint should be absolute URL: {lola_endpoint}" def test_rfc8414_authorization_code_flow_support(): @@ -143,7 +131,7 @@ def test_rfc8414_oauth_endpoints_match(): "Authorization endpoint should use /oauth/authorize/ path" assert '/oauth/token/' in data['token_endpoint'], \ "Token endpoint should use /oauth/token/ path" - - lola_metadata = data['activitypub_account_portability'] - assert lola_metadata['authorization_endpoint'] == data['authorization_endpoint'], \ + + # The LOLA portability URL string must resolve to the same authorization endpoint + assert data['activitypub_account_portability'] == data['authorization_endpoint'], \ "LOLA portability endpoint should point to the same authorization endpoint" diff --git a/testbed/core/views/api.py b/testbed/core/views/api.py index 807e2aa..696a61b 100644 --- a/testbed/core/views/api.py +++ b/testbed/core/views/api.py @@ -387,11 +387,7 @@ def oauth_authorization_server_metadata(request): "response_types_supported": ["code"], "grant_types_supported": ["authorization_code"], # LOLA-specific parameter for account portability endpoint discovery - "activitypub_account_portability": { - "supported": True, - "authorization_endpoint": authorization_endpoint, - "scopes": ["activitypub_account_portability"], - }, + "activitypub_account_portability": authorization_endpoint, } response = JsonResponse(metadata)