pypomes-iam 0.7.6__py3-none-any.whl → 0.8.5__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 +20 -12
- pypomes_iam/iam_actions.py +188 -66
- pypomes_iam/iam_common.py +71 -29
- pypomes_iam/iam_pomes.py +122 -99
- pypomes_iam/iam_services.py +326 -121
- pypomes_iam/provider_pomes.py +210 -39
- pypomes_iam/token_pomes.py +27 -0
- {pypomes_iam-0.7.6.dist-info → pypomes_iam-0.8.5.dist-info}/METADATA +2 -2
- pypomes_iam-0.8.5.dist-info/RECORD +11 -0
- pypomes_iam-0.7.6.dist-info/RECORD +0 -11
- {pypomes_iam-0.7.6.dist-info → pypomes_iam-0.8.5.dist-info}/WHEEL +0 -0
- {pypomes_iam-0.7.6.dist-info → pypomes_iam-0.8.5.dist-info}/licenses/LICENSE +0 -0
pypomes_iam/provider_pomes.py
CHANGED
|
@@ -4,8 +4,13 @@ import sys
|
|
|
4
4
|
from base64 import b64encode
|
|
5
5
|
from datetime import datetime
|
|
6
6
|
from enum import StrEnum
|
|
7
|
+
from flask import Flask, Response, request, jsonify
|
|
7
8
|
from logging import Logger
|
|
8
|
-
from pypomes_core import
|
|
9
|
+
from pypomes_core import (
|
|
10
|
+
APP_PREFIX, TZ_LOCAL,
|
|
11
|
+
env_get_str, env_get_strs, env_get_obj, exc_format,
|
|
12
|
+
func_capture_params, func_defaulted_params
|
|
13
|
+
)
|
|
9
14
|
from threading import Lock
|
|
10
15
|
from typing import Any, Final
|
|
11
16
|
|
|
@@ -14,76 +19,152 @@ class ProviderParam(StrEnum):
|
|
|
14
19
|
"""
|
|
15
20
|
Parameters for configuring a *JWT* token provider.
|
|
16
21
|
"""
|
|
17
|
-
|
|
18
|
-
USER = "user"
|
|
19
|
-
PWD = "pwd"
|
|
22
|
+
BODY_DATA = "body-data"
|
|
20
23
|
CUSTOM_AUTH = "custom-auth"
|
|
21
24
|
HEADER_DATA = "headers-data"
|
|
22
|
-
|
|
25
|
+
USER_ID = "user-id"
|
|
26
|
+
USER_SECRET = "user-secret"
|
|
23
27
|
ACCESS_TOKEN = "access-token"
|
|
24
28
|
ACCESS_EXPIRATION = "access-expiration"
|
|
25
29
|
REFRESH_TOKEN = "refresh-token"
|
|
26
30
|
REFRESH_EXPIRATION = "refresh-expiration"
|
|
31
|
+
URL_TOKEN = "url-token"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# the logger for IAM service operations
|
|
35
|
+
# (used exclusively at the HTTP endpoints - all other functions receive the logger as parameter)
|
|
36
|
+
__JWT_LOGGER: Logger | None = None
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def __get_provider_data() -> dict[str, dict[ProviderParam, Any]]:
|
|
40
|
+
"""
|
|
41
|
+
Obtain the configuration data for select *JWT* providers.
|
|
42
|
+
|
|
43
|
+
The configuration parameters for the JWT providers are specified with environment variables,
|
|
44
|
+
or dynamically with *provider_setup_server()*. Specifying configuration parameters with
|
|
45
|
+
environment variables can be done by following these steps:
|
|
46
|
+
|
|
47
|
+
1. Specify *<APP_PREFIX>_AUTH_PROVIDERS* with a list of names (typically, in lower-case), and the data set
|
|
48
|
+
below for each providers, where *<JWT>* stands for the provider's name in upper-case:
|
|
49
|
+
- *<APP_PREFIX>_<JWT>_BODY_DATA* (optional)
|
|
50
|
+
- *<APP_PREFIX>_<JWT>_CUSTOM_AUTH* (optional)
|
|
51
|
+
- *<APP_PREFIX>_<JWT>_HEADER_DATA* (optional)
|
|
52
|
+
- *<APP_PREFIX>_<JWT>_USER_ID* (required)
|
|
53
|
+
- *<APP_PREFIX>_<JWT>_USER_SECRET* (required)
|
|
54
|
+
- *<APP_PREFIX>_<JWT>_URL_TOKEN* (required)
|
|
55
|
+
|
|
56
|
+
2. The special environment variable *<APP_PREFIX>_PROVIDER_ENDPOINT_TOKEN* identifies the endpoint
|
|
57
|
+
from which to obtain JWT tokens. It is not part of the *JWT* providers' setup, but is meant to be
|
|
58
|
+
used by function *provider_setup_endpoint()*, wherein the value in that variable would represent
|
|
59
|
+
the default value for its parameter.
|
|
60
|
+
|
|
61
|
+
:return: the configuration data for the select *JWT* providers.
|
|
62
|
+
"""
|
|
63
|
+
# initialize the return variable
|
|
64
|
+
result: dict[str, dict[ProviderParam, Any]] = {}
|
|
65
|
+
|
|
66
|
+
servers: list[str] = env_get_strs(key=f"{APP_PREFIX}_AUTH_PROVIDERS") or []
|
|
67
|
+
for server in servers:
|
|
68
|
+
prefix = server.upper()
|
|
69
|
+
result[server] = {
|
|
70
|
+
ProviderParam.USER_ID: env_get_str(key=f"{APP_PREFIX}_{prefix}_USER_ID"),
|
|
71
|
+
ProviderParam.USER_SECRET: env_get_str(key=f"{APP_PREFIX}_{prefix}_USER_SECRET"),
|
|
72
|
+
ProviderParam.BODY_DATA: env_get_obj(key=f"{APP_PREFIX}_{prefix}_BODY_DATA"),
|
|
73
|
+
ProviderParam.CUSTOM_AUTH: env_get_strs(key=f"{APP_PREFIX}_{prefix}_CUSTOM_AUTH"),
|
|
74
|
+
ProviderParam.HEADER_DATA: env_get_obj(key=f"{APP_PREFIX}_{prefix}_HEADER_DATA"),
|
|
75
|
+
ProviderParam.URL_TOKEN: env_get_str(key=f"{APP_PREFIX}_{prefix}_URL_TOKEN"),
|
|
76
|
+
ProviderParam.ACCESS_TOKEN: None,
|
|
77
|
+
ProviderParam.ACCESS_EXPIRATION: 0,
|
|
78
|
+
ProviderParam.REFRESH_TOKEN: None,
|
|
79
|
+
ProviderParam.REFRESH_EXPIRATION: 0
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return result
|
|
27
83
|
|
|
28
84
|
|
|
29
85
|
# structure:
|
|
30
86
|
# {
|
|
31
87
|
# <provider-id>: {
|
|
32
|
-
# "url": <strl>,
|
|
33
|
-
# "user": <str>,
|
|
34
|
-
# "pwd": <str>,
|
|
35
|
-
# "custom-auth": <bool>,
|
|
36
|
-
# "headers-data": <dict[str, str]>,
|
|
37
88
|
# "body-data": <dict[str, str],
|
|
89
|
+
# "custom-auth": <tuple[str, str]>,
|
|
90
|
+
# "headers-data": <dict[str, str]>,
|
|
91
|
+
# "user-id": <str>,
|
|
92
|
+
# "user-secret": <str>,
|
|
93
|
+
# "url-token": <strl>,
|
|
94
|
+
# # dinamically set
|
|
38
95
|
# "access-token": <str>,
|
|
39
96
|
# "access-expiration": <timestamp>,
|
|
40
97
|
# "refresh-token": <str>,
|
|
41
98
|
# "refresh-expiration": <timestamp>
|
|
42
99
|
# }
|
|
43
100
|
# }
|
|
44
|
-
_provider_registry: Final[dict[str, dict[str, Any]]] =
|
|
101
|
+
_provider_registry: Final[dict[str, dict[str, Any]]] = __get_provider_data()
|
|
45
102
|
|
|
46
103
|
# the lock protecting the data in '_provider_registry'
|
|
47
104
|
# (because it is 'Final' and set at declaration time, it can be accessed through simple imports)
|
|
48
105
|
_provider_lock: Final[Lock] = Lock()
|
|
49
106
|
|
|
50
107
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
108
|
+
@func_capture_params
|
|
109
|
+
def provider_setup_server(provider_id: str,
|
|
110
|
+
user_id: str = None,
|
|
111
|
+
user_secret: str = None,
|
|
112
|
+
custom_auth: tuple[str, str] = None,
|
|
113
|
+
header_data: dict[str, str] = None,
|
|
114
|
+
body_data: dict[str, str] = None,
|
|
115
|
+
url_token: str = None) -> None:
|
|
58
116
|
"""
|
|
59
|
-
|
|
117
|
+
Setup the *JWT* provider *provider_id*.
|
|
118
|
+
|
|
119
|
+
For the parameters not effectively passed, an attempt is made to obtain a value from the corresponding
|
|
120
|
+
environment variable.
|
|
60
121
|
|
|
61
122
|
If specified, *custom_auth* provides key names for sending credentials (username and password, in this order)
|
|
62
123
|
as key-value pairs in the body of the request. Otherwise, the external provider *provider_id* uses the standard
|
|
63
124
|
HTTP Basic Authorization scheme, wherein the credentials are B64-encoded and sent in the request headers.
|
|
64
125
|
|
|
65
|
-
Optional constant key-value pairs (such as ['Content-Type', 'application/x-www-form-urlencoded']),
|
|
66
|
-
added to the request headers, may be specified in *headers_data*. Likewise, optional constant
|
|
67
|
-
(such as ['grant_type', 'client_credentials']), to be added to the request body,
|
|
126
|
+
Optional constant key-value pairs (such as *['Content-Type', 'application/x-www-form-urlencoded']*),
|
|
127
|
+
to be added to the request headers, may be specified in *headers_data*. Likewise, optional constant
|
|
128
|
+
key-value pairs (such as *['grant_type', 'client_credentials']*), to be added to the request body,
|
|
129
|
+
may be specified in *body_data*.
|
|
68
130
|
|
|
69
131
|
:param provider_id: the provider's identification
|
|
70
|
-
:param
|
|
71
|
-
:param
|
|
72
|
-
:param auth_pwd: the basic authorization password
|
|
132
|
+
:param user_id: the basic authorization user
|
|
133
|
+
:param user_secret: the basic authorization password
|
|
73
134
|
:param custom_auth: optional key names for sending the credentials as key-value pairs in the body of the request
|
|
74
|
-
:param
|
|
135
|
+
:param header_data: optional key-value pairs to be added to the request headers
|
|
75
136
|
:param body_data: optional key-value pairs to be added to the request body
|
|
137
|
+
:param url_token: the url to request *JWT* tokens with
|
|
76
138
|
"""
|
|
77
139
|
global _provider_registry
|
|
78
140
|
|
|
141
|
+
# obtain the defaulted parameters
|
|
142
|
+
defaulted_params: list[str] = func_defaulted_params.get()
|
|
143
|
+
|
|
144
|
+
# read from the environment variables
|
|
145
|
+
prefix: str = provider_id.upper()
|
|
146
|
+
if "user_id" in defaulted_params:
|
|
147
|
+
user_id = env_get_str(key=f"{APP_PREFIX}_{prefix}_USER_ID")
|
|
148
|
+
if "user_secret" in defaulted_params:
|
|
149
|
+
user_secret = env_get_str(key=f"{APP_PREFIX}_{prefix}_USER_SECRET")
|
|
150
|
+
if "custom_auth" in defaulted_params:
|
|
151
|
+
custom_auth = env_get_strs(key=f"{APP_PREFIX}_{prefix}_CUSTOM_AUTH")
|
|
152
|
+
if "header_data" in defaulted_params:
|
|
153
|
+
header_data = env_get_obj(key=f"{APP_PREFIX}_{prefix}_HEADER_DATA")
|
|
154
|
+
if "body_data" in defaulted_params:
|
|
155
|
+
body_data = env_get_obj(key=f"{APP_PREFIX}_{prefix}_BODY_DATA")
|
|
156
|
+
if "url_token" in defaulted_params:
|
|
157
|
+
url_token = env_get_str(key=f"{APP_PREFIX}_{prefix}_URL_TOKEN")
|
|
158
|
+
|
|
79
159
|
with _provider_lock:
|
|
80
160
|
_provider_registry[provider_id] = {
|
|
81
|
-
ProviderParam.URL: auth_url,
|
|
82
|
-
ProviderParam.USER: auth_user,
|
|
83
|
-
ProviderParam.PWD: auth_pwd,
|
|
84
|
-
ProviderParam.CUSTOM_AUTH: custom_auth,
|
|
85
|
-
ProviderParam.HEADER_DATA: headers_data,
|
|
86
161
|
ProviderParam.BODY_DATA: body_data,
|
|
162
|
+
ProviderParam.CUSTOM_AUTH: custom_auth,
|
|
163
|
+
ProviderParam.HEADER_DATA: header_data,
|
|
164
|
+
ProviderParam.USER_ID: user_id,
|
|
165
|
+
ProviderParam.USER_SECRET: user_secret,
|
|
166
|
+
ProviderParam.URL_TOKEN: url_token,
|
|
167
|
+
# dynamically set
|
|
87
168
|
ProviderParam.ACCESS_TOKEN: None,
|
|
88
169
|
ProviderParam.ACCESS_EXPIRATION: 0,
|
|
89
170
|
ProviderParam.REFRESH_TOKEN: None,
|
|
@@ -91,17 +172,107 @@ def provider_register(provider_id: str,
|
|
|
91
172
|
}
|
|
92
173
|
|
|
93
174
|
|
|
175
|
+
@func_capture_params
|
|
176
|
+
def provider_setup_endpoint(flask_app: Flask,
|
|
177
|
+
provider_endpoint: str = None) -> None:
|
|
178
|
+
"""
|
|
179
|
+
Setup the endpoint for requesting token from the registered *JWT* providers.
|
|
180
|
+
|
|
181
|
+
if *provider_endpoint* is not effectively passed, an attempt is made to obtain a value from the corresponding
|
|
182
|
+
environment variable.
|
|
183
|
+
|
|
184
|
+
:param flask_app: the Flask application
|
|
185
|
+
:param provider_endpoint: endpoint for requenting tokens to provider
|
|
186
|
+
"""
|
|
187
|
+
# obtain the defaulted parameters
|
|
188
|
+
defaulted_params: list[str] = func_defaulted_params.get()
|
|
189
|
+
|
|
190
|
+
# read from the environment variable
|
|
191
|
+
if "provider_endpoint" in defaulted_params:
|
|
192
|
+
provider_endpoint = env_get_str(key=f"{APP_PREFIX}_PROVIDER_ENDPOINT_TOKEN")
|
|
193
|
+
|
|
194
|
+
# establish the endpoints
|
|
195
|
+
if provider_endpoint:
|
|
196
|
+
flask_app.add_url_rule(rule=provider_endpoint,
|
|
197
|
+
endpoint=f"provider-get-token",
|
|
198
|
+
view_func=service_get_token,
|
|
199
|
+
methods=["GET"])
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def provider_setup_logger(logger: Logger) -> None:
|
|
203
|
+
"""
|
|
204
|
+
Register the logger for HTTP services.
|
|
205
|
+
|
|
206
|
+
:param logger: the logger to be registered
|
|
207
|
+
"""
|
|
208
|
+
global __JWT_LOGGER
|
|
209
|
+
__JWT_LOGGER = logger
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
# @flask_app.route(rule=<token_endpoint>, # IAM_PROVIDER_ENDPOINT_TOKEN
|
|
213
|
+
# methods=["GET"])
|
|
214
|
+
def service_get_token() -> Response:
|
|
215
|
+
"""
|
|
216
|
+
Entry point for retrieving a token from the *JWT* provider.
|
|
217
|
+
|
|
218
|
+
The provider is identified by the request parameter *jwt-provider*.
|
|
219
|
+
|
|
220
|
+
On success, the returned *Response* will contain the following JSON:
|
|
221
|
+
{
|
|
222
|
+
"access-token": <token>
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
:return: *Response* containing the JWT token, or *BAD REQUEST*
|
|
226
|
+
"""
|
|
227
|
+
# retrieve the request arguments
|
|
228
|
+
args: dict[str, Any] = dict(request.args) or {}
|
|
229
|
+
|
|
230
|
+
# log the request
|
|
231
|
+
if __JWT_LOGGER:
|
|
232
|
+
__JWT_LOGGER.debug(msg=f"Request {request.method}:{request.path}; {json.dumps(obj=args,
|
|
233
|
+
ensure_ascii=False)}")
|
|
234
|
+
|
|
235
|
+
# obtain the provider JWT
|
|
236
|
+
provider_id: str = args.get("jwt-provider")
|
|
237
|
+
|
|
238
|
+
# retrieve the token
|
|
239
|
+
token: str | None = None
|
|
240
|
+
errors: list[str] = []
|
|
241
|
+
if provider_id:
|
|
242
|
+
token: str = provider_get_token(provider_id=provider_id,
|
|
243
|
+
errors=errors,
|
|
244
|
+
logger=__JWT_LOGGER)
|
|
245
|
+
else:
|
|
246
|
+
msg: str = "JWT provider not informed"
|
|
247
|
+
errors.append(msg)
|
|
248
|
+
if __JWT_LOGGER:
|
|
249
|
+
__JWT_LOGGER.error(msg=msg)
|
|
250
|
+
|
|
251
|
+
result: Response
|
|
252
|
+
if errors:
|
|
253
|
+
result = Response(response="; ".join(errors),
|
|
254
|
+
status=400)
|
|
255
|
+
else:
|
|
256
|
+
result = jsonify({"access-token": token})
|
|
257
|
+
if __JWT_LOGGER:
|
|
258
|
+
# log the response (the returned data is not logged, as it contains the token)
|
|
259
|
+
__JWT_LOGGER.debug(msg=f"Response {result}")
|
|
260
|
+
|
|
261
|
+
return result
|
|
262
|
+
|
|
263
|
+
|
|
94
264
|
def provider_get_token(provider_id: str,
|
|
95
265
|
errors: list[str] = None,
|
|
96
266
|
logger: Logger = None) -> str | None:
|
|
97
267
|
"""
|
|
98
|
-
Obtain an
|
|
268
|
+
Obtain an JWT token from the external provider *provider_id*.
|
|
99
269
|
|
|
100
270
|
:param provider_id: the provider's identification
|
|
101
271
|
:param errors: incidental error messages
|
|
102
272
|
:param logger: optional logger
|
|
273
|
+
:return: the JWT token, or *None* if error
|
|
103
274
|
"""
|
|
104
|
-
global _provider_registry
|
|
275
|
+
global _provider_registry
|
|
105
276
|
|
|
106
277
|
# initialize the return variable
|
|
107
278
|
result: str | None = None
|
|
@@ -117,7 +288,7 @@ def provider_get_token(provider_id: str,
|
|
|
117
288
|
# access token has expired
|
|
118
289
|
header_data: dict[str, str] | None = None
|
|
119
290
|
body_data: dict[str, str] | None = None
|
|
120
|
-
url: str = provider.get(ProviderParam.
|
|
291
|
+
url: str = provider.get(ProviderParam.URL_TOKEN)
|
|
121
292
|
refresh_token: str = provider.get(ProviderParam.REFRESH_TOKEN)
|
|
122
293
|
if refresh_token:
|
|
123
294
|
# refresh token exists
|
|
@@ -131,11 +302,11 @@ def provider_get_token(provider_id: str,
|
|
|
131
302
|
"grant_type": "refresh_token",
|
|
132
303
|
"refresh_token": refresh_token
|
|
133
304
|
}
|
|
134
|
-
if not
|
|
305
|
+
if not header_data:
|
|
135
306
|
# refresh token does not exist or has expired
|
|
136
|
-
user: str = provider.get(ProviderParam.
|
|
137
|
-
pwd: str = provider.get(ProviderParam.
|
|
138
|
-
|
|
307
|
+
user: str = provider.get(ProviderParam.USER_ID)
|
|
308
|
+
pwd: str = provider.get(ProviderParam.USER_SECRET)
|
|
309
|
+
header_data: dict[str, str] = provider.get(ProviderParam.HEADER_DATA) or {}
|
|
139
310
|
body_data: dict[str, str] = provider.get(ProviderParam.BODY_DATA) or {}
|
|
140
311
|
custom_auth: tuple[str, str] = provider.get(ProviderParam.CUSTOM_AUTH)
|
|
141
312
|
if custom_auth:
|
|
@@ -143,7 +314,7 @@ def provider_get_token(provider_id: str,
|
|
|
143
314
|
body_data[custom_auth[1]] = pwd
|
|
144
315
|
else:
|
|
145
316
|
enc_bytes: bytes = b64encode(f"{user}:{pwd}".encode())
|
|
146
|
-
|
|
317
|
+
header_data["Authorization"] = f"Basic {enc_bytes.decode()}"
|
|
147
318
|
|
|
148
319
|
# obtain the token
|
|
149
320
|
token_data: dict[str, Any] = __post_for_token(url=url,
|
pypomes_iam/token_pomes.py
CHANGED
|
@@ -46,6 +46,33 @@ def token_get_claims(token: str,
|
|
|
46
46
|
return result
|
|
47
47
|
|
|
48
48
|
|
|
49
|
+
def token_get_values(token: str,
|
|
50
|
+
keys: tuple[str, ...],
|
|
51
|
+
errors: list[str] = None,
|
|
52
|
+
logger: Logger = None) -> tuple:
|
|
53
|
+
"""
|
|
54
|
+
Retrieve the values of *keys* in the token's payload.
|
|
55
|
+
|
|
56
|
+
Ther values are returned in the same order as requested in *keys*.
|
|
57
|
+
For a claim not found, *None* is returned in its position.
|
|
58
|
+
|
|
59
|
+
:param token: the reference token
|
|
60
|
+
:param keys: the names of the claims whose values are to be returned
|
|
61
|
+
:param errors: incidental errors
|
|
62
|
+
:param logger: optiona logger
|
|
63
|
+
:return: a tuple containing the respective values of *claims* in *token*.
|
|
64
|
+
"""
|
|
65
|
+
token_claims: dict[str, dict[str, Any]] = token_get_claims(token=token,
|
|
66
|
+
errors=errors,
|
|
67
|
+
logger=logger)
|
|
68
|
+
payload: dict[str, Any] = token_claims["payload"]
|
|
69
|
+
values: list[Any] = []
|
|
70
|
+
for key in keys:
|
|
71
|
+
values.append(payload.get(key))
|
|
72
|
+
|
|
73
|
+
return tuple(values)
|
|
74
|
+
|
|
75
|
+
|
|
49
76
|
def token_validate(token: str,
|
|
50
77
|
issuer: str = None,
|
|
51
78
|
recipient_id: str = None,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pypomes_iam
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.5
|
|
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
|
|
@@ -12,6 +12,6 @@ Classifier: Programming Language :: Python :: 3
|
|
|
12
12
|
Requires-Python: >=3.12
|
|
13
13
|
Requires-Dist: flask>=3.1.2
|
|
14
14
|
Requires-Dist: pyjwt>=2.10.1
|
|
15
|
-
Requires-Dist: pypomes-core>=2.8.
|
|
15
|
+
Requires-Dist: pypomes-core>=2.8.6
|
|
16
16
|
Requires-Dist: pypomes-crypto>=0.4.8
|
|
17
17
|
Requires-Dist: requests>=2.32.5
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
pypomes_iam/__init__.py,sha256=kkHvF3P79h21dNBmJ566Mp-L27oejhBcJa2VquyVsdg,1619
|
|
2
|
+
pypomes_iam/iam_actions.py,sha256=ORuHoiuMPnrMabvnCUcMeqHI4xfqbTErED1LydOPBCg,51191
|
|
3
|
+
pypomes_iam/iam_common.py,sha256=lJAx0J7xjAyzaMI9WXUXRq2qO7bUGIUP85h1hNE2-RE,17569
|
|
4
|
+
pypomes_iam/iam_pomes.py,sha256=VwqK3FoGj76SHKLARuBmIhziYnd_hoMWoUteMGRjuSc,8963
|
|
5
|
+
pypomes_iam/iam_services.py,sha256=_oAAk3y6iw_2gxDkbcNJDmj6Mk8HByhqX8fUT6Qg9kU,26865
|
|
6
|
+
pypomes_iam/provider_pomes.py,sha256=e2AFGQgEajDOvr47LJYAqJ9Eaf0G0MrBAKKC4JK2Jp0,17705
|
|
7
|
+
pypomes_iam/token_pomes.py,sha256=KiTlBNj3HURbZS_Rmti2RC6hny8VFPpbXeIO--HZ-fI,7703
|
|
8
|
+
pypomes_iam-0.8.5.dist-info/METADATA,sha256=z0_4gG_jLZVliMWrQzcRw9AJD58V703MZjT4ZIfKXEo,661
|
|
9
|
+
pypomes_iam-0.8.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
10
|
+
pypomes_iam-0.8.5.dist-info/licenses/LICENSE,sha256=YvUELgV8qvXlaYsy9hXG5EW3Bmsrkw-OJmmILZnonAc,1086
|
|
11
|
+
pypomes_iam-0.8.5.dist-info/RECORD,,
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
pypomes_iam/__init__.py,sha256=_6tSFfjuU-5p6TAMqNLHSL6IQmaJMSYuEW-TG3ybhTI,1044
|
|
2
|
-
pypomes_iam/iam_actions.py,sha256=zoxAzcw9fBTMEt-y5INaw7Wjfa1R5o-z_ORxvo4kqGU,45612
|
|
3
|
-
pypomes_iam/iam_common.py,sha256=ki_-m6fqJqUbGjgTD41r9zaE-FOXgA_c_tLisIYYTfU,15457
|
|
4
|
-
pypomes_iam/iam_pomes.py,sha256=_kLnrZG25XhJsIv3wqDl_2sIJ2ho_2TIMKrPCyPmA7Q,7362
|
|
5
|
-
pypomes_iam/iam_services.py,sha256=HFK_ihY1n7I4JGptAwV44MxHMPsGLDU5ElsaFOqUDcc,15915
|
|
6
|
-
pypomes_iam/provider_pomes.py,sha256=3mMj5LQs53YEINUEOfFBAxOwOP3aOR_szlE4daEBLK0,10523
|
|
7
|
-
pypomes_iam/token_pomes.py,sha256=K4nSAotKUoHIE2s3ltc_nVimlNeKS9tnD-IlslkAvkk,6626
|
|
8
|
-
pypomes_iam-0.7.6.dist-info/METADATA,sha256=b6eajrnQCM0TsdjAbz1H4xf9EgrGV0ii_phYm51nOQI,661
|
|
9
|
-
pypomes_iam-0.7.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
10
|
-
pypomes_iam-0.7.6.dist-info/licenses/LICENSE,sha256=YvUELgV8qvXlaYsy9hXG5EW3Bmsrkw-OJmmILZnonAc,1086
|
|
11
|
-
pypomes_iam-0.7.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|