Home Assistant Unofficial Reference 2024.12.1
oauth.py
Go to the documentation of this file.
1 """Provide oauth implementations for the Tesla Fleet integration."""
2 
3 import base64
4 import hashlib
5 import secrets
6 from typing import Any
7 
9  AuthImplementation,
10  AuthorizationServer,
11  ClientCredential,
12 )
13 from homeassistant.core import HomeAssistant
14 from homeassistant.helpers import config_entry_oauth2_flow
15 
16 from .const import AUTHORIZE_URL, CLIENT_ID, DOMAIN, SCOPES, TOKEN_URL
17 
18 
19 class TeslaSystemImplementation(config_entry_oauth2_flow.LocalOAuth2Implementation):
20  """Tesla Fleet API open source Oauth2 implementation."""
21 
22  code_verifier: str
23  code_challenge: str
24 
25  def __init__(self, hass: HomeAssistant) -> None:
26  """Initialize open source Oauth2 implementation."""
27 
28  # Setup PKCE
29  self.code_verifiercode_verifier = secrets.token_urlsafe(32)
30  hashed_verifier = hashlib.sha256(self.code_verifiercode_verifier.encode()).digest()
31  self.code_challengecode_challenge = (
32  base64.urlsafe_b64encode(hashed_verifier).decode().replace("=", "")
33  )
34  super().__init__(
35  hass,
36  DOMAIN,
37  CLIENT_ID,
38  "",
39  AUTHORIZE_URL,
40  TOKEN_URL,
41  )
42 
43  @property
44  def name(self) -> str:
45  """Name of the implementation."""
46  return "Built-in open source client ID"
47 
48  @property
49  def extra_authorize_data(self) -> dict[str, Any]:
50  """Extra data that needs to be appended to the authorize url."""
51  return {
52  "prompt": "login",
53  "scope": " ".join(SCOPES),
54  "code_challenge": self.code_challengecode_challenge, # PKCE
55  }
56 
57  async def async_resolve_external_data(self, external_data: Any) -> dict:
58  """Resolve the authorization code to tokens."""
59  return await self._token_request(
60  {
61  "grant_type": "authorization_code",
62  "code": external_data["code"],
63  "redirect_uri": external_data["state"]["redirect_uri"],
64  "code_verifier": self.code_verifiercode_verifier, # PKCE
65  }
66  )
67 
68 
70  """Tesla Fleet API user Oauth2 implementation."""
71 
72  def __init__(
73  self, hass: HomeAssistant, auth_domain: str, credential: ClientCredential
74  ) -> None:
75  """Initialize user Oauth2 implementation."""
76 
77  super().__init__(
78  hass,
79  auth_domain,
80  credential,
81  AuthorizationServer(AUTHORIZE_URL, TOKEN_URL),
82  )
83 
84  @property
85  def extra_authorize_data(self) -> dict[str, Any]:
86  """Extra data that needs to be appended to the authorize url."""
87  return {"prompt": "login", "scope": " ".join(SCOPES)}
None __init__(self, HomeAssistant hass, str auth_domain, ClientCredential credential)
Definition: oauth.py:74