chatCreateWorkspace provides workspace creation for the chat processor. RBAC authorization uses context-based checks via dbauthz.As rather than fake *http.Request objects.
( ctx context.Context, ownerID uuid.UUID, req codersdk.CreateWorkspaceRequest, )
| 3779 | // processor. RBAC authorization uses context-based checks via |
| 3780 | // dbauthz.As rather than fake *http.Request objects. |
| 3781 | func (api *API) chatCreateWorkspace( |
| 3782 | ctx context.Context, |
| 3783 | ownerID uuid.UUID, |
| 3784 | req codersdk.CreateWorkspaceRequest, |
| 3785 | ) (codersdk.Workspace, error) { |
| 3786 | actor, _, err := httpmw.UserRBACSubject(ctx, api.Database, ownerID, rbac.ScopeAll) |
| 3787 | if err != nil { |
| 3788 | return codersdk.Workspace{}, xerrors.Errorf("load user authorization: %w", err) |
| 3789 | } |
| 3790 | ctx = dbauthz.As(ctx, actor) |
| 3791 | |
| 3792 | ownerUser, err := api.Database.GetUserByID(ctx, ownerID) |
| 3793 | if err != nil { |
| 3794 | return codersdk.Workspace{}, xerrors.Errorf("get workspace owner: %w", err) |
| 3795 | } |
| 3796 | owner := workspaceOwner{ |
| 3797 | ID: ownerUser.ID, |
| 3798 | Username: ownerUser.Username, |
| 3799 | AvatarURL: ownerUser.AvatarURL, |
| 3800 | } |
| 3801 | |
| 3802 | auditor := api.Auditor.Load() |
| 3803 | if auditor == nil { |
| 3804 | return codersdk.Workspace{}, xerrors.New("auditor is not configured") |
| 3805 | } |
| 3806 | |
| 3807 | // The audit system requires a ResponseWriter to capture the |
| 3808 | // HTTP status code. Since this is a programmatic call, we use |
| 3809 | // a recorder. The audit entry still captures the owner, action, |
| 3810 | // and resource correctly. |
| 3811 | rw := httptest.NewRecorder() |
| 3812 | sw := &tracing.StatusWriter{ResponseWriter: rw} |
| 3813 | |
| 3814 | // Build a minimal synthetic request so the audit commit |
| 3815 | // closure can extract a request ID and user agent. The RBAC |
| 3816 | // subject is already on the context via dbauthz.As above. |
| 3817 | auditReq, err := http.NewRequestWithContext( |
| 3818 | httpmw.WithRequestID(ctx, uuid.New()), |
| 3819 | http.MethodPost, |
| 3820 | "http://localhost/internal/chat/workspace", |
| 3821 | nil, |
| 3822 | ) |
| 3823 | if err != nil { |
| 3824 | return codersdk.Workspace{}, xerrors.Errorf("create audit request: %w", err) |
| 3825 | } |
| 3826 | |
| 3827 | aReq, commitAudit := audit.InitRequest[database.WorkspaceTable](sw, &audit.RequestParams{ |
| 3828 | Audit: *auditor, |
| 3829 | Log: api.Logger, |
| 3830 | Request: auditReq, |
| 3831 | Action: database.AuditActionCreate, |
| 3832 | AdditionalFields: audit.AdditionalFields{ |
| 3833 | WorkspaceOwner: owner.Username, |
| 3834 | }, |
| 3835 | }) |
| 3836 | aReq.UserID = ownerID |
| 3837 | defer commitAudit() |
| 3838 |
nothing calls this directly
no test coverage detected