diff --git a/src/controller/http_v1/workspace_members.py b/src/controller/http_v1/workspace_members.py index 9901ac1..081a361 100644 --- a/src/controller/http_v1/workspace_members.py +++ b/src/controller/http_v1/workspace_members.py @@ -11,6 +11,18 @@ from src.adapter.jwt import JWTPayload workspace_members_router = APIRouter(prefix='/workspaces/{workspace_id}/members', tags=['workspace members']) +@workspace_members_router.get('/me') +async def get_current_member_permissions( + workspace_id: uuid.UUID, + current_user: Annotated[JWTPayload, Depends(deps.get_current_user)], +) -> dto.WorkspaceMemberOutput: + """Get current user's membership and permissions in the workspace.""" + return await deps.get_usecase().get_current_member_permissions( + workspace_id=workspace_id, + user_id=current_user.user_id, + ) + + @workspace_members_router.get('') async def list_workspace_members( workspace_id: uuid.UUID, diff --git a/src/usecase/__init__.py b/src/usecase/__init__.py index 86d9495..a152dc4 100644 --- a/src/usecase/__init__.py +++ b/src/usecase/__init__.py @@ -57,7 +57,7 @@ from .workspace.create_workspace_invite import create_workspace_invite from .workspace.delete_workspace import delete_workspace from .workspace.delete_workspace_avatar import delete_workspace_avatar from .workspace.get_workspace_invites import get_workspace_invites -from .workspace.get_workspace_members import get_workspace_members +from .workspace.get_workspace_members import get_workspace_members, get_current_member_permissions from .workspace.get_workspaces import get_workspaces from .workspace.tg_accept_workspace_invite import tg_accept_workspace_invite from .workspace.update_workspace import update_workspace @@ -267,6 +267,7 @@ class Usecase: update_workspace_avatar = update_workspace_avatar delete_workspace_avatar = delete_workspace_avatar get_workspace_members = get_workspace_members + get_current_member_permissions = get_current_member_permissions update_workspace_member_permissions = update_workspace_member_permissions create_workspace_invite = create_workspace_invite get_workspace_invites = get_workspace_invites diff --git a/src/usecase/purchase/get_placements.py b/src/usecase/purchase/get_placements.py index a0efd09..c3d36bd 100644 --- a/src/usecase/purchase/get_placements.py +++ b/src/usecase/purchase/get_placements.py @@ -27,6 +27,9 @@ async def get_placements(self: 'Usecase', input: dto.GetPlacementsInput) -> dto. context.ensure_project_permission(domain.PermissionKey.PLACEMENTS_READ, project.id) + # Check analytics permissions to determine if subscription data should be hidden + hide_subscriptions = context.should_hide_subscriptions() + # Prefetch project channel for output building if project.channel is None: project_channel = await self.database.get_channel(channel_id=project.channel_id) @@ -75,9 +78,11 @@ async def get_placements(self: 'Usecase', input: dto.GetPlacementsInput) -> dto. time_on_top = time_on_top_map.get(placement_post.id) if placement_post.post: views_count = views_map.get(placement_post.post.id, (None,))[0] + # Hide subscriptions if user doesn't have analytics_read permission + subscriptions_count = 0 if hide_subscriptions else subscriptions_counts.get(placement_post.placement_id, 0) placement_post_output = _build_placement_post_output( placement_post, - subscriptions_counts.get(placement_post.placement_id, 0), + subscriptions_count, views_count, time_on_top, ) diff --git a/src/usecase/workspace/get_workspace_members.py b/src/usecase/workspace/get_workspace_members.py index 6cc1817..6b62846 100644 --- a/src/usecase/workspace/get_workspace_members.py +++ b/src/usecase/workspace/get_workspace_members.py @@ -9,6 +9,21 @@ if TYPE_CHECKING: from .. import Usecase +async def get_current_member_permissions( + self: Usecase, workspace_id: uuid.UUID, user_id: uuid.UUID +) -> dto.WorkspaceMemberOutput: + """Get current user's membership and permissions in the workspace. + + This endpoint does NOT require ADMIN_FULL - any workspace member can access their own permissions. + """ + membership = await self.database.get_workspace_membership(workspace_id, user_id) + + if not membership: + raise domain.WorkspaceNotFound(workspace_id) + + return dto.WorkspaceMemberOutput.from_domain(membership) + + async def get_workspace_members( self: Usecase, workspace_id: uuid.UUID, user_id: uuid.UUID ) -> list[dto.WorkspaceMemberOutput]: