alpha-python 0.2.4__tar.gz → 0.2.5__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 (145) hide show
  1. {alpha_python-0.2.4 → alpha_python-0.2.5}/PKG-INFO +1 -1
  2. {alpha_python-0.2.4 → alpha_python-0.2.5}/pyproject.toml +1 -1
  3. alpha_python-0.2.5/src/alpha/__init__.py +116 -0
  4. alpha_python-0.2.5/src/alpha/adapters/__init__.py +5 -0
  5. alpha_python-0.2.5/src/alpha/domain/__init__.py +10 -0
  6. alpha_python-0.2.5/src/alpha/domain/models/__init__.py +10 -0
  7. alpha_python-0.2.5/src/alpha/factories/__init__.py +9 -0
  8. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/factories/model_class_factory.py +2 -2
  9. alpha_python-0.2.5/src/alpha/infra/__init__.py +18 -0
  10. alpha_python-0.2.5/src/alpha/infra/connectors/__init__.py +5 -0
  11. alpha_python-0.2.5/src/alpha/infra/databases/__init__.py +5 -0
  12. alpha_python-0.2.5/src/alpha/infra/models/__init__.py +14 -0
  13. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/infra/models/query_clause.py +3 -5
  14. alpha_python-0.2.5/src/alpha/interfaces/__init__.py +44 -0
  15. alpha_python-0.2.5/src/alpha/mixins/__init__.py +3 -0
  16. alpha_python-0.2.5/src/alpha/providers/__init__.py +23 -0
  17. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/providers/ldap_provider.py +106 -30
  18. alpha_python-0.2.5/src/alpha/providers/models/__init__.py +17 -0
  19. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/providers/models/identity.py +44 -2
  20. alpha_python-0.2.5/src/alpha/repositories/__init__.py +7 -0
  21. alpha_python-0.2.5/src/alpha/repositories/models/__init__.py +5 -0
  22. alpha_python-0.2.5/src/alpha/services/__init__.py +5 -0
  23. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/services/authentication_service.py +32 -27
  24. alpha_python-0.2.5/src/alpha/utils/__init__.py +21 -0
  25. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha_python.egg-info/PKG-INFO +1 -1
  26. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha_python.egg-info/SOURCES.txt +1 -1
  27. alpha_python-0.2.4/src/alpha/__init__.py +0 -14
  28. alpha_python-0.2.4/src/alpha/domain/models/__init__.py +0 -2
  29. alpha_python-0.2.4/src/alpha/handlers/__init__.py +0 -0
  30. alpha_python-0.2.4/src/alpha/handlers/models/__init__.py +0 -0
  31. alpha_python-0.2.4/src/alpha/handlers/templates/__init__.py +0 -0
  32. alpha_python-0.2.4/src/alpha/infra/__init__.py +0 -0
  33. alpha_python-0.2.4/src/alpha/infra/connectors/__init__.py +0 -0
  34. alpha_python-0.2.4/src/alpha/infra/databases/__init__.py +0 -0
  35. alpha_python-0.2.4/src/alpha/infra/models/__init__.py +0 -0
  36. alpha_python-0.2.4/src/alpha/interfaces/__init__.py +0 -0
  37. alpha_python-0.2.4/src/alpha/mixins/__init__.py +0 -0
  38. alpha_python-0.2.4/src/alpha/providers/__init__.py +0 -0
  39. alpha_python-0.2.4/src/alpha/providers/models/__init__.py +0 -0
  40. alpha_python-0.2.4/src/alpha/repositories/__init__.py +0 -0
  41. alpha_python-0.2.4/src/alpha/repositories/models/__init__.py +0 -0
  42. alpha_python-0.2.4/src/alpha/services/__init__.py +0 -0
  43. alpha_python-0.2.4/src/alpha/utils/__init__.py +0 -0
  44. {alpha_python-0.2.4 → alpha_python-0.2.5}/LICENSE +0 -0
  45. {alpha_python-0.2.4 → alpha_python-0.2.5}/README.md +0 -0
  46. {alpha_python-0.2.4 → alpha_python-0.2.5}/setup.cfg +0 -0
  47. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/adapters/sqla_unit_of_work.py +0 -0
  48. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/cli.py +0 -0
  49. {alpha_python-0.2.4/src/alpha/adapters → alpha_python-0.2.5/src/alpha/containers}/__init__.py +0 -0
  50. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/containers/container.py +0 -0
  51. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/domain/models/base_model.py +0 -0
  52. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/domain/models/life_cycle_base.py +0 -0
  53. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/domain/models/user.py +0 -0
  54. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/encoder.py +0 -0
  55. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/exceptions.py +0 -0
  56. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/factories/_type_conversion_matrix.py +0 -0
  57. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/factories/_type_mapping.py +0 -0
  58. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/factories/class_factories.py +0 -0
  59. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/factories/default_field_factory.py +0 -0
  60. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/factories/field_iterator.py +0 -0
  61. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/factories/jwt_factory.py +0 -0
  62. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/factories/logging_handler_factory.py +0 -0
  63. {alpha_python-0.2.4/src/alpha/containers → alpha_python-0.2.5/src/alpha/factories/models}/__init__.py +0 -0
  64. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/factories/models/factory_classes.py +0 -0
  65. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/factories/request_factory.py +0 -0
  66. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/factories/response_factory.py +0 -0
  67. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/factories/type_factories.py +0 -0
  68. {alpha_python-0.2.4/src/alpha/domain → alpha_python-0.2.5/src/alpha/handlers}/__init__.py +0 -0
  69. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/api_generate_handler.py +0 -0
  70. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/api_run_handler.py +0 -0
  71. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/base_handler.py +0 -0
  72. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/gen-code.sh +0 -0
  73. {alpha_python-0.2.4/src/alpha/factories → alpha_python-0.2.5/src/alpha/handlers/models}/__init__.py +0 -0
  74. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/models/argument.py +0 -0
  75. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/models/command.py +0 -0
  76. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/models/section.py +0 -0
  77. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/models/subparser.py +0 -0
  78. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/run-api.sh +0 -0
  79. {alpha_python-0.2.4/src/alpha/factories/models → alpha_python-0.2.5/src/alpha/handlers/templates}/__init__.py +0 -0
  80. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/Dockerfile.mustache +0 -0
  81. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/README.mustache +0 -0
  82. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/__init__model.mustache +0 -0
  83. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/__init__test.mustache +0 -0
  84. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/__main__.mustache +0 -0
  85. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/base_model.mustache +0 -0
  86. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/controller.mustache +0 -0
  87. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/controller_test.mustache +0 -0
  88. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/dockerignore.mustache +0 -0
  89. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/encoder.mustache +0 -0
  90. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/git_push.sh.mustache +0 -0
  91. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/gitignore.mustache +0 -0
  92. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/model.mustache +0 -0
  93. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/openapi.mustache +0 -0
  94. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/param_type.mustache +0 -0
  95. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/requirements.mustache +0 -0
  96. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/security_controller_.mustache +0 -0
  97. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/setup.mustache +0 -0
  98. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/test-requirements.mustache +0 -0
  99. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/tox.mustache +0 -0
  100. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/travis.mustache +0 -0
  101. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/typing_utils.mustache +0 -0
  102. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/handlers/templates/python-flask/util.mustache +0 -0
  103. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/infra/connectors/ldap_connector.py +0 -0
  104. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/infra/databases/sql_alchemy.py +0 -0
  105. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/infra/models/filter_operators.py +0 -0
  106. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/infra/models/json_patch.py +0 -0
  107. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/infra/models/order_by.py +0 -0
  108. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/infra/models/search_filter.py +0 -0
  109. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/interfaces/attrs_instance.py +0 -0
  110. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/interfaces/dataclass_instance.py +0 -0
  111. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/interfaces/factories.py +0 -0
  112. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/interfaces/handler.py +0 -0
  113. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/interfaces/openapi_model.py +0 -0
  114. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/interfaces/patchable.py +0 -0
  115. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/interfaces/providers.py +0 -0
  116. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/interfaces/pydantic_instance.py +0 -0
  117. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/interfaces/sql_database.py +0 -0
  118. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/interfaces/sql_mapper.py +0 -0
  119. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/interfaces/sql_repository.py +0 -0
  120. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/interfaces/token_factory.py +0 -0
  121. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/interfaces/unit_of_work.py +0 -0
  122. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/interfaces/updateable.py +0 -0
  123. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/mixins/jwt_provider.py +0 -0
  124. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/providers/api_key_provider.py +0 -0
  125. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/providers/database_provider.py +0 -0
  126. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/providers/keycloak_provider.py +0 -0
  127. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/providers/local_provider.py +0 -0
  128. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/providers/models/credentials.py +0 -0
  129. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/providers/models/token.py +0 -0
  130. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/py.typed +0 -0
  131. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/repositories/models/repository_model.py +0 -0
  132. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/repositories/sql_alchemy_repository.py +0 -0
  133. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/utils/_http_codes.py +0 -0
  134. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/utils/is_attrs.py +0 -0
  135. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/utils/is_pydantic.py +0 -0
  136. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/utils/logging_configurator.py +0 -0
  137. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/utils/logging_level_checker.py +0 -0
  138. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/utils/response_object.py +0 -0
  139. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha/utils/verify_identity.py +0 -0
  140. /alpha_python-0.2.4/src/alpha/utils/version_check.py → /alpha_python-0.2.5/src/alpha/utils/version_checker.py +0 -0
  141. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha_python.egg-info/dependency_links.txt +0 -0
  142. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha_python.egg-info/entry_points.txt +0 -0
  143. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha_python.egg-info/requires.txt +0 -0
  144. {alpha_python-0.2.4 → alpha_python-0.2.5}/src/alpha_python.egg-info/top_level.txt +0 -0
  145. {alpha_python-0.2.4 → alpha_python-0.2.5}/tests/test_encoder.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alpha-python
