pypomes-iam 0.5.4__tar.gz → 0.5.6__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 pypomes-iam might be problematic. Click here for more details.
- {pypomes_iam-0.5.4 → pypomes_iam-0.5.6}/PKG-INFO +1 -1
- {pypomes_iam-0.5.4 → pypomes_iam-0.5.6}/pyproject.toml +1 -1
- pypomes_iam-0.5.6/src/__init__.py +0 -0
- {pypomes_iam-0.5.4 → pypomes_iam-0.5.6}/src/pypomes_iam/__init__.py +14 -6
- pypomes_iam-0.5.4/src/pypomes_iam/iam_pomes.py → pypomes_iam-0.5.6/src/pypomes_iam/iam_actions.py +22 -97
- {pypomes_iam-0.5.4 → pypomes_iam-0.5.6}/src/pypomes_iam/iam_common.py +1 -1
- pypomes_iam-0.5.6/src/pypomes_iam/iam_pomes.py +82 -0
- {pypomes_iam-0.5.4 → pypomes_iam-0.5.6}/src/pypomes_iam/iam_services.py +23 -23
- {pypomes_iam-0.5.4 → pypomes_iam-0.5.6}/src/pypomes_iam/jusbr_pomes.py +5 -5
- {pypomes_iam-0.5.4 → pypomes_iam-0.5.6}/src/pypomes_iam/keycloak_pomes.py +5 -5
- {pypomes_iam-0.5.4 → pypomes_iam-0.5.6}/src/pypomes_iam/provider_pomes.py +3 -3
- {pypomes_iam-0.5.4 → pypomes_iam-0.5.6}/.gitignore +0 -0
- {pypomes_iam-0.5.4 → pypomes_iam-0.5.6}/LICENSE +0 -0
- {pypomes_iam-0.5.4 → pypomes_iam-0.5.6}/README.md +0 -0
- {pypomes_iam-0.5.4 → pypomes_iam-0.5.6}/src/pypomes_iam/token_pomes.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pypomes_iam
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.6
|
|
4
4
|
Summary: A collection of Python pomes, penyeach (IAM modules)
|
|
5
5
|
Project-URL: Homepage, https://github.com/TheWiseCoder/PyPomes-IAM
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/TheWiseCoder/PyPomes-IAM/issues
|
|
File without changes
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
from .iam_actions import (
|
|
2
|
+
action_callback, action_exchange,
|
|
3
|
+
action_login, action_logout, action_token
|
|
4
|
+
)
|
|
5
|
+
from .iam_common import (
|
|
6
|
+
IamServer
|
|
7
|
+
)
|
|
1
8
|
from .iam_pomes import (
|
|
2
|
-
|
|
3
|
-
login_callback, token_exchange,
|
|
4
|
-
user_login, user_logout, user_token
|
|
9
|
+
jwt_required
|
|
5
10
|
)
|
|
6
11
|
from .iam_services import (
|
|
7
12
|
logger_register
|
|
@@ -20,10 +25,13 @@ from .token_pomes import (
|
|
|
20
25
|
)
|
|
21
26
|
|
|
22
27
|
__all__ = [
|
|
23
|
-
#
|
|
28
|
+
# iam_actions
|
|
29
|
+
"action_callback", "action_exchange",
|
|
30
|
+
"action_login", "action_logout", "action_token",
|
|
31
|
+
# iam_commons
|
|
24
32
|
"IamServer",
|
|
25
|
-
|
|
26
|
-
"
|
|
33
|
+
# iam_pomes
|
|
34
|
+
"jwt_required",
|
|
27
35
|
# iam_services
|
|
28
36
|
"logger_register",
|
|
29
37
|
# jusbr_pomes
|
pypomes_iam-0.5.4/src/pypomes_iam/iam_pomes.py → pypomes_iam-0.5.6/src/pypomes_iam/iam_actions.py
RENAMED
|
@@ -4,7 +4,6 @@ import secrets
|
|
|
4
4
|
import string
|
|
5
5
|
import sys
|
|
6
6
|
from datetime import datetime
|
|
7
|
-
from flask import Request, Response, request
|
|
8
7
|
from logging import Logger
|
|
9
8
|
from pypomes_core import TZ_LOCAL, exc_format
|
|
10
9
|
from typing import Any
|
|
@@ -12,32 +11,15 @@ from typing import Any
|
|
|
12
11
|
from .iam_common import (
|
|
13
12
|
IamServer, _iam_lock,
|
|
14
13
|
_get_iam_users, _get_iam_registry, # _get_public_key,
|
|
15
|
-
_get_login_timeout, _get_user_data
|
|
14
|
+
_get_login_timeout, _get_user_data
|
|
16
15
|
)
|
|
17
|
-
from .token_pomes import
|
|
16
|
+
from .token_pomes import token_validate
|
|
18
17
|
|
|
19
18
|
|
|
20
|
-
def
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
:param func: the function being decorated
|
|
25
|
-
"""
|
|
26
|
-
# ruff: noqa: ANN003 - Missing type annotation for *{name}
|
|
27
|
-
def wrapper(*args, **kwargs) -> Response:
|
|
28
|
-
response: Response = __request_validate(request=request)
|
|
29
|
-
return response if response else func(*args, **kwargs)
|
|
30
|
-
|
|
31
|
-
# prevent a rogue error ("View function mapping is overwriting an existing endpoint function")
|
|
32
|
-
wrapper.__name__ = func.__name__
|
|
33
|
-
|
|
34
|
-
return wrapper
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def user_login(iam_server: IamServer,
|
|
38
|
-
args: dict[str, Any],
|
|
39
|
-
errors: list[str] = None,
|
|
40
|
-
logger: Logger = None) -> str:
|
|
19
|
+
def action_login(iam_server: IamServer,
|
|
20
|
+
args: dict[str, Any],
|
|
21
|
+
errors: list[str] = None,
|
|
22
|
+
logger: Logger = None) -> str:
|
|
41
23
|
"""
|
|
42
24
|
Build the URL for redirecting the request to *iam_server*'s authentication page.
|
|
43
25
|
|
|
@@ -95,10 +77,10 @@ def user_login(iam_server: IamServer,
|
|
|
95
77
|
return result
|
|
96
78
|
|
|
97
79
|
|
|
98
|
-
def
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
80
|
+
def action_logout(iam_server: IamServer,
|
|
81
|
+
args: dict[str, Any],
|
|
82
|
+
errors: list[str] = None,
|
|
83
|
+
logger: Logger = None) -> None:
|
|
102
84
|
"""
|
|
103
85
|
Logout the user, by removing all data associating it from *iam_server*'s registry.
|
|
104
86
|
|
|
@@ -126,10 +108,10 @@ def user_logout(iam_server: IamServer,
|
|
|
126
108
|
logger.debug(msg=f"User '{user_id}' removed from {iam_server}'s registry")
|
|
127
109
|
|
|
128
110
|
|
|
129
|
-
def
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
111
|
+
def action_token(iam_server: IamServer,
|
|
112
|
+
args: dict[str, Any],
|
|
113
|
+
errors: list[str] = None,
|
|
114
|
+
logger: Logger = None) -> str:
|
|
133
115
|
"""
|
|
134
116
|
Retrieve the authentication token for the user, from *iam_server*.
|
|
135
117
|
|
|
@@ -212,10 +194,10 @@ def user_token(iam_server: IamServer,
|
|
|
212
194
|
return result
|
|
213
195
|
|
|
214
196
|
|
|
215
|
-
def
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
197
|
+
def action_callback(iam_server: IamServer,
|
|
198
|
+
args: dict[str, Any],
|
|
199
|
+
errors: list[str] = None,
|
|
200
|
+
logger: Logger = None) -> tuple[str, str] | None:
|
|
219
201
|
"""
|
|
220
202
|
Entry point for the callback from *iam_server* via the front-end application, on authentication operations.
|
|
221
203
|
|
|
@@ -282,10 +264,10 @@ def login_callback(iam_server: IamServer,
|
|
|
282
264
|
return result
|
|
283
265
|
|
|
284
266
|
|
|
285
|
-
def
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
267
|
+
def action_exchange(iam_server: IamServer,
|
|
268
|
+
args: dict[str, Any],
|
|
269
|
+
errors: list[str] = None,
|
|
270
|
+
logger: Logger = None) -> dict[str, Any]:
|
|
289
271
|
"""
|
|
290
272
|
Request *iam_server* to issue a token in exchange for the token obtained from another *IAM* server.
|
|
291
273
|
|
|
@@ -357,63 +339,6 @@ def token_exchange(iam_server: IamServer,
|
|
|
357
339
|
return result
|
|
358
340
|
|
|
359
341
|
|
|
360
|
-
def __request_validate(request: Request) -> Response:
|
|
361
|
-
"""
|
|
362
|
-
Verify whether the HTTP *request* has the proper authorization, as per the JWT standard.
|
|
363
|
-
|
|
364
|
-
This implementation assumes that HTTP requests are handled with the *Flask* framework.
|
|
365
|
-
|
|
366
|
-
:param request: the *request* to be verified
|
|
367
|
-
:return: *None* if the *request* is valid, otherwise a *Response* reporting the error
|
|
368
|
-
"""
|
|
369
|
-
# initialize the return variable
|
|
370
|
-
result: Response | None = None
|
|
371
|
-
|
|
372
|
-
# retrieve the authorization from the request header
|
|
373
|
-
auth_header: str = request.headers.get("Authorization")
|
|
374
|
-
|
|
375
|
-
# validate the authorization token
|
|
376
|
-
bad_token: bool = True
|
|
377
|
-
if auth_header and auth_header.startswith("Bearer "):
|
|
378
|
-
# extract and validate the JWT access token
|
|
379
|
-
token: str = auth_header.split(" ")[1]
|
|
380
|
-
claims: dict[str, Any] = token_get_claims(token=token)
|
|
381
|
-
if claims:
|
|
382
|
-
issuer: str = claims["payload"].get("iss")
|
|
383
|
-
recipient_attr: str | None = None
|
|
384
|
-
recipient_id: str = request.values.get("user-id") or request.values.get("login")
|
|
385
|
-
with _iam_lock:
|
|
386
|
-
iam_server: IamServer = _iam_server_from_issuer(issuer=issuer,
|
|
387
|
-
errors=None,
|
|
388
|
-
logger=None)
|
|
389
|
-
# public_key: str = _get_public_key(iam_server=iam_server,
|
|
390
|
-
# errors=errors,
|
|
391
|
-
# logger=logger)
|
|
392
|
-
public_key = None
|
|
393
|
-
|
|
394
|
-
# validate the token's recipient only if a user identification is provided
|
|
395
|
-
if recipient_id:
|
|
396
|
-
registry: dict[str, Any] = _get_iam_registry(iam_server=iam_server,
|
|
397
|
-
errors=None,
|
|
398
|
-
logger=None)
|
|
399
|
-
recipient_attr = registry["recipient-attr"]
|
|
400
|
-
|
|
401
|
-
# validate the token
|
|
402
|
-
if token_validate(token=token,
|
|
403
|
-
issuer=issuer,
|
|
404
|
-
recipient_id=recipient_id,
|
|
405
|
-
recipient_attr=recipient_attr,
|
|
406
|
-
public_key=public_key):
|
|
407
|
-
# token is valid
|
|
408
|
-
bad_token = False
|
|
409
|
-
|
|
410
|
-
# deny the authorization
|
|
411
|
-
if bad_token:
|
|
412
|
-
result = Response(response="Authorization failed",
|
|
413
|
-
status=401)
|
|
414
|
-
return result
|
|
415
|
-
|
|
416
|
-
|
|
417
342
|
def __post_for_token(iam_server: IamServer,
|
|
418
343
|
body_data: dict[str, Any],
|
|
419
344
|
errors: list[str] | None,
|
|
@@ -50,7 +50,7 @@ class IamServer(StrEnum):
|
|
|
50
50
|
# }
|
|
51
51
|
_IAM_SERVERS: Final[dict[IamServer, dict[str, Any]]] = {}
|
|
52
52
|
|
|
53
|
-
# the lock protecting the data in '
|
|
53
|
+
# the lock protecting the data in '_IAM_SERVERS'
|
|
54
54
|
# (because it is 'Final' and set at declaration time, it can be accessed through simple imports)
|
|
55
55
|
_iam_lock: Final[RLock] = RLock()
|
|
56
56
|
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
from flask import Request, Response, request
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from .iam_common import (
|
|
5
|
+
IamServer, _iam_lock, _get_iam_registry,
|
|
6
|
+
_iam_server_from_issuer # _get_public_key
|
|
7
|
+
)
|
|
8
|
+
from .token_pomes import token_get_claims, token_validate
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def jwt_required(func: callable) -> callable:
|
|
12
|
+
"""
|
|
13
|
+
Create a decorator to authenticate service endpoints with JWT tokens.
|
|
14
|
+
|
|
15
|
+
:param func: the function being decorated
|
|
16
|
+
"""
|
|
17
|
+
# ruff: noqa: ANN003 - Missing type annotation for *{name}
|
|
18
|
+
def wrapper(*args, **kwargs) -> Response:
|
|
19
|
+
response: Response = __request_validate(request=request)
|
|
20
|
+
return response if response else func(*args, **kwargs)
|
|
21
|
+
|
|
22
|
+
# prevent a rogue error ("View function mapping is overwriting an existing endpoint function")
|
|
23
|
+
wrapper.__name__ = func.__name__
|
|
24
|
+
|
|
25
|
+
return wrapper
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def __request_validate(request: Request) -> Response:
|
|
29
|
+
"""
|
|
30
|
+
Verify whether the HTTP *request* has the proper authorization, as per the JWT standard.
|
|
31
|
+
|
|
32
|
+
This implementation assumes that HTTP requests are handled with the *Flask* framework.
|
|
33
|
+
|
|
34
|
+
:param request: the *request* to be verified
|
|
35
|
+
:return: *None* if the *request* is valid, otherwise a *Response* reporting the error
|
|
36
|
+
"""
|
|
37
|
+
# initialize the return variable
|
|
38
|
+
result: Response | None = None
|
|
39
|
+
|
|
40
|
+
# retrieve the authorization from the request header
|
|
41
|
+
auth_header: str = request.headers.get("Authorization")
|
|
42
|
+
|
|
43
|
+
# validate the authorization token
|
|
44
|
+
bad_token: bool = True
|
|
45
|
+
if auth_header and auth_header.startswith("Bearer "):
|
|
46
|
+
# extract and validate the JWT access token
|
|
47
|
+
token: str = auth_header.split(" ")[1]
|
|
48
|
+
claims: dict[str, Any] = token_get_claims(token=token)
|
|
49
|
+
if claims:
|
|
50
|
+
issuer: str = claims["payload"].get("iss")
|
|
51
|
+
recipient_attr: str | None = None
|
|
52
|
+
recipient_id: str = request.values.get("user-id") or request.values.get("login")
|
|
53
|
+
with _iam_lock:
|
|
54
|
+
iam_server: IamServer = _iam_server_from_issuer(issuer=issuer,
|
|
55
|
+
errors=None,
|
|
56
|
+
logger=None)
|
|
57
|
+
# public_key: str = _get_public_key(iam_server=iam_server,
|
|
58
|
+
# errors=errors,
|
|
59
|
+
# logger=logger)
|
|
60
|
+
public_key = None
|
|
61
|
+
|
|
62
|
+
# validate the token's recipient only if a user identification is provided
|
|
63
|
+
if recipient_id:
|
|
64
|
+
registry: dict[str, Any] = _get_iam_registry(iam_server=iam_server,
|
|
65
|
+
errors=None,
|
|
66
|
+
logger=None)
|
|
67
|
+
recipient_attr = registry["recipient-attr"]
|
|
68
|
+
|
|
69
|
+
# validate the token
|
|
70
|
+
if token_validate(token=token,
|
|
71
|
+
issuer=issuer,
|
|
72
|
+
recipient_id=recipient_id,
|
|
73
|
+
recipient_attr=recipient_attr,
|
|
74
|
+
public_key=public_key):
|
|
75
|
+
# token is valid
|
|
76
|
+
bad_token = False
|
|
77
|
+
|
|
78
|
+
# deny the authorization
|
|
79
|
+
if bad_token:
|
|
80
|
+
result = Response(response="Authorization failed",
|
|
81
|
+
status=401)
|
|
82
|
+
return result
|
|
@@ -4,9 +4,9 @@ from logging import Logger
|
|
|
4
4
|
from typing import Any
|
|
5
5
|
|
|
6
6
|
from .iam_common import IamServer, _iam_lock, _iam_server_from_endpoint
|
|
7
|
-
from .
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
from .iam_actions import (
|
|
8
|
+
action_login, action_logout,
|
|
9
|
+
action_token, action_exchange, action_callback
|
|
10
10
|
)
|
|
11
11
|
|
|
12
12
|
# the logger for IAM service operations
|
|
@@ -60,10 +60,10 @@ def service_login() -> Response:
|
|
|
60
60
|
logger=__IAM_LOGGER)
|
|
61
61
|
if iam_server:
|
|
62
62
|
# obtain the login URL
|
|
63
|
-
login_url: str =
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
login_url: str = action_login(iam_server=iam_server,
|
|
64
|
+
args=request.args,
|
|
65
|
+
errors=errors,
|
|
66
|
+
logger=__IAM_LOGGER)
|
|
67
67
|
if login_url:
|
|
68
68
|
result = jsonify({"login-url": login_url})
|
|
69
69
|
if errors:
|
|
@@ -106,10 +106,10 @@ def service_logout() -> Response:
|
|
|
106
106
|
logger=__IAM_LOGGER)
|
|
107
107
|
if iam_server:
|
|
108
108
|
# logout the user
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
action_logout(iam_server=iam_server,
|
|
110
|
+
args=request.args,
|
|
111
|
+
errors=errors,
|
|
112
|
+
logger=__IAM_LOGGER)
|
|
113
113
|
if errors:
|
|
114
114
|
result = Response(response="; ".join(errors),
|
|
115
115
|
status=400)
|
|
@@ -160,10 +160,10 @@ def service_callback() -> Response:
|
|
|
160
160
|
logger=__IAM_LOGGER)
|
|
161
161
|
if iam_server:
|
|
162
162
|
# process the callback operation
|
|
163
|
-
token_data =
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
163
|
+
token_data = action_callback(iam_server=iam_server,
|
|
164
|
+
args=request.args,
|
|
165
|
+
errors=errors,
|
|
166
|
+
logger=__IAM_LOGGER)
|
|
167
167
|
result: Response
|
|
168
168
|
if errors:
|
|
169
169
|
result = jsonify({"errors": "; ".join(errors)})
|
|
@@ -215,10 +215,10 @@ def service_token() -> Response:
|
|
|
215
215
|
if iam_server:
|
|
216
216
|
# retrieve the token
|
|
217
217
|
errors: list[str] = []
|
|
218
|
-
token: str =
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
218
|
+
token: str = action_token(iam_server=iam_server,
|
|
219
|
+
args=args,
|
|
220
|
+
errors=errors,
|
|
221
|
+
logger=__IAM_LOGGER)
|
|
222
222
|
else:
|
|
223
223
|
msg: str = "User identification not provided"
|
|
224
224
|
errors.append(msg)
|
|
@@ -278,10 +278,10 @@ def service_exchange() -> Response:
|
|
|
278
278
|
token_data: dict[str, Any] | None = None
|
|
279
279
|
if iam_server:
|
|
280
280
|
errors: list[str] = []
|
|
281
|
-
token_data =
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
281
|
+
token_data = action_exchange(iam_server=iam_server,
|
|
282
|
+
args=request.args,
|
|
283
|
+
errors=errors,
|
|
284
|
+
logger=__IAM_LOGGER)
|
|
285
285
|
result: Response
|
|
286
286
|
if errors:
|
|
287
287
|
result = Response(response="; ".join(errors),
|
|
@@ -7,7 +7,7 @@ from pypomes_core import (
|
|
|
7
7
|
from typing import Any, Final
|
|
8
8
|
|
|
9
9
|
from .iam_common import _IAM_SERVERS, IamServer, _iam_lock
|
|
10
|
-
from .
|
|
10
|
+
from .iam_actions import action_token
|
|
11
11
|
|
|
12
12
|
JUSBR_CLIENT_ID: Final[str] = env_get_str(key=f"{APP_PREFIX}_JUSBR_CLIENT_ID")
|
|
13
13
|
JUSBR_CLIENT_SECRET: Final[str] = env_get_str(key=f"{APP_PREFIX}_JUSBR_CLIENT_SECRET")
|
|
@@ -118,8 +118,8 @@ def jusbr_get_token(user_id: str,
|
|
|
118
118
|
# retrieve the token
|
|
119
119
|
args: dict[str, Any] = {"user-id": user_id}
|
|
120
120
|
with _iam_lock:
|
|
121
|
-
result =
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
result = action_token(iam_server=IamServer.IAM_JUSRBR,
|
|
122
|
+
args=args,
|
|
123
|
+
errors=errors,
|
|
124
|
+
logger=logger)
|
|
125
125
|
return result
|
|
@@ -7,7 +7,7 @@ from pypomes_core import (
|
|
|
7
7
|
from typing import Any, Final
|
|
8
8
|
|
|
9
9
|
from .iam_common import _IAM_SERVERS, IamServer, _iam_lock
|
|
10
|
-
from .
|
|
10
|
+
from .iam_actions import action_token
|
|
11
11
|
|
|
12
12
|
KEYCLOAK_CLIENT_ID: Final[str] = env_get_str(key=f"{APP_PREFIX}_KEYCLOAK_CLIENT_ID")
|
|
13
13
|
KEYCLOAK_CLIENT_SECRET: Final[str] = env_get_str(key=f"{APP_PREFIX}_KEYCLOAK_CLIENT_SECRET")
|
|
@@ -129,8 +129,8 @@ def keycloak_get_token(user_id: str,
|
|
|
129
129
|
# retrieve the token
|
|
130
130
|
args: dict[str, Any] = {"user-id": user_id}
|
|
131
131
|
with _iam_lock:
|
|
132
|
-
result =
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
132
|
+
result = action_token(iam_server=IamServer.IAM_KEYCLOAK,
|
|
133
|
+
args=args,
|
|
134
|
+
errors=errors,
|
|
135
|
+
logger=logger)
|
|
136
136
|
return result
|
|
@@ -5,7 +5,7 @@ from base64 import b64encode
|
|
|
5
5
|
from datetime import datetime
|
|
6
6
|
from logging import Logger
|
|
7
7
|
from pypomes_core import TZ_LOCAL, exc_format
|
|
8
|
-
from threading import
|
|
8
|
+
from threading import Lock
|
|
9
9
|
from typing import Any, Final
|
|
10
10
|
|
|
11
11
|
# structure:
|
|
@@ -25,7 +25,7 @@ _provider_registry: Final[dict[str, dict[str, Any]]] = {}
|
|
|
25
25
|
|
|
26
26
|
# the lock protecting the data in '_provider_registry'
|
|
27
27
|
# (because it is 'Final' and set at declaration time, it can be accessed through simple imports)
|
|
28
|
-
_provider_lock: Final[
|
|
28
|
+
_provider_lock: Final[Lock] = Lock()
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
def provider_register(provider_id: str,
|
|
@@ -133,7 +133,7 @@ def provider_get_token(provider_id: str,
|
|
|
133
133
|
provider["access-token"] = reply.get("access_token")
|
|
134
134
|
provider["access-expiration"] = now + int(reply.get("expires_in"))
|
|
135
135
|
if reply.get("refresh_token"):
|
|
136
|
-
provider["refresh-token"] = reply["
|
|
136
|
+
provider["refresh-token"] = reply["refresh_token"]
|
|
137
137
|
if reply.get("refresh_expires_in"):
|
|
138
138
|
provider["refresh-expiration"] = now + int(reply.get("refresh_expires_in"))
|
|
139
139
|
else:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|