1 """application_credentials platform the fitbit integration.
3 See https://dev.fitbit.com/build/reference/web-api/authorization/ for additional
4 details on Fitbit authorization.
8 from http
import HTTPStatus
10 from typing
import Any, cast
23 from .const
import CONF_CLIENT_ID, CONF_CLIENT_SECRET, OAUTH2_AUTHORIZE, OAUTH2_TOKEN
24 from .exceptions
import FitbitApiException, FitbitAuthException
26 _LOGGER = logging.getLogger(__name__)
30 """Local OAuth2 implementation for Fitbit.
32 This implementation is needed to send the client id and secret as a Basic
37 """Resolve the authorization code to tokens."""
38 return await self._post(
40 "grant_type":
"authorization_code",
41 "code": external_data[
"code"],
42 "redirect_uri": external_data[
"state"][
"redirect_uri"],
46 async
def _token_request(self, data: dict) -> dict:
47 """Make a token request."""
48 return await self._post(
51 CONF_CLIENT_ID: self.client_id,
52 CONF_CLIENT_SECRET: self.client_secret,
56 async
def _post(self, data: dict[str, Any]) -> dict[str, Any]:
59 resp = await session.post(self.token_url, data=data, headers=self._headers)
60 resp.raise_for_status()
61 except aiohttp.ClientResponseError
as err:
62 if _LOGGER.isEnabledFor(logging.DEBUG):
64 error_body = await resp.text()
65 except aiohttp.ClientError:
68 "Client response error status=%s, body=%s", err.status, error_body
70 if err.status == HTTPStatus.UNAUTHORIZED:
72 if err.status == HTTPStatus.BAD_REQUEST:
75 except aiohttp.ClientError
as err:
77 return cast(dict, await resp.json())
80 def _headers(self) -> dict[str, str]:
81 """Build necessary authorization headers."""
82 basic_auth = base64.b64encode(
83 f
"{self.client_id}:{self.client_secret}".encode()
85 return {
"Authorization": f
"Basic {basic_auth}"}
89 hass: HomeAssistant, auth_domain: str, credential: ClientCredential
90 ) -> config_entry_oauth2_flow.AbstractOAuth2Implementation:
91 """Return a custom auth implementation."""
97 authorize_url=OAUTH2_AUTHORIZE,
98 token_url=OAUTH2_TOKEN,
dict async_resolve_external_data(self, dict[str, Any] external_data)
config_entry_oauth2_flow.AbstractOAuth2Implementation async_get_auth_implementation(HomeAssistant hass, str auth_domain, ClientCredential credential)
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)