Various fixes from fast follows
- Sort roles by alphabetical order
- Change some tooltips
- During role creation, role should have all permissions enabled by
default
- Changed Permission icons design and refactored duplicating logic in a
dedicated component
- Changed "Revoked by" design
- Display role icon in default role picker
- Workspace member avatar was missing in role list and member picker
- Set "seeded" member role as editable for new workspaces
- Various css fixes
In this PR we are
- (if permissionsV2 is enabled) executing permission checks at query
builder level. To do so we want to override the query builders methods
that are performing db calls (.execute(), .getMany(), ... etc.) For now
I have just overriden some of the query builders methods for the poc. To
do so I created custom query builder classes that extend typeorm's query
builder (selectQueryBuilder and updateQueryBuilder, for now and later I
will tackle softDeleteQueryBuilder, etc.).
- adding a notion of roles permissions version and roles permissions
object to datasources. We will now use one datasource per roleId and
rolePermissionVersion. Both rolesPermissionsVersion and rolesPermissions
objects are stored in redis and recomputed at role update or if queried
and found empty. Unlike for metadata version we don't need to store a
version in the db that stands for the source of truth. We also don't
need to destroy and recreate the datasource if the rolesPermissions
version changes, but only to update the value for rolesPermissions and
rolesPermissionsVersions on the existing datasource.
What this PR misses
- computing of roles permissions should take into account
objectPermissions table (for now it only looks at what's on the roles
table)
- pursue extension of query builder classes and overriding of their db
calling-methods
- what should the behaviour be for calls from twentyOrmGlobalManager
that don't have a roleId?
In this PR
- updateWorkspaceMemberRole api was changed to stop allowing null as a
valid value for roleId. it is not possible anymore to just unassign a
role from a user. instead it is only possible to assign a different role
to a user, which will unassign them from their previous role. For this
reason in the FE the bins icons next to the workspaceMember on a role
page were removed
- updateWorkspaceMemberRole will throw if a user attempts to update
their own role
- tests tests tests!
## Context
Adding a defaultRole to each workspace, this role will be automatically
added when a member joins a workspace via invite link or public link
(seeds work differently though).
Took the occasion to refactor a bit the frontend components, splitting
them in smaller components for more readability.
## Test
<img width="948" alt="Screenshot 2025-02-24 at 14 54 02"
src="https://github.com/user-attachments/assets/13ef1452-d3c9-4385-940c-2ced0f0b05ef"
/>
Adding SettingsPermissionsGuard to execute permission check.
The guard is added directly in resolver, either at resolver level (ex:
roles) or resolver-endpoint level (ex: metadata). this can be challenged
!
In this PR, we are implementing the updateRole endpoint with the
following rules
1. A user can only update a member's role if they have the permission (=
the admin role)
2. Admin role can't be unassigned if there are no other admin in the
workspace
3. (For now) as members can only have one role for now, when they are
assigned a new role, they are first unassigned the other role (if any)
4. (For now) removing a member's admin role = leaving the member with no
role = calling updateRole with a null roleId
In this PR
- introducing roles module to separate roles logic (assign a Role, get a
workspace's roles etc.) from permission logic (check if a user has a
permission)
- Introduces getRoles endpoint to fetch a workspace's roles
- introduces the first permission check: getRoles in only accessible to
users with permission on ROLE setting. Implemented
validatesUserHasWorkspaceSettingPermissionOrThrow