simple-module-auth 0.0.38__tar.gz → 0.0.39__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.
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/PKG-INFO +5 -4
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/auth/middleware.py +9 -12
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/auth/state.py +9 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/package.json +1 -1
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/pyproject.toml +6 -4
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/.gitignore +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/LICENSE +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/README.md +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/auth/__init__.py +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/auth/_route_match.py +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/auth/contracts/__init__.py +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/auth/contracts/provider.py +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/auth/contracts/resolver.py +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/auth/contracts/schemas.py +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/auth/contracts/tokens.py +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/auth/deps.py +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/auth/locales/de.json +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/auth/locales/en.json +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/auth/locales/es.json +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/auth/module.py +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/auth/py.typed +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/tests/test_auth_middleware.py +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/tests/test_auth_next_target.py +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/tests/test_auth_parse_bearer.py +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/tests/test_auth_provider_protocol.py +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/tests/test_auth_unknown_paths.py +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/tests/test_deps.py +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/tests/test_module.py +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/tests/test_resolver_registry.py +0 -0
- {simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/tests/test_user_context.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: simple_module_auth
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.39
|
|
4
4
|
Summary: Session-cookie authentication primitives — middleware, login/logout, redirect helpers for simple_module
|
|
5
5
|
Project-URL: Homepage, https://github.com/antosubash/simple_module_python
|
|
6
6
|
Project-URL: Repository, https://github.com/antosubash/simple_module_python
|
|
@@ -21,9 +21,10 @@ Classifier: Topic :: Internet :: WWW/HTTP
|
|
|
21
21
|
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
22
22
|
Classifier: Typing :: Typed
|
|
23
23
|
Requires-Python: >=3.12
|
|
24
|
-
Requires-Dist: itsdangerous
|
|
25
|
-
Requires-Dist: simple-module-core==0.0.
|
|
26
|
-
Requires-Dist: simple-module-db==0.0.
|
|
24
|
+
Requires-Dist: itsdangerous<3,>=2.2
|
|
25
|
+
Requires-Dist: simple-module-core==0.0.39
|
|
26
|
+
Requires-Dist: simple-module-db==0.0.39
|
|
27
|
+
Requires-Dist: simple-module-hosting==0.0.39
|
|
27
28
|
Description-Content-Type: text/markdown
|
|
28
29
|
|
|
29
30
|
# simple_module_auth
|
|
@@ -10,9 +10,10 @@ from __future__ import annotations
|
|
|
10
10
|
|
|
11
11
|
import logging
|
|
12
12
|
|
|
13
|
-
from simple_module_core.
|
|
13
|
+
from simple_module_core.app_state import get_openapi_url
|
|
14
14
|
from simple_module_core.redirect_safety import SESSION_NEXT_KEY, safe_next_or_none
|
|
15
15
|
from simple_module_db.listeners import current_user_id
|
|
16
|
+
from simple_module_hosting.public_access import is_public as route_is_public
|
|
16
17
|
from starlette.requests import Request
|
|
17
18
|
from starlette.responses import JSONResponse, RedirectResponse
|
|
18
19
|
from starlette.types import ASGIApp, Receive, Scope, Send
|
|
@@ -87,19 +88,10 @@ class AuthMiddleware:
|
|
|
87
88
|
any(path.startswith(p) for p in _FRAMEWORK_PUBLIC_PREFIXES)
|
|
88
89
|
or path in _FRAMEWORK_PUBLIC_EXACT
|
|
89
90
|
# Anonymous exactly when the host serves it (dev, or openapi_public).
|
|
90
|
-
or path ==
|
|
91
|
+
or path == get_openapi_url(scope["app"])
|
|
91
92
|
)
|
|
92
|
-
# Module-contributed public routes (register_public_routes hook). Method
|
|
93
|
-
# -aware, so a GET read route can be exempted without opening sibling
|
|
94
|
-
# POST/PATCH mutations under the same prefix.
|
|
95
93
|
if not is_public:
|
|
96
|
-
|
|
97
|
-
is_public = public_routes is not None and public_routes.matches(method, path)
|
|
98
|
-
# Deprecated provider-declared paths (prefix-only, method-agnostic); honoured
|
|
99
|
-
# until 0.1.0 for third-party providers. users/keycloak use the registry.
|
|
100
|
-
if not is_public:
|
|
101
|
-
prefix_paths, exact_paths = legacy_provider_public_paths(provider)
|
|
102
|
-
is_public = any(path.startswith(p) for p in prefix_paths) or path in exact_paths
|
|
94
|
+
is_public = route_is_public(scope["app"], method, path)
|
|
103
95
|
|
|
104
96
|
# Contract with the host's RateLimitMiddleware (plain scope key, no import
|
|
105
97
|
# between them): whether *this* middleware treats the request as anonymous-
|
|
@@ -159,6 +151,11 @@ class AuthMiddleware:
|
|
|
159
151
|
|
|
160
152
|
if user_ctx is not None:
|
|
161
153
|
request.state.user = user_ctx
|
|
154
|
+
for guard in auth_state.principal_guards:
|
|
155
|
+
refusal = guard(request)
|
|
156
|
+
if refusal is not None:
|
|
157
|
+
await refusal(scope, receive, send)
|
|
158
|
+
return
|
|
162
159
|
token = current_user_id.set(user_ctx.id)
|
|
163
160
|
try:
|
|
164
161
|
await self.app(scope, receive, send)
|
|
@@ -9,12 +9,16 @@ principal-resolver registry. Apps register additional resolvers from their
|
|
|
9
9
|
|
|
10
10
|
from __future__ import annotations
|
|
11
11
|
|
|
12
|
+
from collections.abc import Callable
|
|
12
13
|
from dataclasses import dataclass, field
|
|
13
14
|
from typing import TYPE_CHECKING
|
|
14
15
|
|
|
15
16
|
from auth.contracts.resolver import PrincipalResolver
|
|
16
17
|
|
|
17
18
|
if TYPE_CHECKING:
|
|
19
|
+
from starlette.requests import Request
|
|
20
|
+
from starlette.responses import Response
|
|
21
|
+
|
|
18
22
|
from auth.contracts.provider import AuthProvider
|
|
19
23
|
|
|
20
24
|
|
|
@@ -24,6 +28,11 @@ class AuthState:
|
|
|
24
28
|
|
|
25
29
|
auth_provider: AuthProvider | None = None
|
|
26
30
|
principal_resolvers: list[PrincipalResolver] = field(default_factory=list)
|
|
31
|
+
# Run once a principal has resolved (any credential source), before downstream
|
|
32
|
+
# middleware; anonymous requests never reach them.
|
|
33
|
+
# A guard is a sync callable returning a refusal response or None to continue.
|
|
34
|
+
# An exception propagates (a 500), so a broken guard fails closed, never open.
|
|
35
|
+
principal_guards: list[Callable[[Request], Response | None]] = field(default_factory=list)
|
|
27
36
|
|
|
28
37
|
|
|
29
38
|
__all__ = ["AuthState"]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "simple_module_auth"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.39"
|
|
4
4
|
description = "Session-cookie authentication primitives — middleware, login/logout, redirect helpers for simple_module"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
@@ -21,9 +21,10 @@ classifiers = [
|
|
|
21
21
|
"Typing :: Typed",
|
|
22
22
|
]
|
|
23
23
|
dependencies = [
|
|
24
|
-
"itsdangerous>=2.2",
|
|
25
|
-
"simple_module_core==0.0.
|
|
26
|
-
"simple_module_db==0.0.
|
|
24
|
+
"itsdangerous>=2.2,<3",
|
|
25
|
+
"simple_module_core==0.0.39",
|
|
26
|
+
"simple_module_db==0.0.39",
|
|
27
|
+
"simple_module_hosting==0.0.39",
|
|
27
28
|
]
|
|
28
29
|
|
|
29
30
|
[project.entry-points.simple_module]
|
|
@@ -50,3 +51,4 @@ packages = ["auth"]
|
|
|
50
51
|
[tool.uv.sources]
|
|
51
52
|
simple_module_core = { workspace = true }
|
|
52
53
|
simple_module_db = { workspace = true }
|
|
54
|
+
simple_module_hosting = { workspace = true }
|
|
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
|
{simple_module_auth-0.0.38 → simple_module_auth-0.0.39}/tests/test_auth_provider_protocol.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|