cardo-python-utils 0.5.dev9__tar.gz → 0.5.dev10__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.
Files changed (34) hide show
  1. {cardo_python_utils-0.5.dev9/cardo_python_utils.egg-info → cardo_python_utils-0.5.dev10}/PKG-INFO +1 -1
  2. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10/cardo_python_utils.egg-info}/PKG-INFO +1 -1
  3. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/pyproject.toml +1 -1
  4. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/django/keycloak/service.py +53 -23
  5. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/LICENSE +0 -0
  6. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/MANIFEST.in +0 -0
  7. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/README.rst +0 -0
  8. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/cardo_python_utils.egg-info/SOURCES.txt +0 -0
  9. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/cardo_python_utils.egg-info/dependency_links.txt +0 -0
  10. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/cardo_python_utils.egg-info/requires.txt +0 -0
  11. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/cardo_python_utils.egg-info/top_level.txt +0 -0
  12. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/__init__.py +0 -0
  13. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/choices.py +0 -0
  14. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/data_structures.py +0 -0
  15. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/db.py +0 -0
  16. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/django/keycloak/__init__.py +0 -0
  17. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/django/keycloak/admin/__init__.py +0 -0
  18. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/django/keycloak/admin/auth.py +0 -0
  19. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/django/keycloak/admin/user_group.py +0 -0
  20. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/django/keycloak/admin/user_groups_changelist.html +0 -0
  21. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/django/keycloak/api/__init__.py +0 -0
  22. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/django/keycloak/api/drf.py +0 -0
  23. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/django/keycloak/api/ninja.py +0 -0
  24. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/django/keycloak/models/__init__.py +0 -0
  25. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/django/keycloak/models/user_group.py +0 -0
  26. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/django/utils.py +0 -0
  27. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/esma_choices.py +0 -0
  28. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/exceptions.py +0 -0
  29. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/imports.py +0 -0
  30. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/math.py +0 -0
  31. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/text.py +0 -0
  32. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/time.py +0 -0
  33. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/python_utils/types_hinting.py +0 -0
  34. {cardo_python_utils-0.5.dev9 → cardo_python_utils-0.5.dev10}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cardo-python-utils
3
- Version: 0.5.dev9
3
+ Version: 0.5.dev10
4
4
  Summary: Python library enhanced with a wide range of functions for different scenarios.
5
5
  Author-email: CardoAI <hello@cardoai.com>
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cardo-python-utils
3
- Version: 0.5.dev9
3
+ Version: 0.5.dev10
4
4
  Summary: Python library enhanced with a wide range of functions for different scenarios.
5
5
  Author-email: CardoAI <hello@cardoai.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "cardo-python-utils"
7
- version = "0.5.dev9"
7
+ version = "0.5.dev10"
8
8
  description = "Python library enhanced with a wide range of functions for different scenarios."
9
9
  readme = "README.rst"
10
10
  requires-python = ">=3.8"
@@ -4,10 +4,32 @@ from keycloak import KeycloakAdmin
4
4
  from keycloak import KeycloakOpenIDConnection
5
5
  from keycloak.exceptions import KeycloakGetError
6
6
 
7
+ def _get_user_group_model():
8
+ """
9
+ Dynamically get the UserGroup model.
10
+
11
+ Attempts to use the model specified in settings.KEYCLOAK_USER_GROUP_MODEL.
12
+
13
+ Returns:
14
+ The UserGroup model class.
15
+
16
+ Raises:
17
+ LookupError: If the model cannot be found.
18
+ """
19
+ try:
20
+ model_string = getattr(settings, "KEYCLOAK_USER_GROUP_MODEL")
21
+ except AttributeError:
22
+ raise LookupError(
23
+ "Please set KEYCLOAK_USER_GROUP_MODEL in your Django settings "
24
+ "(e.g., 'myapp.UserGroup')."
25
+ )
26
+
27
+ return apps.get_model(model_string)
28
+
7
29
 
8
30
  class KeycloakService:
9
31
  def __init__(self):
10
- self._user_group_model = self._get_user_group_model()
32
+ self._user_group_model = _get_user_group_model()
11
33
  self._keycloak_admin = self._get_keycloak_admin()
12
34
 
13
35
  def sync_user_groups(self, raise_exceptions: bool = False):
@@ -53,28 +75,6 @@ class KeycloakService:
53
75
  )
54
76
  return KeycloakAdmin(connection=keycloak_connection)
55
77
 
56
- def _get_user_group_model(self):
57
- """
58
- Dynamically get the UserGroup model.
59
-
60
- Attempts to use the model specified in settings.KEYCLOAK_USER_GROUP_MODEL.
61
-
62
- Returns:
63
- The UserGroup model class.
64
-
65
- Raises:
66
- LookupError: If the model cannot be found.
67
- """
68
- try:
69
- model_string = getattr(settings, "KEYCLOAK_USER_GROUP_MODEL")
70
- except AttributeError:
71
- raise LookupError(
72
- "Please set KEYCLOAK_USER_GROUP_MODEL in your Django settings "
73
- "(e.g., 'myapp.UserGroup')."
74
- )
75
-
76
- return apps.get_model(model_string)
77
-
78
78
  def _process_group_recursively(
79
79
  self, group, existing_groups_by_id, reported_group_ids
80
80
  ):
@@ -98,3 +98,33 @@ class KeycloakService:
98
98
  self._process_group_recursively(
99
99
  subgroup, existing_groups_by_id, reported_group_ids
100
100
  )
101
+
102
+
103
+ class AuthServiceBase:
104
+ @staticmethod
105
+ def _get_all_level_paths(path: str) -> list[str]:
106
+ """
107
+ Given a group path, return all level paths up to the root.
108
+ E.g., for "/a/b/c", return ["/a/b/c", "/a/b", "/a"]
109
+ """
110
+ paths = []
111
+ while "/" in path:
112
+ paths.append(path)
113
+ path = "/".join(path.split("/")[:-1])
114
+ return paths
115
+
116
+ @classmethod
117
+ def _get_user_groups_from_paths(cls, group_paths: list[str]):
118
+ all_group_paths = set()
119
+ for path in group_paths:
120
+ all_group_paths.update(cls._get_all_level_paths(path))
121
+
122
+ UserGroup = _get_user_group_model()
123
+ user_groups = UserGroup.objects.filter(path__in=all_group_paths)
124
+
125
+ # If a group is missing/has been renamed in Keycloak, sync the groups
126
+ if user_groups.count() != len(all_group_paths):
127
+ KeycloakService().sync_user_groups()
128
+ user_groups = UserGroup.objects.filter(path__in=all_group_paths)
129
+
130
+ return user_groups