pypomes-iam 0.7.2__py3-none-any.whl → 0.8.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.
- pypomes_iam/__init__.py +22 -12
- pypomes_iam/iam_actions.py +116 -56
- pypomes_iam/iam_common.py +70 -29
- pypomes_iam/iam_pomes.py +111 -98
- pypomes_iam/iam_services.py +228 -96
- pypomes_iam/provider_pomes.py +197 -30
- pypomes_iam/token_pomes.py +27 -0
- {pypomes_iam-0.7.2.dist-info → pypomes_iam-0.8.0.dist-info}/METADATA +2 -2
- pypomes_iam-0.8.0.dist-info/RECORD +11 -0
- pypomes_iam-0.7.2.dist-info/RECORD +0 -11
- {pypomes_iam-0.7.2.dist-info → pypomes_iam-0.8.0.dist-info}/WHEEL +0 -0
- {pypomes_iam-0.7.2.dist-info → pypomes_iam-0.8.0.dist-info}/licenses/LICENSE +0 -0
pypomes_iam/iam_pomes.py
CHANGED
|
@@ -1,37 +1,38 @@
|
|
|
1
1
|
from flask import Flask
|
|
2
|
-
from
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
from pypomes_core import (
|
|
3
|
+
APP_PREFIX,
|
|
4
|
+
env_get_int, env_get_str,
|
|
5
|
+
func_capture_params, func_defaulted_params
|
|
6
|
+
)
|
|
5
7
|
|
|
6
8
|
from .iam_common import (
|
|
7
9
|
_IAM_SERVERS, IamServer, IamParam, _iam_lock
|
|
8
10
|
)
|
|
9
|
-
from .iam_actions import action_token
|
|
10
11
|
from .iam_services import (
|
|
11
|
-
service_login, service_logout,
|
|
12
|
+
service_login, service_logout,
|
|
13
|
+
service_callback, service_callback_exchange, service_exchange, service_get_token
|
|
12
14
|
)
|
|
13
15
|
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
callback_endpoint: str = None,
|
|
27
|
-
exchange_endpoint: str = None,
|
|
28
|
-
login_endpoint: str = None,
|
|
29
|
-
logout_endpoint: str = None,
|
|
30
|
-
token_endpoint: str = None) -> None:
|
|
17
|
+
@func_capture_params
|
|
18
|
+
def iam_setup_server(iam_server: IamServer,
|
|
19
|
+
admin_id: str = None,
|
|
20
|
+
admin_secret: str = None,
|
|
21
|
+
client_id: str = None,
|
|
22
|
+
client_realm: str = None,
|
|
23
|
+
client_secret: str = None,
|
|
24
|
+
login_timeout: int = None,
|
|
25
|
+
pk_lifetime: int = None,
|
|
26
|
+
recipient_attr: str = None,
|
|
27
|
+
url_base: str = None) -> None:
|
|
31
28
|
"""
|
|
32
|
-
|
|
29
|
+
Setup the *IAM* server *iam_server*.
|
|
30
|
+
|
|
31
|
+
For the parameters not effectively passed, an attempt is made to obtain a value from the corresponding
|
|
32
|
+
environment variables. Most parameters are required to have values, which must be assigned either
|
|
33
|
+
throught the function invocation, or from the corresponding environment variables.
|
|
33
34
|
|
|
34
|
-
The parameters *admin_id* and *admin_* are required only if administrative
|
|
35
|
+
The parameters *admin_id* and *admin_* are required only if performing administrative task are intended.
|
|
35
36
|
The optional parameter *client_timeout* refers to the maximum time in seconds allowed for the
|
|
36
37
|
user to login at the *IAM* server's login page, and defaults to no time limit.
|
|
37
38
|
|
|
@@ -39,47 +40,118 @@ def iam_setup(flask_app: Flask,
|
|
|
39
40
|
it is not provided, but *admin_id* and *admin_secret* are, it is obtained from the *IAM* server itself
|
|
40
41
|
the first time it is needed.
|
|
41
42
|
|
|
42
|
-
:param flask_app: the Flask application
|
|
43
43
|
:param iam_server: identifies the supported *IAM* server (currently, *jusbr* or *keycloak*)
|
|
44
|
-
:param base_url: base URL to request services
|
|
45
|
-
:param client_id: the client's identification with the *IAM* server
|
|
46
|
-
:param client_realm: the client realm
|
|
47
|
-
:param client_secret: the client's password with the *IAM* server
|
|
48
|
-
:param recipient_attribute: attribute in the token's payload holding the token's subject
|
|
49
44
|
:param admin_id: identifies the realm administrator
|
|
50
45
|
:param admin_secret: password for the realm administrator
|
|
46
|
+
:param client_id: the client's identification with the *IAM* server
|
|
47
|
+
:param client_realm: the client's realm
|
|
48
|
+
:param client_secret: the client's password with the *IAM* server
|
|
51
49
|
:param login_timeout: timeout for login authentication (in seconds,defaults to no timeout)
|
|
52
|
-
:param
|
|
53
|
-
:param
|
|
54
|
-
:param
|
|
55
|
-
:param login_endpoint: endpoint for redirecting user to the *IAM* server's login page
|
|
56
|
-
:param logout_endpoint: endpoint for terminating user access
|
|
57
|
-
:param token_endpoint: endpoint for retrieving authentication token
|
|
50
|
+
:param pk_lifetime: how long to use *IAM* server's public key, before refreshing it (in seconds)
|
|
51
|
+
:param recipient_attr: attribute in the token's payload holding the token's subject
|
|
52
|
+
:param url_base: base URL to request services
|
|
58
53
|
"""
|
|
54
|
+
# obtain the defaulted parameters
|
|
55
|
+
defaulted_params: list[str] = func_defaulted_params.get()
|
|
56
|
+
|
|
57
|
+
# read from the environment variables
|
|
58
|
+
prefix: str = iam_server.name
|
|
59
|
+
if "admin_id" in defaulted_params:
|
|
60
|
+
admin_id = env_get_str(key=f"{APP_PREFIX}_{prefix}_ADMIN_ID")
|
|
61
|
+
if "admin_secret" in defaulted_params:
|
|
62
|
+
admin_secret = env_get_str(key=f"{APP_PREFIX}_{prefix}_ADMIN_SECRET")
|
|
63
|
+
if "client_id" in defaulted_params:
|
|
64
|
+
client_id = env_get_str(key=f"{APP_PREFIX}_{prefix}_CLIENT_ID")
|
|
65
|
+
if "client_realm" in defaulted_params:
|
|
66
|
+
client_realm = env_get_str(key=f"{APP_PREFIX}_{prefix}_CLIENT_REALM")
|
|
67
|
+
if "client_secret" in defaulted_params:
|
|
68
|
+
client_secret = env_get_str(key=f"{APP_PREFIX}_{prefix}_CLIENT_SECRET")
|
|
69
|
+
if "login_timeout" in defaulted_params:
|
|
70
|
+
login_timeout = env_get_str(key=f"{APP_PREFIX}_{prefix}_LOGIN_TIMEOUT")
|
|
71
|
+
if "pk_lifetime" in defaulted_params:
|
|
72
|
+
pk_lifetime = env_get_int(key=f"{APP_PREFIX}_{prefix}_PUBLIC_KEY_LIFETIME")
|
|
73
|
+
if "recipient_attr" in defaulted_params:
|
|
74
|
+
recipient_attr = env_get_str(key=f"{APP_PREFIX}_{prefix}_RECIPIENT_ATTR")
|
|
75
|
+
if "url_base" in defaulted_params:
|
|
76
|
+
url_base = env_get_str(key=f"{APP_PREFIX}_{prefix}_URL_AUTH_BASE")
|
|
59
77
|
|
|
60
78
|
# configure the Keycloak registry
|
|
61
79
|
with _iam_lock:
|
|
62
80
|
_IAM_SERVERS[iam_server] = {
|
|
63
|
-
IamParam.URL_BASE: base_url,
|
|
64
81
|
IamParam.CLIENT_ID: client_id,
|
|
65
82
|
IamParam.CLIENT_REALM: client_realm,
|
|
66
83
|
IamParam.CLIENT_SECRET: client_secret,
|
|
67
|
-
IamParam.RECIPIENT_ATTR:
|
|
84
|
+
IamParam.RECIPIENT_ATTR: recipient_attr,
|
|
68
85
|
IamParam.ADMIN_ID: admin_id,
|
|
69
86
|
IamParam.ADMIN_SECRET: admin_secret,
|
|
70
87
|
IamParam.LOGIN_TIMEOUT: login_timeout,
|
|
71
|
-
IamParam.PK_LIFETIME:
|
|
88
|
+
IamParam.PK_LIFETIME: pk_lifetime,
|
|
89
|
+
IamParam.URL_BASE: url_base,
|
|
90
|
+
# dynamic attributes
|
|
72
91
|
IamParam.PK_EXPIRATION: 0,
|
|
73
92
|
IamParam.PUBLIC_KEY: None,
|
|
74
93
|
IamParam.USERS: {}
|
|
75
94
|
}
|
|
76
95
|
|
|
96
|
+
|
|
97
|
+
@func_capture_params
|
|
98
|
+
def iam_setup_endpoints(flask_app: Flask,
|
|
99
|
+
iam_server: IamServer,
|
|
100
|
+
callback_endpoint: str = None,
|
|
101
|
+
callback_exchange_endpoint: str = None,
|
|
102
|
+
exchange_endpoint: str = None,
|
|
103
|
+
login_endpoint: str = None,
|
|
104
|
+
logout_endpoint: str = None,
|
|
105
|
+
token_endpoint: str = None) -> None:
|
|
106
|
+
"""
|
|
107
|
+
Setup the endpoints for accessing the services provided by *iam_server*.
|
|
108
|
+
|
|
109
|
+
For the parameters not effectively passed, an attempt is made to obtain a value from the corresponding
|
|
110
|
+
environment variables.
|
|
111
|
+
|
|
112
|
+
:param flask_app: the Flask application
|
|
113
|
+
:param iam_server: identifies the supported *IAM* server (currently, *jusbr* or *keycloak*)
|
|
114
|
+
:param callback_endpoint: endpoint for the callback from the front end
|
|
115
|
+
:param callback_exchange_endpoint: endpoint for the combination callback and exchange
|
|
116
|
+
:param exchange_endpoint: endpoint for requesting token exchange
|
|
117
|
+
:param login_endpoint: endpoint for redirecting user to the *IAM* server's login page
|
|
118
|
+
:param logout_endpoint: endpoint for terminating user access
|
|
119
|
+
:param token_endpoint: endpoint for retrieving authentication token
|
|
120
|
+
"""
|
|
121
|
+
# obtain the defaulted parameters
|
|
122
|
+
defaulted_params: list[str] = func_defaulted_params.get()
|
|
123
|
+
|
|
124
|
+
# read from the environment variables
|
|
125
|
+
prefix: str = iam_server.name
|
|
126
|
+
if "callback_endpoint" in defaulted_params:
|
|
127
|
+
callback_endpoint = env_get_str(key=f"{APP_PREFIX}_{prefix}_ENDPOINT_CALLBACK")
|
|
128
|
+
if "callback_exchange_endpoint" in defaulted_params:
|
|
129
|
+
callback_exchange_endpoint = env_get_str(key=f"{APP_PREFIX}_{prefix}_ENDPOINT_CALLBACK_EXCHANGE")
|
|
130
|
+
if "exchange_endpoint" in defaulted_params:
|
|
131
|
+
callback_endpoint = env_get_str(key=f"{APP_PREFIX}_{prefix}_ENDPOINT_EXCHANGE")
|
|
132
|
+
if "login_endpoint" in defaulted_params:
|
|
133
|
+
login_endpoint = env_get_str(key=f"{APP_PREFIX}_{prefix}_ENDPOINT_LOGIN")
|
|
134
|
+
if "logout_endpoint" in defaulted_params:
|
|
135
|
+
logout_endpoint = env_get_str(key=f"{APP_PREFIX}_{prefix}_ENDPOINT_LOGOUT")
|
|
136
|
+
if "token_endpoint" in defaulted_params:
|
|
137
|
+
token_endpoint = env_get_str(key=f"{APP_PREFIX}_{prefix}_ENDPOINT_TOKEN")
|
|
138
|
+
|
|
77
139
|
# establish the endpoints
|
|
78
140
|
if callback_endpoint:
|
|
79
141
|
flask_app.add_url_rule(rule=callback_endpoint,
|
|
80
142
|
endpoint=f"{iam_server}-callback",
|
|
81
143
|
view_func=service_callback,
|
|
82
144
|
methods=["GET"])
|
|
145
|
+
if callback_exchange_endpoint:
|
|
146
|
+
flask_app.add_url_rule(rule=callback_exchange_endpoint,
|
|
147
|
+
endpoint=f"{iam_server}-callback-exchange",
|
|
148
|
+
view_func=service_callback_exchange,
|
|
149
|
+
methods=["GET"])
|
|
150
|
+
if exchange_endpoint:
|
|
151
|
+
flask_app.add_url_rule(rule=exchange_endpoint,
|
|
152
|
+
endpoint=f"{iam_server}-exchange",
|
|
153
|
+
view_func=service_exchange,
|
|
154
|
+
methods=["POST"])
|
|
83
155
|
if login_endpoint:
|
|
84
156
|
flask_app.add_url_rule(rule=login_endpoint,
|
|
85
157
|
endpoint=f"{iam_server}-login",
|
|
@@ -93,64 +165,5 @@ def iam_setup(flask_app: Flask,
|
|
|
93
165
|
if token_endpoint:
|
|
94
166
|
flask_app.add_url_rule(rule=token_endpoint,
|
|
95
167
|
endpoint=f"{iam_server}-token",
|
|
96
|
-
view_func=
|
|
168
|
+
view_func=service_get_token,
|
|
97
169
|
methods=["GET"])
|
|
98
|
-
if exchange_endpoint:
|
|
99
|
-
flask_app.add_url_rule(rule=exchange_endpoint,
|
|
100
|
-
endpoint=f"{iam_server}-exchange",
|
|
101
|
-
view_func=service_exchange,
|
|
102
|
-
methods=["POST"])
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
def iam_get_env_parameters(iam_prefix: str = None) -> dict[str, Any]:
|
|
106
|
-
"""
|
|
107
|
-
Retrieve the set parameters for a *IAM* server from the environment.
|
|
108
|
-
|
|
109
|
-
the parameters are returned ready to be used as a '**kwargs' parameter set in a call to *iam_setup()*,
|
|
110
|
-
and sorted in the order appropriate to use them instead with a '*args' parameter set.
|
|
111
|
-
|
|
112
|
-
:param iam_prefix: the prefix classifying the parameters
|
|
113
|
-
:return: the sorted parameters classified by *prefix*
|
|
114
|
-
"""
|
|
115
|
-
return {
|
|
116
|
-
"base_url": env_get_str(key=f"{APP_PREFIX}_{iam_prefix}_URL_AUTH_BASE"),
|
|
117
|
-
"client_id": env_get_str(key=f"{APP_PREFIX}_{iam_prefix}_CLIENT_ID"),
|
|
118
|
-
"client_realm": env_get_str(key=f"{APP_PREFIX}_{iam_prefix}_CLIENT_REALM"),
|
|
119
|
-
"client_secret": env_get_str(key=f"{APP_PREFIX}_{iam_prefix}_CLIENT_SECRET"),
|
|
120
|
-
"recipient_attribute": env_get_str(key=f"{APP_PREFIX}_{iam_prefix}_RECIPIENT_ATTR"),
|
|
121
|
-
"admin_id": env_get_str(key=f"{APP_PREFIX}_{iam_prefix}_ADMIN_ID"),
|
|
122
|
-
"admin_secret": env_get_str(key=f"{APP_PREFIX}_{iam_prefix}_ADMIN_SECRET"),
|
|
123
|
-
"login_timeout": env_get_str(key=f"{APP_PREFIX}_{iam_prefix}_LOGIN_TIMEOUT"),
|
|
124
|
-
"public_key_lifetime": env_get_int(key=f"{APP_PREFIX}_{iam_prefix}_PUBLIC_KEY_LIFETIME"),
|
|
125
|
-
"callback_endpoint": env_get_str(key=f"{APP_PREFIX}_{iam_prefix}_ENDPOINT_CALLBACK"),
|
|
126
|
-
"exchange_endpoint": env_get_str(key=f"{APP_PREFIX}_{iam_prefix}_ENDPOINT_EXCHANGE"),
|
|
127
|
-
"login_endpoint": env_get_str(key=f"{APP_PREFIX}_{iam_prefix}_ENDPOINT_LOGIN"),
|
|
128
|
-
"logout_endpoint": env_get_str(key=f"{APP_PREFIX}_{iam_prefix}_ENDPOINT_LOGOUT"),
|
|
129
|
-
"token_endpoint": env_get_str(key=f"{APP_PREFIX}_{iam_prefix}_ENDPOINT_TOKEN")
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
def iam_get_token(iam_server: IamServer,
|
|
134
|
-
user_id: str,
|
|
135
|
-
errors: list[str] = None,
|
|
136
|
-
logger: Logger = None) -> str:
|
|
137
|
-
"""
|
|
138
|
-
Retrieve an authentication token for *user_id*.
|
|
139
|
-
|
|
140
|
-
:param iam_server: identifies the *IAM* server
|
|
141
|
-
:param user_id: identifies the user
|
|
142
|
-
:param errors: incidental errors
|
|
143
|
-
:param logger: optional logger
|
|
144
|
-
:return: the uthentication tokem
|
|
145
|
-
"""
|
|
146
|
-
# declare the return variable
|
|
147
|
-
result: str
|
|
148
|
-
|
|
149
|
-
# retrieve the token
|
|
150
|
-
args: dict[str, Any] = {"user-id": user_id}
|
|
151
|
-
with _iam_lock:
|
|
152
|
-
result = action_token(iam_server=iam_server,
|
|
153
|
-
args=args,
|
|
154
|
-
errors=errors,
|
|
155
|
-
logger=logger)
|
|
156
|
-
return result
|