Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return a better workspace user roles json #338

Merged
merged 1 commit into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion fixbackend/permissions/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ async def list_roles(

roles = no_assigned_roles + roles

return [UserRolesRead.from_model(role) for role in roles]
only_workspace_roles = [role for role in roles if role.workspace_id == workspace.id]

return [UserRolesRead.from_model(role) for role in only_workspace_roles]

@router.put("/{workspace_id}/roles/{user_id}")
async def update_user_role(
Expand Down
2 changes: 1 addition & 1 deletion fixbackend/workspaces/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ async def list_users(
) -> List[WorkspaceUserRead]:
user_ids = workspace.all_users()
users = await user_repository.get_by_ids(user_ids)
return [WorkspaceUserRead.from_model(user) for user in users]
return [WorkspaceUserRead.from_model(user, workspace.id) for user in users]

@router.post("/{workspace_id}/invites/")
async def invite_to_organization(
Expand Down
42 changes: 38 additions & 4 deletions fixbackend/workspaces/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.

from datetime import datetime
from functools import reduce
from typing import List, Literal, Optional, Union
from fixbackend.auth.models import User
from fixbackend.ids import InvitationId, WorkspaceId, UserId, ExternalId

from pydantic import BaseModel, EmailStr, Field

from fixbackend.permissions.models import Roles, UserRole
from fixbackend.workspaces.models import Workspace, WorkspaceInvitation
from fixbackend.permissions.schemas import UserRolesRead


class WorkspaceRead(BaseModel):
Expand Down Expand Up @@ -179,22 +180,55 @@ class FixUserSource(BaseModel):
UserSource = Union[FixUserSource]


class WorkspaceUserRoleRead(BaseModel):
member: bool = Field(description="if user has member role")
admin: bool = Field(description="if user has admin role")
owner: bool = Field(description="if user has owner role")
billing_admin: bool = Field(description="if user has billing role")

@staticmethod
def from_model(model: List[UserRole]) -> "WorkspaceUserRoleRead":
role_names = reduce(lambda x, y: x | y, [role.role_names for role in model], Roles(0))

return WorkspaceUserRoleRead(
member=Roles.workspace_member in role_names,
admin=Roles.workspace_admin in role_names,
owner=Roles.workspace_owner in role_names,
billing_admin=Roles.workspace_billing_admin in role_names,
)

model_config = {
"json_schema_extra": {
"examples": [
{
"user_id": "00000000-0000-0000-0000-000000000000",
"user_email": "[email protected]",
"member": True,
"owner": True,
"admin": False,
"billing_admin": False,
}
]
}
}


class WorkspaceUserRead(BaseModel):
id: UserId = Field(description="The user's unique identifier")
sources: List[UserSource] = Field(description="Where the user is found")
name: str = Field(description="The user's name")
email: str = Field(description="The user's email")
roles: List[UserRolesRead] = Field(description="The user's roles")
roles: WorkspaceUserRoleRead = Field(description="The user's roles")
last_login: Optional[datetime] = Field(description="The user's last login time, if any")

@staticmethod
def from_model(user: User) -> "WorkspaceUserRead":
def from_model(user: User, workspace_id: WorkspaceId) -> "WorkspaceUserRead":
return WorkspaceUserRead(
id=user.id,
sources=[FixUserSource()],
name=user.email,
email=user.email,
roles=[UserRolesRead.from_model(role) for role in user.roles],
roles=WorkspaceUserRoleRead.from_model([role for role in user.roles if role.workspace_id == workspace_id]),
last_login=None,
)

Expand Down
32 changes: 12 additions & 20 deletions tests/fixbackend/workspaces/router_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,27 +110,19 @@ async def test_list_workspace_users(
assert user_json.get("id") == str(user.id)
assert user_json.get("email") == user.email
assert user_json.get("name") == user.email
assert user_json.get("roles") == [
{
"user_id": str(user.id),
"workspace_id": str(workspace.id),
"member": False,
"admin": False,
"owner": True,
"billing_admin": False,
}
]
assert user_json.get("roles") == {
"member": False,
"admin": False,
"owner": True,
"billing_admin": False,
}

await role_repository.add_roles(user.id, workspace.id, Roles.workspace_admin)
response = await client.get(f"/api/workspaces/{workspace.id}/users/")
user_json = response.json()[0]
assert user_json.get("roles") == [
{
"user_id": str(user.id),
"workspace_id": str(workspace.id),
"member": False,
"admin": True,
"owner": True,
"billing_admin": False,
}
]
assert user_json.get("roles") == {
"member": False,
"admin": True,
"owner": True,
"billing_admin": False,
}
Loading