2020-01-17 10:28:44 -08:00
|
|
|
import jwt
|
2021-08-03 19:49:49 +08:00
|
|
|
import os
|
2020-01-17 10:28:44 -08:00
|
|
|
import requests
|
2024-06-11 13:45:15 -07:00
|
|
|
from datetime import datetime, timedelta, UTC
|
2023-11-30 09:55:48 -08:00
|
|
|
from openpilot.system.hardware.hw import Paths
|
2023-08-20 20:49:55 -07:00
|
|
|
from openpilot.system.version import get_version
|
2020-01-17 10:28:44 -08:00
|
|
|
|
2021-08-03 19:49:49 +08:00
|
|
|
API_HOST = os.getenv('API_HOST', 'https://api.commadotai.com')
|
|
|
|
|
|
2025-12-11 18:00:43 -08:00
|
|
|
# name: jwt signature algorithm
|
|
|
|
|
KEYS = {"id_rsa": "RS256",
|
|
|
|
|
"id_ecdsa": "ES256"}
|
|
|
|
|
|
2025-11-03 22:45:00 -08:00
|
|
|
|
2024-05-20 17:43:54 -07:00
|
|
|
class Api:
|
2020-01-17 10:28:44 -08:00
|
|
|
def __init__(self, dongle_id):
|
|
|
|
|
self.dongle_id = dongle_id
|
2025-11-03 22:45:00 -08:00
|
|
|
self.jwt_algorithm, self.private_key, _ = get_key_pair()
|
2020-01-17 10:28:44 -08:00
|
|
|
|
|
|
|
|
def get(self, *args, **kwargs):
|
|
|
|
|
return self.request('GET', *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
def post(self, *args, **kwargs):
|
|
|
|
|
return self.request('POST', *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
def request(self, method, endpoint, timeout=None, access_token=None, **params):
|
|
|
|
|
return api_get(endpoint, method=method, timeout=timeout, access_token=access_token, **params)
|
|
|
|
|
|
2025-09-18 17:03:16 -07:00
|
|
|
def get_token(self, payload_extra=None, expiry_hours=1):
|
2024-06-11 13:45:15 -07:00
|
|
|
now = datetime.now(UTC).replace(tzinfo=None)
|
2020-01-17 10:28:44 -08:00
|
|
|
payload = {
|
|
|
|
|
'identity': self.dongle_id,
|
|
|
|
|
'nbf': now,
|
|
|
|
|
'iat': now,
|
2022-05-30 15:15:51 +02:00
|
|
|
'exp': now + timedelta(hours=expiry_hours)
|
2020-01-17 10:28:44 -08:00
|
|
|
}
|
2025-09-18 17:03:16 -07:00
|
|
|
if payload_extra is not None:
|
|
|
|
|
payload.update(payload_extra)
|
2025-11-03 22:45:00 -08:00
|
|
|
token = jwt.encode(payload, self.private_key, algorithm=self.jwt_algorithm)
|
2021-02-02 20:06:04 +05:30
|
|
|
if isinstance(token, bytes):
|
|
|
|
|
token = token.decode('utf8')
|
|
|
|
|
return token
|
2021-11-29 19:38:55 +01:00
|
|
|
|
2020-01-17 10:28:44 -08:00
|
|
|
|
|
|
|
|
def api_get(endpoint, method='GET', timeout=None, access_token=None, **params):
|
|
|
|
|
headers = {}
|
|
|
|
|
if access_token is not None:
|
2021-11-29 19:38:55 +01:00
|
|
|
headers['Authorization'] = "JWT " + access_token
|
2020-01-17 10:28:44 -08:00
|
|
|
|
2021-11-29 19:38:55 +01:00
|
|
|
headers['User-Agent'] = "openpilot-" + get_version()
|
2020-01-17 10:28:44 -08:00
|
|
|
|
2021-08-03 15:33:41 +02:00
|
|
|
return requests.request(method, API_HOST + "/" + endpoint, timeout=timeout, headers=headers, params=params)
|
2025-11-03 22:45:00 -08:00
|
|
|
|
2025-12-11 18:00:43 -08:00
|
|
|
|
|
|
|
|
def get_key_pair() -> tuple[str, str, str] | tuple[None, None, None]:
|
2025-11-03 22:45:00 -08:00
|
|
|
for key in KEYS:
|
|
|
|
|
if os.path.isfile(Paths.persist_root() + f'/comma/{key}') and os.path.isfile(Paths.persist_root() + f'/comma/{key}.pub'):
|
|
|
|
|
with open(Paths.persist_root() + f'/comma/{key}') as private, open(Paths.persist_root() + f'/comma/{key}.pub') as public:
|
|
|
|
|
return KEYS[key], private.read(), public.read()
|
|
|
|
|
return None, None, None
|