pypomes-iam 0.3.4__py3-none-any.whl → 0.3.6__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.

Potentially problematic release.


This version of pypomes-iam might be problematic. Click here for more details.

@@ -3,8 +3,14 @@ from flask import Request, Response, request, jsonify
3
3
  from logging import Logger
4
4
  from typing import Any
5
5
 
6
- from .iam_common import IamServer, _get_logger, _get_iam_server
7
- from .iam_pomes import user_login, user_logout, user_token, token_exchange, login_callback
6
+ from .iam_common import (
7
+ IamServer, _iam_lock,
8
+ _get_logger, _get_iam_server
9
+ )
10
+ from .iam_pomes import (
11
+ user_login, user_logout,
12
+ user_token, token_exchange, login_callback
13
+ )
8
14
 
9
15
 
10
16
  # @flask_app.route(rule=<login_endpoint>, # JUSBR_ENDPOINT_LOGIN
@@ -28,19 +34,20 @@ def service_login() -> Response:
28
34
  # log the request
29
35
  logger.debug(msg=_log_init(request=request))
30
36
 
31
- # retrieve the IAM server
32
37
  errors: list[str] = []
33
- iam_server: IamServer = _get_iam_server(endpoint=request.endpoint,
34
- errors=errors,
35
- logger=logger)
36
- if iam_server:
37
- # obtain the login URL
38
- login_data: dict[str, str] = user_login(iam_server=iam_server,
39
- args=request.args,
40
- errors=errors,
41
- logger=logger)
42
- if login_data:
43
- result = jsonify(login_data)
38
+ with _iam_lock:
39
+ # retrieve the IAM server
40
+ iam_server: IamServer = _get_iam_server(endpoint=request.endpoint,
41
+ errors=errors,
42
+ logger=logger)
43
+ if iam_server:
44
+ # obtain the login URL
45
+ login_data: dict[str, str] = user_login(iam_server=iam_server,
46
+ args=request.args,
47
+ errors=errors,
48
+ logger=logger)
49
+ if login_data:
50
+ result = jsonify(login_data)
44
51
 
45
52
  if errors:
46
53
  result = Response("; ".join(errors))
@@ -74,17 +81,18 @@ def service_logout() -> Response:
74
81
  # log the request
75
82
  logger.debug(msg=_log_init(request=request))
76
83
 
77
- # retrieve the IAM server
78
84
  errors: list[str] = []
79
- iam_server: IamServer = _get_iam_server(endpoint=request.endpoint,
80
- errors=errors,
81
- logger=logger)
82
- if iam_server:
83
- # logout the user
84
- user_logout(iam_server=iam_server,
85
- args=request.args,
86
- errors=errors,
87
- logger=logger)
85
+ with _iam_lock:
86
+ # retrieve the IAM server
87
+ iam_server: IamServer = _get_iam_server(endpoint=request.endpoint,
88
+ errors=errors,
89
+ logger=logger)
90
+ if iam_server:
91
+ # logout the user
92
+ user_logout(iam_server=iam_server,
93
+ args=request.args,
94
+ errors=errors,
95
+ logger=logger)
88
96
  if errors:
89
97
  result = Response("; ".join(errors))
90
98
  result.status_code = 400
@@ -106,10 +114,11 @@ def service_callback() -> Response:
106
114
  """
107
115
  Entry point for the callback from JusBR on authentication operation.
108
116
 
109
- This callback is typically invoked from a front-end application after a successful login at the
110
- JusBR login page, forwarding the data received.
117
+ This callback is invoked from a front-end application after a successful login at the
118
+ *IAM* server's login page, forwarding the data received. In a typical OAuth2 flow faction,
119
+ this data is then used to effectively obtain the token from the *IAM* server.
111
120
 
112
- :return: the response containing the token, or *BAD REQUEST*
121
+ :return: the *Response* containing the reference user identification and the token, or *BAD REQUEST*
113
122
  """
114
123
  # retrieve the operations's logger