3
- Version: 0.2.4
3
+ Version: 0.2.5
4
4
  Summary: Alpha is intended to be the first dependency you need to add to your Python application. It is a Python library which contains standard building blocks that can be used in applications that are used as APIs and/or make use of database interaction.
5
5
  Author-email: Bart Reijling <bart@reijling.eu>
6
6
  Requires-Python: >=3.11
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "alpha-python"
3
- version = "0.2.4"
3
+ version = "0.2.5"
4
4
  description = "Alpha is intended to be the first dependency you need to add to your Python application. It is a Python library which contains standard building blocks that can be used in applications that are used as APIs and/or make use of database interaction."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -0,0 +1,116 @@
1
+ from alpha.adapters.sqla_unit_of_work import SqlAlchemyUnitOfWork
2
+ from alpha.factories.jwt_factory import JWTFactory
3
+ from alpha.factories.logging_handler_factory import LoggingHandlerFactory
4
+ from alpha.factories.model_class_factory import ModelClassFactory
5
+ from alpha.domain.models.user import User
6
+ from alpha.domain.models.base_model import BaseDomainModel, DomainModel
7
+ from alpha.domain.models.life_cycle_base import LifeCycleBase
8
+ from alpha.infra.connectors.ldap_connector import LDAPConnector
9
+ from alpha.infra.databases.sql_alchemy import SqlAlchemyDatabase
10
+ from alpha.infra.models.filter_operators import And, Or
11
+ from alpha.infra.models.json_patch import JsonPatch
12
+ from alpha.infra.models.order_by import OrderBy, Order
13
+ from alpha.infra.models.search_filter import SearchFilter, Operator
14
+ from alpha.interfaces.attrs_instance import AttrsInstance
15
+ from alpha.interfaces.dataclass_instance import DataclassInstance
16
+ from alpha.interfaces.pydantic_instance import PydanticInstance
17
+ from alpha.interfaces.openapi_model import OpenAPIModel
18
+ from alpha.interfaces.updateable import Updateable
19
+ from alpha.interfaces.patchable import Patchable
20
+ from alpha.interfaces.sql_repository import SqlRepository
21
+ from alpha.interfaces.sql_mapper import SqlMapper
22
+ from alpha.interfaces.sql_database import SqlDatabase
23
+ from alpha.interfaces.unit_of_work import UnitOfWork
24
+ from alpha.interfaces.providers import (
25
+ IdentityProvider,
26
+ PasswordAuthenticator,
27
+ UserDirectory,
28
+ PasswordChanger,
29
+ TokenIssuer,
30
+ TokenValidator,
31
+ )
32
+ from alpha.interfaces.token_factory import TokenFactory
33
+ from alpha.mixins.jwt_provider import JWTProviderMixin
34
+ from alpha.providers.models.identity import (
35
+ Identity,
36
+ DEFAULT_LDAP_MAPPINGS,
37
+ DEFAULT_AD_MAPPINGS,
38
+ AD_SEARCH_ATTRIBUTES,
39
+ )
40
+ from alpha.providers.models.credentials import PasswordCredentials
41
+ from alpha.providers.models.token import Token
42
+ from alpha.providers.ldap_provider import LDAPProvider, ADProvider
43
+ from alpha.repositories.models.repository_model import RepositoryModel
44
+ from alpha.repositories.sql_alchemy_repository import SqlAlchemyRepository
45
+ from alpha.services.authentication_service import AuthenticationService
46
+ from alpha.utils.is_attrs import is_attrs
47
+ from alpha.utils.is_pydantic import is_pydantic
48
+ from alpha.utils.logging_configurator import (
49
+ LoggingConfigurator,
50
+ GunicornLogger,
51
+ )
52
+ from alpha.utils.logging_level_checker import logging_level_checker
53
+ from alpha.utils.response_object import create_response_object
54
+ from alpha.utils.verify_identity import verify_identity
55
+ from alpha.utils.version_checker import minor_version_gte
56
+
57
+
58
+ from alpha.encoder import JSONEncoder
59
+
60
+ __all__ = [
61
+ "SqlAlchemyUnitOfWork",
62
+ "JWTFactory",
63
+ "LoggingHandlerFactory",
64
+ "ModelClassFactory",
65
+ "BaseDomainModel",
66
+ "DomainModel",
67
+ "LifeCycleBase",
68
+ "User",
69
+ "LDAPConnector",
70
+ "SqlAlchemyDatabase",
71
+ "And",
72
+ "Or",
73
+ "JsonPatch",
74
+ "OrderBy",
75
+ "Order",
76
+ "SearchFilter",
77
+ "Operator",
78
+ "AttrsInstance",
79
+ "DataclassInstance",
80
+ "PydanticInstance",
81
+ "OpenAPIModel",
82
+ "Updateable",
83
+ "Patchable",
84
+ "SqlRepository",
85
+ "SqlMapper",
86
+ "SqlDatabase",
87
+ "UnitOfWork",
88
+ "IdentityProvider",
89
+ "PasswordAuthenticator",
90
+ "TokenValidator",
91
+ "UserDirectory",
92
+ "PasswordChanger",
93
+ "TokenIssuer",
94
+ "TokenFactory",
95
+ "JWTProviderMixin",
96
+ "Identity",
97
+ "DEFAULT_LDAP_MAPPINGS",
98
+ "DEFAULT_AD_MAPPINGS",
99
+ "AD_SEARCH_ATTRIBUTES",
100
+ "PasswordCredentials",
101
+ "Token",
102
+ "LDAPProvider",
103
+ "ADProvider",
104
+ "RepositoryModel",
105
+ "SqlAlchemyRepository",
106
+ "AuthenticationService",
107
+ "is_attrs",
108
+ "is_pydantic",
109
+ "LoggingConfigurator",
110
+ "GunicornLogger",
111
+ "logging_level_checker",
112
+ "create_response_object",
113
+ "verify_identity",
114
+ "minor_version_gte",
115
+ "JSONEncoder",
116
+ ]
@@ -0,0 +1,5 @@
1
+ from alpha.adapters.sqla_unit_of_work import SqlAlchemyUnitOfWork
2
+
3
+ __all__ = [
4
+ "SqlAlchemyUnitOfWork",
5
+ ]
@@ -0,0 +1,10 @@
1
+ from alpha.domain.models.user import User
2
+ from alpha.domain.models.base_model import BaseDomainModel, DomainModel
3
+ from alpha.domain.models.life_cycle_base import LifeCycleBase
4
+
5
+ __all__ = [
6
+ "BaseDomainModel",
7
+ "DomainModel",
8
+ "LifeCycleBase",
9
+ "User",
10
+ ]
@@ -0,0 +1,10 @@
1
+ from alpha.domain.models.user import User
2
+ from alpha.domain.models.base_model import BaseDomainModel, DomainModel
3
+ from alpha.domain.models.life_cycle_base import LifeCycleBase
4
+
5
+ __all__ = [
6
+ "BaseDomainModel",
7
+ "DomainModel",
8
+ "LifeCycleBase",
9
+ "User",
10
+ ]
@@ -0,0 +1,9 @@
1
+ from alpha.factories.jwt_factory import JWTFactory
2
+ from alpha.factories.logging_handler_factory import LoggingHandlerFactory
3
+ from alpha.factories.model_class_factory import ModelClassFactory
4
+
5
+ __all__ = [
6
+ "JWTFactory",
7
+ "LoggingHandlerFactory",
8
+ "ModelClassFactory",
9
+ ]
@@ -33,7 +33,7 @@ from alpha.interfaces.factories import (
33
33
  )
