pypomes-iam 0.8.0__py3-none-any.whl → 0.8.9__py3-none-any.whl
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.
- pypomes_iam/__init__.py +15 -15
- pypomes_iam/iam_actions.py +144 -40
- pypomes_iam/iam_common.py +38 -42
- pypomes_iam/iam_pomes.py +33 -23
- pypomes_iam/iam_services.py +124 -50
- pypomes_iam/provider_pomes.py +77 -68
- {pypomes_iam-0.8.0.dist-info → pypomes_iam-0.8.9.dist-info}/METADATA +1 -1
- pypomes_iam-0.8.9.dist-info/RECORD +11 -0
- pypomes_iam-0.8.0.dist-info/RECORD +0 -11
- {pypomes_iam-0.8.0.dist-info → pypomes_iam-0.8.9.dist-info}/WHEEL +0 -0
- {pypomes_iam-0.8.0.dist-info → pypomes_iam-0.8.9.dist-info}/licenses/LICENSE +0 -0
pypomes_iam/iam_pomes.py
CHANGED
|
@@ -6,11 +6,12 @@ from pypomes_core import (
|
|
|
6
6
|
)
|
|
7
7
|
|
|
8
8
|
from .iam_common import (
|
|
9
|
-
_IAM_SERVERS, IamServer,
|
|
9
|
+
_IAM_SERVERS, IamServer, ServerParam, _iam_lock
|
|
10
10
|
)
|
|
11
11
|
from .iam_services import (
|
|
12
12
|
service_login, service_logout,
|
|
13
|
-
service_callback, service_callback_exchange,
|
|
13
|
+
service_callback, service_callback_exchange,
|
|
14
|
+
service_exchange, service_get_token, service_userinfo
|
|
14
15
|
)
|
|
15
16
|
|
|
16
17
|
|
|
@@ -40,7 +41,7 @@ def iam_setup_server(iam_server: IamServer,
|
|
|
40
41
|
it is not provided, but *admin_id* and *admin_secret* are, it is obtained from the *IAM* server itself
|
|
41
42
|
the first time it is needed.
|
|
42
43
|
|
|
43
|
-
:param iam_server: identifies the supported *IAM* server
|
|
44
|
+
:param iam_server: identifies the supported *IAM* server
|
|
44
45
|
:param admin_id: identifies the realm administrator
|
|
45
46
|
:param admin_secret: password for the realm administrator
|
|
46
47
|
:param client_id: the client's identification with the *IAM* server
|
|
@@ -69,28 +70,28 @@ def iam_setup_server(iam_server: IamServer,
|
|
|
69
70
|
if "login_timeout" in defaulted_params:
|
|
70
71
|
login_timeout = env_get_str(key=f"{APP_PREFIX}_{prefix}_LOGIN_TIMEOUT")
|
|
71
72
|
if "pk_lifetime" in defaulted_params:
|
|
72
|
-
pk_lifetime = env_get_int(key=f"{APP_PREFIX}_{prefix}
|
|
73
|
+
pk_lifetime = env_get_int(key=f"{APP_PREFIX}_{prefix}_PK_LIFETIME")
|
|
73
74
|
if "recipient_attr" in defaulted_params:
|
|
74
75
|
recipient_attr = env_get_str(key=f"{APP_PREFIX}_{prefix}_RECIPIENT_ATTR")
|
|
75
76
|
if "url_base" in defaulted_params:
|
|
76
|
-
url_base = env_get_str(key=f"{APP_PREFIX}_{prefix}
|
|
77
|
+
url_base = env_get_str(key=f"{APP_PREFIX}_{prefix}_URL_BASE")
|
|
77
78
|
|
|
78
|
-
# configure the
|
|
79
|
+
# configure the IAM server's registry
|
|
79
80
|
with _iam_lock:
|
|
80
81
|
_IAM_SERVERS[iam_server] = {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
82
|
+
ServerParam.CLIENT_ID: client_id,
|
|
83
|
+
ServerParam.CLIENT_REALM: client_realm,
|
|
84
|
+
ServerParam.CLIENT_SECRET: client_secret,
|
|
85
|
+
ServerParam.RECIPIENT_ATTR: recipient_attr,
|
|
86
|
+
ServerParam.ADMIN_ID: admin_id,
|
|
87
|
+
ServerParam.ADMIN_SECRET: admin_secret,
|
|
88
|
+
ServerParam.LOGIN_TIMEOUT: login_timeout,
|
|
89
|
+
ServerParam.PK_LIFETIME: pk_lifetime,
|
|
90
|
+
ServerParam.URL_BASE: url_base,
|
|
90
91
|
# dynamic attributes
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
ServerParam.PK_EXPIRATION: 0,
|
|
93
|
+
ServerParam.PUBLIC_KEY: None,
|
|
94
|
+
ServerParam.USERS: {}
|
|
94
95
|
}
|
|
95
96
|
|
|
96
97
|
|
|
@@ -102,7 +103,8 @@ def iam_setup_endpoints(flask_app: Flask,
|
|
|
102
103
|
exchange_endpoint: str = None,
|
|
103
104
|
login_endpoint: str = None,
|
|
104
105
|
logout_endpoint: str = None,
|
|
105
|
-
token_endpoint: str = None
|
|
106
|
+
token_endpoint: str = None,
|
|
107
|
+
userinfo_endpoint: str = None) -> None:
|
|
106
108
|
"""
|
|
107
109
|
Setup the endpoints for accessing the services provided by *iam_server*.
|
|
108
110
|
|
|
@@ -110,13 +112,14 @@ def iam_setup_endpoints(flask_app: Flask,
|
|
|
110
112
|
environment variables.
|
|
111
113
|
|
|
112
114
|
:param flask_app: the Flask application
|
|
113
|
-
:param iam_server: identifies the supported *IAM* server
|
|
115
|
+
:param iam_server: identifies the supported *IAM* server
|
|
114
116
|
:param callback_endpoint: endpoint for the callback from the front end
|
|
115
117
|
:param callback_exchange_endpoint: endpoint for the combination callback and exchange
|
|
116
118
|
:param exchange_endpoint: endpoint for requesting token exchange
|
|
117
119
|
:param login_endpoint: endpoint for redirecting user to the *IAM* server's login page
|
|
118
120
|
:param logout_endpoint: endpoint for terminating user access
|
|
119
121
|
:param token_endpoint: endpoint for retrieving authentication token
|
|
122
|
+
:param userinfo_endpoint: endpoint for retrieving user data
|
|
120
123
|
"""
|
|
121
124
|
# obtain the defaulted parameters
|
|
122
125
|
defaulted_params: list[str] = func_defaulted_params.get()
|
|
@@ -128,20 +131,22 @@ def iam_setup_endpoints(flask_app: Flask,
|
|
|
128
131
|
if "callback_exchange_endpoint" in defaulted_params:
|
|
129
132
|
callback_exchange_endpoint = env_get_str(key=f"{APP_PREFIX}_{prefix}_ENDPOINT_CALLBACK_EXCHANGE")
|
|
130
133
|
if "exchange_endpoint" in defaulted_params:
|
|
131
|
-
|
|
134
|
+
exchange_endpoint = env_get_str(key=f"{APP_PREFIX}_{prefix}_ENDPOINT_EXCHANGE")
|
|
132
135
|
if "login_endpoint" in defaulted_params:
|
|
133
136
|
login_endpoint = env_get_str(key=f"{APP_PREFIX}_{prefix}_ENDPOINT_LOGIN")
|
|
134
137
|
if "logout_endpoint" in defaulted_params:
|
|
135
138
|
logout_endpoint = env_get_str(key=f"{APP_PREFIX}_{prefix}_ENDPOINT_LOGOUT")
|
|
136
139
|
if "token_endpoint" in defaulted_params:
|
|
137
140
|
token_endpoint = env_get_str(key=f"{APP_PREFIX}_{prefix}_ENDPOINT_TOKEN")
|
|
141
|
+
if "userinfo_endpoint" in defaulted_params:
|
|
142
|
+
userinfo_endpoint = env_get_str(key=f"{APP_PREFIX}_{prefix}_ENDPOINT_USERINFO")
|
|
138
143
|
|
|
139
144
|
# establish the endpoints
|
|
140
145
|
if callback_endpoint:
|
|
141
146
|
flask_app.add_url_rule(rule=callback_endpoint,
|
|
142
147
|
endpoint=f"{iam_server}-callback",
|
|
143
148
|
view_func=service_callback,
|
|
144
|
-
methods=["GET"])
|
|
149
|
+
methods=["GET", "POST"])
|
|
145
150
|
if callback_exchange_endpoint:
|
|
146
151
|
flask_app.add_url_rule(rule=callback_exchange_endpoint,
|
|
147
152
|
endpoint=f"{iam_server}-callback-exchange",
|
|
@@ -161,9 +166,14 @@ def iam_setup_endpoints(flask_app: Flask,
|
|
|
161
166
|
flask_app.add_url_rule(rule=logout_endpoint,
|
|
162
167
|
endpoint=f"{iam_server}-logout",
|
|
163
168
|
view_func=service_logout,
|
|
164
|
-
methods=["
|
|
169
|
+
methods=["POST"])
|
|
165
170
|
if token_endpoint:
|
|
166
171
|
flask_app.add_url_rule(rule=token_endpoint,
|
|
167
172
|
endpoint=f"{iam_server}-token",
|
|
168
173
|
view_func=service_get_token,
|
|
169
174
|
methods=["GET"])
|
|
175
|
+
if userinfo_endpoint:
|
|
176
|
+
flask_app.add_url_rule(rule=userinfo_endpoint,
|
|
177
|
+
endpoint=f"{iam_server}-userinfo",
|
|
178
|
+
view_func=service_userinfo,
|
|
179
|
+
methods=["GET"])
|
pypomes_iam/iam_services.py
CHANGED
|
@@ -4,13 +4,13 @@ from logging import Logger
|
|
|
4
4
|
from typing import Any
|
|
5
5
|
|
|
6
6
|
from .iam_common import (
|
|
7
|
-
IamServer,
|
|
7
|
+
IamServer, ServerParam, _iam_lock,
|
|
8
8
|
_get_iam_registry, _get_public_key,
|
|
9
9
|
_iam_server_from_endpoint, _iam_server_from_issuer
|
|
10
10
|
)
|
|
11
11
|
from .iam_actions import (
|
|
12
|
-
iam_login, iam_logout,
|
|
13
|
-
|
|
12
|
+
iam_login, iam_logout, iam_callback,
|
|
13
|
+
iam_exchange, iam_get_token, iam_userinfo
|
|
14
14
|
)
|
|
15
15
|
from .token_pomes import token_get_claims, token_validate
|
|
16
16
|
|
|
@@ -47,19 +47,16 @@ def __request_validate(request: Request) -> Response:
|
|
|
47
47
|
Because this code has a high usage frequency, only authentication failures are logged.
|
|
48
48
|
|
|
49
49
|
:param request: the *request* to be verified
|
|
50
|
-
:return: *None* if the *request* is valid, otherwise a *Response
|
|
50
|
+
:return: *None* if the *request* is valid, otherwise a *Response NOT AUTHORIZED*
|
|
51
51
|
"""
|
|
52
52
|
# initialize the return variable
|
|
53
53
|
result: Response | None = None
|
|
54
54
|
|
|
55
|
-
# retrieve the authorization from the request header
|
|
56
|
-
auth_header: str = request.headers.get("Authorization")
|
|
57
|
-
|
|
58
55
|
# validate the authorization token
|
|
59
56
|
bad_token: bool = True
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
57
|
+
token: str = __get_bearer_token(request=request)
|
|
58
|
+
if token:
|
|
59
|
+
# extract token claims
|
|
63
60
|
claims: dict[str, Any] = token_get_claims(token=token)
|
|
64
61
|
if claims:
|
|
65
62
|
issuer: str = claims["payload"].get("iss")
|
|
@@ -77,7 +74,7 @@ def __request_validate(request: Request) -> Response:
|
|
|
77
74
|
errors=None,
|
|
78
75
|
logger=__IAM_LOGGER)
|
|
79
76
|
if registry:
|
|
80
|
-
recipient_attr = registry[
|
|
77
|
+
recipient_attr = registry[ServerParam.RECIPIENT_ATTR]
|
|
81
78
|
public_key = _get_public_key(iam_server=iam_server,
|
|
82
79
|
errors=None,
|
|
83
80
|
logger=__IAM_LOGGER)
|
|
@@ -103,6 +100,26 @@ def __request_validate(request: Request) -> Response:
|
|
|
103
100
|
return result
|
|
104
101
|
|
|
105
102
|
|
|
103
|
+
def __get_bearer_token(request: Request) -> str:
|
|
104
|
+
"""
|
|
105
|
+
Retrieve the bearer token sent in the header of *request*.
|
|
106
|
+
|
|
107
|
+
This implementation assumes that HTTP requests are handled with the *Flask* framework.
|
|
108
|
+
|
|
109
|
+
:param request: the *request* to retrieve the token from
|
|
110
|
+
:return: the bearer token, or *None* if not found
|
|
111
|
+
"""
|
|
112
|
+
# initialize the return variable
|
|
113
|
+
result: str | None = None
|
|
114
|
+
|
|
115
|
+
# retrieve the authorization from the request header
|
|
116
|
+
auth_header: str = request.headers.get("Authorization")
|
|
117
|
+
if auth_header and auth_header.startswith("Bearer "):
|
|
118
|
+
result: str = auth_header.split(" ")[1]
|
|
119
|
+
|
|
120
|
+
return result
|
|
121
|
+
|
|
122
|
+
|
|
106
123
|
def iam_setup_logger(logger: Logger) -> None:
|
|
107
124
|
"""
|
|
108
125
|
Register the logger for HTTP services.
|
|
@@ -120,7 +137,7 @@ def service_setup_server() -> Response:
|
|
|
120
137
|
Entry point to setup a *IAM* server.
|
|
121
138
|
|
|
122
139
|
These are the expected parameters in the request's body, in a JSON or as form data:
|
|
123
|
-
- *iam_server*: identifies the supported *IAM* server
|
|
140
|
+
- *iam_server*: identifies the supported *IAM* server
|
|
124
141
|
- *admin_id*: identifies the realm administrator
|
|
125
142
|
- *admin_secret*: password for the realm administrator
|
|
126
143
|
- *client_id*: the client's identification with the *IAM* server
|
|
@@ -145,13 +162,13 @@ def service_setup_server() -> Response:
|
|
|
145
162
|
|
|
146
163
|
:return: *Response OK*
|
|
147
164
|
"""
|
|
165
|
+
# retrieve the request arguments
|
|
166
|
+
args: dict[str, Any] = (dict(request.json) if request.is_json else dict(request.form)) or {}
|
|
167
|
+
|
|
148
168
|
# log the request
|
|
149
169
|
if __IAM_LOGGER:
|
|
150
|
-
__IAM_LOGGER.debug(msg=f"{
|
|
151
|
-
|
|
152
|
-
# retrieve the arguments
|
|
153
|
-
args: dict[str, Any] = request.json if request.is_json else request.form
|
|
154
|
-
|
|
170
|
+
__IAM_LOGGER.debug(msg=f"Request {request.method}:{request.path}; {json.dumps(obj=args,
|
|
171
|
+
ensure_ascii=False)}")
|
|
155
172
|
# setup the server
|
|
156
173
|
from .iam_pomes import iam_setup_server
|
|
157
174
|
iam_setup_server(**args)
|
|
@@ -164,7 +181,7 @@ def service_setup_server() -> Response:
|
|
|
164
181
|
return result
|
|
165
182
|
|
|
166
183
|
|
|
167
|
-
# @flask_app.route(rule=<login_endpoint>,
|
|
184
|
+
# @flask_app.route(rule=<login_endpoint>,
|
|
168
185
|
# methods=["GET"])
|
|
169
186
|
def service_login() -> Response:
|
|
170
187
|
"""
|
|
@@ -191,10 +208,13 @@ def service_login() -> Response:
|
|
|
191
208
|
# declare the return variable
|
|
192
209
|
result: Response | None = None
|
|
193
210
|
|
|
211
|
+
# retrieve the request arguments
|
|
212
|
+
args: dict[str, Any] = dict(request.args) or {}
|
|
213
|
+
|
|
194
214
|
# log the request
|
|
195
215
|
if __IAM_LOGGER:
|
|
196
|
-
__IAM_LOGGER.debug(msg=
|
|
197
|
-
|
|
216
|
+
__IAM_LOGGER.debug(msg=f"Request {request.method}:{request.path}; {json.dumps(obj=args,
|
|
217
|
+
ensure_ascii=False)}")
|
|
198
218
|
errors: list[str] = []
|
|
199
219
|
with _iam_lock:
|
|
200
220
|
# retrieve the IAM server
|
|
@@ -204,7 +224,7 @@ def service_login() -> Response:
|
|
|
204
224
|
if iam_server:
|
|
205
225
|
# obtain the login URL
|
|
206
226
|
login_url: str = iam_login(iam_server=iam_server,
|
|
207
|
-
args=
|
|
227
|
+
args=args,
|
|
208
228
|
errors=errors,
|
|
209
229
|
logger=__IAM_LOGGER)
|
|
210
230
|
if login_url:
|
|
@@ -220,8 +240,9 @@ def service_login() -> Response:
|
|
|
220
240
|
return result
|
|
221
241
|
|
|
222
242
|
|
|
223
|
-
# @flask_app.route(rule=<logout_endpoint>,
|
|
224
|
-
# methods=["
|
|
243
|
+
# @flask_app.route(rule=<logout_endpoint>,
|
|
244
|
+
# methods=["POST"])
|
|
245
|
+
@jwt_required
|
|
225
246
|
def service_logout() -> Response:
|
|
226
247
|
"""
|
|
227
248
|
Entry point for the *IAM* server's logout service.
|
|
@@ -239,10 +260,13 @@ def service_logout() -> Response:
|
|
|
239
260
|
# declare the return variable
|
|
240
261
|
result: Response | None
|
|
241
262
|
|
|
263
|
+
# retrieve the request arguments
|
|
264
|
+
args: dict[str, Any] = dict(request.args) or {}
|
|
265
|
+
|
|
242
266
|
# log the request
|
|
243
267
|
if __IAM_LOGGER:
|
|
244
|
-
__IAM_LOGGER.debug(msg=
|
|
245
|
-
|
|
268
|
+
__IAM_LOGGER.debug(msg=f"Request {request.method}:{request.path}; {json.dumps(obj=args,
|
|
269
|
+
ensure_ascii=False)}")
|
|
246
270
|
errors: list[str] = []
|
|
247
271
|
with _iam_lock:
|
|
248
272
|
# retrieve the IAM server
|
|
@@ -252,7 +276,7 @@ def service_logout() -> Response:
|
|
|
252
276
|
if iam_server:
|
|
253
277
|
# logout the user
|
|
254
278
|
iam_logout(iam_server=iam_server,
|
|
255
|
-
args=
|
|
279
|
+
args=args,
|
|
256
280
|
errors=errors,
|
|
257
281
|
logger=__IAM_LOGGER)
|
|
258
282
|
if errors:
|
|
@@ -268,7 +292,7 @@ def service_logout() -> Response:
|
|
|
268
292
|
return result
|
|
269
293
|
|
|
270
294
|
|
|
271
|
-
# @flask_app.route(rule=<callback_endpoint>,
|
|
295
|
+
# @flask_app.route(rule=<callback_endpoint>,
|
|
272
296
|
# methods=["GET", "POST"])
|
|
273
297
|
def service_callback() -> Response:
|
|
274
298
|
"""
|
|
@@ -294,10 +318,13 @@ def service_callback() -> Response:
|
|
|
294
318
|
|
|
295
319
|
:return: *Response* containing the reference user identification and the token, or *BAD REQUEST*
|
|
296
320
|
"""
|
|
321
|
+
# retrieve the request arguments
|
|
322
|
+
args: dict[str, Any] = dict(request.args) or {}
|
|
323
|
+
|
|
297
324
|
# log the request
|
|
298
325
|
if __IAM_LOGGER:
|
|
299
|
-
__IAM_LOGGER.debug(msg=
|
|
300
|
-
|
|
326
|
+
__IAM_LOGGER.debug(msg=f"Request {request.method}:{request.path}; {json.dumps(obj=args,
|
|
327
|
+
ensure_ascii=False)}")
|
|
301
328
|
errors: list[str] = []
|
|
302
329
|
token_data: tuple[str, str] | None = None
|
|
303
330
|
with _iam_lock:
|
|
@@ -308,7 +335,7 @@ def service_callback() -> Response:
|
|
|
308
335
|
if iam_server:
|
|
309
336
|
# process the callback operation
|
|
310
337
|
token_data = iam_callback(iam_server=iam_server,
|
|
311
|
-
args=
|
|
338
|
+
args=args,
|
|
312
339
|
errors=errors,
|
|
313
340
|
logger=__IAM_LOGGER)
|
|
314
341
|
result: Response
|
|
@@ -325,7 +352,7 @@ def service_callback() -> Response:
|
|
|
325
352
|
return result
|
|
326
353
|
|
|
327
354
|
|
|
328
|
-
# @flask_app.route(rule=<callback_endpoint>,
|
|
355
|
+
# @flask_app.route(rule=<callback_endpoint>,
|
|
329
356
|
# methods=["POST"])
|
|
330
357
|
def service_exchange() -> Response:
|
|
331
358
|
"""
|
|
@@ -350,10 +377,13 @@ def service_exchange() -> Response:
|
|
|
350
377
|
|
|
351
378
|
:return: *Response* containing the reference user identification and the token, or *BAD REQUEST*
|
|
352
379
|
"""
|
|
380
|
+
# retrieve the request arguments
|
|
381
|
+
args: dict[str, Any] = dict(request.args) or {}
|
|
382
|
+
|
|
353
383
|
# log the request
|
|
354
384
|
if __IAM_LOGGER:
|
|
355
|
-
__IAM_LOGGER.debug(msg=
|
|
356
|
-
|
|
385
|
+
__IAM_LOGGER.debug(msg=f"Request {request.method}:{request.path}; {json.dumps(obj=args,
|
|
386
|
+
ensure_ascii=False)}")
|
|
357
387
|
errors: list[str] = []
|
|
358
388
|
with _iam_lock:
|
|
359
389
|
# retrieve the IAM server
|
|
@@ -365,7 +395,7 @@ def service_exchange() -> Response:
|
|
|
365
395
|
if iam_server:
|
|
366
396
|
errors: list[str] = []
|
|
367
397
|
token_info = iam_exchange(iam_server=iam_server,
|
|
368
|
-
args=
|
|
398
|
+
args=args,
|
|
369
399
|
errors=errors,
|
|
370
400
|
logger=__IAM_LOGGER)
|
|
371
401
|
result: Response
|
|
@@ -415,10 +445,13 @@ def service_callback_exchange() -> Response:
|
|
|
415
445
|
# declare the return variable
|
|
416
446
|
result: Response | None = None
|
|
417
447
|
|
|
448
|
+
# retrieve the request arguments
|
|
449
|
+
args: dict[str, Any] = dict(request.args) or {}
|
|
450
|
+
|
|
418
451
|
# log the request
|
|
419
452
|
if __IAM_LOGGER:
|
|
420
|
-
__IAM_LOGGER.debug(msg=
|
|
421
|
-
|
|
453
|
+
__IAM_LOGGER.debug(msg=f"Request {request.method}:{request.path}; {json.dumps(obj=args,
|
|
454
|
+
ensure_ascii=False)}")
|
|
422
455
|
errors: list[str] = []
|
|
423
456
|
with _iam_lock:
|
|
424
457
|
# retrieve the IAM server
|
|
@@ -427,7 +460,7 @@ def service_callback_exchange() -> Response:
|
|
|
427
460
|
logger=__IAM_LOGGER)
|
|
428
461
|
# obtain the login URL
|
|
429
462
|
token_info: tuple[str, str] = iam_callback(iam_server=iam_server,
|
|
430
|
-
args=
|
|
463
|
+
args=args,
|
|
431
464
|
errors=errors,
|
|
432
465
|
logger=__IAM_LOGGER)
|
|
433
466
|
if token_info:
|
|
@@ -457,7 +490,7 @@ def service_callback_exchange() -> Response:
|
|
|
457
490
|
return result
|
|
458
491
|
|
|
459
492
|
|
|
460
|
-
# @flask_app.route(rule=<token_endpoint>,
|
|
493
|
+
# @flask_app.route(rule=<token_endpoint>,
|
|
461
494
|
# methods=["GET"])
|
|
462
495
|
def service_get_token() -> Response:
|
|
463
496
|
"""
|
|
@@ -477,13 +510,13 @@ def service_get_token() -> Response:
|
|
|
477
510
|
|
|
478
511
|
:return: *Response* containing the user reference identification and the token, or *BAD REQUEST*
|
|
479
512
|
"""
|
|
513
|
+
# retrieve the request arguments
|
|
514
|
+
args: dict[str, Any] = dict(request.args) or {}
|
|
515
|
+
|
|
480
516
|
# log the request
|
|
481
517
|
if __IAM_LOGGER:
|
|
482
|
-
__IAM_LOGGER.debug(msg=
|
|
483
|
-
|
|
484
|
-
# obtain the request arguments
|
|
485
|
-
args: dict[str, Any] = request.args
|
|
486
|
-
|
|
518
|
+
__IAM_LOGGER.debug(msg=f"Request {request.method}:{request.path}; {json.dumps(obj=args,
|
|
519
|
+
ensure_ascii=False)}")
|
|
487
520
|
errors: list[str] = []
|
|
488
521
|
token_info: dict[str, str] | None = None
|
|
489
522
|
with _iam_lock:
|
|
@@ -511,14 +544,55 @@ def service_get_token() -> Response:
|
|
|
511
544
|
return result
|
|
512
545
|
|
|
513
546
|
|
|
514
|
-
|
|
547
|
+
# @flask_app.route(rule=<token_endpoint>,
|
|
548
|
+
# methods=["GET"])
|
|
549
|
+
@jwt_required
|
|
550
|
+
def service_userinfo() -> Response:
|
|
515
551
|
"""
|
|
516
|
-
|
|
552
|
+
Entry point for retrieving user data from the *IAM* server.
|
|
517
553
|
|
|
518
|
-
|
|
519
|
-
|
|
554
|
+
When registering this endpoint, the name used in *Flask*'s *endpoint* parameter must be prefixed with
|
|
555
|
+
the name of the *IAM* server in charge of handling this service. This prefixing is done automatically
|
|
556
|
+
if the endpoint is established with a call to *iam_setup_endpoints()*.
|
|
557
|
+
|
|
558
|
+
The user is identified by the attribute *user-id* or "login", provided as a request parameter.
|
|
559
|
+
|
|
560
|
+
On success, the returned *Response* will contain a JSON with information kept by *iam_server* about *user_id*.
|
|
561
|
+
|
|
562
|
+
:return: *Response* containing user data, or *BAD REQUEST*
|
|
520
563
|
"""
|
|
564
|
+
# retrieve the request arguments
|
|
565
|
+
args: dict[str, Any] = dict(request.args) or {}
|
|
521
566
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
567
|
+
# log the request
|
|
568
|
+
if __IAM_LOGGER:
|
|
569
|
+
__IAM_LOGGER.debug(msg=f"Request {request.method}:{request.path}; {json.dumps(obj=args,
|
|
570
|
+
ensure_ascii=False)}")
|
|
571
|
+
# retrieve the bearer token
|
|
572
|
+
args["access-token"] = __get_bearer_token(request=request)
|
|
573
|
+
|
|
574
|
+
errors: list[str] = []
|
|
575
|
+
user_info: dict[str, str] | None = None
|
|
576
|
+
with _iam_lock:
|
|
577
|
+
# retrieve the IAM server
|
|
578
|
+
iam_server: IamServer = _iam_server_from_endpoint(endpoint=request.endpoint,
|
|
579
|
+
errors=errors,
|
|
580
|
+
logger=__IAM_LOGGER)
|
|
581
|
+
if iam_server:
|
|
582
|
+
# retrieve the token
|
|
583
|
+
errors: list[str] = []
|
|
584
|
+
user_info = iam_userinfo(iam_server=iam_server,
|
|
585
|
+
args=args,
|
|
586
|
+
errors=errors,
|
|
587
|
+
logger=__IAM_LOGGER)
|
|
588
|
+
result: Response
|
|
589
|
+
if errors:
|
|
590
|
+
result = Response(response="; ".join(errors),
|
|
591
|
+
status=400)
|
|
592
|
+
else:
|
|
593
|
+
result = jsonify(user_info)
|
|
594
|
+
if __IAM_LOGGER:
|
|
595
|
+
# log the response
|
|
596
|
+
__IAM_LOGGER.debug(msg=f"Response {result}; {json.dumps(obj=user_info,
|
|
597
|
+
ensure_ascii=False)}")
|
|
598
|
+
return result
|