nlbone 0.7.2__tar.gz → 0.7.3__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 (115) hide show
  1. {nlbone-0.7.2 → nlbone-0.7.3}/PKG-INFO +1 -1
  2. {nlbone-0.7.2 → nlbone-0.7.3}/pyproject.toml +1 -1
  3. nlbone-0.7.3/src/nlbone/adapters/auth/auth_service.py +25 -0
  4. nlbone-0.7.3/src/nlbone/adapters/db/postgres/types.py +21 -0
  5. nlbone-0.7.3/src/nlbone/adapters/snowflake.py +70 -0
  6. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/config/settings.py +5 -0
  7. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/core/domain/base.py +37 -1
  8. nlbone-0.7.3/src/nlbone/interfaces/api/middleware/authentication.py +80 -0
  9. nlbone-0.7.2/src/nlbone/interfaces/api/middleware/authentication.py +0 -59
  10. {nlbone-0.7.2 → nlbone-0.7.3}/.gitignore +0 -0
  11. {nlbone-0.7.2 → nlbone-0.7.3}/LICENSE +0 -0
  12. {nlbone-0.7.2 → nlbone-0.7.3}/README.md +0 -0
  13. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/__init__.py +0 -0
  14. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/__init__.py +0 -0
  15. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/auth/__init__.py +0 -0
  16. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/auth/keycloak.py +0 -0
  17. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/auth/token_provider.py +0 -0
  18. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/cache/__init__.py +0 -0
  19. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/cache/async_redis.py +0 -0
  20. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/cache/memory.py +0 -0
  21. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/cache/pubsub_listener.py +0 -0
  22. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/cache/redis.py +0 -0
  23. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/db/__init__.py +0 -0
  24. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/db/postgres/__init__.py +0 -0
  25. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/db/postgres/audit.py +0 -0
  26. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/db/postgres/base.py +0 -0
  27. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/db/postgres/engine.py +0 -0
  28. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/db/postgres/query_builder.py +0 -0
  29. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/db/postgres/repository.py +0 -0
  30. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/db/postgres/schema.py +0 -0
  31. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/db/postgres/uow.py +0 -0
  32. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/db/redis/__init__.py +0 -0
  33. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/db/redis/client.py +0 -0
  34. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/http_clients/__init__.py +0 -0
  35. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/http_clients/pricing/__init__.py +0 -0
  36. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/http_clients/pricing/pricing_service.py +0 -0
  37. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/http_clients/uploadchi/__init__.py +0 -0
  38. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/http_clients/uploadchi/uploadchi.py +0 -0
  39. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/http_clients/uploadchi/uploadchi_async.py +0 -0
  40. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/messaging/__init__.py +0 -0
  41. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/messaging/event_bus.py +0 -0
  42. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/messaging/rabbitmq.py +0 -0
  43. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/outbox/__init__.py +0 -0
  44. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/outbox/outbox_consumer.py +0 -0
  45. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/outbox/outbox_repo.py +0 -0
  46. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/percolation/__init__.py +0 -0
  47. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/percolation/connection.py +0 -0
  48. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/repositories/__init__.py +0 -0
  49. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/ticketing/__init__.py +0 -0
  50. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/adapters/ticketing/client.py +0 -0
  51. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/config/__init__.py +0 -0
  52. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/config/logging.py +0 -0
  53. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/container.py +0 -0
  54. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/core/__init__.py +0 -0
  55. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/core/application/__init__.py +0 -0
  56. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/core/application/base_worker.py +0 -0
  57. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/core/application/bus.py +0 -0
  58. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/core/application/di.py +0 -0
  59. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/core/application/registry.py +0 -0
  60. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/core/application/services/__init__.py +0 -0
  61. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/core/application/use_case.py +0 -0
  62. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/core/domain/__init__.py +0 -0
  63. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/core/domain/models.py +0 -0
  64. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/core/ports/__init__.py +0 -0
  65. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/core/ports/auth.py +0 -0
  66. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/core/ports/cache.py +0 -0
  67. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/core/ports/event_bus.py +0 -0
  68. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/core/ports/files.py +0 -0
  69. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/core/ports/outbox.py +0 -0
  70. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/core/ports/repository.py +0 -0
  71. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/core/ports/uow.py +0 -0
  72. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/__init__.py +0 -0
  73. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/__init__.py +0 -0
  74. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/additional_filed/__init__.py +0 -0
  75. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/additional_filed/assembler.py +0 -0
  76. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/additional_filed/default_field_rules/__init__.py +0 -0
  77. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/additional_filed/default_field_rules/image_field_rules.py +0 -0
  78. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/additional_filed/field_registry.py +0 -0
  79. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/additional_filed/resolver.py +0 -0
  80. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/dependencies/__init__.py +0 -0
  81. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/dependencies/async_auth.py +0 -0
  82. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/dependencies/auth.py +0 -0
  83. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/dependencies/db.py +0 -0
  84. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/dependencies/uow.py +0 -0
  85. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/exception_handlers.py +0 -0
  86. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/exceptions.py +0 -0
  87. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/middleware/__init__.py +0 -0
  88. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/middleware/access_log.py +0 -0
  89. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/middleware/add_request_context.py +0 -0
  90. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/pagination/__init__.py +0 -0
  91. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/pagination/offset_base.py +0 -0
  92. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/routers.py +0 -0
  93. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/schema/__init__.py +0 -0
  94. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/schema/adaptive_schema.py +0 -0
  95. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/schema/base_response_model.py +0 -0
  96. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/api/schemas.py +0 -0
  97. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/cli/__init__.py +0 -0
  98. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/cli/crypto.py +0 -0
  99. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/cli/init_db.py +0 -0
  100. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/cli/main.py +0 -0
  101. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/cli/ticket.py +0 -0
  102. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/jobs/__init__.py +0 -0
  103. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/jobs/dispatch_outbox.py +0 -0
  104. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/interfaces/jobs/sync_tokens.py +0 -0
  105. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/types.py +0 -0
  106. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/utils/__init__.py +0 -0
  107. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/utils/cache.py +0 -0
  108. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/utils/cache_keys.py +0 -0
  109. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/utils/cache_registry.py +0 -0
  110. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/utils/context.py +0 -0
  111. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/utils/crypto.py +0 -0
  112. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/utils/http.py +0 -0
  113. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/utils/normalize_mobile.py +0 -0
  114. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/utils/redactor.py +0 -0
  115. {nlbone-0.7.2 → nlbone-0.7.3}/src/nlbone/utils/time.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nlbone
