pypomes-iam 0.2.3__py3-none-any.whl → 0.7.0__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.
- pypomes_iam/__init__.py +20 -8
- pypomes_iam/iam_actions.py +878 -0
- pypomes_iam/iam_common.py +388 -0
- pypomes_iam/iam_pomes.py +137 -157
- pypomes_iam/iam_services.py +394 -0
- pypomes_iam/provider_pomes.py +175 -72
- pypomes_iam/token_pomes.py +63 -8
- {pypomes_iam-0.2.3.dist-info → pypomes_iam-0.7.0.dist-info}/METADATA +1 -2
- pypomes_iam-0.7.0.dist-info/RECORD +11 -0
- pypomes_iam/common_pomes.py +0 -397
- pypomes_iam/jusbr_pomes.py +0 -167
- pypomes_iam/keycloak_pomes.py +0 -170
- pypomes_iam-0.2.3.dist-info/RECORD +0 -11
- {pypomes_iam-0.2.3.dist-info → pypomes_iam-0.7.0.dist-info}/WHEEL +0 -0
- {pypomes_iam-0.2.3.dist-info → pypomes_iam-0.7.0.dist-info}/licenses/LICENSE +0 -0
pypomes_iam/jusbr_pomes.py
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
from cachetools import Cache, FIFOCache
|
|
2
|
-
from datetime import datetime
|
|
3
|
-
from flask import Flask
|
|
4
|
-
from logging import Logger
|
|
5
|
-
from pypomes_core import (
|
|
6
|
-
APP_PREFIX, TZ_LOCAL, env_get_int, env_get_str
|
|
7
|
-
)
|
|
8
|
-
from typing import Any, Final
|
|
9
|
-
|
|
10
|
-
from .common_pomes import _service_token
|
|
11
|
-
|
|
12
|
-
JUSBR_CLIENT_ID: Final[str] = env_get_str(key=f"{APP_PREFIX}_JUSBR_CLIENT_ID")
|
|
13
|
-
JUSBR_CLIENT_SECRET: Final[str] = env_get_str(key=f"{APP_PREFIX}_JUSBR_CLIENT_SECRET")
|
|
14
|
-
JUSBR_CLIENT_TIMEOUT: Final[int] = env_get_int(key=f"{APP_PREFIX}_JUSBR_CLIENT_TIMEOUT")
|
|
15
|
-
|
|
16
|
-
JUSBR_ENDPOINT_CALLBACK: Final[str] = env_get_str(key=f"{APP_PREFIX}_JUSBR_ENDPOINT_CALLBACK",
|
|
17
|
-
def_value="/iam/jusbr:callback")
|
|
18
|
-
JUSBR_ENDPOINT_LOGIN: Final[str] = env_get_str(key=f"{APP_PREFIX}_JUSBR_ENDPOINT_LOGIN",
|
|
19
|
-
def_value="/iam/jusbr:login")
|
|
20
|
-
JUSBR_ENDPOINT_LOGOUT: Final[str] = env_get_str(key=f"{APP_PREFIX}_JUSBR_ENDPOINT_LOGOUT",
|
|
21
|
-
def_value="/iam/jusbr:logout")
|
|
22
|
-
JUSBR_ENDPOINT_TOKEN: Final[str] = env_get_str(key=f"{APP_PREFIX}_JUSBR_ENDPOINT_TOKEN",
|
|
23
|
-
def_value="/iam/jusbr:get-token")
|
|
24
|
-
|
|
25
|
-
JUSBR_PUBLIC_KEY_LIFETIME: Final[int] = env_get_int(key=f"{APP_PREFIX}_JUSBR_PUBLIC_KEY_LIFETIME",
|
|
26
|
-
def_value=86400) # 24 hours
|
|
27
|
-
JUSBR_URL_AUTH_BASE: Final[str] = env_get_str(key=f"{APP_PREFIX}_JUSBR_URL_AUTH_BASE")
|
|
28
|
-
JUSBR_URL_AUTH_CALLBACK: Final[str] = env_get_str(key=f"{APP_PREFIX}_JUSBR_URL_AUTH_CALLBACK")
|
|
29
|
-
|
|
30
|
-
# registry structure:
|
|
31
|
-
# {
|
|
32
|
-
# "client-id": <str>,
|
|
33
|
-
# "client-secret": <str>,
|
|
34
|
-
# "client-timeout": <int>,
|
|
35
|
-
# "public_key": <str>,
|
|
36
|
-
# "key-lifetime": <int>,
|
|
37
|
-
# "key-expiration": <int>,
|
|
38
|
-
# "base-url": <str>,
|
|
39
|
-
# "callback-url": <str>,
|
|
40
|
-
# "safe-cache": <FIFOCache>
|
|
41
|
-
# }
|
|
42
|
-
# data in "safe-cache":
|
|
43
|
-
# {
|
|
44
|
-
# "users": {
|
|
45
|
-
# "<user-id>": {
|
|
46
|
-
# "access-token": <str>
|
|
47
|
-
# "refresh-token": <str>
|
|
48
|
-
# "access-expiration": <timestamp>,
|
|
49
|
-
# "login-expiration": <timestamp>, <-- transient
|
|
50
|
-
# "login-id": <str>, <-- transient
|
|
51
|
-
# }
|
|
52
|
-
# }
|
|
53
|
-
# }
|
|
54
|
-
_jusbr_registry: dict[str, Any] | None = None
|
|
55
|
-
|
|
56
|
-
# dafault logger
|
|
57
|
-
_jusbr_logger: Logger | None = None
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def jusbr_setup(flask_app: Flask,
|
|
61
|
-
client_id: str = JUSBR_CLIENT_ID,
|
|
62
|
-
client_secret: str = JUSBR_CLIENT_SECRET,
|
|
63
|
-
client_timeout: int = JUSBR_CLIENT_TIMEOUT,
|
|
64
|
-
public_key_lifetime: int = JUSBR_PUBLIC_KEY_LIFETIME,
|
|
65
|
-
callback_endpoint: str = JUSBR_ENDPOINT_CALLBACK,
|
|
66
|
-
token_endpoint: str = JUSBR_ENDPOINT_TOKEN,
|
|
67
|
-
login_endpoint: str = JUSBR_ENDPOINT_LOGIN,
|
|
68
|
-
logout_endpoint: str = JUSBR_ENDPOINT_LOGOUT,
|
|
69
|
-
base_url: str = JUSBR_URL_AUTH_BASE,
|
|
70
|
-
callback_url: str = JUSBR_URL_AUTH_CALLBACK,
|
|
71
|
-
logger: Logger = None) -> None:
|
|
72
|
-
"""
|
|
73
|
-
Configure the JusBR IAM.
|
|
74
|
-
|
|
75
|
-
This should be invoked only once, before the first access to a JusBR service.
|
|
76
|
-
|
|
77
|
-
:param flask_app: the Flask application
|
|
78
|
-
:param client_id: the client's identification with JusBR
|
|
79
|
-
:param client_secret: the client's password with JusBR
|
|
80
|
-
:param client_timeout: timeout for login authentication (in seconds,defaults to no timeout)
|
|
81
|
-
:param public_key_lifetime: how long to use JusBR's public key, before refreshing it (in seconds)
|
|
82
|
-
:param callback_endpoint: endpoint for the callback from JusBR
|
|
83
|
-
:param token_endpoint: endpoint for retrieving the JusBR authentication token
|
|
84
|
-
:param login_endpoint: endpoint for redirecting user to JusBR login page
|
|
85
|
-
:param logout_endpoint: endpoint for terminating user access to JusBR
|
|
86
|
-
:param base_url: base URL to request the JusBR services
|
|
87
|
-
:param callback_url: URL for JusBR to callback on login
|
|
88
|
-
:param logger: optional logger
|
|
89
|
-
"""
|
|
90
|
-
from .iam_pomes import service_login, service_logout, service_callback, service_token
|
|
91
|
-
global _jusbr_logger, _jusbr_registry
|
|
92
|
-
|
|
93
|
-
# establish the logger
|
|
94
|
-
_logger = logger
|
|
95
|
-
|
|
96
|
-
# configure the JusBR registry
|
|
97
|
-
safe_cache: Cache = FIFOCache(maxsize=1048576)
|
|
98
|
-
safe_cache["users"] = {}
|
|
99
|
-
_jusbr_registry = {
|
|
100
|
-
"client-id": client_id,
|
|
101
|
-
"client-secret": client_secret,
|
|
102
|
-
"client-timeout": client_timeout,
|
|
103
|
-
"base-url": base_url,
|
|
104
|
-
"callback-url": callback_url,
|
|
105
|
-
"key-expiration": int(datetime.now(tz=TZ_LOCAL).timestamp()),
|
|
106
|
-
"key-lifetime": public_key_lifetime,
|
|
107
|
-
"safe-cache": safe_cache
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
# establish the endpoints
|
|
111
|
-
if login_endpoint:
|
|
112
|
-
flask_app.add_url_rule(rule=login_endpoint,
|
|
113
|
-
endpoint="jusbr-login",
|
|
114
|
-
view_func=service_login,
|
|
115
|
-
methods=["GET"])
|
|
116
|
-
if logout_endpoint:
|
|
117
|
-
flask_app.add_url_rule(rule=logout_endpoint,
|
|
118
|
-
endpoint="jusbr-logout",
|
|
119
|
-
view_func=service_logout,
|
|
120
|
-
methods=["GET"])
|
|
121
|
-
if callback_endpoint:
|
|
122
|
-
flask_app.add_url_rule(rule=callback_endpoint,
|
|
123
|
-
endpoint="jusbr-callback",
|
|
124
|
-
view_func=service_callback,
|
|
125
|
-
methods=["GET", "POST"])
|
|
126
|
-
if token_endpoint:
|
|
127
|
-
flask_app.add_url_rule(rule=token_endpoint,
|
|
128
|
-
endpoint="jusbr-token",
|
|
129
|
-
view_func=service_token,
|
|
130
|
-
methods=["GET"])
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
def jusbr_get_token(user_id: str,
|
|
134
|
-
errors: list[str] = None,
|
|
135
|
-
logger: Logger = None) -> str:
|
|
136
|
-
"""
|
|
137
|
-
Retrieve a JusBR authentication token for *user_id*.
|
|
138
|
-
|
|
139
|
-
:param user_id: the user's identification
|
|
140
|
-
:param errors: incidental errors
|
|
141
|
-
:param logger: optional logger
|
|
142
|
-
:return: the uthentication tokem
|
|
143
|
-
"""
|
|
144
|
-
global _jusbr_registry
|
|
145
|
-
|
|
146
|
-
# retrieve the token
|
|
147
|
-
args: dict[str, Any] = {"user-id": user_id}
|
|
148
|
-
return _service_token(registry=_jusbr_registry,
|
|
149
|
-
args=args,
|
|
150
|
-
errors=errors,
|
|
151
|
-
logger=logger)
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
def _jusbr_get_logger() -> Logger:
|
|
155
|
-
"""
|
|
156
|
-
Retrieve the logger for JusBR operations.
|
|
157
|
-
:return: the Keycloak logger
|
|
158
|
-
"""
|
|
159
|
-
return _jusbr_logger
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
def _jusbr_get_registry() -> dict[str, Any]:
|
|
163
|
-
"""
|
|
164
|
-
Retrieve the registry holding user authentication data related to JusBR operations.
|
|
165
|
-
:return: the Keycloak registry
|
|
166
|
-
"""
|
|
167
|
-
return _jusbr_registry
|
pypomes_iam/keycloak_pomes.py
DELETED
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
from cachetools import Cache, FIFOCache
|
|
2
|
-
from datetime import datetime
|
|
3
|
-
from flask import Flask
|
|
4
|
-
from logging import Logger
|
|
5
|
-
from pypomes_core import (
|
|
6
|
-
APP_PREFIX, TZ_LOCAL, env_get_int, env_get_str
|
|
7
|
-
)
|
|
8
|
-
from typing import Any, Final
|
|
9
|
-
|
|
10
|
-
from .common_pomes import _service_token
|
|
11
|
-
|
|
12
|
-
KEYCLOAK_CLIENT_ID: Final[str] = env_get_str(key=f"{APP_PREFIX}_KEYCLOAK_CLIENT_ID")
|
|
13
|
-
KEYCLOAK_CLIENT_SECRET: Final[str] = env_get_str(key=f"{APP_PREFIX}_KEYCLOAK_CLIENT_SECRET")
|
|
14
|
-
KEYCLOAK_CLIENT_TIMEOUT: Final[int] = env_get_int(key=f"{APP_PREFIX}_KEYCLOAK_CLIENT_TIMEOUT")
|
|
15
|
-
|
|
16
|
-
KEYCLOAK_ENDPOINT_CALLBACK: Final[str] = env_get_str(key=f"{APP_PREFIX}_KEYCLOAK_ENDPOINT_CALLBACK",
|
|
17
|
-
def_value="/iam/keycloak:callback")
|
|
18
|
-
KEYCLOAK_ENDPOINT_LOGIN: Final[str] = env_get_str(key=f"{APP_PREFIX}_KEYCLOAK_ENDPOINT_LOGIN",
|
|
19
|
-
def_value="/iam/keycloak:login")
|
|
20
|
-
KEYCLOAK_ENDPOINT_LOGOUT: Final[str] = env_get_str(key=f"{APP_PREFIX}_KEYCLOAK_ENDPOINT_LOGOUT",
|
|
21
|
-
def_value="/iam/keycloak:logout")
|
|
22
|
-
KEYCLOAK_ENDPOINT_TOKEN: Final[str] = env_get_str(key=f"{APP_PREFIX}_KEYCLOAK_ENDPOINT_TOKEN",
|
|
23
|
-
def_value="/iam/keycloak:get-token")
|
|
24
|
-
|
|
25
|
-
KEYCLOAK_PUBLIC_KEY_LIFETIME: Final[int] = env_get_int(key=f"{APP_PREFIX}_KEYCLOAK_PUBLIC_KEY_LIFETIME",
|
|
26
|
-
def_value=86400) # 24 hours
|
|
27
|
-
KEYCLOAK_REALM: Final[str] = env_get_str(key=f"{APP_PREFIX}_KEYCLOAK_REALM")
|
|
28
|
-
KEYCLOAK_URL_AUTH_BASE: Final[str] = env_get_str(key=f"{APP_PREFIX}_KEYCLOAK_URL_AUTH_BASE")
|
|
29
|
-
KEYCLOAK_URL_AUTH_CALLBACK: Final[str] = env_get_str(key=f"{APP_PREFIX}_KEYCLOAK_URL_AUTH_CALLBACK")
|
|
30
|
-
|
|
31
|
-
# registry structure:
|
|
32
|
-
# {
|
|
33
|
-
# "client-id": <str>,
|
|
34
|
-
# "client-secret": <str>,
|
|
35
|
-
# "client-timeout": <int>,
|
|
36
|
-
# "public_key": <str>,
|
|
37
|
-
# "key-lifetime": <int>,
|
|
38
|
-
# "key-expiration": <int>,
|
|
39
|
-
# "base-url": <str>,
|
|
40
|
-
# "callback-url": <str>,
|
|
41
|
-
# "safe-cache": <FIFOCache>
|
|
42
|
-
# }
|
|
43
|
-
# data in "safe-cache":
|
|
44
|
-
# {
|
|
45
|
-
# "users": {
|
|
46
|
-
# "<user-id>": {
|
|
47
|
-
# "access-token": <str>
|
|
48
|
-
# "refresh-token": <str>
|
|
49
|
-
# "access-expiration": <timestamp>,
|
|
50
|
-
# "login-expiration": <timestamp>, <-- transient
|
|
51
|
-
# "login-id": <str>, <-- transient
|
|
52
|
-
# }
|
|
53
|
-
# }
|
|
54
|
-
# }
|
|
55
|
-
_keycloak_registry: dict[str, Any] = {}
|
|
56
|
-
|
|
57
|
-
# dafault logger
|
|
58
|
-
_keycloak_logger: Logger | None = None
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def keycloak_setup(flask_app: Flask,
|
|
62
|
-
client_id: str = KEYCLOAK_CLIENT_ID,
|
|
63
|
-
client_secret: str = KEYCLOAK_CLIENT_SECRET,
|
|
64
|
-
client_timeout: int = KEYCLOAK_CLIENT_TIMEOUT,
|
|
65
|
-
public_key_lifetime: int = KEYCLOAK_PUBLIC_KEY_LIFETIME,
|
|
66
|
-
realm: str = KEYCLOAK_REALM,
|
|
67
|
-
callback_endpoint: str = KEYCLOAK_ENDPOINT_CALLBACK,
|
|
68
|
-
token_endpoint: str = KEYCLOAK_ENDPOINT_TOKEN,
|
|
69
|
-
login_endpoint: str = KEYCLOAK_ENDPOINT_LOGIN,
|
|
70
|
-
logout_endpoint: str = KEYCLOAK_ENDPOINT_LOGOUT,
|
|
71
|
-
base_url: str = KEYCLOAK_URL_AUTH_BASE,
|
|
72
|
-
callback_url: str = KEYCLOAK_URL_AUTH_CALLBACK,
|
|
73
|
-
logger: Logger = None) -> None:
|
|
74
|
-
"""
|
|
75
|
-
Configure the Keycloak IAM.
|
|
76
|
-
|
|
77
|
-
This should be invoked only once, before the first access to a Keycloak service.
|
|
78
|
-
|
|
79
|
-
:param flask_app: the Flask application
|
|
80
|
-
:param client_id: the client's identification with JusBR
|
|
81
|
-
:param client_secret: the client's password with JusBR
|
|
82
|
-
:param client_timeout: timeout for login authentication (in seconds,defaults to no timeout)
|
|
83
|
-
:param public_key_lifetime: how long to use Keycloak's public key, before refreshing it (in seconds)
|
|
84
|
-
:param realm: the Keycloak realm
|
|
85
|
-
:param callback_endpoint: endpoint for the callback from JusBR
|
|
86
|
-
:param token_endpoint: endpoint for retrieving the JusBR authentication token
|
|
87
|
-
:param login_endpoint: endpoint for redirecting user to JusBR login page
|
|
88
|
-
:param logout_endpoint: endpoint for terminating user access to JusBR
|
|
89
|
-
:param base_url: base URL to request the JusBR services
|
|
90
|
-
:param callback_url: URL for Keycloak to callback on login
|
|
91
|
-
:param logger: optional logger
|
|
92
|
-
"""
|
|
93
|
-
from .iam_pomes import service_login, service_logout, service_callback, service_token
|
|
94
|
-
global _keycloak_logger, _keycloak_registry
|
|
95
|
-
|
|
96
|
-
# establish the logger
|
|
97
|
-
_keycloak_logger = logger
|
|
98
|
-
|
|
99
|
-
# configure the JusBR registry
|
|
100
|
-
safe_cache: Cache = FIFOCache(maxsize=1048576)
|
|
101
|
-
safe_cache["users"] = {}
|
|
102
|
-
_keycloak_registry = {
|
|
103
|
-
"client-id": client_id,
|
|
104
|
-
"client-secret": client_secret,
|
|
105
|
-
"client-timeout": client_timeout,
|
|
106
|
-
"base-url": f"{base_url}/realms/{realm}",
|
|
107
|
-
"callback-url": callback_url,
|
|
108
|
-
"key-expiration": int(datetime.now(tz=TZ_LOCAL).timestamp()),
|
|
109
|
-
"key-lifetime": public_key_lifetime,
|
|
110
|
-
"safe-cache": safe_cache
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
# establish the endpoints
|
|
114
|
-
if token_endpoint:
|
|
115
|
-
flask_app.add_url_rule(rule=token_endpoint,
|
|
116
|
-
endpoint="keycloak-token",
|
|
117
|
-
view_func=service_token,
|
|
118
|
-
methods=["GET"])
|
|
119
|
-
if login_endpoint:
|
|
120
|
-
flask_app.add_url_rule(rule=login_endpoint,
|
|
121
|
-
endpoint="keycloak-login",
|
|
122
|
-
view_func=service_login,
|
|
123
|
-
methods=["GET"])
|
|
124
|
-
if logout_endpoint:
|
|
125
|
-
flask_app.add_url_rule(rule=logout_endpoint,
|
|
126
|
-
endpoint="keycloak-logout",
|
|
127
|
-
view_func=service_logout,
|
|
128
|
-
methods=["GET"])
|
|
129
|
-
if callback_endpoint:
|
|
130
|
-
flask_app.add_url_rule(rule=callback_endpoint,
|
|
131
|
-
endpoint="keycloak-callback",
|
|
132
|
-
view_func=service_callback,
|
|
133
|
-
methods=["POST"])
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
def keycloak_get_token(user_id: str,
|
|
137
|
-
errors: list[str] = None,
|
|
138
|
-
logger: Logger = None) -> str:
|
|
139
|
-
"""
|
|
140
|
-
Retrieve a Keycloak authentication token for *user_id*.
|
|
141
|
-
|
|
142
|
-
:param user_id: the user's identification
|
|
143
|
-
:param errors: incidental errors
|
|
144
|
-
:param logger: optional logger
|
|
145
|
-
:return: the uthentication tokem
|
|
146
|
-
"""
|
|
147
|
-
global _keycloak_registry
|
|
148
|
-
|
|
149
|
-
# retrieve the token
|
|
150
|
-
args: dict[str, Any] = {"user-id": user_id}
|
|
151
|
-
return _service_token(registry=_keycloak_registry,
|
|
152
|
-
args=args,
|
|
153
|
-
errors=errors,
|
|
154
|
-
logger=logger)
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
def _keycloak_get_logger() -> Logger:
|
|
158
|
-
"""
|
|
159
|
-
Retrieve the logger for Keycloak operations.
|
|
160
|
-
:return: the Keycloak logger
|
|
161
|
-
"""
|
|
162
|
-
return _keycloak_logger
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
def _keycloak_get_registry() -> dict[str, Any]:
|
|
166
|
-
"""
|
|
167
|
-
Retrieve the registry holding user authentication data related to Keycloak operations.
|
|
168
|
-
:return: the Keycloak registry
|
|
169
|
-
"""
|
|
170
|
-
return _keycloak_registry
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
pypomes_iam/__init__.py,sha256=u-gNGbsayMf-2SWTB8VcoTCADoczZuwNEH50BPxTZZ8,682
|
|
2
|
-
pypomes_iam/common_pomes.py,sha256=08G8-Rcpuld4JxciEEhzORMt575kErHGEVk8_QC1uC4,15710
|
|
3
|
-
pypomes_iam/iam_pomes.py,sha256=-2XppbAAuY58jYKd4ZN2MMjQd7wh6n9I8cofgAt0_9s,5639
|
|
4
|
-
pypomes_iam/jusbr_pomes.py,sha256=FFTzhpxB4Y7T_JKYC1xvYIcb-ca-Frtl-7LK7dDkIXQ,6723
|
|
5
|
-
pypomes_iam/keycloak_pomes.py,sha256=_hR1nZhk-ejZpYrwijIcEm_GyfrtQkWtNdqJI7hcZuY,7129
|
|
6
|
-
pypomes_iam/provider_pomes.py,sha256=eP8XzjTUEpwejTkO0wmDiqKjqbIEOzRNCR2ju5E15og,5856
|
|
7
|
-
pypomes_iam/token_pomes.py,sha256=McjKB8omCjuicenwvDVPiWYu3-7gQeLg1AzgAVKK32M,4309
|
|
8
|
-
pypomes_iam-0.2.3.dist-info/METADATA,sha256=IzheEi4k7zb4WSewyRmLbQvJ83kKZq1OfqL7TlVEp3s,694
|
|
9
|
-
pypomes_iam-0.2.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
10
|
-
pypomes_iam-0.2.3.dist-info/licenses/LICENSE,sha256=YvUELgV8qvXlaYsy9hXG5EW3Bmsrkw-OJmmILZnonAc,1086
|
|
11
|
-
pypomes_iam-0.2.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|