fix: rewrite Login Flow v2 poll endpoint URL to use configured host
Nextcloud returns poll/login URLs using its internal hostname (e.g. http://localhost/login/v2/poll) which is unreachable from the MCP server container in Docker networks. Rewrite the poll endpoint's origin to use the configured NEXTCLOUD_HOST so server-side polling works correctly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
c2f23a566c
commit
eefede8c47
@@ -10,6 +10,7 @@ The flow has two steps:
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
import ssl
|
import ssl
|
||||||
|
from urllib.parse import urlparse, urlunparse
|
||||||
|
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
@@ -91,9 +92,16 @@ class LoginFlowV2Client:
|
|||||||
poll_data = data.get("poll", {})
|
poll_data = data.get("poll", {})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
raw_poll_endpoint = poll_data["endpoint"]
|
||||||
|
# Nextcloud returns URLs using its internal hostname (e.g.
|
||||||
|
# http://localhost/login/v2/poll) which may be unreachable from
|
||||||
|
# this process. Rewrite the poll endpoint to use nextcloud_host
|
||||||
|
# so server-side polling works across Docker networks.
|
||||||
|
poll_endpoint = self._rewrite_to_nextcloud_host(raw_poll_endpoint)
|
||||||
|
|
||||||
result = LoginFlowInitResponse(
|
result = LoginFlowInitResponse(
|
||||||
login_url=data["login"],
|
login_url=data["login"],
|
||||||
poll_endpoint=poll_data["endpoint"],
|
poll_endpoint=poll_endpoint,
|
||||||
poll_token=poll_data["token"],
|
poll_token=poll_data["token"],
|
||||||
)
|
)
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
@@ -104,6 +112,25 @@ class LoginFlowV2Client:
|
|||||||
logger.info(f"Login Flow v2 initiated: login_url={result.login_url[:60]}...")
|
logger.info(f"Login Flow v2 initiated: login_url={result.login_url[:60]}...")
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def _rewrite_to_nextcloud_host(self, url: str) -> str:
|
||||||
|
"""Rewrite a URL's origin to use self.nextcloud_host.
|
||||||
|
|
||||||
|
Nextcloud may return URLs with its internal hostname (e.g.
|
||||||
|
http://localhost) which differs from the configured NEXTCLOUD_HOST
|
||||||
|
(e.g. http://app:80). This replaces the scheme+host+port while
|
||||||
|
preserving the path and query.
|
||||||
|
"""
|
||||||
|
parsed_url = urlparse(url)
|
||||||
|
parsed_host = urlparse(self.nextcloud_host)
|
||||||
|
rewritten = parsed_url._replace(
|
||||||
|
scheme=parsed_host.scheme,
|
||||||
|
netloc=parsed_host.netloc,
|
||||||
|
)
|
||||||
|
result = urlunparse(rewritten)
|
||||||
|
if result != url:
|
||||||
|
logger.debug(f"Rewrote Login Flow v2 URL: {url} → {result}")
|
||||||
|
return result
|
||||||
|
|
||||||
async def poll(self, poll_endpoint: str, poll_token: str) -> LoginFlowPollResult:
|
async def poll(self, poll_endpoint: str, poll_token: str) -> LoginFlowPollResult:
|
||||||
"""Poll for Login Flow v2 completion by sending an HTTP POST to the Nextcloud instance.
|
"""Poll for Login Flow v2 completion by sending an HTTP POST to the Nextcloud instance.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user