3
- Version: 0.7.2
3
+ Version: 0.7.3
4
4
  Summary: Backbone package for interfaces and infrastructure in Python projects
5
5
  Author-email: Amir Hosein Kahkbazzadeh <a.khakbazzadeh@gmail.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "nlbone"
7
- version = "0.7.2"
7
+ version = "0.7.3"
8
8
  description = "Backbone package for interfaces and infrastructure in Python projects"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -0,0 +1,25 @@
1
+ import requests
2
+
3
+ from nlbone.config.settings import get_settings
4
+ from nlbone.core.ports.auth import AuthService as BaseAuthService
5
+ from nlbone.utils.http import normalize_https_base
6
+
7
+
8
+ class AuthService(BaseAuthService):
9
+ def __init__(self):
10
+ s = get_settings()
11
+ self._base_url = normalize_https_base(s.AUTH_SERVICE_URL.unicode_string())
12
+ self._timeout = float(s.HTTP_TIMEOUT_SECONDS)
13
+ self._client = requests.session()
14
+
15
+ def has_access(self, token: str, permissions: list[str]) -> bool: ...
16
+ def verify_token(self, token: str) -> dict | None:
17
+ url = f"{self._base_url}/introspect"
18
+ result = self._client.post(url, data={
19
+ "token": token
20
+ })
21
+ return result.json()
22
+ def get_client_token(self) -> dict | None: ...
23
+ def is_client_token(self, token: str, allowed_clients: set[str] | None = None) -> bool: ...
24
+ def client_has_access(self, token: str, perms: list[str], allowed_clients: set[str] | None = None) -> bool: ...
25
+ def get_permissions(self, token: str) -> list[str]: ...
@@ -0,0 +1,21 @@
1
+ from sqlalchemy.types import TypeDecorator, BigInteger
2
+
3
+ class BaseIntegerIdType(TypeDecorator):
4
+ """Maps BaseId subclasses <-> BIGINT transparently (Infrastructure-only)."""
5
+ impl = BigInteger
6
+ cache_ok = True
7
+
8
+ def __init__(self, id_cls):
9
+ super().__init__()
10
+ self.id_cls = id_cls
11
+
12
+ def process_bind_param(self, value, dialect):
13
+ # Python -> DB
14
+ if value is None:
15
+ return None
16
+ return int(value)
17
+
18
+ def process_result_value(self, value, dialect):
19
+ if value is None:
20
+ return None
21
+ return self.id_cls(int(value))
@@ -0,0 +1,70 @@
1
+ import threading
2
+ import time
3
+ from datetime import datetime, timezone
4
+
5
+ from nlbone.config.settings import get_settings
6
+
7
+
8
+ class Snowflake:
9
+ WORKER_ID_BITS = 5
10
+ DATACENTER_ID_BITS = 5
11
+ SEQUENCE_BITS = 12
12
+
13
+ MAX_WORKER_ID = (1 << WORKER_ID_BITS) - 1 # 31
14
+ MAX_DATACENTER_ID = (1 << DATACENTER_ID_BITS) - 1 # 31
15
+ SEQUENCE_MASK = (1 << SEQUENCE_BITS) - 1 # 4095
16
+
17
+ WORKER_ID_SHIFT = SEQUENCE_BITS
18
+ DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS
19
+ TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATACENTER_ID_BITS
20
+
21
+ EPOCH = int(datetime(2020, 1, 1, tzinfo=timezone.utc).timestamp() * 1000)
22
+
23
+ def __init__(self, datacenter_id: int, worker_id: int):
24
+ if not (0 <= worker_id <= self.MAX_WORKER_ID):
25
+ raise ValueError(f"worker_id must be 0..{self.MAX_WORKER_ID}")
26
+ if not (0 <= datacenter_id <= self.MAX_DATACENTER_ID):
27
+ raise ValueError(f"datacenter_id must be 0..{self.MAX_DATACENTER_ID}")
28
+
29
+ self.datacenter_id = datacenter_id
30
+ self.worker_id = worker_id
31
+ self.sequence = 0
32
+ self.last_ts = -1
33
+ self._lock = threading.Lock()
34
+
35
+ @staticmethod
36
+ def _timestamp_ms() -> int:
37
+ return int(time.time() * 1000)
38
+
39
+ def _wait_next_ms(self, last_ts: int) -> int:
40
+ ts = self._timestamp_ms()
41
+ while ts <= last_ts:
42
+ ts = self._timestamp_ms()
43
+ return ts
44
+
45
+ def next_id(self) -> int:
46
+ with self._lock:
47
+ ts = self._timestamp_ms()
48
+
49
+ if ts < self.last_ts:
50
+ ts = self._wait_next_ms(self.last_ts)
51
+
52
+ if ts == self.last_ts:
53
+ self.sequence = (self.sequence + 1) & self.SEQUENCE_MASK
54
+ if self.sequence == 0:
55
+ ts = self._wait_next_ms(self.last_ts)
56
+ else:
57
+ self.sequence = 0
58
+
59
+ self.last_ts = ts
60
+
61
+ id64 = ((ts - self.EPOCH) << self.TIMESTAMP_SHIFT) | \
62
+ (self.datacenter_id << self.DATACENTER_ID_SHIFT) | \
63
+ (self.worker_id << self.WORKER_ID_SHIFT) | \
64
+ self.sequence
65
+ return id64
66
+
67
+ setting = get_settings()
68
+ _DC_ID = int(setting.SNOWFLAKE_DATACENTER_ID)
69
+ _WORKER_ID = int(setting.SNOWFLAKE_WORKER_ID)
70
+ SNOWFLAKE = Snowflake(datacenter_id=_DC_ID, worker_id=_WORKER_ID)
@@ -43,6 +43,9 @@ class Settings(BaseSettings):
43
43
  LOG_LEVEL: Literal["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"] = Field(default="INFO")
