feat: add organization-related models and update schemas for organization management
This commit is contained in:
@@ -13,6 +13,14 @@ from app.models.agents import Agent
|
||||
from app.models.boards import Board
|
||||
from app.models.tasks import Task
|
||||
from app.models.users import User
|
||||
from app.models.organizations import Organization
|
||||
from app.services.organizations import (
|
||||
OrganizationContext,
|
||||
ensure_member_for_user,
|
||||
get_active_membership,
|
||||
is_org_admin,
|
||||
require_board_access,
|
||||
)
|
||||
from app.services.admin_access import require_admin
|
||||
|
||||
|
||||
@@ -40,6 +48,31 @@ def require_admin_or_agent(
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
|
||||
async def require_org_member(
|
||||
auth: AuthContext = Depends(get_auth_context),
|
||||
session: AsyncSession = Depends(get_session),
|
||||
) -> OrganizationContext:
|
||||
if auth.user is None:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
|
||||
member = await get_active_membership(session, auth.user)
|
||||
if member is None:
|
||||
member = await ensure_member_for_user(session, auth.user)
|
||||
if member is None:
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
|
||||
organization = await session.get(Organization, member.organization_id)
|
||||
if organization is None:
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
|
||||
return OrganizationContext(organization=organization, member=member)
|
||||
|
||||
|
||||
async def require_org_admin(
|
||||
ctx: OrganizationContext = Depends(require_org_member),
|
||||
) -> OrganizationContext:
|
||||
if not is_org_admin(ctx.member):
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
|
||||
return ctx
|
||||
|
||||
|
||||
async def get_board_or_404(
|
||||
board_id: str,
|
||||
session: AsyncSession = Depends(get_session),
|
||||
@@ -50,9 +83,73 @@ async def get_board_or_404(
|
||||
return board
|
||||
|
||||
|
||||
async def get_board_for_actor_read(
|
||||
board_id: str,
|
||||
session: AsyncSession = Depends(get_session),
|
||||
actor: ActorContext = Depends(require_admin_or_agent),
|
||||
) -> Board:
|
||||
board = await session.get(Board, board_id)
|
||||
if board is None:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
|
||||
if actor.actor_type == "agent":
|
||||
if actor.agent and actor.agent.board_id and actor.agent.board_id != board.id:
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
|
||||
return board
|
||||
if actor.user is None:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
|
||||
await require_board_access(session, user=actor.user, board=board, write=False)
|
||||
return board
|
||||
|
||||
|
||||
async def get_board_for_actor_write(
|
||||
board_id: str,
|
||||
session: AsyncSession = Depends(get_session),
|
||||
actor: ActorContext = Depends(require_admin_or_agent),
|
||||
) -> Board:
|
||||
board = await session.get(Board, board_id)
|
||||
if board is None:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
|
||||
if actor.actor_type == "agent":
|
||||
if actor.agent and actor.agent.board_id and actor.agent.board_id != board.id:
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
|
||||
return board
|
||||
if actor.user is None:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
|
||||
await require_board_access(session, user=actor.user, board=board, write=True)
|
||||
return board
|
||||
|
||||
|
||||
async def get_board_for_user_read(
|
||||
board_id: str,
|
||||
session: AsyncSession = Depends(get_session),
|
||||
auth: AuthContext = Depends(get_auth_context),
|
||||
) -> Board:
|
||||
board = await session.get(Board, board_id)
|
||||
if board is None:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
|
||||
if auth.user is None:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
|
||||
await require_board_access(session, user=auth.user, board=board, write=False)
|
||||
return board
|
||||
|
||||
|
||||
async def get_board_for_user_write(
|
||||
board_id: str,
|
||||
session: AsyncSession = Depends(get_session),
|
||||
auth: AuthContext = Depends(get_auth_context),
|
||||
) -> Board:
|
||||
board = await session.get(Board, board_id)
|
||||
if board is None:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
|
||||
if auth.user is None:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
|
||||
await require_board_access(session, user=auth.user, board=board, write=True)
|
||||
return board
|
||||
|
||||
|
||||
async def get_task_or_404(
|
||||
task_id: str,
|
||||
board: Board = Depends(get_board_or_404),
|
||||
board: Board = Depends(get_board_for_actor_read),
|
||||
session: AsyncSession = Depends(get_session),
|
||||
) -> Task:
|
||||
task = await session.get(Task, task_id)
|
||||
|
||||
Reference in New Issue
Block a user