Skip to content

Commit

Permalink
Add RBAC to teams API : 295
Browse files Browse the repository at this point in the history
Resolves: AlmaLinux/build-system#295
* Anyone can now create teams/products, fixed unexpected 404 error during creation
* Team router dependency switched from get_current_super_user to get_current_user
* can_perform checks added to endpoints, updated routers to pass user
  • Loading branch information
amizhen committed Jul 1, 2024
1 parent 1955a76 commit 9241287
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 7 deletions.
2 changes: 1 addition & 1 deletion alws/crud/products.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ async def modify_product(
db_user = await get_user(db, user_id=user_id)
if not db_user:
raise DataNotFoundError(f"User={user_id} doesn't exist")
if not can_perform(db_product, db_user, actions.ReleaseToProduct.name):
if not can_perform(db_product, db_user, actions.UpdateProduct.name):
raise PermissionDenied(
'User has no permissions '
f'to modify the product "{db_product.name}"'
Expand Down
47 changes: 46 additions & 1 deletion alws/crud/teams.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,30 @@
]


from alws.perms.authorization import can_perform
from alws.errors import (
PermissionDenied,
)
from alws.perms import actions
from alws.perms.actions import (
CreateTeam,
DeleteTeam,
InviteToTeam,
LeaveTeam,
ReadTeam,
RemoveFromTeam,
UpdateTeam,
)
from alws.models import (
Team,
User,
UserAction,
UserRole,
)
from alws.crud.actions import ensure_all_actions_exist
from alws.crud.user import get_user


def get_team_role_name(team_name: str, role_name: str):
return f'{team_name}_{role_name}'

Expand Down Expand Up @@ -191,6 +215,7 @@ async def update_members(
payload: team_schema.TeamMembersUpdate,
team_id: int,
modification: str,
user_id: int,
) -> Team:
items_to_update = []
db_team = (
Expand All @@ -210,6 +235,14 @@ async def update_members(
)
if not db_team:
raise TeamError(f'Team={team_id} doesn`t exist')

db_user = await get_user(session, user_id=user_id)

if not can_perform(db_team, db_user, actions.UpdateTeam.name):
raise PermissionDenied(
f"User has no permissions to update the team {db_team.name}"
)

db_users = await session.execute(
select(User)
.where(User.id.in_((user.id for user in payload.members_to_update)))
Expand Down Expand Up @@ -241,10 +274,22 @@ async def update_members(
return db_team


async def remove_team(db: AsyncSession, team_id: int):
async def remove_team(
db: AsyncSession,
team_id: int,
user_id: int,
):
db_team = await get_teams(db, team_id=team_id)
db_user = await get_user(db, user_id=user_id)

if not db_team:
raise TeamError(f'Team={team_id} doesn`t exist')

if not can_perform(db_team, db_user, actions.DeleteTeam.name):
raise PermissionDenied(
f"User has no permissions to delete the team {db_team.name}"
)

if db_team.products:
raise TeamError(
f"Cannot delete Team={team_id}, team contains undeleted products",
Expand Down
15 changes: 10 additions & 5 deletions alws/routers/teams.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,18 @@
from fastapi_sqla import AsyncSessionDependency
from sqlalchemy.ext.asyncio import AsyncSession

from alws.auth import get_current_superuser
from alws.auth import get_current_user
from alws.crud import teams
from alws.dependencies import get_async_db_key
from alws.errors import TeamError
from alws.schemas import team_schema
from alws.models import User


router = APIRouter(
prefix='/teams',
tags=['teams'],
dependencies=[Depends(get_current_superuser)],
dependencies=[Depends(get_current_user)],
)

public_router = APIRouter(
Expand Down Expand Up @@ -53,9 +55,10 @@ async def add_members(
team_id: int,
payload: team_schema.TeamMembersUpdate,
db: AsyncSession = Depends(AsyncSessionDependency(key=get_async_db_key())),
user: User = Depends(get_current_user),
):
try:
db_team = await teams.update_members(db, payload, team_id, 'add')
db_team = await teams.update_members(db, payload, team_id, 'add', user.id)
except TeamError as exc:
raise HTTPException(
detail=str(exc),
Expand All @@ -69,9 +72,10 @@ async def remove_members(
team_id: int,
payload: team_schema.TeamMembersUpdate,
db: AsyncSession = Depends(AsyncSessionDependency(key=get_async_db_key())),
user: User = Depends(get_current_user),
):
try:
db_team = await teams.update_members(db, payload, team_id, 'remove')
db_team = await teams.update_members(db, payload, team_id, 'remove', user.id)
except TeamError as exc:
raise HTTPException(
detail=str(exc),
Expand Down Expand Up @@ -99,9 +103,10 @@ async def create_team(
async def remove_team(
team_id: int,
db: AsyncSession = Depends(AsyncSessionDependency(key=get_async_db_key())),
user: User = Depends(get_current_user),
):
try:
await teams.remove_team(db, team_id)
await teams.remove_team(db, team_id, user.id)
except TeamError as exc:
raise HTTPException(
detail=str(exc),
Expand Down

0 comments on commit 9241287

Please sign in to comment.