44
44
  LOG_JSON: bool = Field(default=True)
45
45
 
46
+ SNOWFLAKE_WORKER_ID : int = Field(default=1)
47
+ SNOWFLAKE_DATACENTER_ID: int = Field(default=1)
48
+
46
49
  AUDIT_DEFAULT_ENABLE: bool = False
47
50
 
48
51
  # ---------------------------
@@ -58,6 +61,8 @@ class Settings(BaseSettings):
58
61
  KEYCLOAK_CLIENT_ID: str = Field(default="nlbone")
59
62
  KEYCLOAK_CLIENT_SECRET: SecretStr = Field(default=SecretStr("dev-secret"))
60
63
 
64
+ AUTH_SERVICE_URL: AnyHttpUrl = Field(default="https://auth.numberland.ir")
65
+
61
66
  # ---------------------------
62
67
  # Database
63
68
  # ---------------------------
@@ -3,11 +3,13 @@ from __future__ import annotations
3
3
  from dataclasses import dataclass
4
4
  from datetime import datetime, timezone
5
5
  from enum import Enum
6
- from typing import Any, Generic, List, TypeVar
6
+ from typing import Any, Generic, List, TypeVar, Callable, ClassVar
7
7
  from uuid import uuid4
8
8
 
9
9
  from pydantic import BaseModel
