feat: add sharing info to /workspaces endpoint (#21049)

closes: https://github.com/coder/internal/issues/858

Similar to https://github.com/coder/coder/pull/19375, this one uses
system permissions for fetching actual user and group data.

Modifies the `workspaces_expanded` view to fetch the required data; this way it's made available to all code paths that make use of it.  

Also fixes a bug in a test helper function that can result in `null` being saved to the DB for `user_acl` or `group_acl` and break tests; a defensive check constraint that prevents this is worth a PR, e.g:

`ALTER TABLE workspaces
   ADD CONSTRAINT group_acl_is_object CHECK (jsonb_typeof(group_acl) = 'object');`

Also adds missing  `OwnerName` in `ConvertWorkspaceRows`.
This commit is contained in:
George K
2025-12-15 08:42:08 -08:00
committed by GitHub
parent 7ecfd1aa07
commit 103967ed02
22 changed files with 838 additions and 92 deletions
+25 -2
View File
@@ -658,7 +658,7 @@ func ConvertUserRows(rows []GetUsersRow) []User {
return users
}
func ConvertWorkspaceRows(rows []GetWorkspacesRow) []Workspace {
func ConvertWorkspaceRows(rows []GetWorkspacesRow) ([]Workspace, error) {
workspaces := make([]Workspace, len(rows))
for i, r := range rows {
workspaces[i] = Workspace{
@@ -679,6 +679,7 @@ func ConvertWorkspaceRows(rows []GetWorkspacesRow) []Workspace {
Favorite: r.Favorite,
OwnerAvatarUrl: r.OwnerAvatarUrl,
OwnerUsername: r.OwnerUsername,
OwnerName: r.OwnerName,
OrganizationName: r.OrganizationName,
OrganizationDisplayName: r.OrganizationDisplayName,
OrganizationIcon: r.OrganizationIcon,
@@ -690,9 +691,31 @@ func ConvertWorkspaceRows(rows []GetWorkspacesRow) []Workspace {
NextStartAt: r.NextStartAt,
TaskID: r.TaskID,
}
var err error
err = workspaces[i].UserACL.Scan(r.UserACL)
if err != nil {
return nil, xerrors.Errorf("scan user ACL %q: %w", r.UserACL, err)
}
err = workspaces[i].GroupACL.Scan(r.GroupACL)
if err != nil {
return nil, xerrors.Errorf("scan group ACL %q: %w", r.GroupACL, err)
}
err = workspaces[i].UserACLDisplayInfo.Scan(r.UserACLDisplayInfo)
if err != nil {
return nil, xerrors.Errorf("scan user ACL display info %q: %w",
r.UserACLDisplayInfo, err)
}
err = workspaces[i].GroupACLDisplayInfo.Scan(r.GroupACLDisplayInfo)
if err != nil {
return nil, xerrors.Errorf("scan group ACL display info %q: %w",
r.GroupACLDisplayInfo, err)
}
}
return workspaces
return workspaces, nil
}
func (g Group) IsEveryone() bool {