dotstat_io 1.0.0__tar.gz → 1.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dotstat_io might be problematic. Click here for more details.
- {dotstat_io-1.0.0 → dotstat_io-1.0.2}/PKG-INFO +1 -1
- {dotstat_io-1.0.0 → dotstat_io-1.0.2}/dotstat_io/authentication.py +42 -28
- {dotstat_io-1.0.0 → dotstat_io-1.0.2}/dotstat_io/client.py +39 -13
- {dotstat_io-1.0.0 → dotstat_io-1.0.2}/pyproject.toml +1 -1
- {dotstat_io-1.0.0 → dotstat_io-1.0.2}/README.md +0 -0
- {dotstat_io-1.0.0 → dotstat_io-1.0.2}/dotstat_io/__init__.py +0 -0
|
@@ -18,10 +18,6 @@ class AuthenticationMode(IntEnum):
|
|
|
18
18
|
# super class to manage authentication
|
|
19
19
|
class Authentication(ABC):
|
|
20
20
|
|
|
21
|
-
# protected constants
|
|
22
|
-
_ERROR_OCCURRED = "An error occurred: "
|
|
23
|
-
_SUCCESS = "Successful authentication"
|
|
24
|
-
|
|
25
21
|
# protected variables
|
|
26
22
|
_access_token = None
|
|
27
23
|
_refresh_token = None
|
|
@@ -96,6 +92,10 @@ class Authentication(ABC):
|
|
|
96
92
|
|
|
97
93
|
# sub class to manage ADFS authentication using OIDC flows
|
|
98
94
|
class AdfsAuthentication(Authentication):
|
|
95
|
+
# private constants
|
|
96
|
+
__ERROR_OCCURRED = "An error occurred: "
|
|
97
|
+
__SUCCESSFUL_AUTHENTICATION = "Successful authentication"
|
|
98
|
+
|
|
99
99
|
#
|
|
100
100
|
def _initialize_token(self):
|
|
101
101
|
self._access_token = None
|
|
@@ -193,20 +193,20 @@ class AdfsAuthentication(Authentication):
|
|
|
193
193
|
self._refresh_token = response_interactive.get("refresh_token")
|
|
194
194
|
self._creation_time = time.time()
|
|
195
195
|
self._expiration_time = time.time() + int(response_interactive.get("expires_in")) - 60 # one minute margin
|
|
196
|
-
self.init_status = self.
|
|
196
|
+
self.init_status = self.__SUCCESSFUL_AUTHENTICATION
|
|
197
197
|
else:
|
|
198
|
-
self.init_status = f'{self.
|
|
198
|
+
self.init_status = f'{self.__ERROR_OCCURRED}{response_interactive.get("error")} Error description: {response_interactive.get("error_description")}'
|
|
199
199
|
else:
|
|
200
200
|
if "access_token" in response_silent:
|
|
201
201
|
self._access_token = response_silent.get("access_token")
|
|
202
202
|
self._refresh_token = response_silent.get("refresh_token")
|
|
203
203
|
self._creation_time = time.time()
|
|
204
204
|
self._expiration_time = time.time() + int(response_silent.get("expires_in")) - 60 # one minute margin
|
|
205
|
-
self.init_status = self.
|
|
205
|
+
self.init_status = self.__SUCCESSFUL_AUTHENTICATION
|
|
206
206
|
else:
|
|
207
|
-
self.init_status = f'{self.
|
|
207
|
+
self.init_status = f'{self.__ERROR_OCCURRED}{response_silent.get("error")} Error description: {response_silent.get("error_description")}'
|
|
208
208
|
except Exception as err:
|
|
209
|
-
self.init_status = f'{self.
|
|
209
|
+
self.init_status = f'{self.__ERROR_OCCURRED}{err}\n'
|
|
210
210
|
|
|
211
211
|
# Authentication non-interactively using any account - aka Client Credentials flow
|
|
212
212
|
def __acquire_token_noninteractive_with_secret(self):
|
|
@@ -216,12 +216,12 @@ class AdfsAuthentication(Authentication):
|
|
|
216
216
|
self._access_token = response.get("access_token")
|
|
217
217
|
self._creation_time = time.time()
|
|
218
218
|
self._expiration_time = time.time() + int(response.get("expires_in")) - 60 # one minute margin
|
|
219
|
-
self.init_status = self.
|
|
219
|
+
self.init_status = self.__SUCCESSFUL_AUTHENTICATION
|
|
220
220
|
else:
|
|
221
|
-
self.init_status = f'{self.
|
|
221
|
+
self.init_status = f'{self.__ERROR_OCCURRED}{response.get("error")} Error description: {response.get("error_description")}'
|
|
222
222
|
|
|
223
223
|
except Exception as err:
|
|
224
|
-
self.init_status = f'{self.
|
|
224
|
+
self.init_status = f'{self.__ERROR_OCCURRED}{err}\n'
|
|
225
225
|
|
|
226
226
|
# Authentication non-interactively using service account - aka Windows Client Authentication
|
|
227
227
|
def __acquire_token_noninteractive_with_adfs(self):
|
|
@@ -250,26 +250,35 @@ class AdfsAuthentication(Authentication):
|
|
|
250
250
|
self._access_token = results_json['access_token']
|
|
251
251
|
self._creation_time = time.time()
|
|
252
252
|
self._expiration_time = time.time() + int(results_json['expires_in']) - 60 # one minute margin
|
|
253
|
-
self.init_status = self.
|
|
253
|
+
self.init_status = self.__SUCCESSFUL_AUTHENTICATION
|
|
254
254
|
else:
|
|
255
|
-
message = f'{self.
|
|
255
|
+
message = f'{self.__ERROR_OCCURRED} Error code: {response.status_code}'
|
|
256
256
|
if len(str(response.reason)) > 0:
|
|
257
257
|
message += os.linesep + 'Reason: ' + str(response.reason) + os.linesep
|
|
258
258
|
if len(response.text) > 0:
|
|
259
|
-
message += f'{self.
|
|
259
|
+
message += f'{self.__ERROR_OCCURRED}{results_json.get("error")} Error description: {results_json.get("error_description")}\n'
|
|
260
260
|
|
|
261
261
|
self.init_status = message
|
|
262
262
|
except ValueError as err:
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
263
|
+
self.init_status = self.__ERROR_OCCURRED + os.linesep
|
|
264
|
+
if len(str(response.status_code)) > 0:
|
|
265
|
+
self.init_status += 'Error code: ' + str(response.status_code) + os.linesep
|
|
266
|
+
if len(str(response.reason)) > 0:
|
|
267
|
+
self.init_status += 'Reason: ' + str(response.reason) + os.linesep
|
|
268
|
+
if len(response.text) > 0:
|
|
269
|
+
self.init_status += str(response.text)
|
|
270
|
+
else:
|
|
271
|
+
self.init_status += str(err)
|
|
267
272
|
except Exception as err:
|
|
268
|
-
self.init_status = f'{self.
|
|
273
|
+
self.init_status = f'{self.__ERROR_OCCURRED} {err}\n'
|
|
269
274
|
|
|
270
275
|
|
|
271
276
|
# sub class to manage Keycloak authentication
|
|
272
|
-
class KeycloakAuthentication(Authentication):
|
|
277
|
+
class KeycloakAuthentication(Authentication):
|
|
278
|
+
# private constants
|
|
279
|
+
__ERROR_OCCURRED = "An error occurred: "
|
|
280
|
+
__SUCCESSFUL_AUTHENTICATION = "Successful authentication"
|
|
281
|
+
|
|
273
282
|
#
|
|
274
283
|
def _initialize_token(self):
|
|
275
284
|
self._access_token = None
|
|
@@ -320,7 +329,7 @@ class KeycloakAuthentication(Authentication):
|
|
|
320
329
|
|
|
321
330
|
response = requests.post(self._token_url, proxies=self._proxies, headers=headers, data=payload)
|
|
322
331
|
if response.status_code not in {200, 201}:
|
|
323
|
-
self.init_status = f'{self.
|
|
332
|
+
self.init_status = f'{self.__ERROR_OCCURRED}{response}'
|
|
324
333
|
else:
|
|
325
334
|
# If the response object cannot be converted to json, return an error
|
|
326
335
|
results_json = None
|
|
@@ -330,11 +339,16 @@ class KeycloakAuthentication(Authentication):
|
|
|
330
339
|
self._refresh_token = results_json['refresh_token']
|
|
331
340
|
self._creation_time = time.time()
|
|
332
341
|
self._expiration_time = time.time() + int(results_json['expires_in']) - 60 # one minute margin
|
|
333
|
-
self.init_status = self.
|
|
342
|
+
self.init_status = self.__SUCCESSFUL_AUTHENTICATION
|
|
334
343
|
except ValueError as err:
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
344
|
+
self.init_status = self.__ERROR_OCCURRED + os.linesep
|
|
345
|
+
if len(str(response.status_code)) > 0:
|
|
346
|
+
self.init_status += 'Error code: ' + str(response.status_code) + os.linesep
|
|
347
|
+
if len(str(response.reason)) > 0:
|
|
348
|
+
self.init_status += 'Reason: ' + str(response.reason) + os.linesep
|
|
349
|
+
if len(response.text) > 0:
|
|
350
|
+
self.init_status += str(response.text)
|
|
351
|
+
else:
|
|
352
|
+
self.init_status += str(err)
|
|
339
353
|
except Exception as err:
|
|
340
|
-
self.init_status = f'{self.
|
|
354
|
+
self.init_status = f'{self.__ERROR_OCCURRED}{err}\n'
|
|
@@ -97,10 +97,15 @@ class Client():
|
|
|
97
97
|
self.__log.info(' ' + line)
|
|
98
98
|
else:
|
|
99
99
|
if response.status_code != 200:
|
|
100
|
-
returned_result = self.__ERROR_OCCURRED
|
|
101
|
-
|
|
100
|
+
returned_result = self.__ERROR_OCCURRED
|
|
101
|
+
if len(str(response.status_code)) > 0:
|
|
102
|
+
returned_result += 'Error code: ' + str(response.status_code) + os.linesep
|
|
103
|
+
if len(str(response.reason)) > 0:
|
|
104
|
+
returned_result += 'Reason: ' + str(response.reason) + os.linesep
|
|
102
105
|
if len(response.text) > 0:
|
|
103
|
-
returned_result +=
|
|
106
|
+
returned_result += 'Text: ' + response.text
|
|
107
|
+
|
|
108
|
+
returned_result += os.linesep
|
|
104
109
|
else:
|
|
105
110
|
if os.path.isfile(file_path):
|
|
106
111
|
os.remove(file_path)
|
|
@@ -237,22 +242,31 @@ class Client():
|
|
|
237
242
|
|
|
238
243
|
returned_result = returned_result + result + os.linesep
|
|
239
244
|
else:
|
|
240
|
-
returned_result = self.__ERROR_OCCURRED
|
|
245
|
+
returned_result = self.__ERROR_OCCURRED
|
|
246
|
+
if len(str(response.status_code)) > 0:
|
|
247
|
+
returned_result += 'Error code: ' + str(response.status_code) + os.linesep
|
|
241
248
|
if len(str(response.reason)) > 0:
|
|
242
249
|
returned_result += 'Reason: ' + str(response.reason) + os.linesep
|
|
243
250
|
if len(response.text) > 0:
|
|
244
|
-
returned_result
|
|
251
|
+
returned_result += 'Text: ' + response.text
|
|
245
252
|
|
|
246
|
-
returned_result
|
|
253
|
+
returned_result += os.linesep
|
|
247
254
|
# Write the result to the log
|
|
248
255
|
for line in returned_result.split(os.linesep):
|
|
249
256
|
if len(line) > 0:
|
|
250
257
|
self.__log.info(' ' + line)
|
|
251
258
|
except ValueError as err:
|
|
259
|
+
returned_result = self.__ERROR_OCCURRED
|
|
260
|
+
if len(str(response.status_code)) > 0:
|
|
261
|
+
returned_result += 'Error code: ' + str(response.status_code) + os.linesep
|
|
262
|
+
if len(str(response.reason)) > 0:
|
|
263
|
+
returned_result += 'Reason: ' + str(response.reason) + os.linesep
|
|
252
264
|
if len(response.text) > 0:
|
|
253
|
-
|
|
265
|
+
returned_result += 'Text: ' + str(response.text)
|
|
254
266
|
else:
|
|
255
|
-
|
|
267
|
+
returned_result += str(err)
|
|
268
|
+
|
|
269
|
+
returned_result += os.linesep
|
|
256
270
|
finally:
|
|
257
271
|
return returned_result
|
|
258
272
|
|
|
@@ -378,15 +392,27 @@ class Client():
|
|
|
378
392
|
returned_result = returned_result + 'Log' + str(index) + ': ' + results_json['logs'][index]['message'] + os.linesep
|
|
379
393
|
index += 1
|
|
380
394
|
else:
|
|
381
|
-
returned_result = self.__ERROR_OCCURRED
|
|
382
|
-
|
|
395
|
+
returned_result = self.__ERROR_OCCURRED
|
|
396
|
+
if len(str(response.status_code)) > 0:
|
|
397
|
+
returned_result += 'Error code: ' + str(response.status_code) + os.linesep
|
|
398
|
+
if len(str(response.reason)) > 0:
|
|
399
|
+
returned_result += 'Reason: ' + str(response.reason) + os.linesep
|
|
383
400
|
if len(response.text) > 0:
|
|
384
|
-
returned_result
|
|
401
|
+
returned_result += 'Text: ' + str(response.text)
|
|
402
|
+
|
|
403
|
+
returned_result += os.linesep
|
|
385
404
|
except ValueError as err:
|
|
405
|
+
returned_result = self.__ERROR_OCCURRED
|
|
406
|
+
if len(str(response.status_code)) > 0:
|
|
407
|
+
returned_result += 'Error code: ' + str(response.status_code) + os.linesep
|
|
408
|
+
if len(str(response.reason)) > 0:
|
|
409
|
+
returned_result += 'Reason: ' + str(response.reason) + os.linesep
|
|
386
410
|
if len(response.text) > 0:
|
|
387
|
-
|
|
411
|
+
returned_result += 'Text: ' + str(response.text)
|
|
388
412
|
else:
|
|
389
|
-
|
|
413
|
+
returned_result += str(err)
|
|
414
|
+
|
|
415
|
+
returned_result += os.linesep
|
|
390
416
|
finally:
|
|
391
417
|
return returned_result
|
|
392
418
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "dotstat_io"
|
|
3
|
-
version = "1.0.
|
|
3
|
+
version = "1.0.2"
|
|
4
4
|
description = "Utility to download or upload data from/to .Stat Suite using ADFS authentication to connect to it"
|
|
5
5
|
license = "MIT"
|
|
6
6
|
authors = ["Gyorgy Gyomai <gyorgy.gyomai@oecd.org>", "Abdel Aliaoui <abdel.aliaoui@oecd.org>"]
|
|
File without changes
|
|
File without changes
|