34
34
  from alpha.interfaces.openapi_model import OpenAPIModel
35
35
  from alpha.interfaces.pydantic_instance import PydanticInstance
36
- from alpha.utils.version_check import minor_version_gte
36
+ from alpha.utils.version_checker import minor_version_gte
37
37
 
38
38
 
39
39
  CLASS_FACTORIES: dict[str, ClassFactory] = {
@@ -173,4 +173,4 @@ class ModelClassFactory:
173
173
  f"{field.type.__class__=}; "
174
174
  ) from exc
175
175
  params[field.name] = value
176
- return cls(**params)
176
+ return cls(**params) # type: ignore
@@ -0,0 +1,18 @@
1
+ from alpha.infra.connectors.ldap_connector import LDAPConnector
2
+ from alpha.infra.databases.sql_alchemy import SqlAlchemyDatabase
3
+ from alpha.infra.models.filter_operators import And, Or
4
+ from alpha.infra.models.json_patch import JsonPatch
5
+ from alpha.infra.models.order_by import OrderBy, Order
6
+ from alpha.infra.models.search_filter import SearchFilter, Operator
7
+
8
+ __all__ = [
9
+ "LDAPConnector",
10
+ "SqlAlchemyDatabase",
11
+ "And",
12
+ "Or",
13
+ "JsonPatch",
14
+ "OrderBy",
15
+ "Order",
16
+ "SearchFilter",
17
+ "Operator",
18
+ ]
@@ -0,0 +1,5 @@
1
+ from alpha.infra.connectors.ldap_connector import LDAPConnector
2
+
3
+ __all__ = [
4
+ "LDAPConnector",
5
+ ]
@@ -0,0 +1,5 @@
1
+ from alpha.infra.databases.sql_alchemy import SqlAlchemyDatabase
2
+
3
+ __all__ = [
4
+ "SqlAlchemyDatabase",
5
+ ]
@@ -0,0 +1,14 @@
1
+ from alpha.infra.models.filter_operators import And, Or
2
+ from alpha.infra.models.json_patch import JsonPatch
3
+ from alpha.infra.models.order_by import OrderBy, Order
4
+ from alpha.infra.models.search_filter import SearchFilter, Operator
5
+
6
+ __all__ = [
7
+ "And",
8
+ "Or",
9
+ "JsonPatch",
10
+ "OrderBy",
11
+ "Order",
12
+ "SearchFilter",
13
+ "Operator",
14
+ ]
@@ -37,9 +37,7 @@ class QueryClause:
37
37
 
