Home Assistant Unofficial Reference 2024.12.1
oauth2.py
Go to the documentation of this file.
1 """OAuth2 implementations for Toon."""
2 
3 from __future__ import annotations
4 
5 from typing import Any, cast
6 
7 from homeassistant.core import HomeAssistant
8 from homeassistant.helpers import config_entry_oauth2_flow
9 from homeassistant.helpers.aiohttp_client import async_get_clientsession
10 
11 from . import config_flow
12 
13 
15  hass: HomeAssistant, client_id: str, client_secret: str
16 ) -> None:
17  """Register Toon OAuth2 implementations."""
18  config_flow.ToonFlowHandler.async_register_implementation(
19  hass,
21  hass,
22  client_id=client_id,
23  client_secret=client_secret,
24  name="Eneco Toon",
25  tenant_id="eneco",
26  issuer="identity.toon.eu",
27  ),
28  )
29  config_flow.ToonFlowHandler.async_register_implementation(
30  hass,
32  hass,
33  client_id=client_id,
34  client_secret=client_secret,
35  name="Engie Electrabel Boxx",
36  tenant_id="electrabel",
37  issuer="identity.toon.eu",
38  ),
39  )
40  config_flow.ToonFlowHandler.async_register_implementation(
41  hass,
43  hass,
44  client_id=client_id,
45  client_secret=client_secret,
46  name="Viesgo",
47  tenant_id="viesgo",
48  ),
49  )
50 
51 
52 class ToonLocalOAuth2Implementation(config_entry_oauth2_flow.LocalOAuth2Implementation):
53  """Local OAuth2 implementation for Toon."""
54 
55  def __init__(
56  self,
57  hass: HomeAssistant,
58  client_id: str,
59  client_secret: str,
60  name: str,
61  tenant_id: str,
62  issuer: str | None = None,
63  ) -> None:
64  """Local Toon Oauth Implementation."""
65  self._name_name = name
66  self.tenant_idtenant_id = tenant_id
67  self.issuerissuer = issuer
68 
69  super().__init__(
70  hass=hass,
71  domain=tenant_id,
72  client_id=client_id,
73  client_secret=client_secret,
74  authorize_url="https://api.toon.eu/authorize",
75  token_url="https://api.toon.eu/token",
76  )
77 
78  @property
79  def name(self) -> str:
80  """Name of the implementation."""
81  return f"{self._name} via Configuration.yaml"
82 
83  @property
84  def extra_authorize_data(self) -> dict:
85  """Extra data that needs to be appended to the authorize url."""
86  data = {"tenant_id": self.tenant_idtenant_id}
87 
88  if self.issuerissuer is not None:
89  data["issuer"] = self.issuerissuer
90 
91  return data
92 
93  async def async_resolve_external_data(self, external_data: Any) -> dict:
94  """Initialize local Toon auth implementation."""
95  data = {
96  "grant_type": "authorization_code",
97  "code": external_data["code"],
98  "redirect_uri": external_data["state"]["redirect_uri"],
99  "tenant_id": self.tenant_idtenant_id,
100  }
101 
102  if self.issuerissuer is not None:
103  data["issuer"] = self.issuerissuer
104 
105  return await self._token_request_token_request(data)
106 
107  async def _async_refresh_token(self, token: dict) -> dict:
108  """Refresh tokens."""
109  data = {
110  "grant_type": "refresh_token",
111  "client_id": self.client_id,
112  "refresh_token": token["refresh_token"],
113  "tenant_id": self.tenant_idtenant_id,
114  }
115 
116  new_token = await self._token_request_token_request(data)
117  return {**token, **new_token}
118 
119  async def _token_request(self, data: dict) -> dict:
120  """Make a token request."""
121  session = async_get_clientsession(self.hass)
122  headers = {}
123 
124  data["client_id"] = self.client_id
125  data["tenant_id"] = self.tenant_idtenant_id
126 
127  if self.client_secret is not None:
128  data["client_secret"] = self.client_secret
129 
130  if self.issuerissuer is not None:
131  data["issuer"] = self.issuerissuer
132  headers["issuer"] = self.issuerissuer
133 
134  resp = await session.post(self.token_url, data=data, headers=headers)
135  resp.raise_for_status()
136  resp_json = cast(dict, await resp.json())
137  # The Toon API returns "expires_in" as a string for some tenants.
138  # This is not according to OAuth specifications.
139  resp_json["expires_in"] = float(resp_json["expires_in"])
140  return resp_json
None __init__(self, HomeAssistant hass, str client_id, str client_secret, str name, str tenant_id, str|None issuer=None)
Definition: oauth2.py:63
None register_oauth2_implementations(HomeAssistant hass, str client_id, str client_secret)
Definition: oauth2.py:16
aiohttp.ClientSession async_get_clientsession(HomeAssistant hass, bool verify_ssl=True, socket.AddressFamily family=socket.AF_UNSPEC, ssl_util.SSLCipherList ssl_cipher=ssl_util.SSLCipherList.PYTHON_DEFAULT)