permissions2fast-fastapi 0.1.0__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 (45) hide show
  1. permissions2fast_fastapi-0.1.0/LICENSE +21 -0
  2. permissions2fast_fastapi-0.1.0/PKG-INFO +141 -0
  3. permissions2fast_fastapi-0.1.0/README.md +87 -0
  4. permissions2fast_fastapi-0.1.0/pyproject.toml +68 -0
  5. permissions2fast_fastapi-0.1.0/setup.cfg +4 -0
  6. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/__init__.py +26 -0
  7. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/__version__.py +1 -0
  8. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/dependencies.py +123 -0
  9. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/models/__init__.py +21 -0
  10. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/models/permission_assignment_model.py +13 -0
  11. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/models/permission_category_model.py +18 -0
  12. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/models/permission_model.py +17 -0
  13. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/models/permission_route_model.py +13 -0
  14. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/models/role_model.py +21 -0
  15. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/models/route_model.py +14 -0
  16. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/models/tenant_model.py +16 -0
  17. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/models/user_role_model.py +12 -0
  18. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/models/user_tenant_role_model.py +15 -0
  19. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/routers/__init__.py +5 -0
  20. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/routers/permissions_router.py +191 -0
  21. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/routers/roles_router.py +177 -0
  22. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/routers/routes_router.py +44 -0
  23. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/schemas/__init__.py +53 -0
  24. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/schemas/permission_category_schema.py +10 -0
  25. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/schemas/permission_schema.py +35 -0
  26. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/schemas/role_schema.py +40 -0
  27. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/schemas/route_schema.py +11 -0
  28. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/services/__init__.py +6 -0
  29. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/services/access_service.py +110 -0
  30. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/services/permission_service.py +197 -0
  31. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/services/role_service.py +256 -0
  32. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/services/route_service.py +44 -0
  33. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/settings.py +64 -0
  34. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/utils/__init__.py +27 -0
  35. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/utils/permission_cache.py +251 -0
  36. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi/utils/redis_client.py +82 -0
  37. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi.egg-info/PKG-INFO +141 -0
  38. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi.egg-info/SOURCES.txt +43 -0
  39. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi.egg-info/dependency_links.txt +1 -0
  40. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi.egg-info/requires.txt +9 -0
  41. permissions2fast_fastapi-0.1.0/src/permissions2fast_fastapi.egg-info/top_level.txt +1 -0
  42. permissions2fast_fastapi-0.1.0/tests/test_models.py +130 -0
  43. permissions2fast_fastapi-0.1.0/tests/test_multitenancy_config.py +34 -0
  44. permissions2fast_fastapi-0.1.0/tests/test_multitenancy_rbac.py +123 -0
  45. permissions2fast_fastapi-0.1.0/tests/test_permissions.py +153 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Angel Daniel Sanchez Castillo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,141 @@