10
10
 
11
+ from nlbone.adapters.snowflake import SNOWFLAKE
12
+
11
13
  TId = TypeVar("TId")
12
14
 
13
15
 
@@ -70,3 +72,37 @@ class AggregateRoot(Entity[TId]):
70
72
 
71
73
  class BaseEnum(Enum):
72
74
  pass
75
+
76
+
77
+
78
+ ID = TypeVar("ID", bound="BaseId")
79
+
80
+ @dataclass(frozen=True)
81
+ class BaseId(ValueObject):
82
+ value: int
83
+
84
+ _generator: ClassVar[Callable[[], int]] = lambda: SNOWFLAKE.next_id()
85
+
86
+ def __post_init__(self):
87
+ if not isinstance(self.value, int):
88
+ raise TypeError("BaseId.value must be int")
89
+ if self.value <= 0:
90
+ raise ValueError("BaseId must be a positive integer")
91
+
92
+ def __int__(self) -> int:
93
+ return self.value
94
+
95
+ def __str__(self) -> str:
96
+ return str(self.value)
97
+
98
+ @classmethod
99
+ def set_generator(cls, gen: Callable[[], int]) -> None:
100
+ cls._generator = gen
101
+
102
+ @classmethod
103
+ def new(cls: type[ID]) -> ID:
104
+ return cls(cls._generator())
105
+
106
+ @classmethod
107
+ def from_int(cls: type[ID], v: int) -> ID:
108
+ return cls(v)
@@ -0,0 +1,80 @@
1
+ from typing import Callable, Optional, Union
2
+
3
+ from fastapi import Request
4
+ from starlette.middleware.base import BaseHTTPMiddleware
5
+
6
+ from nlbone.adapters.auth.auth_service import AuthService
7
+
8
+ try:
9
+ from dependency_injector import providers
10
+
11
+ ProviderType = providers.Provider # type: ignore
12
+ except Exception:
13
+ ProviderType = object
14
+
15
+ from nlbone.core.ports.auth import AuthService as BaseAuthService
16
+
17
+
18
+ def _to_factory(auth: Union[BaseAuthService, Callable[[], BaseAuthService], ProviderType]):
19
+ try:
20
+ from dependency_injector import providers as _p # type: ignore
21
+
22
+ if isinstance(auth, _p.Provider):
23
+ return auth
24
+ except Exception:
25
+ pass
26
+ if callable(auth) and not hasattr(auth, "verify_token"):
27
+ return auth
28
+ return lambda: auth
29
+
30
+
31
+ def authenticate_admin_user(request, auth_service):
32
+ token: Optional[str] = None
33
+ authz = request.headers.get("Authorization")
34
+ if authz:
35
+ try:
36
+ scheme, token = authz.split(" ", 1)
37
+ if scheme.lower() != "bearer":
38
+ token = None
39
+ except ValueError:
40
+ token = None
41
+
42
+ if token:
43
+ request.state.token = token
44
+ try:
45
+ service: BaseAuthService = auth_service()
46
+ data = service.verify_token(token)
47
+ if data:
48
+ request.state.user_id = data.get("user_id")
49
+ except Exception:
50
+ pass
51
+
52
+ def authenticate_user(request):
53
+ token = request.cookies.get("access_token") or request.cookies.get("j_token")
54
+
55
+ if token:
56
+ request.state.token = token
57
+ try:
58
+ service: BaseAuthService = AuthService()
59
+ data = service.verify_token(token)
60
+ if data:
61
+ request.state.user_id = data.get("sub")
62
+ except Exception:
63
+ pass
64
+
65
+
66
+ class AuthenticationMiddleware(BaseHTTPMiddleware):
67
+ def __init__(self, app, auth: Union[BaseAuthService, Callable[[], BaseAuthService], ProviderType]):
68
+ super().__init__(app)
69
+ self._get_auth = _to_factory(auth)
70
+
71
+ async def dispatch(self, request: Request, call_next):
72
+ request.state.client_id = request.headers.get("X-Client-Id")
73
+ request.state.user_id = None
74
+ request.state.token = None
75
+ if request.cookies.get("access_token"):
76
+ authenticate_user(request)
77
+ elif request.headers.get("Authorization"):
78
+ authenticate_admin_user(request, auth_service=self._get_auth)
79
+
80
+ return await call_next(request)
@@ -1,59 +0,0 @@
1
- from typing import Callable, Optional, Union
2
-
3
- from fastapi import Request
4
- from starlette.middleware.base import BaseHTTPMiddleware
5
-
6
- try:
7
- from dependency_injector import providers
8
-
9
- ProviderType = providers.Provider # type: ignore
10
- except Exception:
11
- ProviderType = object
12
-
13
- from nlbone.core.ports.auth import AuthService
14
-
15
-
16
- def _to_factory(auth: Union[AuthService, Callable[[], AuthService], ProviderType]):
17
- try:
18
- from dependency_injector import providers as _p # type: ignore
19
-
20
- if isinstance(auth, _p.Provider):
21
- return auth
22
- except Exception:
23
- pass
24
- if callable(auth) and not hasattr(auth, "verify_token"):
25
- return auth
26
- return lambda: auth
27
-
28
-
29
- class AuthenticationMiddleware(BaseHTTPMiddleware):
30
- def __init__(self, app, auth: Union[AuthService, Callable[[], AuthService], ProviderType]):
31
- super().__init__(app)
32
- self._get_auth = _to_factory(auth)
33
-
34
- async def dispatch(self, request: Request, call_next):
35
- request.state.client_id = request.headers.get("X-Client-Id")
36
- request.state.user_id = None
37
- request.state.token = None
38
-
39
- token: Optional[str] = None
40
- authz = request.headers.get("Authorization")
41
- if authz:
42
- try:
43
- scheme, token = authz.split(" ", 1)
44
- if scheme.lower() != "bearer":
45
- token = None
46
- except ValueError:
47
- token = None
48
-
49
- if token:
50
- request.state.token = token
51
- try:
52
- service: AuthService = self._get_auth()
53
- data = service.verify_token(token)
54
- if data:
55
- request.state.user_id = data.get("user_id")
56
- except Exception:
57
- pass
58
-
59
- return await call_next(request)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes