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/iam_pomes.py CHANGED
@@ -1,37 +1,38 @@
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, service_exchange, service_get_token
12
14
  )
13
15
 
14
16
 
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:
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
- Establish the provided parameters for configuring the *IAM* server *iam_server*.
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 are task are planned.
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 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
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: recipient_attribute,
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: public_key_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=service_token,
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