38
38
  def _raise_instrumented_attr_exception(self):
39
39
  raise exceptions.InstrumentedAttributeMissing(
40
- """
41
- The 'field' attribute needs to be of an \
42
- sqlalchemy.orm.InstrumentedAttribute type, or specify the mapped domain model \
43
- by adding the _domain_model attribute
44
- """
40
+ "The \'field\' attribute needs to be of an "
41
+ "sqlalchemy.orm.InstrumentedAttribute type, or specify the mapped "
42
+ "domain model by adding the _domain_model attribute"
45
43
  )
@@ -0,0 +1,44 @@
1
+ # import dataclass and equivalent or related interfaces
2
+ from alpha.interfaces.attrs_instance import AttrsInstance
3
+ from alpha.interfaces.dataclass_instance import DataclassInstance
4
+ from alpha.interfaces.pydantic_instance import PydanticInstance
5
+ from alpha.interfaces.openapi_model import OpenAPIModel
6
+ from alpha.interfaces.updateable import Updateable
7
+ from alpha.interfaces.patchable import Patchable
8
+
9
+ # import all database related interfaces
10
+ from alpha.interfaces.sql_repository import SqlRepository
11
+ from alpha.interfaces.sql_mapper import SqlMapper
12
+ from alpha.interfaces.sql_database import SqlDatabase
13
+ from alpha.interfaces.unit_of_work import UnitOfWork
14
+
15
+ # import all authentication and authorization related interfaces
16
+ from alpha.interfaces.providers import (
17
+ IdentityProvider,
18
+ PasswordAuthenticator,
19
+ UserDirectory,
20
+ PasswordChanger,
21
+ TokenIssuer,
22
+ TokenValidator,
23
+ )
24
+ from alpha.interfaces.token_factory import TokenFactory
25
+
26
+ __all__ = [
27
+ "AttrsInstance",
28
+ "DataclassInstance",
29
+ "PydanticInstance",
30
+ "OpenAPIModel",
31
+ "Updateable",
32
+ "Patchable",
33
+ "SqlRepository",
34
+ "SqlMapper",
35
+ "SqlDatabase",
36
+ "UnitOfWork",
37
+ "IdentityProvider",
38
+ "PasswordAuthenticator",
39
+ "TokenValidator",
40
+ "UserDirectory",
41
+ "PasswordChanger",
42
+ "TokenIssuer",
43
+ "TokenFactory",
44
+ ]
@@ -0,0 +1,3 @@
1
+ from alpha.mixins.jwt_provider import JWTProviderMixin
2
+
3
+ __all__ = ["JWTProviderMixin"]
@@ -0,0 +1,23 @@
1
+ # Models
2
+ from alpha.providers.models.identity import (
3
+ Identity,
4
+ DEFAULT_LDAP_MAPPINGS,
5
+ DEFAULT_AD_MAPPINGS,
6
+ AD_SEARCH_ATTRIBUTES,
7
+ )
8
+ from alpha.providers.models.credentials import PasswordCredentials
9
+ from alpha.providers.models.token import Token
10
+
11
+ # Providers
12
+ from alpha.providers.ldap_provider import LDAPProvider, ADProvider
13
+
14
+ __all__ = [
15
+ "Identity",
16
+ "DEFAULT_LDAP_MAPPINGS",
17
+ "DEFAULT_AD_MAPPINGS",
18
+ "AD_SEARCH_ATTRIBUTES",
19
+ "PasswordCredentials",
20
+ "Token",
21
+ "LDAPProvider",
22
+ "ADProvider",
23
+ ]
@@ -10,14 +10,47 @@ from alpha.infra.connectors.ldap_connector import LDAPConnector
10
10
  from alpha.interfaces.token_factory import TokenFactory
