fastapi-rbac-authz 0.4.0__tar.gz → 0.5.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 (33) hide show
  1. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/PKG-INFO +25 -20
  2. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/README.md +24 -19
  3. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/pyproject.toml +1 -1
  4. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/.github/workflows/checks.yaml +0 -0
  5. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/.github/workflows/pypi-minor-deployment.yaml +0 -0
  6. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/.gitignore +0 -0
  7. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/.pre-commit-config.yaml +0 -0
  8. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/CLAUDE.md +0 -0
  9. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/examples/basic_app.py +0 -0
  10. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/fastapi_rbac/__init__.py +0 -0
  11. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/fastapi_rbac/context.py +0 -0
  12. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/fastapi_rbac/core.py +0 -0
  13. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/fastapi_rbac/dependencies.py +0 -0
  14. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/fastapi_rbac/errors.py +0 -0
  15. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/fastapi_rbac/permissions.py +0 -0
  16. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/fastapi_rbac/py.typed +0 -0
  17. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/fastapi_rbac/router.py +0 -0
  18. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/fastapi_rbac/ui/__init__.py +0 -0
  19. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/fastapi_rbac/ui/routes.py +0 -0
  20. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/fastapi_rbac/ui/schema.py +0 -0
  21. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/fastapi_rbac/ui/static/index.html +0 -0
  22. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/poetry.lock +0 -0
  23. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/tests/__init__.py +0 -0
  24. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/tests/conftest.py +0 -0
  25. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/tests/test_context.py +0 -0
  26. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/tests/test_context_di.py +0 -0
  27. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/tests/test_core.py +0 -0
  28. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/tests/test_dependencies.py +0 -0
  29. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/tests/test_exceptions.py +0 -0
  30. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/tests/test_integration.py +0 -0
  31. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/tests/test_permissions.py +0 -0
  32. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/tests/test_router.py +0 -0
  33. {fastapi_rbac_authz-0.4.0 → fastapi_rbac_authz-0.5.0}/tests/test_ui.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-rbac-authz
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Summary: Role-based access control with contextual authorization for FastAPI
5
5
  Project-URL: Homepage, https://github.com/parikls/fastapi-rbac
6
6
  Author-email: Dmytro Smyk <porovozls@gmail.com>
@@ -24,6 +24,14 @@ Description-Content-Type: text/markdown
24
24
 
25
25
  Role-based access control with contextual authorization for FastAPI.
26
26
 
27
+ Library IS NOT responsible for authentication. You can use any authentication mechanism you want.
28
+
29
+ What you need to provide:
30
+ - A dependency that returns the authenticated user's roles as `set[str]`
31
+ - Permission definitions per role
32
+ - Use `RBACRouter` instead of `APIRouter` for protected routes
33
+ - Define permissions and context checks per endpoint
34
+
27
35
  ## Installation
28
36
 
29
37
  ```bash
@@ -39,23 +47,23 @@ from fastapi_rbac import (
39
47
  RBACAuthz, RBACRouter, Global, Contextual, ContextualAuthz
40
48
  )
41
49
 
42
- # 1. Define your user model
50
+ # 1. You might have your user model (or you may not, we don't care)
43
51
  class User:
44
52
  def __init__(self, user_id: str, roles: set[str]):
45
53
  self.user_id = user_id
46
54
  self.roles = roles
47
55
 
48
- # 2. Define your authentication dependencies
49
- # The library only needs roles - you can authenticate however you like
56
+ # 2. Assuming you have your own dependency that returns a user instance
50
57
  async def get_current_user() -> User:
51
58
  # Your authentication logic here
52
59
  return User(user_id="user-1", roles={"viewer"})
53
60
 
61
+ # 3. Dependency that library **REQUIRES**. **MUST** return a set of user roles
54
62
  async def get_current_user_roles() -> set[str]:
55
63
  user = await get_current_user()
56
64
  return user.roles
57
65
 
58
- # 3. Define role permissions
66
+ # 4. Define your roles permissions
59
67
  PERMISSIONS = {
60
68
  "admin": {
61
69
  Global("report:*"), # Admin can do anything with reports
@@ -65,13 +73,12 @@ PERMISSIONS = {
65
73
  },
66
74
  }
67
75
 
68
- # 4. Create a context check (for contextual permissions)
69
- # Context classes are responsible for their own authentication via FastAPI DI
76
+ # 5. Create context authorization checks
70
77
  class ReportAccessContext(ContextualAuthz):
71
78
  def __init__(
72
79
  self,
73
80
  report_id: int, # <-- Injected from path parameter
74
- user: Annotated[User, Depends(get_current_user)], # Your auth dependency
81
+ user: Annotated[User, Depends(get_current_user)], # Your own way how to get the user if you need it
75
82
  ):
76
83
  self.user = user
77
84
  self.report_id = report_id
@@ -81,7 +88,7 @@ class ReportAccessContext(ContextualAuthz):
81
88
  allowed_reports = {1, 2, 3} # e.g., query from database
82
89
  return self.report_id in allowed_reports
83
90
 
84
- # 5. Create your app and configure RBAC
91
+ # 6. Configure RBAC
85
92
  app = FastAPI()
86
93
 
87
94
  RBACAuthz(
@@ -91,7 +98,7 @@ RBACAuthz(
91
98
  ui_path="/_rbac", # Optional: mount visualization UI
92
99
  )
93
100
 
94
- # 6. Create protected routes
101
+ # 7. Create protected routes
95
102
  router = RBACRouter(permissions={"report:read"}, contexts=[ReportAccessContext])
96
103
 
97
104
  @router.get("/reports/{report_id}")
@@ -105,8 +112,6 @@ async def create_report():
105
112
  app.include_router(router, prefix="/api")
106
113
  ```