115
124
  logger: Logger = _get_logger()
@@ -117,18 +126,19 @@ def service_callback() -> Response:
117
126
  # log the request
118
127
  logger.debug(msg=_log_init(request=request))
119
128
 
120
- # retrieve the IAM server
121
129
  errors: list[str] = []
122
130
  token_data: tuple[str, str] | None = None
123
- iam_server: IamServer = _get_iam_server(endpoint=request.endpoint,
124
- errors=errors,
125
- logger=logger)
126
- if iam_server:
127
- # process the callback operation
128
- token_data = login_callback(iam_server=iam_server,
129
- args=request.args,
130
- errors=errors,
131
- logger=logger)
131
+ with _iam_lock:
132
+ # retrieve the IAM server
133
+ iam_server: IamServer = _get_iam_server(endpoint=request.endpoint,
134
+ errors=errors,
135
+ logger=logger)
136
+ if iam_server:
137
+ # process the callback operation
138
+ token_data = login_callback(iam_server=iam_server,
139
+ args=request.args,
140
+ errors=errors,
141
+ logger=logger)
132
142
  result: Response
133
143
  if errors:
134
144
  result = jsonify({"errors": "; ".join(errors)})
@@ -136,10 +146,8 @@ def service_callback() -> Response:
136
146
  if logger:
137
147
  logger.error(msg=json.dumps(obj=result))
138
148
  else:
139
- result = jsonify({
140
- "user-id": token_data[0],
141
- "access-token": token_data[1]})
142
-
149
+ result = jsonify({"user-id": token_data[0],
150
+ "access-token": token_data[1]})
143
151
  # log the response
144
152
  if logger:
145
153
  logger.debug(msg=f"Response {result}")
@@ -148,14 +156,14 @@ def service_callback() -> Response:
148
156
 
149
157
 
150
158
  # @flask_app.route(rule=<token_endpoint>, # JUSBR_ENDPOINT_TOKEN
151
- # @flask_app.route(rule=<token_endpoint>, # KEYCLOAK_ENDPOINT_TOKEN
152
159
  # methods=["GET"])
160
+ # @flask_app.route(rule=<token_endpoint>, # KEYCLOAK_ENDPOINT_TOKEN
153
161
  # methods=["GET"])
154
162
  def service_token() -> Response:
155
163
  """
156
- Entry point for retrieving token from the *IAM* server.
164
+ Entry point for retrieving a token from the *IAM* server.
157
165
 
158
- :return: the response containing the token, or *UNAUTHORIZED*
166
+ :return: the *Response* containing the user reference identification and the token, or *BAD REQUEST*
159
167
  """
160
168
  # retrieve the operations's logger
161
169
  logger: Logger = _get_logger()
@@ -163,26 +171,38 @@ def service_token() -> Response:
163
171
  # log the request
164
172
  logger.debug(msg=_log_init(request=request))
165
173
 
166
- # retrieve the IAM server
174
+ # obtain the user's identification
175
+ args: dict[str, Any] = request.args
176
+ user_id: str = args.get("user-id") or args.get("user_id") or args.get("login")
177
+
167
178
  errors: list[str] = []
168
- iam_server: IamServer = _get_iam_server(endpoint=request.endpoint,
169
- errors=errors,
170
- logger=logger)
171
- # retrieve the token
172
179
  token: str | None = None
173
- if iam_server:
174
- errors: list[str] = []
175
- token: str = user_token(iam_server=iam_server,
176
- args=request.args,
177
- errors=errors,
178
- logger=logger)
180
+ if user_id:
181
+ with _iam_lock:
182
+ # retrieve the IAM server
183
+ iam_server: IamServer = _get_iam_server(endpoint=request.endpoint,
184
+ errors=errors,
185
+ logger=logger)
186
+ if iam_server:
187
+ # retrieve the token
188
+ errors: list[str] = []
189
+ token: str = user_token(iam_server=iam_server,
190
+ args=args,
191
+ errors=errors,
192
+ logger=logger)
193
+ else:
194
+ msg: str = "User identification not provided"
195
+ errors.append(msg)
196
+ if logger:
197
+ logger.error(msg=msg)
198
+
179
199
  result: Response
