forked from QuivrHQ/quivr
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Authorization] Check user role before operations (QuivrHQ#588)
* feat(security): add RBAC on /explore/* * feat(security): add RBAC on /brains/*
- Loading branch information
1 parent
1be71e9
commit 72924b5
Showing
5 changed files
with
122 additions
and
6 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
Empty file.
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,60 @@ | ||
from functools import wraps | ||
from typing import Optional | ||
from uuid import UUID | ||
|
||
from fastapi import HTTPException, status | ||
from models.brains import Brain | ||
from models.users import User | ||
|
||
|
||
def has_brain_authorization(required_role: str = "Owner"): | ||
def decorator(func): | ||
@wraps(func) | ||
async def wrapper(current_user: User, *args, **kwargs): | ||
brain_id: Optional[UUID] = kwargs.get("brain_id") | ||
user_id = current_user.id | ||
|
||
if brain_id is None: | ||
raise HTTPException( | ||
status_code=status.HTTP_400_BAD_REQUEST, | ||
detail="Missing brain ID", | ||
) | ||
|
||
validate_brain_authorization( | ||
brain_id, user_id=user_id, required_role=required_role | ||
) | ||
|
||
return await func(*args, **kwargs) | ||
|
||
return wrapper | ||
|
||
return decorator | ||
|
||
|
||
def validate_brain_authorization( | ||
brain_id: UUID, | ||
user_id: UUID, | ||
required_role: Optional[str] = "Owner", | ||
): | ||
if required_role is None: | ||
raise HTTPException( | ||
status_code=status.HTTP_400_BAD_REQUEST, | ||
detail="Missing required role", | ||
) | ||
|
||
brain = Brain(id=brain_id) | ||
user_brain = brain.get_brain_for_user(user_id) | ||
|
||
if user_brain is None: | ||
raise HTTPException( | ||
status_code=status.HTTP_404_NOT_FOUND, | ||
detail="You don't have permission for this brain", | ||
) | ||
|
||
# TODO: Update this logic when we have more roles | ||
# Eg: Owner > Admin > User ... this should be taken into account | ||
if user_brain.get("rights") != required_role: | ||
raise HTTPException( | ||
status_code=status.HTTP_403_FORBIDDEN, | ||
detail="You don't have the required role for this brain", | ||
) |
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