Skip to content

Commit

Permalink
Merge pull request #74 from unipoll/development
Browse files Browse the repository at this point in the history
Updated get/update policies routes
  • Loading branch information
mike-pisman authored Oct 15, 2023
2 parents 7d4feb0 + b65dc01 commit 6a950e6
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 134 deletions.
54 changes: 7 additions & 47 deletions src/unipoll_api/routes/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from typing import Annotated, Literal
from fastapi import APIRouter, Body, Depends, HTTPException, Query, status
from unipoll_api import dependencies as Dependencies
from unipoll_api import AccountManager
from unipoll_api.actions import GroupActions, PermissionsActions, MembersActions, PolicyActions
from unipoll_api.exceptions.resource import APIException
from unipoll_api.schemas import GroupSchemas, PolicySchemas, MemberSchemas
Expand Down Expand Up @@ -128,34 +127,22 @@ async def remove_group_member(group: Group = Depends(Dependencies.get_group),
# List all policies in the workspace
@router.get("/{group_id}/policies",
response_description="List of all policies",
response_model=PolicySchemas.PolicyList,)
async def get_group_policies(group: Group = Depends(Dependencies.get_group)) -> PolicySchemas.PolicyList:
response_model=PolicySchemas.PolicyList)
async def get_group_policies(group: Group = Depends(Dependencies.get_group),
account_id: ResourceID = Query(None)) -> PolicySchemas.PolicyList:
try:
return await PolicyActions.get_policies(resource=group)
except APIException as e:
raise HTTPException(status_code=e.code, detail=str(e))


# List user's permissions in the group
@router.get("/{group_id}/policy",
response_description="List of all member policies",
response_model=PolicySchemas.PolicyOutput)
async def get_group_policy(group: Group = Depends(Dependencies.get_group),
account_id: ResourceID | None = None):
try:
account = await Dependencies.get_account(account_id) if account_id else AccountManager.active_user.get()
policy_list = await PolicyActions.get_policies(resource=group, policy_holder=account)
policy = policy_list.policies[0]
return PolicySchemas.PolicyOutput(**policy.model_dump())
account = await Dependencies.get_account(account_id) if account_id else None
return await PolicyActions.get_policies(resource=group, policy_holder=account)
except APIException as e:
raise HTTPException(status_code=e.code, detail=str(e))


