pypomes-iam 0.2.1__tar.gz → 0.2.2__tar.gz

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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pypomes_iam
3
- Version: 0.2.1
3
+ Version: 0.2.2
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
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
 
7
7
  [project]
8
8
  name = "pypomes_iam"
9
- version = "0.2.1"
9
+ version = "0.2.2"
10
10
  authors = [
11
11
  { name="GT Nunes", email="wisecoder01@gmail.com" }
12
12
  ]
@@ -8,6 +8,7 @@ from datetime import datetime
8
8
  from flask import Request
9
9
  from logging import Logger
10
10
  from pypomes_core import TZ_LOCAL, exc_format
11
+ from pypomes_crypto import crypto_jwk_convert
11
12
  from typing import Any
12
13
 
13
14
  # registry structure:
@@ -36,75 +37,6 @@ from typing import Any
36
37
  # }
37
38
 
38
39
 
39
- def _service_callback(registry: dict[str, Any],
40
- args: dict[str, Any],
41
- errors: list[str],
42
- logger: Logger | None) -> tuple[str, str]:
43
- """
44
- Entry point for the callback from JusBR on authentication operation.
45
-
46
- :param registry: the registry holding the authentication data
47
- :param args: the arguments passed when requesting the service
48
- :param errors: incidental errors
49
- :param logger: optional logger
50
- """
51
- from .token_pomes import token_validate
52
-
53
- # initialize the return variable
54
- result: tuple[str, str] | None = None
55
-
56
- # retrieve the users authentication data
57
- cache: Cache = registry["safe-cache"]
58
- users: dict[str, dict[str, Any]] = cache.get("users")
59
-
60
- # validate the OAuth2 state
61
- oauth_state: str = args.get("state")
62
- user_data: dict[str, Any] | None = None
63
- if oauth_state:
64
- for user, data in users.items():
65
- if user == oauth_state:
66
- user_data = data
67
- break
68
-
69
- # exchange 'code' for the token
70
- if user_data:
71
- users.pop(oauth_state)
72
- code: str = args.get("code")
73
- body_data: dict[str, Any] = {
74
- "grant_type": "authorization_code",
75
- "code": code,
76
- "redirect_uri": registry.get("callback-url"),
77
- }
78
- token = _post_for_token(registry=registry,
79
- user_data=user_data,
80
- body_data=body_data,
81
- errors=errors,
82
- logger=logger)
83
- # retrieve the token's claims
84
- if not errors:
85
- public_key: bytes = _get_public_key(registry=registry,
86
- logger=logger)
87
- token_claims: dict[str, dict[str, Any]] = token_validate(token=token,
88
- issuer=registry["base-url"],
89
- public_key=public_key,
90
- errors=errors,
91
- logger=logger)
92
- if not errors:
93
- token_user: str = token_claims["payload"].get("preferred_username")
94
- if token_user == oauth_state:
95
- users[token_user] = user_data
96
- result = (token_user, token)
97
- else:
98
- errors.append(f"Token was issued to user '{token_user}'")
99
- else:
100
- msg: str = "Unknown OAuth2 code received"
101
- if _get_login_timeout(registry=registry):
102
- msg += " - possible operation timeout"
103
- errors.append(msg)
104
-
105
- return result
106
-
107
-
108
40
  def _service_login(registry: dict[str, Any],
109
41
  args: dict[str, Any],
110
42
  logger: Logger | None) -> str:
