agios-auth-verify 1.0.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.
@@ -0,0 +1,61 @@
1
+ Metadata-Version: 2.4
2
+ Name: agios-auth-verify
3
+ Version: 1.0.0
4
+ Summary: FastAPI dependency that verifies a user's RBAC permission against the auth-service
5
+ License-Expression: ISC
6
+ Project-URL: Repository, https://github.com/AGIOS-AI-RT/auth-verify-python
7
+ Keywords: fastapi,rbac,authorization,permissions,auth,middleware
8
+ Requires-Python: >=3.9
9
+ Description-Content-Type: text/markdown
10
+ Requires-Dist: fastapi>=0.100
11
+ Requires-Dist: httpx>=0.24
12
+
13
+ # agios-auth-verify
14
+
15
+ FastAPI dependency that verifies a user's RBAC permission by calling
16
+ `POST {AUTH_SERVICE_URL}/api/auth/check-permission`.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ pip install agios-auth-verify
22
+ ```
23
+
24
+ Requires `fastapi` and `httpx`. Set `AUTH_SERVICE_URL` in the environment
25
+ (e.g. `http://127.0.0.1:8000`).
26
+
27
+ ## Usage
28
+
29
+ ```python
30
+ from fastapi import Depends, FastAPI
31
+ from auth_verify import authorize
32
+
33
+ app = FastAPI()
34
+
35
+ # An upstream middleware must set `request.state.user`
36
+ # (a dict or object with `userId`, optionally `tenantId`).
37
+
38
+ @app.delete("/users/{user_id}", dependencies=[Depends(authorize("users:delete"))])
39
+ async def delete_user(user_id: str):
40
+ return {"ok": True}
41
+ ```
42
+
43
+ The request forwards the incoming `Authorization` header and a `tenant-id`
44
+ header (`user["tenantId"]`, falling back to the request's `tenant-id` header)
45
+ to the auth-service, and sends `{"userId": ..., "permissionKey": ...}` as the body.
46
+
47
+ ## Responses
48
+
49
+ Raises `fastapi.HTTPException` with body `{"success": false, "message": ...}`:
50
+
51
+ | Status | When |
52
+ | ------ | ----------------------------------------------------------- |
53
+ | `401` | No authenticated user, or the auth-service returns 401 |
54
+ | `403` | The auth-service responds with `allowed: false` |
55
+ | `503` | The auth-service is unreachable or errors |
56
+
57
+ ## Build
58
+
59
+ ```bash
60
+ python -m build
61
+ ```
@@ -0,0 +1,49 @@
1
+ # agios-auth-verify
2
+
3
+ FastAPI dependency that verifies a user's RBAC permission by calling
4
+ `POST {AUTH_SERVICE_URL}/api/auth/check-permission`.
5
+
6
+ ## Install
7
+
8
+ ```bash
9
+ pip install agios-auth-verify
10
+ ```
11
+
12
+ Requires `fastapi` and `httpx`. Set `AUTH_SERVICE_URL` in the environment
13
+ (e.g. `http://127.0.0.1:8000`).
14
+
15
+ ## Usage
16
+
17
+ ```python
18
+ from fastapi import Depends, FastAPI
19
+ from auth_verify import authorize
20
+
21
+ app = FastAPI()
22
+
23
+ # An upstream middleware must set `request.state.user`
24
+ # (a dict or object with `userId`, optionally `tenantId`).
25
+
26
+ @app.delete("/users/{user_id}", dependencies=[Depends(authorize("users:delete"))])
27
+ async def delete_user(user_id: str):
28
+ return {"ok": True}
29
+ ```
30
+
31
+ The request forwards the incoming `Authorization` header and a `tenant-id`
32
+ header (`user["tenantId"]`, falling back to the request's `tenant-id` header)
33
+ to the auth-service, and sends `{"userId": ..., "permissionKey": ...}` as the body.
34
+
35
+ ## Responses
36
+
37
+ Raises `fastapi.HTTPException` with body `{"success": false, "message": ...}`:
38
+
39
+ | Status | When |
40
+ | ------ | ----------------------------------------------------------- |
41
+ | `401` | No authenticated user, or the auth-service returns 401 |
42
+ | `403` | The auth-service responds with `allowed: false` |
43
+ | `503` | The auth-service is unreachable or errors |
44
+
45
+ ## Build
46
+
47
+ ```bash
48
+ python -m build
49
+ ```
@@ -0,0 +1,22 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "agios-auth-verify"
7
+ version = "1.0.0"
8
+ description = "FastAPI dependency that verifies a user's RBAC permission against the auth-service"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = "ISC"
12
+ keywords = ["fastapi", "rbac", "authorization", "permissions", "auth", "middleware"]
13
+ dependencies = [
14
+ "fastapi>=0.100",
15
+ "httpx>=0.24",
16
+ ]
17
+
18
+ [project.urls]
19
+ Repository = "https://github.com/AGIOS-AI-RT/auth-verify-python"
20
+
21
+ [tool.setuptools.packages.find]
22
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,61 @@
1
+ Metadata-Version: 2.4
2
+ Name: agios-auth-verify
3
+ Version: 1.0.0
4
+ Summary: FastAPI dependency that verifies a user's RBAC permission against the auth-service
5
+ License-Expression: ISC
6
+ Project-URL: Repository, https://github.com/AGIOS-AI-RT/auth-verify-python
7
+ Keywords: fastapi,rbac,authorization,permissions,auth,middleware
8
+ Requires-Python: >=3.9
9
+ Description-Content-Type: text/markdown
10
+ Requires-Dist: fastapi>=0.100
11
+ Requires-Dist: httpx>=0.24
12
+
13
+ # agios-auth-verify
14
+
15
+ FastAPI dependency that verifies a user's RBAC permission by calling
16
+ `POST {AUTH_SERVICE_URL}/api/auth/check-permission`.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ pip install agios-auth-verify
22
+ ```
23
+
24
+ Requires `fastapi` and `httpx`. Set `AUTH_SERVICE_URL` in the environment
25
+ (e.g. `http://127.0.0.1:8000`).
26
+
27
+ ## Usage
28
+
29
+ ```python
30
+ from fastapi import Depends, FastAPI
31
+ from auth_verify import authorize
32
+
33
+ app = FastAPI()
34
+
35
+ # An upstream middleware must set `request.state.user`
36
+ # (a dict or object with `userId`, optionally `tenantId`).
37
+
38
+ @app.delete("/users/{user_id}", dependencies=[Depends(authorize("users:delete"))])
39
+ async def delete_user(user_id: str):
40
+ return {"ok": True}
41
+ ```
42
+
43
+ The request forwards the incoming `Authorization` header and a `tenant-id`
44
+ header (`user["tenantId"]`, falling back to the request's `tenant-id` header)
45
+ to the auth-service, and sends `{"userId": ..., "permissionKey": ...}` as the body.
46
+
47
+ ## Responses
48
+
49
+ Raises `fastapi.HTTPException` with body `{"success": false, "message": ...}`:
50
+
51
+ | Status | When |
52
+ | ------ | ----------------------------------------------------------- |
53
+ | `401` | No authenticated user, or the auth-service returns 401 |
54
+ | `403` | The auth-service responds with `allowed: false` |
55
+ | `503` | The auth-service is unreachable or errors |
56
+
57
+ ## Build
58
+
59
+ ```bash
60
+ python -m build
61
+ ```
@@ -0,0 +1,9 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/agios_auth_verify.egg-info/PKG-INFO
4
+ src/agios_auth_verify.egg-info/SOURCES.txt
5
+ src/agios_auth_verify.egg-info/dependency_links.txt
6
+ src/agios_auth_verify.egg-info/requires.txt
7
+ src/agios_auth_verify.egg-info/top_level.txt
8
+ src/auth_verify/__init__.py
9
+ src/auth_verify/authorize.py
@@ -0,0 +1,2 @@
1
+ fastapi>=0.100
2
+ httpx>=0.24
@@ -0,0 +1,4 @@
1
+ from .authorize import authorize
2
+
3
+ __all__ = ["authorize"]
4
+ __version__ = "1.0.0"
@@ -0,0 +1,48 @@
1
+ import os
2
+
3
+ import httpx
4
+ from fastapi import HTTPException, Request
5
+
6
+ AUTH_SERVICE_URL = os.environ.get("AUTH_SERVICE_URL", "")
7
+
8
+
9
+ def authorize(required_permission: str):
10
+ async def middleware(request: Request) -> None:
11
+ user = getattr(request.state, "user", None)
12
+ user_id = (user or {}).get("userId") if isinstance(user, dict) else getattr(user, "userId", None)
13
+ if not user_id:
14
+ raise HTTPException(status_code=401, detail={"success": False, "message": "Authentication required"})
15
+
16
+ tenant_id = None
17
+ if isinstance(user, dict):
18
+ tenant_id = user.get("tenantId")
19
+ elif user is not None:
20
+ tenant_id = getattr(user, "tenantId", None)
21
+
22
+ try:
23
+ async with httpx.AsyncClient() as client:
24
+ response = await client.post(
25
+ f"{AUTH_SERVICE_URL}/api/auth/check-permission",
26
+ json={"userId": user_id, "permissionKey": required_permission},
27
+ headers={
28
+ "Authorization": request.headers.get("authorization", ""),
29
+ "tenant-id": tenant_id or request.headers.get("tenant-id", ""),
30
+ },
31
+ )
32
+ response.raise_for_status()
33
+
34
+ if not response.json().get("allowed"):
35
+ raise HTTPException(
36
+ status_code=403,
37
+ detail={"success": False, "message": "You do not have permission to perform this action"},
38
+ )
39
+ except HTTPException:
40
+ raise
41
+ except httpx.HTTPStatusError as error:
42
+ if error.response.status_code == 401:
43
+ raise HTTPException(status_code=401, detail={"success": False, "message": "Authentication required"})
44
+ raise HTTPException(status_code=503, detail={"success": False, "message": "Authorization service unavailable"})
45
+ except httpx.RequestError:
46
+ raise HTTPException(status_code=503, detail={"success": False, "message": "Authorization service unavailable"})
47
+
48
+ return middleware