180
200
  if errors:
181
201
  result = Response("; ".join(errors))
182
202
  result.status_code = 400
183
203
  else:
184
- result = jsonify({"token": token})
185
-
204
+ result = jsonify({"user-id": user_id,
205
+ "token": token})
186
206
  # log the response
187
207
  if logger:
188
208
  logger.debug(msg=f"Response {result}")
@@ -196,26 +216,45 @@ def service_exchange() -> Response:
196
216
  """
197
217
  Entry point for requesting the *IAM* server to exchange the token.
198
218
 
199
- This is currently limit to the *Keycloak* server
219
+ This is currently limited to the *KEYCLOAK* server. The token itself is stored in *KEYCLOAK*'s registry.
220
+ The expected parameters in the request are:
221
+ - client-id: identification for the reference user (aliases: 'client_id', 'login')
222
+ - token: the token to be exchanged
223
+
224
+ If the exchange is successful, the token data is stored in the *IAM* server's registry, and returned.
225
+ Otherwise, *errors* will contain the appropriate error message.
226
+
227
+ The typical *Response* returned contains the following attributes:
228
+ {
229
+ "token_type": "Bearer",
230
+ "access_token": <str>,
231
+ "expires_in": <number-of-seconds>,
232
+ "refresh_token": <str>,
233
+ "refesh_expires_in": <number-of-seconds>
234
+ }
200
235
 
201
- :return: the response containing the token, or *UNAUTHORIZED*
236
+ :return: the *Response* containing the token data, or *UNAUTHORIZED*
202
237
  """
203
238
  # retrieve the operations's logger
204
239
  logger: Logger = _get_logger()
240
+ if logger:
241
+ # log the request
242
+ logger.debug(msg=_log_init(request=request))
205
243
 
206
- # retrieve the IAM server (currently, only 'Keycloak' is supported)
207
244
  errors: list[str] = []
208
- iam_server: IamServer = _get_iam_server(endpoint=request.endpoint,
209
- errors=errors,
210
- logger=logger)
211
- # exchange the token
212
- token_data: dict[str, Any] | None = None
213
- if iam_server:
214
- errors: list[str] = []
215
- token_data = token_exchange(iam_server=iam_server,
216
- args=request.args,
217
- errors=errors,
218
- logger=logger)
245
+ with _iam_lock:
246
+ # retrieve the IAM server (currently, only 'IAM_KEYCLOAK' is supported)
247
+ iam_server: IamServer = _get_iam_server(endpoint=request.endpoint,
248
+ errors=errors,
249
+ logger=logger)
250
+ # exchange the token
251
+ token_data: dict[str, Any] | None = None
252
+ if iam_server:
253
+ errors: list[str] = []
254
+ token_data = token_exchange(iam_server=iam_server,
255
+ args=request.args,
256
+ errors=errors,
257
+ logger=logger)
219
258
  result: Response
220
259
  if errors:
221
260
  result = Response("; ".join(errors))
@@ -7,7 +7,7 @@ from pypomes_core import (
7
7
  )
8
8
  from typing import Any, Final
9
9
 
10
- from .iam_common import _IAM_SERVERS, IamServer
10
+ from .iam_common import _IAM_SERVERS, IamServer, _iam_lock
11
11
  from .iam_pomes import user_token
12
12
 
13
13
  JUSBR_CLIENT_ID: Final[str] = env_get_str(key=f"{APP_PREFIX}_JUSBR_CLIENT_ID")