11
11
  from alpha.mixins.jwt_provider import JWTProviderMixin
12
12
  from alpha.providers.models.credentials import PasswordCredentials
13
- from alpha.providers.models.identity import DEFAULT_LDAP_MAPPINGS, Identity
13
+ from alpha.providers.models.identity import (
14
+ DEFAULT_LDAP_MAPPINGS,
15
+ DEFAULT_AD_MAPPINGS,
16
+ AD_SEARCH_ATTRIBUTES,
17
+ Identity,
18
+ )
14
19
  from alpha import exceptions
15
20
 
16
21
 
17
22
  class LDAPProvider(JWTProviderMixin):
18
- """LDAP Identity Provider"""
23
+ """LDAP Identity Provider
24
+
25
+ Parameters
26
+ ----------
27
+ connector
28
+ Connector to use for LDAP operations
29
+ search_filter_key, optional
30
+ Key to use for LDAP search filter, by default "uid"
31
+ search_base, optional
32
+ Base DN for LDAP search, by default "cn=users,dc=example,dc=com"
33
+ search_attributes, optional
34
+ Attributes to retrieve during LDAP search, by default
35
+ [ALL_ATTRIBUTES]
36
+ identity_mappings, optional
37
+ Mappings from LDAP attributes to Identity fields, by default
38
+ DEFAULT_LDAP_MAPPINGS
39
+ populate_groups, optional
40
+ Whether to populate groups in the Identity, by default True
41
+ populate_permissions, optional
42
+ Whether to populate permissions in the Identity, by default False
43
+ populate_claims, optional
44
+ Whether to populate claims in the Identity, by default True
45
+ auto_connect, optional
46
+ Whether to automatically connect using the connector, by default
47
+ True
48
+ change_password_supported, optional
49
+ Whether the provider supports changing passwords, by default False
50
+ """
19
51
 
