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