nlbone 0.3.0__tar.gz → 0.3.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.
- {nlbone-0.3.0 → nlbone-0.3.2}/PKG-INFO +1 -1
- {nlbone-0.3.0 → nlbone-0.3.2}/pyproject.toml +1 -1
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/adapters/auth/keycloak.py +12 -4
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/config/settings.py +8 -3
- nlbone-0.3.2/src/nlbone/interfaces/api/dependencies/__init__.py +2 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/interfaces/api/dependencies/auth.py +17 -6
- nlbone-0.3.0/src/nlbone/interfaces/api/dependencies/__init__.py +0 -1
- {nlbone-0.3.0 → nlbone-0.3.2}/.gitignore +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/LICENSE +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/README.md +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/adapters/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/adapters/auth/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/adapters/db/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/adapters/db/memory.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/adapters/db/postgres.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/adapters/db/sqlalchemy/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/adapters/db/sqlalchemy/base.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/adapters/db/sqlalchemy/engine.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/adapters/db/sqlalchemy/query_builder.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/adapters/db/sqlalchemy/schema.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/adapters/http_clients/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/adapters/http_clients/email_gateway.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/adapters/http_clients/uploadchi.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/adapters/http_clients/uploadchi_async.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/adapters/messaging/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/adapters/messaging/redis.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/config/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/config/logging.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/container.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/core/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/core/application/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/core/application/services/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/core/application/services.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/core/application/use_cases/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/core/application/use_cases/register_user.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/core/domain/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/core/domain/events.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/core/domain/models.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/core/ports/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/core/ports/auth.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/core/ports/files.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/core/ports/messaging.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/core/ports/repo.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/interfaces/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/interfaces/api/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/interfaces/api/dependencies/db.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/interfaces/api/exception_handlers.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/interfaces/api/exceptions.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/interfaces/api/middleware/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/interfaces/api/middleware/access_log.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/interfaces/api/middleware/add_request_context.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/interfaces/api/middleware/authentication.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/interfaces/api/pagination/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/interfaces/api/pagination/offset_base.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/interfaces/api/routers.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/interfaces/api/schemas.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/interfaces/cli/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/interfaces/cli/init_db.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/interfaces/cli/main.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/interfaces/jobs/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/interfaces/jobs/sync_tokens.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/types.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/utils/__init__.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/utils/context.py +0 -0
- {nlbone-0.3.0 → nlbone-0.3.2}/src/nlbone/utils/time.py +0 -0
|
@@ -43,15 +43,23 @@ class KeycloakAuthService(AuthService):
|
|
|
43
43
|
print(f"Failed to get client token: {e}")
|
|
44
44
|
return None
|
|
45
45
|
|
|
46
|
-
def
|
|
46
|
+
def get_client_id(self, token: str):
|
|
47
47
|
data = self.verify_token(token)
|
|
48
48
|
if not data:
|
|
49
|
-
return
|
|
49
|
+
return None
|
|
50
50
|
|
|
51
|
-
is_service_account = bool(data.get("username").startswith(
|
|
51
|
+
is_service_account = bool(data.get("username").startswith("service-account-"))
|
|
52
52
|
client_id = data.get("client_id")
|
|
53
53
|
|
|
54
54
|
if not is_service_account or not client_id:
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
return client_id
|
|
58
|
+
|
|
59
|
+
def is_client_token(self, token: str, allowed_clients: set[str] | None = None) -> bool:
|
|
60
|
+
client_id = self.get_client_id(token)
|
|
61
|
+
|
|
62
|
+
if not client_id:
|
|
55
63
|
return False
|
|
56
64
|
|
|
57
65
|
if allowed_clients is not None and client_id not in allowed_clients:
|
|
@@ -62,4 +70,4 @@ class KeycloakAuthService(AuthService):
|
|
|
62
70
|
def client_has_access(self, token: str, permissions: list[str], allowed_clients: set[str] | None = None) -> bool:
|
|
63
71
|
if not self.is_client_token(token, allowed_clients):
|
|
64
72
|
return False
|
|
65
|
-
return self.has_access(token, permissions)
|
|
73
|
+
return self.has_access(token, permissions)
|
|
@@ -26,6 +26,7 @@ class Settings(BaseSettings):
|
|
|
26
26
|
# ---------------------------
|
|
27
27
|
# App
|
|
28
28
|
# ---------------------------
|
|
29
|
+
PORT: int = 8000
|
|
29
30
|
ENV: Literal["local", "dev", "staging", "prod"] = Field(default="local")
|
|
30
31
|
DEBUG: bool = Field(default=False)
|
|
31
32
|
LOG_LEVEL: Literal["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"] = Field(default="INFO")
|
|
@@ -53,7 +54,8 @@ class Settings(BaseSettings):
|
|
|
53
54
|
# ---------------------------
|
|
54
55
|
# Database
|
|
55
56
|
# ---------------------------
|
|
56
|
-
POSTGRES_DB_DSN: str = Field(default="postgresql+asyncpg://user:pass@localhost:5432/nlbone"
|
|
57
|
+
POSTGRES_DB_DSN: str = Field(default="postgresql+asyncpg://user:pass@localhost:5432/nlbone", validation_alias=AliasChoices("NLBONE_POSTGRES_DB_DSN",
|
|
58
|
+
"POSTGRES_DB_DSN", "DATABASE_URL", "DB_DSN"))
|
|
57
59
|
|
|
58
60
|
# ---------------------------
|
|
59
61
|
# Messaging / Cache
|
|
@@ -76,6 +78,10 @@ class Settings(BaseSettings):
|
|
|
76
78
|
extra="ignore",
|
|
77
79
|
)
|
|
78
80
|
|
|
81
|
+
@classmethod
|
|
82
|
+
def load(cls, env_file: str | None = None) -> "Settings":
|
|
83
|
+
return cls(_env_file=env_file or _guess_env_file())
|
|
84
|
+
|
|
79
85
|
|
|
80
86
|
@lru_cache(maxsize=4)
|
|
81
87
|
def get_settings(env_file: str | None = None) -> Settings:
|
|
@@ -85,5 +91,4 @@ def get_settings(env_file: str | None = None) -> Settings:
|
|
|
85
91
|
from nlbone.config.settings import get_settings
|
|
86
92
|
settings = get_settings()
|
|
87
93
|
"""
|
|
88
|
-
|
|
89
|
-
return Settings(_env_file=env_file)
|
|
94
|
+
return Settings.load(env_file)
|
|
@@ -5,6 +5,20 @@ from nlbone.interfaces.api.exceptions import ForbiddenException, UnauthorizedExc
|
|
|
5
5
|
from nlbone.utils.context import current_request
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
def current_user_id() -> int:
|
|
9
|
+
user_id = current_request().state.user_id
|
|
10
|
+
if user_id is not None:
|
|
11
|
+
return int(user_id)
|
|
12
|
+
raise UnauthorizedException()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def current_client_id() -> str:
|
|
16
|
+
request = current_request()
|
|
17
|
+
if client_id := KeycloakAuthService().get_client_id(request.state.token):
|
|
18
|
+
return str(client_id)
|
|
19
|
+
raise UnauthorizedException()
|
|
20
|
+
|
|
21
|
+
|
|
8
22
|
def client_has_access(*, permissions=None):
|
|
9
23
|
def decorator(func):
|
|
10
24
|
@functools.wraps(func)
|
|
@@ -19,12 +33,10 @@ def client_has_access(*, permissions=None):
|
|
|
19
33
|
return decorator
|
|
20
34
|
|
|
21
35
|
|
|
22
|
-
|
|
23
36
|
def user_authenticated(func):
|
|
24
37
|
@functools.wraps(func)
|
|
25
38
|
async def wrapper(*args, **kwargs):
|
|
26
|
-
|
|
27
|
-
if not request.state.user_id:
|
|
39
|
+
if not current_user_id():
|
|
28
40
|
raise UnauthorizedException()
|
|
29
41
|
return await func(*args, **kwargs)
|
|
30
42
|
|
|
@@ -36,7 +48,7 @@ def has_access(*, permissions=None):
|
|
|
36
48
|
@functools.wraps(func)
|
|
37
49
|
def wrapper(*args, **kwargs):
|
|
38
50
|
request = current_request()
|
|
39
|
-
if not
|
|
51
|
+
if not current_user_id():
|
|
40
52
|
raise UnauthorizedException()
|
|
41
53
|
if not KeycloakAuthService().has_access(request.state.token, permissions=permissions):
|
|
42
54
|
raise ForbiddenException(f"Forbidden {permissions}")
|
|
@@ -44,5 +56,4 @@ def has_access(*, permissions=None):
|
|
|
44
56
|
return func(*args, **kwargs)
|
|
45
57
|
|
|
46
58
|
return wrapper
|
|
47
|
-
return decorator
|
|
48
|
-
|
|
59
|
+
return decorator
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from .db import get_session, get_async_session
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|