@@ -69,11 +69,11 @@ def _check_token_is_valid(self):
6969
7070 if (now_unix > expiry_in_token ) or \
7171 (now_unix > self ._token ["unix_timestamp_token_received" ] + self ._token ["expires_in_sec" ]):
72-
72+
7373 if self ._raw :
7474 print ("--- Token is invalid" )
7575 return False
76-
76+
7777 if self ._raw :
7878 print ("--- Token is valid" )
7979 return True
@@ -82,6 +82,32 @@ def _check_token_is_valid(self):
8282 print ("--- Token is invalid" )
8383 return False
8484
85+ def _get_api_key (self , timestamp , token ):
86+ try :
87+ date = datetime .datetime .strptime (timestamp , '%Y-%m-%d %H:%M:%S' )
88+ timestamp_ms = str (int (date .replace (tzinfo = datetime .timezone .utc ).timestamp () * 1000 ))
89+
90+ components = [
91+ 'Comfort Cloud' .encode ('utf-8' ),
92+ '521325fb2dd486bf4831b47644317fca' .encode ('utf-8' ),
93+ timestamp_ms .encode ('utf-8' ),
94+ 'Bearer ' .encode ('utf-8' ),
95+ token .encode ('utf-8' )
96+ ]
97+
98+ input_buffer = b'' .join (components )
99+ hash_obj = hashlib .sha256 ()
100+ hash_obj .update (input_buffer )
101+ hash_str = hash_obj .hexdigest ()
102+
103+ result = hash_str [:9 ] + 'cfc' + hash_str [9 :]
104+ return result
105+ except Exception as ex :
106+ raise exceptions .ResponseError (
107+ f"(CFC: Failed to generate API key: " +
108+ f"{ ex } "
109+ )
110+
85111 def _get_new_token (self ):
86112 requests_session = requests .Session ()
87113
@@ -242,7 +268,7 @@ def _get_new_token(self):
242268 "x-app-timestamp" : timestamp ,
243269 "x-app-type" : "1" ,
244270 "x-app-version" : self ._app_version ,
245- "x-cfc-api-key" : generate_random_string_hex ( 128 ),
271+ "x-cfc-api-key" : self . _get_api_key ( timestamp , token_response [ "access_token" ] ),
246272 "x-user-authorization-v2" : "Bearer " + token_response ["access_token" ]
247273 },
248274 json = {
@@ -265,7 +291,7 @@ def _get_new_token(self):
265291
266292 def get_token (self ):
267293 return self ._token
268-
294+
269295 def set_token (self , token ):
270296 self ._token = token
271297
@@ -280,7 +306,7 @@ def login(self):
280306 else :
281307 self ._get_new_token ()
282308 return "Authenticating"
283-
309+
284310 return "Valid"
285311
286312 def logout (self ):
@@ -311,11 +337,11 @@ def _refresh_token(self):
311337 "grant_type" : "refresh_token"
312338 },
313339 allow_redirects = False )
314-
340+
315341 if response .status_code != 200 :
316342 self ._get_new_token ()
317343 return
318-
344+
319345 token_response = json .loads (response .text )
320346
321347 self ._token = {
@@ -338,9 +364,7 @@ def _get_header_for_api_calls(self, no_client_id=False):
338364 "x-app-timestamp" : timestamp ,
339365 "x-app-type" : "1" ,
340366 "x-app-version" : self ._app_version ,
341- # Seems to work by either setting X-CFC-API-KEY to 0 or to a 128-long hex string
342- # "X-CFC-API-KEY": "0",
343- "x-cfc-api-key" : generate_random_string_hex (128 ),
367+ "x-cfc-api-key" : self ._get_api_key (timestamp , self ._token ["access_token" ]),
344368 "x-client-id" : self ._token ["acc_client_id" ],
345369 "x-user-authorization-v2" : "Bearer " + self ._token ["access_token" ]
346370 }
@@ -425,7 +449,8 @@ def _update_app_version(self):
425449 return
426450 else :
427451 self ._app_version = constants .X_APP_VERSION
428- print ("--- Error finding meta_tag" )
452+ if self ._raw :
453+ print ("--- Error finding meta_tag" )
429454 return
430455
431456 except Exception :
0 commit comments