20
52
  protocol = "ldap"
53
+ _token_factory: TokenFactory | None = None
21
54
 
22
55
  def __init__(
23
56
  self,
@@ -33,34 +66,7 @@ class LDAPProvider(JWTProviderMixin):
33
66
  auto_connect: bool = True,
34
67
  change_password_supported: bool = False,
35
68
  ) -> None:
36
- """_summary_
37
-
38
- Parameters
39
- ----------
40
- connector
41
- Connector to use for LDAP operations
42
- search_filter_key, optional
43
- Key to use for LDAP search filter, by default "uid"
44
- search_base, optional
45
- Base DN for LDAP search, by default "cn=users,dc=example,dc=com"
46
- search_attributes, optional
47
- Attributes to retrieve during LDAP search, by default
48
- [ALL_ATTRIBUTES]
49
- identity_mappings, optional
50
- Mappings from LDAP attributes to Identity fields, by default
51
- DEFAULT_LDAP_MAPPINGS
52
- populate_groups, optional
53
- Whether to populate groups in the Identity, by default True
54
- populate_permissions, optional
55
- Whether to populate permissions in the Identity, by default False
56
- populate_claims, optional
57
- Whether to populate claims in the Identity, by default True
58
- auto_connect, optional
59
- Whether to automatically connect using the connector, by default
60
- True
61
- change_password_supported, optional
62
- Whether the provider supports changing passwords, by default False
63
- """
69
+ """Initialize LDAPProvider"""
64
70
  self._connector = connector
65
71
  self._token_factory = token_factory
66
72
  self._search_filter_key = search_filter_key
@@ -252,3 +258,73 @@ class LDAPProvider(JWTProviderMixin):
252
258
  populate_permissions=self._populate_permissions,
253
259
  )
254
260
  return identity