1
+ Metadata-Version: 2.4
2
+ Name: permissions2fast-fastapi
3
+ Version: 0.1.0
4
+ Summary: Role-based access control (RBAC) and permission management extension for oauth2fast-fastapi
5
+ Author-email: Angel Daniel Sanchez Castillo <angeldaniel.sanchezcastillo@gmail.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Angel Daniel Sanchez Castillo
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/AngelDanielSanchezCastillo/permissions2fast-fastapi
29
+ Project-URL: Repository, https://github.com/AngelDanielSanchezCastillo/permissions2fast-fastapi
30
+ Project-URL: Issues, https://github.com/AngelDanielSanchezCastillo/permissions2fast-fastapi/issues
31
+ Keywords: fastapi,permissions,rbac,oauth2,authorization,sqlmodel
32
+ Classifier: Development Status :: 3 - Alpha
33
+ Classifier: Intended Audience :: Developers
34
+ Classifier: License :: OSI Approved :: MIT License
35
+ Classifier: Programming Language :: Python :: 3
36
+ Classifier: Programming Language :: Python :: 3.10
37
+ Classifier: Programming Language :: Python :: 3.11
38
+ Classifier: Programming Language :: Python :: 3.12
39
+ Classifier: Framework :: FastAPI
40
+ Classifier: Topic :: Security
41
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
42
+ Requires-Python: >=3.10
43
+ Description-Content-Type: text/markdown
44
+ License-File: LICENSE
45
+ Requires-Dist: oauth2fast-fastapi>=0.2.2
46
+ Provides-Extra: dev
47
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
48
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
49
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
50
+ Requires-Dist: httpx>=0.24.0; extra == "dev"
51
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
52
+ Requires-Dist: python-dotenv>=1.0.0; extra == "dev"
53
+ Dynamic: license-file
54
+
55
+ # permissions2fast-fastapi
56
+
57
+ 🔒 Role-Based Access Control (RBAC) extension for `oauth2fast-fastapi`.
58
+
59
+ Easily manage user roles and permissions in your FastAPI application with support for Multi-Tenancy and High-Performance Redis Caching.
60
+
61
+ ## Features
62
+
63
+ - 👥 **Role Management**: Create, assign, and manage roles for users.
64
+ - 🔑 **Granular Permissions**: Define specific permissions and assign them to roles or directly to users (polymorphic assignments).
65
+ - 🏢 **Multi-Tenancy (Optional)**: Isolate roles and permissions per tenant context.
66
+ - � **Redis Caching (Optional)**: High-performance permission evaluation using Redis to minimize database lookups.
67
+ - �🛡️ **Route Protection**: Dependencies to protect endpoints based on roles or permissions.
68
+ - ⚡ **Async Support**: Fully async database interactions via `pgsqlasync2fast-fastapi`.
69
+ - 🔌 **Seamless Integration**: Built to extend `oauth2fast-fastapi`.
70
+
71
+ ## Installation
72
+
73
+ ```bash
74
+ pip install permissions2fast-fastapi
75
+ ```
76
+
77
+ ## Configuration
78
+
79
+ This package uses the same database connection logic as `oauth2fast-fastapi`. Configure your environment variables in `.env`.
80
+
81
+ ### Basic Settings
82
+
83
+ ```bash
84
+ # Database Configuration
85
+ DB_CONNECTIONS__AUTH__USERNAME=db_user
86
+ DB_CONNECTIONS__AUTH__PASSWORD=db_password
87
+ DB_CONNECTIONS__AUTH__HOST=localhost
88
+ DB_CONNECTIONS__AUTH__DATABASE=db_name
89
+ DB_CONNECTIONS__AUTH__PORT=5432
90
+ ```
91
+
92
+ ### Advanced Features (Multi-Tenancy & Redis)
93
+
94
+ You can enable multi-tenancy and Redis caching by setting the following environment variables:
95
+
96
+ ```bash
97
+ PERMISSIONS_ENABLE_TENANCY=True
98
+ PERMISSIONS_REDIS_RBAC_ENABLED=True
99
+
100
+ # Redis connection details (if caching is enabled)
101
+ PERMISSIONS_REDIS__HOST=localhost
102
+ PERMISSIONS_REDIS__PORT=6379
103
+ PERMISSIONS_REDIS__DB=0
104
+ # PERMISSIONS_REDIS__PASSWORD=your_redis_password
105
+ ```
106
+
107
+ ## Usage
108
+
109
+ ### 1. Basic Integration
110
+
111
+ ```python
112
+ from fastapi import FastAPI
113
+ from permissions2fast_fastapi import permissions_router, roles_router
114
+ from oauth2fast_fastapi import router as auth_router
115
+
116
+ app = FastAPI()
117
+
118
+ app.include_router(auth_router)
119
+ app.include_router(permissions_router)
120
+ app.include_router(roles_router)
121
+ ```
122
+
123
+ ### 2. Protecting Routes
124
+
125
+ Use the provided dependencies to restrict access to endpoints. The system will automatically check Redis cache if enabled, and fallback to database queries if needed. Tenant context is automatically respected if Tenancy is enabled and a Tenant ID is injected in the request context.
126
+
127
+ ```python
128
+ from fastapi import Depends
129
+ from permissions2fast_fastapi.dependencies import has_permission, has_role
130
+ from oauth2fast_fastapi.models import User
131
+
132
+ # Require a specific role
133
+ @app.get("/admin-dashboard")
134
+ async def admin_dashboard(user: User = Depends(has_role("admin"))):
135
+ return {"message": "Welcome Admin"}
136
+
137
+ # Require a specific permission
138
+ @app.get("/edit-post")
139
+ async def edit_post(user: User = Depends(has_permission("posts.edit"))):
140
+ return {"message": "You can edit posts"}
141
+ ```
@@ -0,0 +1,87 @@
1
+ # permissions2fast-fastapi
2
+
3
+ 🔒 Role-Based Access Control (RBAC) extension for `oauth2fast-fastapi`.
4
+
5
+ Easily manage user roles and permissions in your FastAPI application with support for Multi-Tenancy and High-Performance Redis Caching.
6
+
7
+ ## Features
8
+
9
+ - 👥 **Role Management**: Create, assign, and manage roles for users.
10
+ - 🔑 **Granular Permissions**: Define specific permissions and assign them to roles or directly to users (polymorphic assignments).
11
+ - 🏢 **Multi-Tenancy (Optional)**: Isolate roles and permissions per tenant context.
12
+ - � **Redis Caching (Optional)**: High-performance permission evaluation using Redis to minimize database lookups.
13
+ - �🛡️ **Route Protection**: Dependencies to protect endpoints based on roles or permissions.
14
+ - ⚡ **Async Support**: Fully async database interactions via `pgsqlasync2fast-fastapi`.
15
+ - 🔌 **Seamless Integration**: Built to extend `oauth2fast-fastapi`.
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ pip install permissions2fast-fastapi
21
+ ```
22
+
23
+ ## Configuration
24
+
25
+ This package uses the same database connection logic as `oauth2fast-fastapi`. Configure your environment variables in `.env`.
26
+
27
+ ### Basic Settings
28
+
29
+ ```bash
30
+ # Database Configuration
31
+ DB_CONNECTIONS__AUTH__USERNAME=db_user
32
+ DB_CONNECTIONS__AUTH__PASSWORD=db_password
33
+ DB_CONNECTIONS__AUTH__HOST=localhost
34
+ DB_CONNECTIONS__AUTH__DATABASE=db_name
35
+ DB_CONNECTIONS__AUTH__PORT=5432
36
+ ```
37
+
38
+ ### Advanced Features (Multi-Tenancy & Redis)
39
+
40
+ You can enable multi-tenancy and Redis caching by setting the following environment variables:
41
+
42
+ ```bash
43
+ PERMISSIONS_ENABLE_TENANCY=True
44
+ PERMISSIONS_REDIS_RBAC_ENABLED=True
45
+
46
+ # Redis connection details (if caching is enabled)
47
+ PERMISSIONS_REDIS__HOST=localhost
48
+ PERMISSIONS_REDIS__PORT=6379
49
+ PERMISSIONS_REDIS__DB=0
50
+ # PERMISSIONS_REDIS__PASSWORD=your_redis_password
51
+ ```
52
+
53
+ ## Usage
54
+
55
+ ### 1. Basic Integration
56
+
57
+ ```python
58
+ from fastapi import FastAPI
59
+ from permissions2fast_fastapi import permissions_router, roles_router
60
+ from oauth2fast_fastapi import router as auth_router
61
+
62
+ app = FastAPI()
63
+
64
+ app.include_router(auth_router)
65
+ app.include_router(permissions_router)
66
+ app.include_router(roles_router)
67
+ ```
68
+
69
+ ### 2. Protecting Routes
70
+
71
+ Use the provided dependencies to restrict access to endpoints. The system will automatically check Redis cache if enabled, and fallback to database queries if needed. Tenant context is automatically respected if Tenancy is enabled and a Tenant ID is injected in the request context.
72
+
73
+ ```python
74
+ from fastapi import Depends
75
+ from permissions2fast_fastapi.dependencies import has_permission, has_role
76
+ from oauth2fast_fastapi.models import User
77
+
78
+ # Require a specific role
79
+ @app.get("/admin-dashboard")
80
+ async def admin_dashboard(user: User = Depends(has_role("admin"))):
81
+ return {"message": "Welcome Admin"}
82
+
83
+ # Require a specific permission
84
+ @app.get("/edit-post")
85
+ async def edit_post(user: User = Depends(has_permission("posts.edit"))):
86
+ return {"message": "You can edit posts"}
87
+ ```
@@ -0,0 +1,68 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "permissions2fast-fastapi"
7
+ version = "0.1.0"
8
+ description = "Role-based access control (RBAC) and permission management extension for oauth2fast-fastapi"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = {file = "LICENSE"}
12
+ authors = [
13
+ {name = "Angel Daniel Sanchez Castillo", email = "angeldaniel.sanchezcastillo@gmail.com"}
14
+ ]
15
+ keywords = ["fastapi", "permissions", "rbac", "oauth2", "authorization", "sqlmodel"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Framework :: FastAPI",
25
+ "Topic :: Security",
26
+ "Topic :: Software Development :: Libraries :: Python Modules",
27
+ ]
28
+
29
+ dependencies = [
30
+ "oauth2fast-fastapi>=0.2.2",
31
+ ]
32
+
33
+ [project.optional-dependencies]
34
+ dev = [
35
+ "pytest>=7.0.0",
36
+ "pytest-asyncio>=0.21.0",
37
+ "pytest-cov>=4.0.0",
38
+ "httpx>=0.24.0",
39
+ "mypy>=1.0.0",
40
+ "python-dotenv>=1.0.0",
41
+ ]
42
+
43
+ [project.urls]
44
+ Homepage = "https://github.com/AngelDanielSanchezCastillo/permissions2fast-fastapi"
45
+ Repository = "https://github.com/AngelDanielSanchezCastillo/permissions2fast-fastapi"
46
+ Issues = "https://github.com/AngelDanielSanchezCastillo/permissions2fast-fastapi/issues"
47
+
48
+ [tool.setuptools]
49
+ package-dir = {"" = "src"}
50
+
51
+ [tool.setuptools.packages.find]
52
+ where = ["src"]
53
+ include = ["permissions2fast_fastapi*"]
54
+
55
+ [tool.pytest.ini_options]
56
+ testpaths = ["tests"]
57
+ python_files = ["test_*.py"]
58
+ python_classes = ["Test*"]
59
+ python_functions = ["test_*"]
60
+ asyncio_mode = "auto"
61
+ asyncio_default_fixture_loop_scope = "session"
62
+ asyncio_default_test_loop_scope = "session"
63
+
64
+ [tool.mypy]
65
+ python_version = "3.10"
66
+ warn_return_any = true
67
+ warn_unused_configs = true
68
+ disallow_untyped_defs = false
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,26 @@
1
+ """
2
+ permissions2fast-fastapi
3
+
4
+ Complete RBAC (Role-Based Access Control) system for FastAPI applications.
5
+ Provides role management, permission checking, and user-role assignments.
6
+ """
7
+
8
+ __version__ = "0.1.0"
9
+
10
+ from .models.role_model import Role
11
+ from .models.permission_model import Permission
12
+ from .models.permission_category_model import PermissionCategory
13
+ from .models.route_model import Route
14
+ from .models.user_role_model import UserRole
15
+ from .models.permission_assignment_model import PermissionAssignment
16
+ from .models.permission_route_model import PermissionRoute
17
+
18
+ __all__ = [
19
+ "Role",
20
+ "Permission",
21
+ "PermissionCategory",
22
+ "Route",
23
+ "UserRole",
24
+ "PermissionAssignment",
25
+ "PermissionRoute",
26
+ ]
@@ -0,0 +1 @@
1
+ __version__ = "0.1.0"
@@ -0,0 +1,123 @@
1
+ """
2
+ FastAPI Dependencies
3
+
4
+ Dependencies for protecting routes based on roles and permissions.
5
+ """
6
+
7
+ from typing import Annotated
8
+
9
+ from fastapi import Depends, HTTPException, Request, status
10
+ from sqlalchemy.ext.asyncio import AsyncSession
11
+
12
+ # Import from oauth2fast-fastapi directly
13
+ from oauth2fast_fastapi.dependencies import get_current_verified_user, get_auth_session
14
+ from oauth2fast_fastapi import User
15
+
16
+ from .services import access_service, role_service
17
+
18
+
19
+ def has_role(
20
+ role_name: str,
21
+ ):
22
+ """
23
+ Dependency to require a specific role.
24
+
25
+ Usage:
26
+ @app.get("/admin")
27
+ def admin_route(user: User = Depends(has_role("admin"))):
28
+ ...
29
+ """
30
+ async def _has_role(
31
+ request: Request,
32
+ user: Annotated[User, Depends(get_current_verified_user)],
33
+ session: Annotated[AsyncSession, Depends(get_auth_session)],
34
+ ) -> User:
35
+ tenant_id = get_tenant_id(request)
36
+ user_roles = await role_service.list_user_roles(user.id, session, tenant_id=tenant_id)
37
+
38
+ has_required = any(r.name == role_name for r in user_roles)
39
+
40
+ if not has_required:
41
+ raise HTTPException(
42
+ status_code=status.HTTP_403_FORBIDDEN,
43
+ detail=f"Missing required role: {role_name}",
44
+ )
45
+
46
+ return user
47
+
48
+ return _has_role
49
+
50
+
51
+ def get_tenant_id(request: Request) -> int | None:
52
+ """
53
+ Extract tenant_id from request.
54
+ Priority:
55
+ 1. request.state.tenant_id (injected by external middleware)
56
+ 2. X-Tenant-ID header
57
+ """
58
+ from .settings import settings
59
+ if not settings.enable_tenancy:
60
+ return None
61
+
62
+ # First check state (injected by middleware)
63
+ if hasattr(request.state, "tenant_id") and request.state.tenant_id:
64
+ try:
65
+ return int(request.state.tenant_id)
66
+ except ValueError:
67
+ pass
68
+
69
+ # Fallback to header
70
+ header_tenant = request.headers.get("X-Tenant-ID")
71
+ if header_tenant:
72
+ try:
73
+ return int(header_tenant)
74
+ except ValueError:
75
+ pass
76
+
77
+ return None
78
+
79
+
80
+ def has_permission(
81
+ permission_route: str | None = None,
82
+ method: str | None = None,
83
+ ):
84
+ """
85
+ Dependency to require permission for a route.
86
+
87
+ If params are None, verifies access to the *current* request path and method.
88
+
89
+ Usage:
90
+ @app.get("/items")
91
+ def items(user: User = Depends(has_permission())):
92
+ # Checks if user can GET /items
93
+ ...
94
+
95
+ @app.get("/items")
96
+ def items(user: User = Depends(has_permission(permission_route="/api/items", method="GET"))):
97
+ ...
98
+ """
99
+ async def _has_permission(
100
+ request: Request,
101
+ user: Annotated[User, Depends(get_current_verified_user)],
102
+ session: Annotated[AsyncSession, Depends(get_auth_session)],
103
+ ) -> User:
104
+ # Determine what to check
105
+ route_to_check = permission_route or request.url.path
106
+ method_to_check = method or request.method
107
+
108
+ # Extract tenant context
109
+ tenant_id = get_tenant_id(request)
110
+
111
+ is_allowed = await access_service.check_user_access(
112
+ user.id, route_to_check, method_to_check, session, tenant_id=tenant_id
113
+ )
114
+
115
+ if not is_allowed:
116
+ raise HTTPException(
117
+ status_code=status.HTTP_403_FORBIDDEN,
118
+ detail="Not enough permissions to access this resource",
119
+ )
120
+
121
+ return user
122
+
123
+ return _has_permission
@@ -0,0 +1,21 @@
1
+ from .role_model import Role
2
+ from .permission_model import Permission
3
+ from .permission_category_model import PermissionCategory
4
+ from .route_model import Route
5
+ from .user_role_model import UserRole
6
+ from .permission_assignment_model import PermissionAssignment
7
+ from .permission_route_model import PermissionRoute
8
+ from .tenant_model import Tenant
9
+ from .user_tenant_role_model import UserTenantRole
10
+
11
+ __all__ = [
12
+ "Role",
13
+ "Permission",
14
+ "PermissionCategory",
15
+ "Route",
16
+ "UserRole",
17
+ "PermissionAssignment",
18
+ "PermissionRoute",
19
+ "Tenant",
20
+ "UserTenantRole",
21
+ ]
@@ -0,0 +1,13 @@
1
+ from sqlmodel import Field, SQLModel
2
+ from oauth2fast_fastapi.models import AuthModel
3
+
4
+ class PermissionAssignment(AuthModel, table=True):
5
+ """
6
+ Polymorphic Permission Assignment for RBAC.
7
+ Description: Assigns a permission directly to an entity (e.g. User or Role).
8
+ """
9
+ __tablename__ = "permission_assignments"
10
+
11
+ permission_id: int = Field(primary_key=True, foreign_key="permissions.id")
12
+ entity_type: str = Field(primary_key=True, index=True) # e.g., "User", "Team"
13
+ entity_id: int = Field(primary_key=True, index=True)
@@ -0,0 +1,18 @@
1
+ from sqlmodel import Field, SQLModel, Relationship
2
+ from typing import Optional, List
3
+
4
+ # Forward reference for relationship
5
+ from oauth2fast_fastapi.models import AuthModel
6
+
7
+ class PermissionCategory(AuthModel, table=True):
8
+ """
9
+ Permission Category definition for RBAC.
10
+ Description: Groups related permissions together.
11
+ """
12
+ __tablename__ = "permission_categories"
13
+
14
+ id: Optional[int] = Field(default=None, primary_key=True)
15
+ name: str = Field(index=True, unique=True)
16
+
17
+ # Relationships
18
+ # permissions: List["Permission"] = Relationship(back_populates="category")
@@ -0,0 +1,17 @@
1
+ from sqlmodel import Field, SQLModel, Relationship
2
+ from typing import Optional
3
+ from oauth2fast_fastapi.models import AuthModel
4
+
5
+ class Permission(AuthModel, table=True):
6
+ """
7
+ Permission definition for RBAC.
8
+ Description: Represents a specific action or access right.
9
+ """
10
+ __tablename__ = "permissions"
11
+
12
+ id: Optional[int] = Field(default=None, primary_key=True)
13
+ name: str = Field(index=True, unique=True)
14
+ permission_category_id: int = Field(foreign_key="permission_categories.id")
15
+
16
+ # Relationships
17
+ # category: "PermissionCategory" = Relationship(back_populates="permissions")
@@ -0,0 +1,13 @@
1
+ from sqlmodel import Field, SQLModel
2
+ from oauth2fast_fastapi.models import AuthModel
3
+
4
+ class PermissionRoute(AuthModel, table=True):
5
+ """
6
+ Permission Route mapping for RBAC.
7
+ Description: Maps permissions to specific API routes.
8
+ """
9
+ __tablename__ = "permission_routes"
10
+
11
+ id: int | None = Field(default=None, primary_key=True)
12
+ permission_id: int = Field(foreign_key="permissions.id")
13
+ route_id: int = Field(foreign_key="routes.id")
@@ -0,0 +1,21 @@
1
+ from sqlmodel import BigInteger, Column, Field
2
+ from sqlmodel import BigInteger, Column, Field, SQLModel
3
+
4
+ from oauth2fast_fastapi.models import AuthModel
5
+
6
+
7
+ class Role(AuthModel, table=True):
8
+ """
9
+ Role definition for RBAC.
10
+ Description: Role model
11
+ """
12
+
13
+ __tablename__ = "roles"
14
+
15
+ id: int = Field(
16
+ default=None, sa_column=Column(BigInteger, index=True, primary_key=True)
17
+ )
18
+ name: str = Field(index=True, unique=True)
19
+ description: str | None = Field(default=None)
20
+ is_active: bool = Field(default=True)
21
+
@@ -0,0 +1,14 @@
1
+ from sqlmodel import Field, SQLModel
2
+ from typing import Optional
3
+ from oauth2fast_fastapi.models import AuthModel
4
+
5
+ class Route(AuthModel, table=True):
6
+ """
7
+ Route definition for RBAC.
8
+ Description: Represents an API endpoint or accessible resource path.
9
+ """
10
+ __tablename__ = "routes"
11
+
12
+ id: Optional[int] = Field(default=None, primary_key=True)
13
+ name: str = Field(index=True, unique=True) # The path
14
+ is_active: bool = Field(default=True)
@@ -0,0 +1,16 @@
1
+ from sqlmodel import Field, SQLModel
2
+ from oauth2fast_fastapi.models import AuthModel
3
+
4
+
5
+ class Tenant(AuthModel, table=True):
6
+ """
7
+ Tenant definition for Multi-tenant RBAC.
8
+ Description: Represents an isolated organization or tenant.
9
+ """
10
+ __tablename__ = "tenants"
11
+
12
+ id: int | None = Field(default=None, primary_key=True)
13
+ name: str = Field(index=True)
14
+ schema_name: str | None = Field(default=None, description="DB Schema name if applicable")
15
+ db_url: str | None = Field(default=None, description="External DB URL if applicable")
16
+ is_active: bool = Field(default=True)
@@ -0,0 +1,12 @@
1
+ from sqlmodel import Field, SQLModel
2
+ from oauth2fast_fastapi.models import AuthModel
3
+
4
+ class UserRole(AuthModel, table=True):
5
+ """
6
+ User Role mapping for RBAC.
7
+ Description: Maps users to their assigned roles.
8
+ """
9
+ __tablename__ = "user_role"
10
+
11
+ role_id: int = Field(primary_key=True, foreign_key="roles.id")
12
+ user_id: int = Field(primary_key=True, index=True, foreign_key="users.id")
@@ -0,0 +1,15 @@
1
+ from sqlmodel import Field, SQLModel
2
+ from oauth2fast_fastapi.models import AuthModel
3
+
4
+
5
+ class UserTenantRole(AuthModel, table=True):
6
+ """
7
+ Tenant-specific Role mapping for RBAC.
8
+ Description: Maps users to roles within a specific tenant context.
9
+ """
10
+ __tablename__ = "user_tenant_roles"
11
+
12
+ id: int | None = Field(default=None, primary_key=True)
13
+ user_id: int = Field(index=True, foreign_key="users.id")
14
+ tenant_id: int = Field(foreign_key="tenants.id", index=True)
15
+ role_id: int = Field(foreign_key="roles.id", index=True)
@@ -0,0 +1,5 @@
1
+ from .permissions_router import router as permissions_router
2
+ from .roles_router import router as roles_router
3
+ from .routes_router import router as routes_router
4
+
5
+ __all__ = ["permissions_router", "roles_router", "routes_router"]