simple-module-auth 0.0.40__tar.gz → 0.0.42__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.40 → simple_module_auth-0.0.42}/PKG-INFO +17 -9
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/README.md +13 -5
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/auth/deps.py +8 -9
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/package.json +5 -6
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/pyproject.toml +4 -4
- simple_module_auth-0.0.42/tests/test_auth_permission_deprecation.py +13 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/.gitignore +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/LICENSE +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/auth/__init__.py +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/auth/_route_match.py +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/auth/contracts/__init__.py +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/auth/contracts/provider.py +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/auth/contracts/resolver.py +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/auth/contracts/schemas.py +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/auth/contracts/tokens.py +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/auth/locales/de.json +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/auth/locales/en.json +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/auth/locales/es.json +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/auth/middleware.py +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/auth/module.py +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/auth/py.typed +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/auth/state.py +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/tests/test_auth_middleware.py +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/tests/test_auth_next_target.py +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/tests/test_auth_parse_bearer.py +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/tests/test_auth_provider_protocol.py +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/tests/test_auth_unknown_paths.py +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/tests/test_deps.py +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/tests/test_module.py +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/tests/test_resolver_registry.py +0 -0
- {simple_module_auth-0.0.40 → simple_module_auth-0.0.42}/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.42
|
|
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
|
|
@@ -22,14 +22,14 @@ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
|
22
22
|
Classifier: Typing :: Typed
|
|
23
23
|
Requires-Python: >=3.12
|
|
24
24
|
Requires-Dist: itsdangerous<3,>=2.2
|
|
25
|
-
Requires-Dist: simple-module-core==0.0.
|
|
26
|
-
Requires-Dist: simple-module-db==0.0.
|
|
27
|
-
Requires-Dist: simple-module-hosting==0.0.
|
|
25
|
+
Requires-Dist: simple-module-core==0.0.42
|
|
26
|
+
Requires-Dist: simple-module-db==0.0.42
|
|
27
|
+
Requires-Dist: simple-module-hosting==0.0.42
|
|
28
28
|
Description-Content-Type: text/markdown
|
|
29
29
|
|
|
30
30
|
# simple_module_auth
|
|
31
31
|
|
|
32
|
-
Pluggable authentication core for [simple_module](https://github.com/antosubash/simple_module_python) apps. Owns the stable public contracts every other module imports — `UserContext`, the `AuthProvider` protocol, the `PrincipalResolver` chain, and the `get_current_user` / `CurrentUser`
|
|
32
|
+
Pluggable authentication core for [simple_module](https://github.com/antosubash/simple_module_python) apps. Owns the stable public contracts every other module imports — `UserContext`, the `AuthProvider` protocol, the `PrincipalResolver` chain, and the `get_current_user` / `CurrentUser` dependencies — plus the `AuthMiddleware` that resolves the current principal on every request.
|
|
33
33
|
|
|
34
34
|
**Heads up:** for most apps you don't install this directly — an auth-provider module (`simple_module_users` for email+password, `simple_module_keycloak` for OIDC) pulls it in and registers itself on `app.state.auth.auth_provider`.
|
|
35
35
|
|
|
@@ -45,7 +45,7 @@ pip install simple_module_auth
|
|
|
45
45
|
- `AuthProvider` protocol — the swappable-backend contract (`resolve_user`, `get_login_url`, `get_logout_url`, `is_bearer_request`); exactly one provider module registers an implementation on `app.state.auth.auth_provider`.
|
|
46
46
|
- `PrincipalResolver` chain — async `(Request) -> UserContext | None` callables apps append to `app.state.auth.principal_resolvers` (e.g. PAT/bearer-token or API-key auth), consulted after the session path.
|
|
47
47
|
- `AuthMiddleware` — delegates to the provider + resolver chain on every request and populates the request principal.
|
|
48
|
-
- `get_current_user` / `CurrentUser` dependency
|
|
48
|
+
- `get_current_user` / `CurrentUser` dependency.
|
|
49
49
|
- Anonymous-access is declared via the framework's method-aware `register_public_routes` hook (with the `SM_AUTH_PUBLIC_PATHS` host-level escape hatch).
|
|
50
50
|
|
|
51
51
|
## Usage
|
|
@@ -63,18 +63,26 @@ async def me(user: CurrentUser):
|
|
|
63
63
|
return {"user_id": user.id, "email": user.email}
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
-
Routes that need a specific permission use
|
|
66
|
+
Routes that need a specific permission use `RequiresPermission` from hosting:
|
|
67
67
|
|
|
68
68
|
```python
|
|
69
69
|
from fastapi import Depends
|
|
70
70
|
|
|
71
|
-
from
|
|
71
|
+
from simple_module_hosting.permissions import RequiresPermission
|
|
72
72
|
|
|
73
|
+
from .constants import PERM_PRODUCTS_CREATE
|
|
73
74
|
|
|
74
|
-
|
|
75
|
+
|
|
76
|
+
@router.post("/", dependencies=[Depends(RequiresPermission(PERM_PRODUCTS_CREATE))])
|
|
75
77
|
async def create_product(): ...
|
|
76
78
|
```
|
|
77
79
|
|
|
80
|
+
`auth.deps.require_permission` is deprecated and will be removed in **0.1.0**
|
|
81
|
+
(#698). It retains its legacy any-of semantics, role-based admin bypass and cached
|
|
82
|
+
permission check. Migrate to `RequiresPermission(PERM_KEY)`; for several required
|
|
83
|
+
permissions, declare a dependency for each. Unlike the legacy helper,
|
|
84
|
+
`RequiresPermission` rechecks administrators demoted during the request.
|
|
85
|
+
|
|
78
86
|
## Depends on
|
|
79
87
|
|
|
80
88
|
- `simple_module_core`, `simple_module_db`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# simple_module_auth
|
|
2
2
|
|
|
3
|
-
Pluggable authentication core for [simple_module](https://github.com/antosubash/simple_module_python) apps. Owns the stable public contracts every other module imports — `UserContext`, the `AuthProvider` protocol, the `PrincipalResolver` chain, and the `get_current_user` / `CurrentUser`
|
|
3
|
+
Pluggable authentication core for [simple_module](https://github.com/antosubash/simple_module_python) apps. Owns the stable public contracts every other module imports — `UserContext`, the `AuthProvider` protocol, the `PrincipalResolver` chain, and the `get_current_user` / `CurrentUser` dependencies — plus the `AuthMiddleware` that resolves the current principal on every request.
|
|
4
4
|
|
|
5
5
|
**Heads up:** for most apps you don't install this directly — an auth-provider module (`simple_module_users` for email+password, `simple_module_keycloak` for OIDC) pulls it in and registers itself on `app.state.auth.auth_provider`.
|
|
6
6
|
|
|
@@ -16,7 +16,7 @@ pip install simple_module_auth
|
|
|
16
16
|
- `AuthProvider` protocol — the swappable-backend contract (`resolve_user`, `get_login_url`, `get_logout_url`, `is_bearer_request`); exactly one provider module registers an implementation on `app.state.auth.auth_provider`.
|
|
17
17
|
- `PrincipalResolver` chain — async `(Request) -> UserContext | None` callables apps append to `app.state.auth.principal_resolvers` (e.g. PAT/bearer-token or API-key auth), consulted after the session path.
|
|
18
18
|
- `AuthMiddleware` — delegates to the provider + resolver chain on every request and populates the request principal.
|
|
19
|
-
- `get_current_user` / `CurrentUser` dependency
|
|
19
|
+
- `get_current_user` / `CurrentUser` dependency.
|
|
20
20
|
- Anonymous-access is declared via the framework's method-aware `register_public_routes` hook (with the `SM_AUTH_PUBLIC_PATHS` host-level escape hatch).
|
|
21
21
|
|
|
22
22
|
## Usage
|
|
@@ -34,18 +34,26 @@ async def me(user: CurrentUser):
|
|
|
34
34
|
return {"user_id": user.id, "email": user.email}
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
Routes that need a specific permission use
|
|
37
|
+
Routes that need a specific permission use `RequiresPermission` from hosting:
|
|
38
38
|
|
|
39
39
|
```python
|
|
40
40
|
from fastapi import Depends
|
|
41
41
|
|
|
42
|
-
from
|
|
42
|
+
from simple_module_hosting.permissions import RequiresPermission
|
|
43
43
|
|
|
44
|
+
from .constants import PERM_PRODUCTS_CREATE
|
|
44
45
|
|
|
45
|
-
|
|
46
|
+
|
|
47
|
+
@router.post("/", dependencies=[Depends(RequiresPermission(PERM_PRODUCTS_CREATE))])
|
|
46
48
|
async def create_product(): ...
|
|
47
49
|
```
|
|
48
50
|
|
|
51
|
+
`auth.deps.require_permission` is deprecated and will be removed in **0.1.0**
|
|
52
|
+
(#698). It retains its legacy any-of semantics, role-based admin bypass and cached
|
|
53
|
+
permission check. Migrate to `RequiresPermission(PERM_KEY)`; for several required
|
|
54
|
+
permissions, declare a dependency for each. Unlike the legacy helper,
|
|
55
|
+
`RequiresPermission` rechecks administrators demoted during the request.
|
|
56
|
+
|
|
49
57
|
## Depends on
|
|
50
58
|
|
|
51
59
|
- `simple_module_core`, `simple_module_db`
|
|
@@ -5,15 +5,14 @@ from __future__ import annotations
|
|
|
5
5
|
from typing import Annotated
|
|
6
6
|
|
|
7
7
|
from fastapi import Depends, HTTPException, Request
|
|
8
|
-
from simple_module_core.
|
|
8
|
+
from simple_module_core.deprecation import deprecated
|
|
9
|
+
from simple_module_core.permissions import ADMIN_ROLE, grants
|
|
9
10
|
from simple_module_hosting.i18n_deps import TranslatorDep
|
|
10
11
|
from simple_module_hosting.permissions import ensure_resolved_permissions
|
|
11
12
|
from simple_module_hosting.token_guard import GATE_PERMISSION, mark_token_gate
|
|
12
13
|
|
|
13
14
|
from auth.contracts.schemas import UserContext
|
|
14
15
|
|
|
15
|
-
_ADMIN_ROLE = "admin"
|
|
16
|
-
|
|
17
16
|
|
|
18
17
|
async def get_current_user(request: Request, t: TranslatorDep) -> UserContext:
|
|
19
18
|
"""Extract the authenticated user from request state.
|
|
@@ -29,13 +28,13 @@ async def get_current_user(request: Request, t: TranslatorDep) -> UserContext:
|
|
|
29
28
|
CurrentUser = Annotated[UserContext, Depends(get_current_user)]
|
|
30
29
|
|
|
31
30
|
|
|
31
|
+
@deprecated(remove_in="0.1.0", use="simple_module_hosting.permissions.RequiresPermission")
|
|
32
32
|
def require_permission(*permissions: str):
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
Usage::
|
|
33
|
+
"""Legacy any-of gate, removed in 0.1.0; use ``RequiresPermission`` instead.
|
|
36
34
|
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
Retains the role-based admin bypass and cached permission behaviour for
|
|
36
|
+
compatibility. ``RequiresPermission`` rechecks a principal demoted during
|
|
37
|
+
the request; this helper does not.
|
|
39
38
|
"""
|
|
40
39
|
|
|
41
40
|
async def check(
|
|
@@ -46,7 +45,7 @@ def require_permission(*permissions: str):
|
|
|
46
45
|
# Admin role bypasses permission checks — but not for a token: an
|
|
47
46
|
# admin's PAT is worth only the scopes it carries, and the resolved
|
|
48
47
|
# set below already applies that cap.
|
|
49
|
-
if
|
|
48
|
+
if ADMIN_ROLE in user.roles and user.scopes is None:
|
|
50
49
|
return
|
|
51
50
|
|
|
52
51
|
# The same resolution RequiresPermission reads: the registry's role map
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simple-module-py/auth",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.42",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Frontend assets for the Auth module",
|
|
6
6
|
"peerDependencies": {
|
|
7
|
+
"@inertiajs/react": "^3.9.1",
|
|
8
|
+
"@simple-module-py/ui": "*",
|
|
7
9
|
"react": "^19.0.0",
|
|
8
|
-
"react-dom": "^19.
|
|
9
|
-
"@inertiajs/react": "^3.7.0",
|
|
10
|
-
"@simple-module-py/ui": "*"
|
|
10
|
+
"react-dom": "^19.3.1"
|
|
11
11
|
},
|
|
12
12
|
"devDependencies": {
|
|
13
13
|
"@simple-module-py/tsconfig": "*"
|
|
14
|
-
}
|
|
15
|
-
"dependencies": {}
|
|
14
|
+
}
|
|
16
15
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "simple_module_auth"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.42"
|
|
4
4
|
description = "Session-cookie authentication primitives — middleware, login/logout, redirect helpers for simple_module"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
@@ -22,9 +22,9 @@ classifiers = [
|
|
|
22
22
|
]
|
|
23
23
|
dependencies = [
|
|
24
24
|
"itsdangerous>=2.2,<3",
|
|
25
|
-
"simple_module_core==0.0.
|
|
26
|
-
"simple_module_db==0.0.
|
|
27
|
-
"simple_module_hosting==0.0.
|
|
25
|
+
"simple_module_core==0.0.42",
|
|
26
|
+
"simple_module_db==0.0.42",
|
|
27
|
+
"simple_module_hosting==0.0.42",
|
|
28
28
|
]
|
|
29
29
|
|
|
30
30
|
[project.entry-points.simple_module]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""The legacy any-of permission helper carries a migration warning (#698)."""
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from auth.deps import require_permission
|
|
5
|
+
from simple_module_core.deprecation import registered_deprecations
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_auth_require_permission_warns_and_registers_removal():
|
|
9
|
+
with pytest.warns(DeprecationWarning, match="RequiresPermission"):
|
|
10
|
+
dependency = require_permission("products.view")
|
|
11
|
+
assert callable(dependency.dependency)
|
|
12
|
+
entry = next(d for d in registered_deprecations() if d.name == "auth.deps.require_permission")
|
|
13
|
+
assert entry.remove_in == "0.1.0"
|
|
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.40 → simple_module_auth-0.0.42}/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
|