107
114
 
108
- > **Note:** The library doesn't care how you authenticate - whether via dependency, middleware, JWT decode, or any other method. You just need to provide a dependency that returns the user's roles as `set[str]`. Context classes are responsible for their own authentication and can use any FastAPI dependency pattern.
109
-
110
115
  ## Permission Scopes
111
116
 
112
117
  Permissions can be granted with two scopes:
@@ -172,7 +177,7 @@ When a request hits an RBAC-protected endpoint:
172
177
  └── roles_dependency runs → User's roles (set[str]) available
173
178
 
174
179
  2. Permission Check
175
- └── Does user have ANY grant (global or contextual) for required permission?
180
+ └── Does user have ANY grant (scoped or wildcard) for required permission?
176
181
  ├── No → 403 Forbidden
177
182
  └── Yes → Continue
178
183
 
@@ -221,8 +226,8 @@ uvicorn examples.basic_app:app --reload
221
226
 
222
227
  Then open your browser:
223
228
 
224
- - **http://localhost:8000/docs** - OpenAPI docs to test the API
225
- - **http://localhost:8000/_rbac** - Authorization visualization UI
229
+ - **http://localhost:18000/docs** - OpenAPI docs to test the API
230
+ - **http://localhost:18000/_rbac** - Authorization visualization UI
226
231
 
227
232
  ### Test with different users
228
233
 
@@ -230,15 +235,15 @@ The example uses `X-Token` header for authentication:
230
235
 
231
236
  ```bash
232
237
  # As admin (has Global("*") - full access)
233
- curl -H "X-Token: admin-token" http://localhost:8000/reports
234
- curl -H "X-Token: admin-token" http://localhost:8000/reports/1
238
+ curl -H "X-Token: admin-token" http://localhost:18000/reports
239
+ curl -H "X-Token: admin-token" http://localhost:18000/reports/1
235
240
 
236
241
  # As user (has Contextual permissions - can only access own reports)
237
- curl -H "X-Token: user-token" http://localhost:8000/reports/1 # OK (owns report 1)
238
- curl -H "X-Token: user-token" http://localhost:8000/reports/3 # 403 (doesn't own report 3)
242
+ curl -H "X-Token: user-token" http://localhost:18000/reports/1 # OK (owns report 1)
243
+ curl -H "X-Token: user-token" http://localhost:18000/reports/3 # 403 (doesn't own report 3)
239
244
 
240
245
  # As viewer (has Contextual read - can only read own reports)
241
- curl -H "X-Token: viewer-token" http://localhost:8000/reports/1 # 403 (doesn't own any)
246
+ curl -H "X-Token: viewer-token" http://localhost:18000/reports/1 # 403 (doesn't own any)
242
247
  ```
243
248
 
244
249
  ## Visualization UI
@@ -2,6 +2,14 @@
2
2
 
3
3
  Role-based access control with contextual authorization for FastAPI.
4
4
 
5
+ Library IS NOT responsible for authentication. You can use any authentication mechanism you want.
6
+
7
+ What you need to provide:
8
+ - A dependency that returns the authenticated user's roles as `set[str]`
9
+ - Permission definitions per role
10
+ - Use `RBACRouter` instead of `APIRouter` for protected routes
11
+ - Define permissions and context checks per endpoint
12
+
5
13
  ## Installation
6
14
 