# Set permissions for a user in a group
@router.put("/{group_id}/policy",
@router.put("/{group_id}/policies/{policy_id}",
response_description="Updated policy",
response_model=PolicySchemas.PolicyOutput)
async def set_group_policy(group: Group = Depends(Dependencies.get_group),
policy: Policy = Depends(Dependencies.get_policy),
permissions: PolicySchemas.PolicyInput = Body(...)):
"""
Sets the permissions for a user in a workspace.
Expand All @@ -166,33 +153,6 @@ async def set_group_policy(group: Group = Depends(Dependencies.get_group),
- **permissions** (int): new permissions for the user
"""
try:
# return await GroupActions.set_group_policy(group, permissions)

policy = None
if permissions.policy_id:
policy = await Dependencies.get_policy(permissions.policy_id) # type: ignore
elif permissions.account_id:
account = await Dependencies.get_account(permissions.account_id)
# policy = await Policy.find_one(Policy.policy_holder.id == account.id, fetch_links=True)
# Temporarily workaround
policy_list = await PolicyActions.get_policies(resource=group, policy_holder=account) # type: ignore
policy = policy_list.policies[0] # type: ignore
policy = await Policy.get(policy.id, fetch_links=True) # type: ignore
elif permissions.group_id:
# Temporarily workaround
group = await Dependencies.get_group(permissions.group_id)
policy_list = await PolicyActions.get_policies(resource=group, policy_holder=group) # type: ignore
policy = policy_list.policies[0] # type: ignore
policy = await Policy.get(policy.id, fetch_links=True) # type: ignore
else:
account = AccountManager.active_user.get()
policy_list = await PolicyActions.get_policies(resource=group, policy_holder=account)
policy = policy_list.policies[0]
policy = await Policy.get(policy.id, fetch_links=True)

if not policy:
raise APIException(404, "Policy not found 404")

return await PolicyActions.update_policy(policy, new_permissions=permissions.permissions)
except APIException as e:
raise HTTPException(status_code=e.code, detail=str(e))
Expand Down
51 changes: 6 additions & 45 deletions src/unipoll_api/routes/workspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from unipoll_api.exceptions.resource import APIException
from unipoll_api.documents import Account, Workspace, ResourceID, Policy
from unipoll_api.schemas import WorkspaceSchemas, PolicySchemas, GroupSchemas, MemberSchemas, PollSchemas
from unipoll_api import AccountManager

# APIRouter creates path operations for user module
open_router: APIRouter = APIRouter()
Expand Down Expand Up @@ -219,33 +218,21 @@ async def remove_workspace_member(workspace: Workspace = Depends(Dependencies.ge
@router.get("/{workspace_id}/policies",
response_description="List of all policies",
response_model=PolicySchemas.PolicyList)
async def get_workspace_policies(workspace: Workspace = Depends(Dependencies.get_workspace)):
async def get_workspace_policies(workspace: Workspace = Depends(Dependencies.get_workspace),
account_id: ResourceID = Query(None)):
try:
return await actions.PolicyActions.get_policies(resource=workspace)
except APIException as e:
raise HTTPException(status_code=e.code, detail=str(e))


# List member's permissions in the workspace
@router.get("/{workspace_id}/policy",
response_description="List member policy(permissions)",
response_model=PolicySchemas.PolicyOutput)
async def get_workspace_policy(workspace: Workspace = Depends(Dependencies.get_workspace),
account_id: ResourceID | None = None):
try:
account = await Dependencies.get_account(account_id) if account_id else AccountManager.active_user.get()
policy_list = await actions.PolicyActions.get_policies(resource=workspace, policy_holder=account)
policy = policy_list.policies[0]
return PolicySchemas.PolicyOutput(**policy.model_dump())
account = await Dependencies.get_account(account_id) if account_id else None
return await actions.PolicyActions.get_policies(resource=workspace, policy_holder=account)
except APIException as e:
raise HTTPException(status_code=e.code, detail=str(e))


# Set permissions for a member in a workspace
@router.put("/{workspace_id}/policy",
@router.put("/{workspace_id}/policies/{policy_id}",
response_description="Updated permissions",
response_model=PolicySchemas.PolicyOutput)
async def set_workspace_policy(workspace: Workspace = Depends(Dependencies.get_workspace),
policy: Policy = Depends(Dependencies.get_policy),
permissions: PolicySchemas.PolicyInput = Body(...)):
"""
Sets the permissions for a user in a workspace.
Expand All @@ -258,32 +245,6 @@ async def set_workspace_policy(workspace: Workspace = Depends(Dependencies.get_w
Returns the updated workspace.
"""
try:
# return await WorkspaceActions.set_workspace_policy(workspace, permissions)
policy = None
if permissions.policy_id:
policy = await Dependencies.get_policy(permissions.policy_id) # type: ignore
elif permissions.account_id:
account = await Dependencies.get_account(permissions.account_id)
# policy = await Policy.find_one(Policy.policy_holder.id == account.id, fetch_links=True)
# Temporarily workaround
policy_list = await actions.PolicyActions.get_policies(resource=workspace, policy_holder=account)
policy = policy_list.policies[0] # type: ignore
policy = await Policy.get(policy.id, fetch_links=True) # type: ignore
elif permissions.group_id:
# Temporarily workaround
group = await Dependencies.get_group(permissions.group_id)
policy_list = await actions.PolicyActions.get_policies(resource=workspace, policy_holder=group)
policy = policy_list.policies[0] # type: ignore
policy = await Policy.get(policy.id, fetch_links=True) # type: ignore
else:
account = AccountManager.active_user.get()
policy_list = await actions.PolicyActions.get_policies(resource=workspace, policy_holder=account)
policy = policy_list.policies[0] # type: ignore
policy = await Policy.get(policy.id, fetch_links=True) # type: ignore

if not policy:
raise APIException(404, "Policy not found 404")

return await actions.PolicyActions.update_policy(policy, new_permissions=permissions.permissions)
except APIException as e:
raise HTTPException(status_code=e.code, detail=str(e))
Expand Down
50 changes: 33 additions & 17 deletions tests/test_2_workspaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,25 +242,30 @@ async def test_get_workspace_members(client_test: AsyncClient):

async def test_get_permissions(client_test: AsyncClient):
print("\n")
colored_dbg.test_info("Getting list of member permissions in workspace [GET /workspaces/{workspace.id}/policy]")
colored_dbg.test_info("Getting list of member permissions in workspace" +
"[GET /workspaces/{workspace.id}/policies?account_id={account_id}]")
workspace = workspaces[0]
active_user = accounts[0]

# Check permission of the user who created the workspace
response = await client_test.get(f"/workspaces/{workspace.id}/policy",
headers={"Authorization": f"Bearer {active_user.token}"})
response = await client_test.get(f"/workspaces/{workspace.id}/policies",
headers={"Authorization": f"Bearer {active_user.token}"},
params={"account_id": str(active_user.id)})
assert response.status_code == status.HTTP_200_OK
response = response.json()
# Creator of the workspace should have all permissions
assert response["permissions"] == Permissions.WORKSPACE_ALL_PERMISSIONS.name.split("|") # type: ignore

policy = response['policies'][0]
assert policy["permissions"] == Permissions.WORKSPACE_ALL_PERMISSIONS.name.split("|") # type: ignore

# Check permission of the rest of the members
for i in range(1, len(accounts)):
response = await client_test.get(f"/workspaces/{workspace.id}/policy",
response = await client_test.get(f"/workspaces/{workspace.id}/policies",
params={"account_id": accounts[i].id}, # type: ignore
headers={"Authorization": f"Bearer {active_user.token}"})
response = response.json()
assert response["permissions"] == Permissions.WORKSPACE_BASIC_PERMISSIONS.name.split("|") # type: ignore
policy = response['policies'][0]
assert policy["permissions"] == Permissions.WORKSPACE_BASIC_PERMISSIONS.name.split("|") # type: ignore
colored_dbg.test_success("All members have the correct permissions")


Expand Down Expand Up @@ -340,12 +345,13 @@ async def test_permissions(client_test: AsyncClient):
assert res.status_code == status.HTTP_403_FORBIDDEN

# Try to get workspace permissions
res = await client_test.get(f"/workspaces/{workspace.id}/policy", headers=headers)
res = await client_test.get(f"/workspaces/{workspace.id}/policies", headers=headers)
# assert res.status_code == status.HTTP_403_FORBIDDEN
assert res.status_code == status.HTTP_200_OK
policy = res.json()["policies"][0]

# Try to set workspace permissions
res = await client_test.put(f"/workspaces/{workspace.id}/policy",
# # Try to set workspace permissions
res = await client_test.put(f"/workspaces/{workspace.id}/policies/{policy['id']}",
json={"permissions": Permissions.WORKSPACE_BASIC_PERMISSIONS.name.split("|")},
headers=headers)
assert res.status_code == status.HTTP_403_FORBIDDEN
Expand All @@ -357,32 +363,42 @@ async def test_permissions(client_test: AsyncClient):

async def test_set_permissions(client_test: AsyncClient):
print("\n")
colored_dbg.test_info("Setting permissions of workspace members [PUT /workspaces/{workspace.id}/policy]")
colored_dbg.test_info("Setting permissions of members [PUT /workspaces/{workspace.id}/policy/{policy_id}]")
active_user = accounts[0]
workspace = workspaces[0]

# Get policy of another member
response = await client_test.get(f"/workspaces/{workspace.id}/policies",
params={"account_id": str(accounts[1].id)},
headers={"Authorization": f"Bearer {active_user.token}"})
assert response.status_code == status.HTTP_200_OK
response = response.json()
policy = response["policies"][0]

# Update policy of another member
response = await client_test.put(f"/workspaces/{workspace.id}/policy?",
json={"account_id": accounts[1].id,
"permissions": Permissions.WORKSPACE_ALL_PERMISSIONS.name.split("|")},
response = await client_test.put(f"/workspaces/{workspace.id}/policies/{policy['id']}",
json={"permissions": Permissions.WORKSPACE_ALL_PERMISSIONS.name.split("|")},
headers={"Authorization": f"Bearer {active_user.token}"})
assert response.status_code == status.HTTP_200_OK
response = response.json()
assert response["permissions"] == Permissions.WORKSPACE_ALL_PERMISSIONS.name.split("|")

# Check permissions
response = await client_test.get(f"/workspaces/{workspace.id}/policy?account_id={accounts[1].id}",
response = await client_test.get(f"/workspaces/{workspace.id}/policies",
params={"account_id": str(accounts[1].id)},
headers={"Authorization": f"Bearer {active_user.token}"})
assert response.status_code == status.HTTP_200_OK
response = response.json()
assert response["permissions"] == Permissions.WORKSPACE_ALL_PERMISSIONS.name.split("|")
policy = response["policies"][0]
assert policy["permissions"] == Permissions.WORKSPACE_ALL_PERMISSIONS.name.split("|")

# Now the member should be able to get their policy information
response = await client_test.get(f"/workspaces/{workspace.id}/policy",
response = await client_test.get(f"/workspaces/{workspace.id}/policies",
headers={"Authorization": f"Bearer {accounts[1].token}"})
assert response.status_code == status.HTTP_200_OK
response = response.json()
assert response["permissions"] == Permissions.WORKSPACE_ALL_PERMISSIONS.name.split("|")
policy = response["policies"][0]
assert policy["permissions"] == Permissions.WORKSPACE_ALL_PERMISSIONS.name.split("|")

colored_dbg.test_success("All members have the correct permissions")

Expand Down
Loading

0 comments on commit 6a950e6

Please sign in to comment.