-
Notifications
You must be signed in to change notification settings - Fork 233
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2166 from Agenta-AI/feature/app-security
[Feature] Application Security
- Loading branch information
Showing
15 changed files
with
430 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
100 changes: 100 additions & 0 deletions
100
agenta-backend/agenta_backend/routers/permissions_router.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
from typing import Optional | ||
from uuid import UUID | ||
|
||
from fastapi import Request, Query, HTTPException | ||
from fastapi.responses import JSONResponse | ||
|
||
from agenta_backend.utils.common import isCloudEE, isOss, APIRouter | ||
from agenta_backend.services import db_manager | ||
|
||
if isCloudEE(): | ||
from agenta_backend.commons.models.shared_models import Permission | ||
from agenta_backend.commons.utils.permissions import check_action_access | ||
|
||
|
||
class Allow(JSONResponse): | ||
def __init__( | ||
self, | ||
credentials: Optional[str] = None, | ||
) -> None: | ||
super().__init__( | ||
status_code=200, | ||
content={ | ||
"effect": "allow", | ||
"credentials": credentials, | ||
}, | ||
) | ||
|
||
|
||
class Deny(HTTPException): | ||
def __init__(self) -> None: | ||
super().__init__( | ||
status_code=401, | ||
detail="Unauthorized", | ||
) | ||
|
||
|
||
router = APIRouter() | ||
|
||
|
||
@router.get( | ||
"/verify", | ||
operation_id="verify_permissions", | ||
) | ||
async def verify_permissions( | ||
request: Request, | ||
action: Optional[str] = Query(None), | ||
resource_type: Optional[str] = Query(None), | ||
resource_id: Optional[UUID] = Query(None), | ||
): | ||
try: | ||
if isOss(): | ||
return Allow(None) | ||
|
||
if not action or not resource_type or not resource_id: | ||
raise Deny() | ||
|
||
if isCloudEE(): | ||
permission = Permission(action) | ||
|
||
# CHECK PERMISSION 1/2: ACTION | ||
allow_action = await check_action_access( | ||
user_uid=request.state.user_id, | ||
project_id=request.state.project_id, | ||
permission=permission, | ||
) | ||
|
||
if not allow_action: | ||
raise Deny() | ||
|
||
# CHECK PERMISSION 2/2: RESOURCE | ||
allow_resource = await check_resource_access( | ||
project_id=UUID(request.state.project_id), | ||
resource_id=resource_id, | ||
resource_type=resource_type, | ||
) | ||
|
||
if not allow_resource: | ||
raise Deny() | ||
|
||
return Allow(request.state.credentials) | ||
|
||
except Exception as exc: # pylint: disable=bare-except | ||
raise Deny() from exc | ||
|
||
|
||
async def check_resource_access( | ||
project_id: UUID, | ||
resource_id: UUID, | ||
resource_type: str, | ||
) -> bool: | ||
resource_project_id = None | ||
|
||
if resource_type == "application": | ||
app = await db_manager.get_app_instance_by_id(app_id=str(resource_id)) | ||
|
||
resource_project_id = app.project_id | ||
|
||
allow_resource = resource_project_id == project_id | ||
|
||
return allow_resource |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.