@Summary Get workspace ACLs @ID get-workspace-acls @Security CoderSessionToken @Produce json @Tags Workspaces @Param workspace path string true "Workspace ID" format(uuid) @Success 200 {object} codersdk.WorkspaceACL @Router /api/v2/workspaces/{workspace}/acl [get]
(rw http.ResponseWriter, r *http.Request)
| 2359 | // @Success 200 {object} codersdk.WorkspaceACL |
| 2360 | // @Router /api/v2/workspaces/{workspace}/acl [get] |
| 2361 | func (api *API) workspaceACL(rw http.ResponseWriter, r *http.Request) { |
| 2362 | var ( |
| 2363 | ctx = r.Context() |
| 2364 | workspace = httpmw.WorkspaceParam(r) |
| 2365 | ) |
| 2366 | |
| 2367 | // Fetch the ACL data. |
| 2368 | workspaceACL, err := api.Database.GetWorkspaceACLByID(ctx, workspace.ID) |
| 2369 | if err != nil { |
| 2370 | httpapi.InternalServerError(rw, err) |
| 2371 | return |
| 2372 | } |
| 2373 | |
| 2374 | // This is largely based on the template ACL implementation, and is far from |
| 2375 | // ideal. Usually, when we use the System context it's because we need to |
| 2376 | // run some query that won't actually be exposed to the user. That is not |
| 2377 | // the case here. This data goes directly to an unauthorized user. We are |
| 2378 | // just straight up breaking security promises. |
| 2379 | // |
| 2380 | // TODO: This needs to be fixed before GA. Currently in beta. |
| 2381 | |
| 2382 | // Fetch all of the users and their organization memberships |
| 2383 | userIDs := make([]uuid.UUID, 0, len(workspaceACL.Users)) |
| 2384 | for userID := range workspaceACL.Users { |
| 2385 | id, err := uuid.Parse(userID) |
| 2386 | if err != nil { |
| 2387 | api.Logger.Warn(ctx, "found invalid user uuid in workspace acl", slog.Error(err), slog.F("workspace_id", workspace.ID)) |
| 2388 | continue |
| 2389 | } |
| 2390 | userIDs = append(userIDs, id) |
| 2391 | } |
| 2392 | // For context see https://github.com/coder/coder/pull/19375 |
| 2393 | // nolint:gocritic |
| 2394 | dbUsers, err := api.Database.GetUsersByIDs(dbauthz.AsSystemRestricted(ctx), userIDs) |
| 2395 | if err != nil && !xerrors.Is(err, sql.ErrNoRows) { |
| 2396 | httpapi.InternalServerError(rw, err) |
| 2397 | return |
| 2398 | } |
| 2399 | |
| 2400 | // Convert the db types to the codersdk.WorkspaceUser type |
| 2401 | users := make([]codersdk.WorkspaceUser, 0, len(dbUsers)) |
| 2402 | for _, it := range dbUsers { |
| 2403 | users = append(users, codersdk.WorkspaceUser{ |
| 2404 | MinimalUser: db2sdk.MinimalUser(it), |
| 2405 | Role: convertToWorkspaceRole(workspaceACL.Users[it.ID.String()].Permissions), |
| 2406 | }) |
| 2407 | } |
| 2408 | |
| 2409 | // Fetch all of the groups |
| 2410 | groupIDs := make([]uuid.UUID, 0, len(workspaceACL.Groups)) |
| 2411 | for groupID := range workspaceACL.Groups { |
| 2412 | id, err := uuid.Parse(groupID) |
| 2413 | if err != nil { |
| 2414 | api.Logger.Warn(ctx, "found invalid group uuid in workspace acl", slog.Error(err), slog.F("workspace_id", workspace.ID)) |
| 2415 | continue |
| 2416 | } |
| 2417 | groupIDs = append(groupIDs, id) |
| 2418 | } |
nothing calls this directly
no test coverage detected