@@ -65,18 +65,19 @@ def jusbr_setup(flask_app: Flask,
65
65
  # configure the JusBR registry
66
66
  cache: Cache = FIFOCache(maxsize=1048576)
67
67
  cache["users"] = {}
68
- _IAM_SERVERS[IamServer.IAM_JUSRBR] = {
69
- "client-id": client_id,
70
- "client-secret": client_secret,
71
- "client-timeout": client_timeout,
72
- "recipient-attr": recipient_attribute,
73
- "base-url": base_url,
74
- "pk-expiration": sys.maxsize,
75
- "pk-lifetime": public_key_lifetime,
76
- "cache": cache,
77
- "logger": logger,
78
- "redirect-uri": None
79
- }
68
+ with _iam_lock:
69
+ _IAM_SERVERS[IamServer.IAM_JUSRBR] = {
70
+ "client-id": client_id,
71
+ "client-secret": client_secret,
72
+ "client-timeout": client_timeout,
73
+ "recipient-attr": recipient_attribute,
74
+ "base-url": base_url,
75
+ "pk-expiration": sys.maxsize,
76
+ "pk-lifetime": public_key_lifetime,
77
+ "cache": cache,
78
+ "logger": logger,
79
+ "redirect-uri": None
80
+ }
80
81
 
81
82
  # establish the endpoints
82
83
  if login_endpoint:
@@ -112,9 +113,14 @@ def jusbr_get_token(user_id: str,
112
113
  :param logger: optional logger
113
114
  :return: the uthentication tokem
114
115
  """
116
+ # declare the return variable
117
+ result: str
118
+
115
119
  # retrieve the token
116
120
  args: dict[str, Any] = {"user-id": user_id}
117
- return user_token(iam_server=IamServer.IAM_JUSRBR,
118
- args=args,
119
- errors=errors,
120
- logger=logger)
121
+ with _iam_lock:
122
+ result = user_token(iam_server=IamServer.IAM_JUSRBR,
123
+ args=args,
124
+ errors=errors,
125
+ logger=logger)
126
+ return result
@@ -7,7 +7,7 @@ from pypomes_core import (
7
7
  )
8
8
  from typing import Any, Final
9
9
 
10
- from .iam_common import _IAM_SERVERS, IamServer
10
+ from .iam_common import _IAM_SERVERS, IamServer, _iam_lock
11
11
  from .iam_pomes import user_token
12
12
 
13
13
  KEYCLOAK_CLIENT_ID: Final[str] = env_get_str(key=f"{APP_PREFIX}_KEYCLOAK_CLIENT_ID")
@@ -74,18 +74,19 @@ def keycloak_setup(flask_app: Flask,
74
74
  # configure the Keycloak registry
75
75
  cache: Cache = FIFOCache(maxsize=1048576)
76
76
  cache["users"] = {}
77
- _IAM_SERVERS[IamServer.IAM_KEYCLOAK] = {
78
- "client-id": client_id,
79
- "client-secret": client_secret,
80
- "client-timeout": client_timeout,
81
- "recipient-attr": recipient_attribute,
82
- "base-url": f"{base_url}/realms/{realm}",
83
- "pk-expiration": sys.maxsize,
84
- "pk-lifetime": public_key_lifetime,
85
- "cache": cache,
86
- "logger": logger,
87
- "redirect-uri": None
88
- }
77
+ with _iam_lock:
78
+ _IAM_SERVERS[IamServer.IAM_KEYCLOAK] = {
79
+ "client-id": client_id,
80
+ "client-secret": client_secret,
81
+ "client-timeout": client_timeout,
82
+ "recipient-attr": recipient_attribute,
83
+ "base-url": f"{base_url}/realms/{realm}",
84
+ "pk-expiration": sys.maxsize,
85
+ "pk-lifetime": public_key_lifetime,
86
+ "cache": cache,
87
+ "logger": logger,
88
+ "redirect-uri": None
89
+ }
89
90
 
90
91
  # establish the endpoints
91
92
  if login_endpoint:
@@ -126,9 +127,14 @@ def keycloak_get_token(user_id: str,
126
127
  :param logger: optional logger
127
128
  :return: the uthentication tokem
128
129
  """
130
+ # declare the return variable
131
+ result: str
132
+
129
133
  # retrieve the token
130
134
  args: dict[str, Any] = {"user-id": user_id}
131
- return user_token(iam_server=IamServer.IAM_KEYCLOAK,
132
- args=args,
133
- errors=errors,
134
- logger=logger)
135
+ with _iam_lock:
136
+ result = user_token(iam_server=IamServer.IAM_KEYCLOAK,
137
+ args=args,
138
+ errors=errors,
139
+ logger=logger)
140
+ return result
@@ -4,7 +4,8 @@ from base64 import b64encode
4
4
  from datetime import datetime
5
5
  from logging import Logger
6
6
  from pypomes_core import TZ_LOCAL, exc_format
7
- from typing import Any
7
+ from threading import Lock
8
+ from typing import Any, Final
8
9
 
9
10
  # structure:
10
11
  # {
@@ -19,7 +20,11 @@ from typing import Any
19
20
  # "expiration": <timestamp>
20
21
  # }
21
22
  # }
22
- _provider_registry: dict[str, dict[str, Any]] = {}
23
+ _provider_registry: Final[dict[str, dict[str, Any]]] = {}
24
+
25
+ # the lock protecting the data in '_provider_registry'
26
+ # (because it is 'Final' and set at declaration time, it can be accessed through simple imports)
27
+ _provider_lock: Final[Lock] = Lock()
23
28
 
24
29
 
25
30
  def provider_register(provider_id: str,
@@ -48,18 +53,19 @@ def provider_register(provider_id: str,
48
53
  :param headers_data: optional key-value pairs to be added to the request headers
49
54
  :param body_data: optional key-value pairs to be added to the request body
50
55
  """
51
- global _provider_registry # noqa: PLW0602
56
+ global _provider_registry
52
57
 
53
- _provider_registry[provider_id] = {
54
- "url": auth_url,
55
- "user": auth_user,
56
- "pwd": auth_pwd,
57
- "custom-auth": custom_auth,
58
- "headers-data": headers_data,
59
- "body-data": body_data,
60
- "token": None,
61
- "expiration": datetime.now(tz=TZ_LOCAL).timestamp()
62
- }
58
+ with _provider_lock:
59
+ _provider_registry[provider_id] = {
60
+ "url": auth_url,
61
+ "user": auth_user,
62
+ "pwd": auth_pwd,
63
+ "custom-auth": custom_auth,
64
+ "headers-data": headers_data,
65
+ "body-data": body_data,
66
+ "token": None,
67
+ "expiration": datetime.now(tz=TZ_LOCAL).timestamp()
68
+ }
63
69
 
64
70
 
65
71
  def provider_get_token(provider_id: str,
@@ -78,53 +84,54 @@ def provider_get_token(provider_id: str,
78
84
  result: str | None = None
79
85
 
80
86
  err_msg: str | None = None
81
- provider: dict[str, Any] = _provider_registry.get(provider_id)
82
- if provider:
83
- now: float = datetime.now(tz=TZ_LOCAL).timestamp()
84
- if now > provider.get("expiration"):
85
- user: str = provider.get("user")
86
- pwd: str = provider.get("pwd")
87
- headers_data: dict[str, str] = provider.get("headers-data") or {}
88
- body_data: dict[str, str] = provider.get("body-data") or {}
89
- custom_auth: tuple[str, str] = provider.get("custom-auth")
90
- if custom_auth:
91
- body_data[custom_auth[0]] = user
92
- body_data[custom_auth[1]] = pwd
93
- else:
94
- enc_bytes: bytes = b64encode(f"{user}:{pwd}".encode())
95
- headers_data["Authorization"] = f"Basic {enc_bytes.decode()}"
96
- url: str = provider.get("url")
97
- try:
98
- # typical return on a token request:
99
- # {
100
- # "token_type": "Bearer",
101
- # "access_token": <str>,
102
- # "expires_in": <number-of-seconds>,
103
- # optional data:
104
- # "refresh_token": <str>,
105
- # "refresh_expires_in": <number-of-seconds>
106
- # }
107
- response: requests.Response = requests.post(url=url,
108
- data=body_data,
109
- headers=headers_data,
110
- timeout=None)
111
- if response.status_code < 200 or response.status_code >= 300:
112
- # request resulted in error, report the problem
113
- err_msg = (f"POST '{url}': failed, "
114
- f"status {response.status_code}, reason '{response.reason}'")
87
+ with _provider_lock:
88
+ provider: dict[str, Any] = _provider_registry.get(provider_id)
89
+ if provider:
90
+ now: float = datetime.now(tz=TZ_LOCAL).timestamp()
91
+ if now > provider.get("expiration"):
92
+ user: str = provider.get("user")
93
+ pwd: str = provider.get("pwd")
94
+ headers_data: dict[str, str] = provider.get("headers-data") or {}
95
+ body_data: dict[str, str] = provider.get("body-data") or {}
96
+ custom_auth: tuple[str, str] = provider.get("custom-auth")
97
+ if custom_auth:
98
+ body_data[custom_auth[0]] = user
99
+ body_data[custom_auth[1]] = pwd
115
100
  else:
116
- reply: dict[str, Any] = response.json()
117
- provider["token"] = reply.get("access_token")
118
- provider["expiration"] = now + int(reply.get("expires_in"))
119
- if logger:
120
- logger.debug(msg=f"POST '{url}': status {response.status_code}")
121
- except Exception as e:
122
- # the operation raised an exception
123
- err_msg = exc_format(exc=e,
124
- exc_info=sys.exc_info())
125
- err_msg = f"POST '{url}': error, '{err_msg}'"
126
- else:
127
- err_msg: str = f"Provider '{provider_id}' not registered"
101
+ enc_bytes: bytes = b64encode(f"{user}:{pwd}".encode())
102
+ headers_data["Authorization"] = f"Basic {enc_bytes.decode()}"
103
+ url: str = provider.get("url")
104
+ try:
105
+ # typical return on a token request:
106
+ # {
107
+ # "token_type": "Bearer",
108
+ # "access_token": <str>,
109
+ # "expires_in": <number-of-seconds>,
110
+ # optional data:
111
+ # "refresh_token": <str>,
112
+ # "refresh_expires_in": <number-of-seconds>
113
+ # }
114
+ response: requests.Response = requests.post(url=url,
115
+ data=body_data,
116
+ headers=headers_data,
117
+ timeout=None)
118
+ if response.status_code < 200 or response.status_code >= 300:
119
+ # request resulted in error, report the problem
120
+ err_msg = (f"POST '{url}': failed, "
121
+ f"status {response.status_code}, reason '{response.reason}'")
122
+ else:
123
+ reply: dict[str, Any] = response.json()
124
+ provider["token"] = reply.get("access_token")
125
+ provider["expiration"] = now + int(reply.get("expires_in"))
126
+ if logger:
127
+ logger.debug(msg=f"POST '{url}': status {response.status_code}")
128
+ except Exception as e:
129
+ # the operation raised an exception
130
+ err_msg = exc_format(exc=e,
131
+ exc_info=sys.exc_info())
132
+ err_msg = f"POST '{url}': error, '{err_msg}'"
133
+ else:
134
+ err_msg: str = f"Provider '{provider_id}' not registered"
128
135
 
129
136
  if err_msg:
130
137
  if isinstance(errors, list):
@@ -40,7 +40,7 @@ def token_validate(token: str,
40
40
  :param recipient_attr: attribute in the token's payload holding the expected subject's identification
41
41
  :param errors: incidental error messages
42
42
  :param logger: optional logger
43
- :return: The token's claims (*header* and *payload*) if it is valid, *None* otherwise
43
+ :return: The token's claims (*header* and *payload*), or *None* if error
44
44
  """
45
45
  # initialize the return variable
46
46
  result: dict[str, dict[str, Any]] | None = None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pypomes_iam
3
- Version: 0.3.4
3
+ Version: 0.3.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
@@ -0,0 +1,12 @@
1
+ pypomes_iam/__init__.py,sha256=H7rUCaUEJBLNJv2rtdmBxwcAB28OItdEPenpv_UEOVw,965
2
+ pypomes_iam/iam_common.py,sha256=f74FUDcnMM2cgzJg-AF17GwCKwbfoezS8LppwxYwPys,10049
3
+ pypomes_iam/iam_pomes.py,sha256=gvDpgff6arB4_Y8AAf6QH2CEWRmdy-kcnQLyD0hx4Y4,23966
4
+ pypomes_iam/iam_services.py,sha256=Ae_hLz5luRjK-l_rhBcuuY03Ov7n7o67UYgBb5rbBys,10002
5
+ pypomes_iam/jusbr_pomes.py,sha256=0qbjJ6EGnlx17K-4Lqh5XkfH58y0joVZiD6HykbwpoE,5823
6
+ pypomes_iam/keycloak_pomes.py,sha256=5ZfpncofF20C1IB5ndO31vfrvfa8Ffy7FJxkGoKKoQQ,6836
7
+ pypomes_iam/provider_pomes.py,sha256=3Rui68hmj8zwY0tnw4aWurz-yQ-niacJFQpi6nWzh-M,6355
8
+ pypomes_iam/token_pomes.py,sha256=1g6PMNNMbmdwLrsvSXvpO8-zdRhso1IFnwAyndNmV4Q,5332
9
+ pypomes_iam-0.3.6.dist-info/METADATA,sha256=q53TFkBnU4mUAZgsJ_r_730kASXLiIyCwW_5mkFz8TU,694
10
+ pypomes_iam-0.3.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
11
+ pypomes_iam-0.3.6.dist-info/licenses/LICENSE,sha256=YvUELgV8qvXlaYsy9hXG5EW3Bmsrkw-OJmmILZnonAc,1086
12
+ pypomes_iam-0.3.6.dist-info/RECORD,,
@@ -1,12 +0,0 @@
1
- pypomes_iam/__init__.py,sha256=H7rUCaUEJBLNJv2rtdmBxwcAB28OItdEPenpv_UEOVw,965
2
- pypomes_iam/iam_common.py,sha256=IWH9DVykF7K-Z9Sn3oP7To9_I2TkO2AzjVod238zUWc,13645
3
- pypomes_iam/iam_pomes.py,sha256=g06NSz3r1qv4LzDpjQ9iozdVyabidt7qLEocQRv1yns,15230
4
- pypomes_iam/iam_services.py,sha256=osqDptxCqL9eZPCRecBwtlS35YiMRvO7EIgdcyovSU4,8182
5
- pypomes_iam/jusbr_pomes.py,sha256=M47h_PUUgbCmFQyKz2sN1H9T00BC5v_oPgwl5ATWMSA,5625
6
- pypomes_iam/keycloak_pomes.py,sha256=GtXJb4TZb-a_5b9ExYdJGetBcU1pEP96ONO6prA_vDo,6638
7
- pypomes_iam/provider_pomes.py,sha256=eP8XzjTUEpwejTkO0wmDiqKjqbIEOzRNCR2ju5E15og,5856
8
- pypomes_iam/token_pomes.py,sha256=cfHdv2qYbsciY-3aEuDYUwCM479uMRSm2uwr4-hCaBQ,5345
9
- pypomes_iam-0.3.4.dist-info/METADATA,sha256=wt98InTB4_MY_-JQHDs9ZTZ1hb2T5MbJtAkduCUopNo,694
10
- pypomes_iam-0.3.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
11
- pypomes_iam-0.3.4.dist-info/licenses/LICENSE,sha256=YvUELgV8qvXlaYsy9hXG5EW3Bmsrkw-OJmmILZnonAc,1086
12
- pypomes_iam-0.3.4.dist-info/RECORD,,