Files
webmail-client/backend/app/plugins/http.py
T

40 lines
1.6 KiB
Python
Raw Normal View History

"""SSRF-guarded, multi-method HTTP client exposed to plugins (SPEC §10.6).
``sdk.http_get`` covers simple GETs; heavy plugins that speak CalDAV/CardDAV need
other verbs (PROPFIND/REPORT/PUT/DELETE) with request bodies and basic auth. This
facade routes all of them through the same SSRF policy (HTTPS-only, public host,
no off-domain redirects, size cap) and returns status + headers + body.
"""
from __future__ import annotations
from app.accounts.ssrf import GuardedResponse, guarded_request
class PluginHttp:
async def request(
self,
method: str,
url: str,
*,
headers: dict[str, str] | None = None,
content: bytes | str | None = None,
auth: tuple[str, str] | None = None,
) -> GuardedResponse:
return await guarded_request(method, url, headers=headers, content=content, auth=auth)
async def get(self, url: str, **kw: object) -> GuardedResponse:
return await self.request("GET", url, **kw) # type: ignore[arg-type]
async def put(self, url: str, **kw: object) -> GuardedResponse:
return await self.request("PUT", url, **kw) # type: ignore[arg-type]
async def delete(self, url: str, **kw: object) -> GuardedResponse:
return await self.request("DELETE", url, **kw) # type: ignore[arg-type]
async def propfind(self, url: str, **kw: object) -> GuardedResponse:
return await self.request("PROPFIND", url, **kw) # type: ignore[arg-type]
async def report(self, url: str, **kw: object) -> GuardedResponse:
return await self.request("REPORT", url, **kw) # type: ignore[arg-type]