124 lines
4.6 KiB
Python
124 lines
4.6 KiB
Python
"""Small async client for the internal AuthZ service."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
import httpx
|
|
|
|
|
|
class AuthzClient:
|
|
def __init__(self, base_url: str, timeout_seconds: int = 10) -> None:
|
|
self.base_url = base_url.rstrip("/")
|
|
self.timeout_seconds = timeout_seconds
|
|
|
|
async def _request(self, method: str, path: str, *, json_body: dict[str, Any] | None = None) -> Any:
|
|
async with httpx.AsyncClient(
|
|
timeout=self.timeout_seconds,
|
|
follow_redirects=True,
|
|
trust_env=False,
|
|
) as client:
|
|
response = await client.request(method, f"{self.base_url}{path}", json=json_body)
|
|
response.raise_for_status()
|
|
if not response.content:
|
|
return None
|
|
return response.json()
|
|
|
|
async def issue_token(
|
|
self,
|
|
*,
|
|
client_id: str,
|
|
client_secret: str,
|
|
audience: str,
|
|
scopes: list[str],
|
|
) -> dict[str, Any]:
|
|
data = await self._request(
|
|
"POST",
|
|
"/oauth/token",
|
|
json_body={
|
|
"grant_type": "client_credentials",
|
|
"client_id": client_id,
|
|
"client_secret": client_secret,
|
|
"aud": audience,
|
|
"scopes": list(scopes),
|
|
},
|
|
)
|
|
return data if isinstance(data, dict) else {}
|
|
|
|
async def get_permissions(self, backend_id: str) -> dict[str, Any]:
|
|
data = await self._request("GET", f"/backends/{backend_id}/permissions")
|
|
return data if isinstance(data, dict) else {}
|
|
|
|
async def set_permissions(self, backend_id: str, payload: dict[str, Any]) -> dict[str, Any]:
|
|
data = await self._request("POST", f"/backends/{backend_id}/permissions", json_body=payload)
|
|
return data if isinstance(data, dict) else {}
|
|
|
|
async def register_user(
|
|
self,
|
|
*,
|
|
username: str,
|
|
password: str,
|
|
email: str | None = None,
|
|
backend_name: str | None = None,
|
|
backend_id: str | None = None,
|
|
base_url: str | None = None,
|
|
frontend_base_url: str | None = None,
|
|
) -> dict[str, Any]:
|
|
payload: dict[str, Any] = {
|
|
"username": username,
|
|
"password": password,
|
|
}
|
|
optional = {
|
|
"email": email,
|
|
"backend_name": backend_name,
|
|
"backend_id": backend_id,
|
|
"base_url": base_url,
|
|
"frontend_base_url": frontend_base_url,
|
|
}
|
|
payload.update({key: value for key, value in optional.items() if value})
|
|
data = await self._request("POST", "/oauth/register", json_body=payload)
|
|
return data if isinstance(data, dict) else {}
|
|
|
|
async def register_backend(
|
|
self,
|
|
*,
|
|
name: str,
|
|
base_url: str,
|
|
frontend_base_url: str | None = None,
|
|
backend_id: str | None = None,
|
|
) -> dict[str, Any]:
|
|
payload: dict[str, Any] = {
|
|
"name": name,
|
|
"base_url": base_url,
|
|
}
|
|
if frontend_base_url:
|
|
payload["frontend_base_url"] = frontend_base_url
|
|
if backend_id:
|
|
payload["backend_id"] = backend_id
|
|
data = await self._request("POST", "/backends/register", json_body=payload)
|
|
return data if isinstance(data, dict) else {}
|
|
|
|
async def get_outlook_settings(self, backend_id: str) -> dict[str, Any]:
|
|
data = await self._request("GET", f"/backends/{backend_id}/settings/outlook")
|
|
return data if isinstance(data, dict) else {}
|
|
|
|
async def set_outlook_settings(self, backend_id: str, payload: dict[str, Any]) -> dict[str, Any]:
|
|
data = await self._request("POST", f"/backends/{backend_id}/settings/outlook", json_body=payload)
|
|
return data if isinstance(data, dict) else {}
|
|
|
|
async def delete_outlook_settings(self, backend_id: str) -> dict[str, Any]:
|
|
data = await self._request("DELETE", f"/backends/{backend_id}/settings/outlook")
|
|
return data if isinstance(data, dict) else {}
|
|
|
|
async def get_minio_settings(self, backend_id: str) -> dict[str, Any]:
|
|
data = await self._request("GET", f"/backends/{backend_id}/settings/minio")
|
|
return data if isinstance(data, dict) else {}
|
|
|
|
async def set_minio_settings(self, backend_id: str, payload: dict[str, Any]) -> dict[str, Any]:
|
|
data = await self._request("POST", f"/backends/{backend_id}/settings/minio", json_body=payload)
|
|
return data if isinstance(data, dict) else {}
|
|
|
|
async def delete_minio_settings(self, backend_id: str) -> dict[str, Any]:
|
|
data = await self._request("DELETE", f"/backends/{backend_id}/settings/minio")
|
|
return data if isinstance(data, dict) else {}
|