261
+
262
+
263
+ class ADProvider(LDAPProvider):
264
+ """Active Directory Identity Provider
265
+
266
+ Inherits from LDAPProvider with default settings for Active Directory.
267
+
268
+ Parameters
269
+ ----------
270
+ connector
271
+ Connector to use for LDAP operations.
272
+ token_factory, optional
273
+ Factory used to create tokens, by default ``None``.
274
+ search_filter_key, optional
275
+ Key to use for Active Directory search filter, by default
276
+ ``"sAMAccountName"``.
277
+ search_base, optional
278
+ Base distinguished name (DN) for Active Directory searches, by default
279
+ ``"CN=users,DC=example,DC=com"``.
280
+ search_attributes, optional
281
+ Attributes to retrieve during Active Directory searches, by default
282
+ ``AD_SEARCH_ATTRIBUTES``.
283
+ identity_mappings, optional
284
+ Mapping of Active Directory attributes to :class:`Identity` fields, by
285
+ default ``DEFAULT_AD_MAPPINGS``.
286
+ populate_groups, optional
287
+ Whether to populate group memberships on the :class:`Identity`, by
288
+ default ``True``.
289
+ populate_permissions, optional
290
+ Whether to populate permissions on the :class:`Identity`, by default
291
+ ``False``.
292
+ populate_claims, optional
293
+ Whether to populate claims on the :class:`Identity`, by default
294
+ ``True``.
295
+ auto_connect, optional
296
+ Whether to automatically open the LDAP connection on first use, by
297
+ default ``True``.
298
+ change_password_supported, optional
299
+ Whether this provider supports changing passwords, by default
300
+ ``False``.
301
+ """
302
+
303
+ def __init__(
304
+ self,
305
+ connector: LDAPConnector,
306
+ token_factory: TokenFactory | None = None,
307
+ search_filter_key: str = "sAMAccountName",
308
+ search_base: str = "CN=users,DC=example,DC=com",
309
+ search_attributes: list[str] = AD_SEARCH_ATTRIBUTES,
310
+ identity_mappings: dict[str, str] = DEFAULT_AD_MAPPINGS,
311
+ populate_groups: bool = True,
312
+ populate_permissions: bool = False,
313
+ populate_claims: bool = True,
314
+ auto_connect: bool = True,
315
+ change_password_supported: bool = False,
316
+ ) -> None:
317
+ """Initialize ADProvider"""
318
+ super().__init__(
319
+ connector=connector,
320
+ token_factory=token_factory,
321
+ search_filter_key=search_filter_key,
322
+ search_base=search_base,
323
+ search_attributes=search_attributes,
324
+ identity_mappings=identity_mappings,
325
+ populate_groups=populate_groups,
326
+ populate_permissions=populate_permissions,
327
+ populate_claims=populate_claims,
328
+ auto_connect=auto_connect,
329
+ change_password_supported=change_password_supported,
330
+ )
@@ -0,0 +1,17 @@
1
+ from alpha.providers.models.identity import (
2
+ Identity,
3
+ DEFAULT_LDAP_MAPPINGS,
4
+ DEFAULT_AD_MAPPINGS,
5
+ AD_SEARCH_ATTRIBUTES,
6
+ )
7
+ from alpha.providers.models.credentials import PasswordCredentials
8
+ from alpha.providers.models.token import Token
9
+
10
+ __all__ = [
11
+ "Identity",
12
+ "DEFAULT_LDAP_MAPPINGS",
13
+ "DEFAULT_AD_MAPPINGS",
14
+ "AD_SEARCH_ATTRIBUTES",
15
+ "PasswordCredentials",
16
+ "Token",
17
+ ]
@@ -26,6 +26,46 @@ DEFAULT_AD_MAPPINGS = {
26
26
  "permissions": "permissions",
27
27
  }
28
28
 
29
+ AD_SEARCH_ATTRIBUTES = [
30
+ 'cn',
31
+ 'generationQualifier',
32
+ 'name',
33
+ 'postalAddress',
34
+ 'lastLogonTimestamp',
35
+ 'mobile',
36
+ 'postalCode',
37
+ 'countryCode',
38
+ 'company',
39
+ 'displayName',
40
+ 'o',
41
+ 'st',
42
+ 'ou',
43
+ 'givenName',
44
+ 'msExchUserCulture',
45
+ 'l',
46
+ 'initials',
47
+ 'msTSLicenseVersion',
48
+ 'memberOf',
49
+ 'whenChanged',
50
+ 'mailNickname',
51
+ 'sn',
52
+ 'street',
53
+ 'accountExpires',
54
+ 'uSNChanged',
55
+ 'distinguishedName',
56
+ 'whenCreated',
57
+ 'sAMAccountName',
58
+ 'c',
59
+ 'employeeID',
60
+ 'streetAddress',
61
+ 'description',
62
+ 'mail',
63
+ 'title',
64
+ 'department',
65
+ 'co',
66
+ 'personalTitle',
67
+ ]
68
+
29
69
 