7
15
  ```bash
@@ -17,23 +25,23 @@ from fastapi_rbac import (
17
25
  RBACAuthz, RBACRouter, Global, Contextual, ContextualAuthz
18
26
  )
19
27
 
20
- # 1. Define your user model
28
+ # 1. You might have your user model (or you may not, we don't care)
21
29
  class User:
22
30
  def __init__(self, user_id: str, roles: set[str]):
23
31
  self.user_id = user_id
24
32
  self.roles = roles
25
33
 
26
- # 2. Define your authentication dependencies
27
- # The library only needs roles - you can authenticate however you like
34
+ # 2. Assuming you have your own dependency that returns a user instance
28
35
  async def get_current_user() -> User:
29
36
  # Your authentication logic here
30
37
  return User(user_id="user-1", roles={"viewer"})
31
38
 
39
+ # 3. Dependency that library **REQUIRES**. **MUST** return a set of user roles
32
40
  async def get_current_user_roles() -> set[str]:
33
41
  user = await get_current_user()
34
42
  return user.roles
35
43
 
36
- # 3. Define role permissions
44
+ # 4. Define your roles permissions
37
45
  PERMISSIONS = {
38
46
  "admin": {
39
47
  Global("report:*"), # Admin can do anything with reports
@@ -43,13 +51,12 @@ PERMISSIONS = {
43
51
  },
44
52
  }
45
53
 
46
- # 4. Create a context check (for contextual permissions)
47
- # Context classes are responsible for their own authentication via FastAPI DI
54
+ # 5. Create context authorization checks
48
55
  class ReportAccessContext(ContextualAuthz):
49
56
  def __init__(
50
57
  self,
51
58
  report_id: int, # <-- Injected from path parameter
52
- user: Annotated[User, Depends(get_current_user)], # Your auth dependency
59
+ user: Annotated[User, Depends(get_current_user)], # Your own way how to get the user if you need it
53
60
  ):
54
61
  self.user = user
55
62
  self.report_id = report_id
@@ -59,7 +66,7 @@ class ReportAccessContext(ContextualAuthz):
59
66
  allowed_reports = {1, 2, 3} # e.g., query from database
60
67
  return self.report_id in allowed_reports
61
68
 
62
- # 5. Create your app and configure RBAC
69
+ # 6. Configure RBAC
63
70
  app = FastAPI()
64
71
 
65
72
  RBACAuthz(
@@ -69,7 +76,7 @@ RBACAuthz(
69
76
  ui_path="/_rbac", # Optional: mount visualization UI
70
77
  )
71
78
 
72
- # 6. Create protected routes
79
+ # 7. Create protected routes
73
80
  router = RBACRouter(permissions={"report:read"}, contexts=[ReportAccessContext])
74
81
 
75
82
  @router.get("/reports/{report_id}")
@@ -83,8 +90,6 @@ async def create_report():
83
90
  app.include_router(router, prefix="/api")
84
91
  ```
85
92
 
86
- > **Note:** The library doesn't care how you authenticate - whether via dependency, middleware, JWT decode, or any other method. You just need to provide a dependency that returns the user's roles as `set[str]`. Context classes are responsible for their own authentication and can use any FastAPI dependency pattern.
87
-
88
93
  ## Permission Scopes
89
94
 
90
95
  Permissions can be granted with two scopes:
@@ -150,7 +155,7 @@ When a request hits an RBAC-protected endpoint:
150
155
  └── roles_dependency runs → User's roles (set[str]) available
151
156
 
152
157
  2. Permission Check
153
- └── Does user have ANY grant (global or contextual) for required permission?
158
+ └── Does user have ANY grant (scoped or wildcard) for required permission?
154
159
  ├── No → 403 Forbidden
155
160
  └── Yes → Continue
156
161
 
@@ -199,8 +204,8 @@ uvicorn examples.basic_app:app --reload
199
204
 
200
205
  Then open your browser:
201
206
 
202
- - **http://localhost:8000/docs** - OpenAPI docs to test the API
203
- - **http://localhost:8000/_rbac** - Authorization visualization UI
207
+ - **http://localhost:18000/docs** - OpenAPI docs to test the API
208
+ - **http://localhost:18000/_rbac** - Authorization visualization UI
204
209
 
205
210
  ### Test with different users
206
211
 
@@ -208,15 +213,15 @@ The example uses `X-Token` header for authentication:
208
213
 
209
214
  ```bash
210
215
  # As admin (has Global("*") - full access)
211
- curl -H "X-Token: admin-token" http://localhost:8000/reports
212
- curl -H "X-Token: admin-token" http://localhost:8000/reports/1
216
+ curl -H "X-Token: admin-token" http://localhost:18000/reports
217
+ curl -H "X-Token: admin-token" http://localhost:18000/reports/1
213
218
 
214
219
  # As user (has Contextual permissions - can only access own reports)
215
- curl -H "X-Token: user-token" http://localhost:8000/reports/1 # OK (owns report 1)
216
- curl -H "X-Token: user-token" http://localhost:8000/reports/3 # 403 (doesn't own report 3)
220
+ curl -H "X-Token: user-token" http://localhost:18000/reports/1 # OK (owns report 1)
221
+ curl -H "X-Token: user-token" http://localhost:18000/reports/3 # 403 (doesn't own report 3)
217
222
 
218
223
  # As viewer (has Contextual read - can only read own reports)
219
- curl -H "X-Token: viewer-token" http://localhost:8000/reports/1 # 403 (doesn't own any)
224
+ curl -H "X-Token: viewer-token" http://localhost:18000/reports/1 # 403 (doesn't own any)
220
225
  ```
221
226
 
222
227
  ## Visualization UI
@@ -7,7 +7,7 @@ packages = [{ include = "fastapi_rbac" }]
7
7
 
8
8
  [project]
9
9
  name = "fastapi-rbac-authz"
10
- version = "0.4.0"
10
+ version = "0.5.0"
11
11
  description = "Role-based access control with contextual authorization for FastAPI"
12
12
  readme = "README.md"
13
13
  license = "MIT"