@@ -94,7 +94,7 @@ def __init__(
94
94
proxy_config = None ,
95
95
):
96
96
self .url = url if url is not None else MerginClient .default_url ()
97
- self ._auth_params = None
97
+ self ._auth_params = {}
98
98
self ._auth_session = None
99
99
self ._user_info = None
100
100
self ._server_type = None
@@ -192,36 +192,32 @@ def user_agent_info(self):
192
192
system_version = platform .mac_ver ()[0 ]
193
193
return f"{ self .client_version } ({ platform .system ()} /{ system_version } )"
194
194
195
- def _check_token (f ):
196
- """Wrapper for creating/renewing authorization token."""
197
-
198
- def wrapper (self , * args ):
199
- if self ._auth_params :
200
- if self ._auth_session :
201
- # Refresh auth token if it expired or will expire very soon
202
- delta = self ._auth_session ["expire" ] - datetime .now (timezone .utc )
203
- if delta .total_seconds () < 5 :
204
- self .log .info ("Token has expired - refreshing..." )
205
- if self ._auth_params .get ("login" , None ) and self ._auth_params .get ("password" , None ):
206
- self .log .info ("Token has expired - refreshing..." )
207
- self .login (self ._auth_params ["login" ], self ._auth_params ["password" ])
208
- else :
209
- raise AuthTokenExpiredError ("Token has expired - please re-login" )
210
- else :
211
- # Create a new authorization token
212
- self .log .info (f"No token - login user: { self ._auth_params ['login' ]} " )
213
- if self ._auth_params .get ("login" , None ) and self ._auth_params .get ("password" , None ):
214
- self .login (self ._auth_params ["login" ], self ._auth_params ["password" ])
215
- else :
216
- raise ClientError ("Missing login or password" )
217
-
218
- return f (self , * args )
195
+ def validate_auth (self ):
196
+ """Validate that client has valid auth token or can be logged in."""
219
197
220
- return wrapper
198
+ if self ._auth_session :
199
+ # Refresh auth token if it expired or will expire very soon
200
+ delta = self ._auth_session ["expire" ] - datetime .now (timezone .utc )
201
+ if delta .total_seconds () < 5 :
202
+ self .log .info ("Token has expired - refreshing..." )
203
+ if self ._auth_params .get ("login" , None ) and self ._auth_params .get ("password" , None ):
204
+ self .log .info ("Token has expired - refreshing..." )
205
+ self .login (self ._auth_params ["login" ], self ._auth_params ["password" ])
206
+ else :
207
+ raise AuthTokenExpiredError ("Token has expired - please re-login" )
208
+ else :
209
+ # Create a new authorization token
210
+ self .log .info (f"No token - login user: { self ._auth_params .get ('login' , None )} " )
211
+ if self ._auth_params .get ("login" , None ) and self ._auth_params .get ("password" , None ):
212
+ self .login (self ._auth_params ["login" ], self ._auth_params ["password" ])
213
+ else :
214
+ raise ClientError ("Missing login or password" )
221
215
222
- @_check_token
223
- def _do_request (self , request ):
216
+ def _do_request (self , request , validate_auth = True ):
224
217
"""General server request method."""
218
+ if validate_auth :
219
+ self .validate_auth ()
220
+
225
221
if self ._auth_session :
226
222
request .add_header ("Authorization" , self ._auth_session ["token" ])
227
223
request .add_header ("User-Agent" , self .user_agent_info ())
@@ -263,31 +259,31 @@ def _do_request(self, request):
263
259
# e.g. when DNS resolution fails (no internet connection?)
264
260
raise ClientError ("Error requesting " + request .full_url + ": " + str (e ))
265
261
266
- def get (self , path , data = None , headers = {}):
262
+ def get (self , path , data = None , headers = {}, validate_auth = True ):
267
263
url = urllib .parse .urljoin (self .url , urllib .parse .quote (path ))
268
264
if data :
269
265
url += "?" + urllib .parse .urlencode (data )
270
266
request = urllib .request .Request (url , headers = headers )
271
- return self ._do_request (request )
267
+ return self ._do_request (request , validate_auth = validate_auth )
272
268
273
- def post (self , path , data = None , headers = {}):
269
+ def post (self , path , data = None , headers = {}, validate_auth = True ):
274
270
url = urllib .parse .urljoin (self .url , urllib .parse .quote (path ))
275
271
if headers .get ("Content-Type" , None ) == "application/json" :
276
272
data = json .dumps (data , cls = DateTimeEncoder ).encode ("utf-8" )
277
273
request = urllib .request .Request (url , data , headers , method = "POST" )
278
- return self ._do_request (request )
274
+ return self ._do_request (request , validate_auth = validate_auth )
279
275
280
- def patch (self , path , data = None , headers = {}):
276
+ def patch (self , path , data = None , headers = {}, validate_auth = True ):
281
277
url = urllib .parse .urljoin (self .url , urllib .parse .quote (path ))
282
278
if headers .get ("Content-Type" , None ) == "application/json" :
283
279
data = json .dumps (data , cls = DateTimeEncoder ).encode ("utf-8" )
284
280
request = urllib .request .Request (url , data , headers , method = "PATCH" )
285
- return self ._do_request (request )
281
+ return self ._do_request (request , validate_auth = validate_auth )
286
282
287
- def delete (self , path ):
283
+ def delete (self , path , validate_auth = True ):
288
284
url = urllib .parse .urljoin (self .url , urllib .parse .quote (path ))
289
285
request = urllib .request .Request (url , method = "DELETE" )
290
- return self ._do_request (request )
286
+ return self ._do_request (request , validate_auth = validate_auth )
291
287
292
288
def login (self , login , password ):
293
289
"""
@@ -303,26 +299,16 @@ def login(self, login, password):
303
299
self ._auth_session = None
304
300
self .log .info (f"Going to log in user { login } " )
305
301
try :
306
- self ._auth_params = params
307
- url = urllib .parse .urljoin (self .url , urllib .parse .quote ("/v1/auth/login" ))
308
- data = json .dumps (self ._auth_params , cls = DateTimeEncoder ).encode ("utf-8" )
309
- request = urllib .request .Request (url , data , {"Content-Type" : "application/json" }, method = "POST" )
310
- request .add_header ("User-Agent" , self .user_agent_info ())
311
- resp = self .opener .open (request )
302
+ resp = self .post (
303
+ "/v1/auth/login" , data = params , headers = {"Content-Type" : "application/json" }, validate_auth = False
304
+ )
312
305
data = json .load (resp )
313
306
session = data ["session" ]
314
- except urllib .error .HTTPError as e :
315
- if e .headers .get ("Content-Type" , "" ) == "application/problem+json" :
316
- info = json .load (e )
317
- self .log .info (f"Login problem: { info .get ('detail' )} " )
318
- raise LoginError (info .get ("detail" ))
319
- self .log .info (f"Login problem: { e .read ().decode ('utf-8' )} " )
320
- raise LoginError (e .read ().decode ("utf-8" ))
321
- except urllib .error .URLError as e :
322
- # e.g. when DNS resolution fails (no internet connection?)
323
- raise ClientError ("failure reason: " + str (e .reason ))
307
+ except ClientError as e :
308
+ self .log .info (f"Login problem: { e .detail } " )
309
+ raise LoginError (e .detail )
324
310
self ._auth_session = {
325
- "token" : "Bearer %s" % session [" token" ] ,
311
+ "token" : f "Bearer { session [' token' ] } " ,
326
312
"expire" : dateutil .parser .parse (session ["expire" ]),
327
313
}
328
314
self ._user_info = {"username" : data ["username" ]}
@@ -367,7 +353,7 @@ def server_type(self):
367
353
"""
368
354
if not self ._server_type :
369
355
try :
370
- resp = self .get ("/config" )
356
+ resp = self .get ("/config" , validate_auth = False )
371
357
config = json .load (resp )
372
358
if config ["server_type" ] == "ce" :
373
359
self ._server_type = ServerType .CE
@@ -389,7 +375,7 @@ def server_version(self):
389
375
"""
390
376
if self ._server_version is None :
391
377
try :
392
- resp = self .get ("/config" )
378
+ resp = self .get ("/config" , validate_auth = False )
393
379
config = json .load (resp )
394
380
self ._server_version = config ["version" ]
395
381
except (ClientError , KeyError ):
@@ -1386,7 +1372,7 @@ def remove_project_collaborator(self, project_id: str, user_id: int):
1386
1372
1387
1373
def server_config (self ) -> dict :
1388
1374
"""Get server configuration as dictionary."""
1389
- response = self .get ("/config" )
1375
+ response = self .get ("/config" , validate_auth = False )
1390
1376
return json .load (response )
1391
1377
1392
1378
def send_logs (
0 commit comments