30
70
  @dataclass
31
71
  class Identity:
@@ -199,8 +239,10 @@ class Identity:
199
239
  User object to update from.
200
240
  """
201
241
  self.username = user.username
202
- self.email = user.email
203
- self.display_name = user.display_name
242
+ if not self.email:
243
+ self.email = user.email
244
+ if not self.display_name:
245
+ self.display_name = user.display_name
204
246
  for permission in user.permissions or []:
205
247
  if permission not in self.permissions:
206
248
  self.permissions.append(permission) # type: ignore
@@ -0,0 +1,7 @@
1
+ from alpha.repositories.models.repository_model import RepositoryModel
2
+ from alpha.repositories.sql_alchemy_repository import SqlAlchemyRepository
3
+
4
+ __all__ = [
5
+ "RepositoryModel",
6
+ "SqlAlchemyRepository",
7
+ ]
@@ -0,0 +1,5 @@
1
+ from alpha.repositories.models.repository_model import RepositoryModel
2
+
3
+ __all__ = [
4
+ "RepositoryModel",
5
+ ]
@@ -0,0 +1,5 @@
1
+ from alpha.services.authentication_service import AuthenticationService
2
+
3
+ __all__ = [
4
+ "AuthenticationService",
5
+ ]
@@ -11,37 +11,40 @@ from alpha import exceptions
11
11
 
12
12
 
13
13
  class AuthenticationService:
14
- """Service for handling authentication operations."""
14
+ """This class is responsible for handling authentication operations in an
15
+ application. It provides methods for user authentication, token, issuance,
16
+ token validation, password change, pretending to login as another user,
17
+ and merging user data with identity data.
18
+
19
+ Parameters
20
+ ----------
21
+ identity_provider
22
+ Identity provider to use for authentication.
23
+ identity_id_attribute, optional
24
+ Attribute name in the identity to use as the unique identifier, by
25
+ default "subject"
26
+ merge_with_database_users, optional
27
+ Whether to merge identity data with database user data, by default
28
+ False
29
+ user_id_attribute, optional
30
+ Attribute name in the user database to use as the unique
31
+ identifier, by default "username"
32
+ uow, optional
33
+ UnitOfWork instance for database operations, by default None
34
+ repository_name, optional
35
+ Name of the user repository in the UnitOfWork, by default "users"
36
+ """
15
37
 
16
38
  def __init__(
17
39
  self,
18
40
  identity_provider: IdentityProvider,
19
41
  identity_id_attribute: str = "subject",
20
42
  merge_with_database_users: bool = False,
21
- user_id_attribute: str = "id",
43
+ user_id_attribute: str = "username",
22
44
  uow: UnitOfWork | None = None,
23
45
  repository_name: str = "users",
24
46
  ) -> None:
25
- """Initialize the AuthenticationService.
26
-
27
- Parameters
28
- ----------
29
- identity_provider
30
- Identity provider to use for authentication.
31
- identity_id_attribute, optional
32
- Attribute name in the identity to use as the unique identifier, by
33
- default "subject"
34
- merge_with_database_users, optional
35
- Whether to merge identity data with database user data, by default
36
- False
37
- user_id_attribute, optional
38
- Attribute name in the user database to use as the unique
39
- identifier, by default "id"
40
- uow, optional
41
- UnitOfWork instance for database operations, by default None
42
- repository_name, optional
43
- Name of the user repository in the UnitOfWork, by default "users"
44
- """
47
+ """Initialize the AuthenticationService."""
45
48
  self._identity_provider = identity_provider
46
49
  self._identity_id_attribute = identity_id_attribute
47
50
  self._merge_with_database_users = merge_with_database_users
@@ -163,7 +166,7 @@ class AuthenticationService:
163
166
  self,
164
167
  identity: Identity,
165
168
  ) -> Identity:
166
- """Merge User data into a Identity instance.
169
+ """Merge User data into an Identity instance.
167
170
 
168
171
  Parameters
169
172
  ----------
@@ -184,11 +187,13 @@ class AuthenticationService:
184
187
  self.uow, self._repository_name
185
188
  )
186
189
  user = users.get_by_id(
187
- identity.subject, id_attribute=self._user_id_attribute
190
+ value=identity.subject, attr=self._user_id_attribute
188
191
  )
189
- if not user:
192
+ if user:
193
+ identity.update_from_user(user)
194
+ else:
195
+ # Create new user from identity if not found in database
190
196
  user = User.from_identity(identity)
191
197
  users.add(user)
192
- identity.update_from_user(user)
193
- self.uow.commit()
198
+ self.uow.commit()
194
199
  return identity