|
2 | 2 |
|
3 | 3 | import base64 |
4 | 4 | import os |
| 5 | +import threading |
5 | 6 | import time |
6 | 7 | import webbrowser |
7 | 8 | from abc import ABC, abstractmethod |
|
10 | 11 | from pathlib import Path |
11 | 12 | from typing import Any, cast |
12 | 13 |
|
| 14 | +import httpx |
13 | 15 | import jwt |
14 | 16 | import requests |
15 | 17 | from pydantic import TypeAdapter |
16 | 18 | from requests.auth import AuthBase |
17 | 19 |
|
18 | | -from blueapi.config import OIDCConfig |
| 20 | +from blueapi.config import OIDCConfig, ServiceAccount |
19 | 21 | from blueapi.service.model import Cache |
20 | 22 |
|
21 | 23 | DEFAULT_CACHE_DIR = "~/.cache/" |
@@ -239,3 +241,28 @@ def __call__(self, request): |
239 | 241 | if self.token: |
240 | 242 | request.headers["Authorization"] = f"Bearer {self.token}" |
241 | 243 | return request |
| 244 | + |
| 245 | + |
| 246 | +class TiledAuth(httpx.Auth): |
| 247 | + def __init__(self, tiled_auth: ServiceAccount): |
| 248 | + if tiled_auth.token_url == "": |
| 249 | + raise RuntimeError("Token URL is not set please check oidc config") |
| 250 | + self._tiled_auth: ServiceAccount = tiled_auth |
| 251 | + self._sync_lock = threading.RLock() |
| 252 | + |
| 253 | + def get_access_token(self): |
| 254 | + with self._sync_lock: |
| 255 | + response = httpx.post( |
| 256 | + self._tiled_auth.token_url, |
| 257 | + data={ |
| 258 | + "client_id": self._tiled_auth.client_id, |
| 259 | + "client_secret": self._tiled_auth.client_secret.get_secret_value(), |
| 260 | + "grant_type": "client_credentials", |
| 261 | + }, |
| 262 | + ) |
| 263 | + response.raise_for_status() |
| 264 | + return response.json().get("access_token") |
| 265 | + |
| 266 | + def sync_auth_flow(self, request): |
| 267 | + request.headers["Authorization"] = f"Bearer {self.get_access_token()}" |
| 268 | + yield request |
0 commit comments