@@ -58,19 +58,57 @@ def load_centml_cred():
5858
5959
6060def get_centml_token ():
61+ # Always use fresh client credentials if available
62+ if settings .CENTML_SERVICE_ACCOUNT_ID and settings .CENTML_SERVICE_ACCOUNT_SECRET :
63+ access_token = authenticate_with_client_credentials ()
64+ if access_token is not None :
65+ return access_token
66+ else :
67+ sys .exit (
68+ "Could not authenticate with client credentials. Please check your service account configuration..."
69+ )
70+
71+ # Fall back to stored credentials for interactive flows
6172 cred = load_centml_cred ()
6273 if not cred :
6374 sys .exit ("CentML credentials not found. Please login..." )
6475 exp_time = int (jwt .decode (cred ["access_token" ], options = {"verify_signature" : False })["exp" ])
6576
6677 if time .time () >= exp_time - 100 :
67- cred = refresh_centml_token (cred ["refresh_token" ])
68- if cred is None :
78+ # Check if we have a refresh token (interactive flow)
79+ refresh_token = cred .get ("refresh_token" )
80+ if refresh_token is not None :
81+ # Use refresh token for interactive authentication
82+ cred = refresh_centml_token (cred ["refresh_token" ])
83+ if cred is None :
84+ sys .exit ("Could not refresh credentials. Please login and try again..." )
85+ else :
6986 sys .exit ("Could not refresh credentials. Please login and try again..." )
7087
7188 return cred ["access_token" ]
7289
7390
91+ def authenticate_with_client_credentials ():
92+ """
93+ Authenticate using client credentials flow for service-to-service authentication.
94+ Returns access token if successful, None otherwise.
95+ """
96+ if not settings .CENTML_SERVICE_ACCOUNT_ID or not settings .CENTML_SERVICE_ACCOUNT_SECRET :
97+ return None
98+
99+ params = {
100+ 'grant_type' : 'client_credentials' ,
101+ 'client_id' : settings .CENTML_SERVICE_ACCOUNT_ID ,
102+ 'client_secret' : settings .CENTML_SERVICE_ACCOUNT_SECRET ,
103+ 'scope' : 'openid profile email' ,
104+ }
105+ response = requests .post (settings .CENTML_SERVICE_ACCOUNT_TOKEN_URL , data = params , timeout = 10 )
106+ response .raise_for_status ()
107+ response_data = response .json ()
108+ access_token = response_data .get ('access_token' )
109+ return access_token
110+
111+
74112def remove_centml_cred ():
75113 if os .path .exists (settings .CENTML_CRED_FILE_PATH ):
76114 os .remove (settings .CENTML_CRED_FILE_PATH )
0 commit comments