11"""Custom OAuth2 implementation."""
2+
23import base64
34import hashlib
45import os
89from homeassistant .core import HomeAssistant
910from homeassistant .helpers .config_entry_oauth2_flow import LocalOAuth2Implementation
1011
11- from pyhilo .const import (
12- AUTH_AUTHORIZE ,
13- AUTH_CHALLENGE_METHOD ,
14- AUTH_CLIENT_ID ,
15- AUTH_SCOPE ,
16- AUTH_TOKEN ,
17- DOMAIN ,
18- )
12+ from pyhilo .const import AUTH_AUTHORIZE , AUTH_CLIENT_ID , AUTH_TOKEN , DOMAIN
13+
14+ from pyhilo .oauth2helper import OAuth2Helper
1915
2016
2117class AuthCodeWithPKCEImplementation (LocalOAuth2Implementation ): # type: ignore[misc]
@@ -34,8 +30,8 @@ def __init__(
3430 AUTH_AUTHORIZE ,
3531 AUTH_TOKEN ,
3632 )
37- self . _code_verifier = self . _get_code_verifier ()
38- self ._code_challenge = self . _get_code_challange ( self . _code_verifier )
33+
34+ self .oauth_helper = OAuth2Helper ( )
3935
4036 # ... Override AbstractOAuth2Implementation details
4137 @property
@@ -46,32 +42,15 @@ def name(self) -> str:
4642 @property
4743 def extra_authorize_data (self ) -> dict :
4844 """Extra data that needs to be appended to the authorize url."""
49- return {
50- "scope" : AUTH_SCOPE ,
51- "code_challenge" : self ._code_challenge ,
52- "code_challenge_method" : AUTH_CHALLENGE_METHOD ,
53- }
45+ return self .oauth_helper .get_authorize_parameters ()
5446
5547 async def async_resolve_external_data (self , external_data : Any ) -> dict :
5648 """Resolve the authorization code to tokens."""
5749 return cast (
5850 dict ,
5951 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_verifier ,
65- },
52+ self .oauth_helper .get_token_request_parameters (
53+ external_data ["code" ], external_data ["state" ]["redirect_uri" ]
54+ )
6655 ),
6756 )
68-
69- # Ref : https://blog.sanghviharshit.com/reverse-engineering-private-api-oauth-code-flow-with-pkce/
70- def _get_code_verifier (self ) -> str :
71- code = base64 .urlsafe_b64encode (os .urandom (40 )).decode ("utf-8" )
72- return re .sub ("[^a-zA-Z0-9]+" , "" , code )
73-
74- def _get_code_challange (self , verifier : str ) -> str :
75- sha_verifier = hashlib .sha256 (verifier .encode ("utf-8" )).digest ()
76- code = base64 .urlsafe_b64encode (sha_verifier ).decode ("utf-8" )
77- return code .replace ("=" , "" )
0 commit comments