@@ -73,7 +73,7 @@ func (api *API) workspace(rw http.ResponseWriter, r *http.Request) {
73
73
group errgroup.Group
74
74
job database.ProvisionerJob
75
75
template database.Template
76
- owner database.User
76
+ users [] database.User
77
77
)
78
78
group .Go (func () (err error ) {
79
79
job ,err = api .Database .GetProvisionerJobByID (r .Context (),build .JobID )
@@ -84,7 +84,7 @@ func (api *API) workspace(rw http.ResponseWriter, r *http.Request) {
84
84
return err
85
85
})
86
86
group .Go (func () (err error ) {
87
- owner ,err = api .Database .GetUserByID (r .Context (),workspace .OwnerID )
87
+ users ,err = api .Database .GetUsersByIDs (r .Context (),[]uuid. UUID { workspace .OwnerID , build . InitiatorID } )
88
88
return err
89
89
})
90
90
err = group .Wait ()
@@ -96,7 +96,8 @@ func (api *API) workspace(rw http.ResponseWriter, r *http.Request) {
96
96
return
97
97
}
98
98
99
- httpapi .Write (rw ,http .StatusOK ,convertWorkspace (workspace ,build ,job ,template ,owner ))
99
+ httpapi .Write (rw ,http .StatusOK ,convertWorkspace (workspace ,build ,job ,template ,
100
+ findUser (workspace .OwnerID ,users ),findUser (build .InitiatorID ,users )))
100
101
}
101
102
102
103
// workspaces returns all workspaces a user can read.
@@ -232,7 +233,16 @@ func (api *API) workspaceByOwnerAndName(rw http.ResponseWriter, r *http.Request)
232
233
return
233
234
}
234
235
235
- httpapi .Write (rw ,http .StatusOK ,convertWorkspace (workspace ,build ,job ,template ,owner ))
236
+ initiator ,err := api .Database .GetUserByID (r .Context (),build .InitiatorID )
237
+ if err != nil {
238
+ httpapi .Write (rw ,http .StatusInternalServerError , httpapi.Response {
239
+ Message :"Internal error fetching template." ,
240
+ Detail :err .Error (),
241
+ })
242
+ return
243
+ }
244
+
245
+ httpapi .Write (rw ,http .StatusOK ,convertWorkspace (workspace ,build ,job ,template ,& owner ,& initiator ))
236
246
}
237
247
238
248
// Create a new workspace for the currently authenticated user.
@@ -465,7 +475,7 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
465
475
})
466
476
return
467
477
}
468
- user ,err := api .Database .GetUserByID (r .Context (),apiKey .UserID )
478
+ users ,err := api .Database .GetUsersByIDs (r .Context (),[]uuid. UUID { apiKey .UserID , workspaceBuild . InitiatorID } )
469
479
if err != nil {
470
480
httpapi .Write (rw ,http .StatusInternalServerError , httpapi.Response {
471
481
Message :"Internal error fetching user." ,
@@ -474,7 +484,8 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
474
484
return
475
485
}
476
486
477
- httpapi .Write (rw ,http .StatusCreated ,convertWorkspace (workspace ,workspaceBuild ,templateVersionJob ,template ,user ))
487
+ httpapi .Write (rw ,http .StatusCreated ,convertWorkspace (workspace ,workspaceBuild ,templateVersionJob ,template ,
488
+ findUser (apiKey .UserID ,users ),findUser (workspaceBuild .InitiatorID ,users )))
478
489
}
479
490
480
491
func (api * API )putWorkspaceAutostart (rw http.ResponseWriter ,r * http.Request ) {
@@ -691,7 +702,7 @@ func (api *API) watchWorkspace(rw http.ResponseWriter, r *http.Request) {
691
702
group errgroup.Group
692
703
job database.ProvisionerJob
693
704
template database.Template
694
- owner database.User
705
+ users [] database.User
695
706
)
696
707
group .Go (func () (err error ) {
697
708
job ,err = api .Database .GetProvisionerJobByID (r .Context (),build .JobID )
@@ -702,7 +713,7 @@ func (api *API) watchWorkspace(rw http.ResponseWriter, r *http.Request) {
702
713
return err
703
714
})
704
715
group .Go (func () (err error ) {
705
- owner ,err = api .Database .GetUserByID (r .Context (),workspace .OwnerID )
716
+ users ,err = api .Database .GetUsersByIDs (r .Context (),[]uuid. UUID { workspace .OwnerID , build . InitiatorID } )
706
717
return err
707
718
})
708
719
err = group .Wait ()
@@ -714,7 +725,8 @@ func (api *API) watchWorkspace(rw http.ResponseWriter, r *http.Request) {
714
725
return
715
726
}
716
727
717
- _ = wsjson .Write (ctx ,c ,convertWorkspace (workspace ,build ,job ,template ,owner ))
728
+ _ = wsjson .Write (ctx ,c ,convertWorkspace (workspace ,build ,job ,template ,
729
+ findUser (workspace .OwnerID ,users ),findUser (build .InitiatorID ,users )))
718
730
case <- ctx .Done ():
719
731
return
720
732
}
@@ -724,16 +736,20 @@ func (api *API) watchWorkspace(rw http.ResponseWriter, r *http.Request) {
724
736
func convertWorkspaces (ctx context.Context ,db database.Store ,workspaces []database.Workspace ) ([]codersdk.Workspace ,error ) {
725
737
workspaceIDs := make ([]uuid.UUID ,0 ,len (workspaces ))
726
738
templateIDs := make ([]uuid.UUID ,0 ,len (workspaces ))
727
- ownerIDs := make ([]uuid.UUID ,0 ,len (workspaces ))
739
+ userIDs := make ([]uuid.UUID ,0 ,len (workspaces ))
728
740
for _ ,workspace := range workspaces {
729
741
workspaceIDs = append (workspaceIDs ,workspace .ID )
730
742
templateIDs = append (templateIDs ,workspace .TemplateID )
731
- ownerIDs = append (ownerIDs ,workspace .OwnerID )
743
+ userIDs = append (userIDs ,workspace .OwnerID )
732
744
}
733
745
workspaceBuilds ,err := db .GetLatestWorkspaceBuildsByWorkspaceIDs (ctx ,workspaceIDs )
734
746
if errors .Is (err ,sql .ErrNoRows ) {
735
747
err = nil
736
748
}
749
+ for _ ,build := range workspaceBuilds {
750
+ userIDs = append (userIDs ,build .InitiatorID )
751
+ }
752
+
737
753
if err != nil {
738
754
return nil ,xerrors .Errorf ("get workspace builds: %w" ,err )
739
755
}
@@ -744,7 +760,7 @@ func convertWorkspaces(ctx context.Context, db database.Store, workspaces []data
744
760
if err != nil {
745
761
return nil ,xerrors .Errorf ("get templates: %w" ,err )
746
762
}
747
- users ,err := db .GetUsersByIDs (ctx ,ownerIDs )
763
+ users ,err := db .GetUsersByIDs (ctx ,userIDs )
748
764
if err != nil {
749
765
return nil ,xerrors .Errorf ("get users: %w" ,err )
750
766
}
@@ -803,11 +819,15 @@ func convertWorkspaces(ctx context.Context, db database.Store, workspaces []data
803
819
if ! exists {
804
820
return nil ,xerrors .Errorf ("build job not found for workspace: %w" ,err )
805
821
}
806
- user ,exists := userByID [workspace .OwnerID ]
822
+ owner ,exists := userByID [workspace .OwnerID ]
807
823
if ! exists {
808
824
return nil ,xerrors .Errorf ("owner not found for workspace: %q" ,workspace .Name )
809
825
}
810
- apiWorkspaces = append (apiWorkspaces ,convertWorkspace (workspace ,build ,job ,template ,user ))
826
+ initiator ,exists := userByID [build .InitiatorID ]
827
+ if ! exists {
828
+ return nil ,xerrors .Errorf ("build initiator not found for workspace: %q" ,workspace .Name )
829
+ }
830
+ apiWorkspaces = append (apiWorkspaces ,convertWorkspace (workspace ,build ,job ,template ,& owner ,& initiator ))
811
831
}
812
832
return apiWorkspaces ,nil
813
833
}
@@ -816,7 +836,9 @@ func convertWorkspace(
816
836
workspaceBuild database.WorkspaceBuild ,
817
837
job database.ProvisionerJob ,
818
838
template database.Template ,
819
- owner database.User ) codersdk.Workspace {
839
+ owner * database.User ,
840
+ initiator * database.User ,
841
+ ) codersdk.Workspace {
820
842
var autostartSchedule * string
821
843
if workspace .AutostartSchedule .Valid {
822
844
autostartSchedule = & workspace .AutostartSchedule .String
@@ -830,7 +852,7 @@ func convertWorkspace(
830
852
OwnerID :workspace .OwnerID ,
831
853
OwnerName :owner .Username ,
832
854
TemplateID :workspace .TemplateID ,
833
- LatestBuild :convertWorkspaceBuild (owner ,workspace ,workspaceBuild ,job ),
855
+ LatestBuild :convertWorkspaceBuild (owner ,initiator , workspace ,workspaceBuild ,job ),
834
856
TemplateName :template .Name ,
835
857
Outdated :workspaceBuild .TemplateVersionID .String ()!= template .ActiveVersionID .String (),
836
858
Name :workspace .Name ,