MCPcopy Index your code
hub / github.com/coder/coder / postUserWorkspaces

Method postUserWorkspaces

coderd/workspaces.go:437–517  ·  view source on GitHub ↗

Create a new workspace for the currently authenticated user. @Summary Create user workspace @Description Create a new workspace using a template. The request must @Description specify either the Template ID or the Template Version ID, @Description not both. If the Template ID is specified, the acti

(rw http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

435// @Success 200 {object} codersdk.Workspace
436// @Router /api/v2/users/{user}/workspaces [post]
437func (api *API) postUserWorkspaces(rw http.ResponseWriter, r *http.Request) {
438 var (
439 ctx = r.Context()
440 apiKey = httpmw.APIKey(r)
441 auditor = api.Auditor.Load()
442 mems = httpmw.OrganizationMembersParam(r)
443 )
444
445 var req codersdk.CreateWorkspaceRequest
446 if !httpapi.Read(ctx, rw, r, &req) {
447 return
448 }
449
450 var owner workspaceOwner
451 if mems.User != nil {
452 // This user fetch is an optimization path for the most common case of creating a
453 // workspace for 'Me'.
454 //
455 // This is also required to allow `owners` to create workspaces for users
456 // that are not in an organization.
457 owner = workspaceOwner{
458 ID: mems.User.ID,
459 Username: mems.User.Username,
460 AvatarURL: mems.User.AvatarURL,
461 }
462 } else {
463 // A workspace can still be created if the caller can read the organization
464 // member. The organization is required, which can be sourced from the
465 // template.
466 //
467 // TODO: This code gets called twice for each workspace build request.
468 // This is inefficient and costs at most 2 extra RTTs to the DB.
469 // This can be optimized. It exists as it is now for code simplicity.
470 // The most common case is to create a workspace for 'Me'. Which does
471 // not enter this code branch.
472 template, err := requestTemplate(ctx, req, api.Database)
473 if err != nil {
474 httperror.WriteResponseError(ctx, rw, err)
475 return
476 }
477
478 // If the caller can find the organization membership in the same org
479 // as the template, then they can continue.
480 orgIndex := slices.IndexFunc(mems.Memberships, func(mem httpmw.OrganizationMember) bool {
481 return mem.OrganizationID == template.OrganizationID
482 })
483 if orgIndex == -1 {
484 httpapi.ResourceNotFound(rw)
485 return
486 }
487
488 member := mems.Memberships[orgIndex]
489 owner = workspaceOwner{
490 ID: member.UserID,
491 Username: member.Username,
492 AvatarURL: member.AvatarURL,
493 }
494 }

Callers

nothing calls this directly

Calls 11

APIKeyFunction · 0.92
OrganizationMembersParamFunction · 0.92
ReadFunction · 0.92
WriteResponseErrorFunction · 0.92
ResourceNotFoundFunction · 0.92
InitRequestFunction · 0.92
WriteFunction · 0.92
requestTemplateFunction · 0.85
createWorkspaceFunction · 0.70
ContextMethod · 0.65
LoadMethod · 0.45

Tested by

no test coverage detected