@@ -165,6 +97,76 @@ def _service_logout(registry: dict[str, Any],
165
97
  logger.debug(msg=f"User '{user_id}' removed from the registry")
166
98
 
167
99
 
100
+ def _service_callback(registry: dict[str, Any],
101
+ args: dict[str, Any],
102
+ errors: list[str],
103
+ logger: Logger | None) -> tuple[str, str]:
104
+ """
105
+ Entry point for the callback from JusBR on authentication operation.
106
+
107
+ :param registry: the registry holding the authentication data
108
+ :param args: the arguments passed when requesting the service
109
+ :param errors: incidental errors
110
+ :param logger: optional logger
111
+ """
112
+ from .token_pomes import token_validate
113
+
114
+ # initialize the return variable
115
+ result: tuple[str, str] | None = None
116
+
117
+ # retrieve the users authentication data
118
+ cache: Cache = registry["safe-cache"]
119
+ users: dict[str, dict[str, Any]] = cache.get("users")
120
+
121
+ # validate the OAuth2 state
122
+ oauth_state: str = args.get("state")
123
+ user_data: dict[str, Any] | None = None
124
+ if oauth_state:
125
+ for user, data in users.items():
126
+ if user == oauth_state:
127
+ user_data = data
128
+ break
129
+
130
+ # exchange 'code' for the token
131
+ if user_data:
132
+ expiration: int = user_data["login-expiration"] or sys.maxsize
133
+ if int(datetime.now(tz=TZ_LOCAL).timestamp()) > expiration:
134
+ errors.append("Operation timeout")
135
+ else:
136
+ users.pop(oauth_state)
137
+ code: str = args.get("code")
138
+ body_data: dict[str, Any] = {
139
+ "grant_type": "authorization_code",
140
+ "code": code,
141
+ "redirect_uri": registry.get("callback-url"),
142
+ }
143
+ token = _post_for_token(registry=registry,
144
+ user_data=user_data,
145
+ body_data=body_data,
146
+ errors=errors,
147
+ logger=logger)
148
+ # retrieve the token's claims
149
+ if not errors:
150
+ public_key: bytes = _get_public_key(registry=registry,
151
+ logger=logger)
152
+ token_claims: dict[str, dict[str, Any]] = token_validate(token=token,
153
+ issuer=registry["base-url"],
154
+ public_key=public_key,
155
+ errors=errors,
156
+ logger=logger)
157
+ if not errors:
158
+ token_user: str = token_claims["payload"].get("preferred_username")
159
+ if token_user == oauth_state:
160
+ users[token_user] = user_data
161
+ result = (token_user, token)
162
+ else:
163
+ errors.append(f"Token was issued to user '{token_user}'")
164
+ else:
165
+ errors.append("Unknown state received")
166
+
167
+ return result
168
+
169
+
168
170
  def _service_token(registry: dict[str, Any],
169
171
  args: dict[str, Any],
170
172
  errors: list[str] = None,
@@ -225,8 +227,6 @@ def _get_public_key(registry: dict[str, Any],
225
227
  :param registry: the registry holding the authentication data
226
228
  :return: the public key, in *DER* format
227
229
  """
228
- from pypomes_crypto import crypto_jwk_convert
229
-
230
230
  # initialize the return variable
231
231
  result: bytes | None = None
232
232
 
@@ -6,8 +6,8 @@ from .common_pomes import (
6
6
  _service_login, _service_logout,
7
7
  _service_callback, _service_token, _log_init
8
8
  )
9
- from .jusbr_pomes import _jusbr_logger, _jusbr_registry
10
- from .keycloak_pomes import _keycloak_logger, _keycloak_registry
9
+ from .jusbr_pomes import _jusbr_get_logger, _jusbr_get_registry
10
+ from .keycloak_pomes import _keycloak_get_logger, _keycloak_get_registry
11
11
 
12
12
 
13
13
  # @flask_app.route(rule=<login_endpoint>, # JUSBR_LOGIN_ENDPOINT: /iam/jusbr:login
@@ -25,11 +25,11 @@ def service_login() -> Response:
25
25
  logger: Logger
26
26
  registry: dict[str, Any]
27
27
  if request.endpoint == "jusbr-login":
28
- logger = _jusbr_logger
29
- registry = _jusbr_registry
28
+ logger = _jusbr_get_logger()
29
+ registry = _jusbr_get_registry()
30
30
  else:
31
- logger = _keycloak_logger
32
- registry = _keycloak_registry
31
+ logger = _keycloak_get_logger()
32
+ registry = _keycloak_get_registry()
33
33
 
34
34
  # log the request
35
35
  if logger:
@@ -64,11 +64,11 @@ def service_logout() -> Response:
64
64
  logger: Logger
65
65
  registry: dict[str, Any]
66
66
  if request.endpoint == "jusbr-logout":
67
- logger = _jusbr_logger
68
- registry = _jusbr_registry
67
+ logger = _jusbr_get_logger()
68
+ registry = _jusbr_get_registry()
69
69
  else:
70
- logger = _keycloak_logger
71
- registry = _keycloak_registry
70
+ logger = _keycloak_get_logger()
71
+ registry = _keycloak_get_registry()
72
72
 
73
73
  # log the request
74
74
  if logger:
@@ -101,11 +101,11 @@ def service_callback() -> Response:
101
101
  logger: Logger
102
102
  registry: dict[str, Any]
103
103
  if request.endpoint == "jusbr-callback":
104
- logger = _jusbr_logger
105
- registry = _jusbr_registry
104
+ logger = _jusbr_get_logger()
105
+ registry = _jusbr_get_registry()
106
106
  else:
107
- logger = _keycloak_logger
108
- registry = _keycloak_registry
107
+ logger = _keycloak_get_logger()
108
+ registry = _keycloak_get_registry()
109
109
 
110
110
  # log the request
111
111
  if logger:
@@ -146,11 +146,11 @@ def service_token() -> Response:
146
146
  logger: Logger
147
147
  registry: dict[str, Any]
148
148
  if request.endpoint == "jusbr-token":
149
- logger = _jusbr_logger
150
- registry = _jusbr_registry
149
+ logger = _jusbr_get_logger()
150
+ registry = _jusbr_get_registry()
151
151
  else:
152
- logger = _keycloak_logger
153
- registry = _keycloak_registry
152
+ logger = _keycloak_get_logger()
153
+ registry = _keycloak_get_registry()
154
154
 
155
155
  # log the request
156
156
  if logger:
@@ -147,3 +147,19 @@ def jusbr_get_token(user_id: str,
147
147
  args=args,
148
148
  errors=errors,
149
149
  logger=logger)
150
+
151
+
152
+ def _jusbr_get_logger() -> Logger:
153
+ """
154
+ Retrieve the logger for JusBR operations.
155
+ :return: the Keycloak logger
156
+ """
157
+ return _jusbr_logger
158
+
159
+
160
+ def _jusbr_get_registry() -> dict[str, Any]:
161
+ """
162
+ Retrieve the registry holding user authentication data related to JusBR operations.
163
+ :return: the Keycloak registry
164
+ """
165
+ return _jusbr_registry
@@ -150,3 +150,19 @@ def keycloak_get_token(user_id: str,
150
150
  args=args,
151
151
  errors=errors,
152
152
  logger=logger)
153
+
154
+
155
+ def _keycloak_get_logger() -> Logger:
156
+ """
157
+ Retrieve the logger for Keycloak operations.
158
+ :return: the Keycloak logger
159
+ """
160
+ return _keycloak_logger
161
+
162
+
163
+ def _keycloak_get_registry() -> dict[str, Any]:
164
+ """
165
+ Retrieve the registry holding user authentication data related to Keycloak operations.
166
+ :return: the Keycloak registry
167
+ """
168
+ return _keycloak_registry
File without changes
File without changes
File without changes