@@ -58,12 +58,18 @@ func (api *api) workspace(rw http.ResponseWriter, r *http.Request) {
58
58
return
59
59
}
60
60
61
+ if ! api .Authorize (rw , r , rbac .ActionRead ,
62
+ rbac .ResourceWorkspace .InOrg (workspace .OrganizationID ).WithOwner (workspace .OwnerID .String ()).WithID (workspace .ID .String ())) {
63
+ return
64
+ }
65
+
61
66
httpapi .Write (rw , http .StatusOK ,
62
67
convertWorkspace (workspace , convertWorkspaceBuild (build , convertProvisionerJob (job )), template , owner ))
63
68
}
64
69
65
70
func (api * api ) workspacesByOrganization (rw http.ResponseWriter , r * http.Request ) {
66
71
organization := httpmw .OrganizationParam (r )
72
+ roles := httpmw .UserRoles (r )
67
73
workspaces , err := api .Database .GetWorkspacesByOrganizationID (r .Context (), database.GetWorkspacesByOrganizationIDParams {
68
74
OrganizationID : organization .ID ,
69
75
Deleted : false ,
@@ -77,7 +83,18 @@ func (api *api) workspacesByOrganization(rw http.ResponseWriter, r *http.Request
77
83
})
78
84
return
79
85
}
80
- apiWorkspaces , err := convertWorkspaces (r .Context (), api .Database , workspaces )
86
+
87
+ allowedWorkspaces := make ([]database.Workspace , 0 )
88
+ for _ , ws := range workspaces {
89
+ ws := ws
90
+ err = api .Authorizer .ByRoleName (r .Context (), roles .ID .String (), roles .Roles , rbac .ActionRead ,
91
+ rbac .ResourceWorkspace .InOrg (ws .OrganizationID ).WithOwner (ws .OwnerID .String ()).WithID (ws .ID .String ()))
92
+ if err == nil {
93
+ allowedWorkspaces = append (allowedWorkspaces , ws )
94
+ }
95
+ }
96
+
97
+ apiWorkspaces , err := convertWorkspaces (r .Context (), api .Database , allowedWorkspaces )
81
98
if err != nil {
82
99
httpapi .Write (rw , http .StatusInternalServerError , httpapi.Response {
83
100
Message : fmt .Sprintf ("convert workspaces: %s" , err ),
@@ -102,6 +119,7 @@ func (api *api) workspacesByUser(rw http.ResponseWriter, r *http.Request) {
102
119
return
103
120
}
104
121
for _ , ws := range userWorkspaces {
122
+ ws := ws
105
123
err = api .Authorizer .ByRoleName (r .Context (), user .ID .String (), roles .Roles , rbac .ActionRead ,
106
124
rbac .ResourceWorkspace .InOrg (ws .OrganizationID ).WithOwner (ws .OwnerID .String ()).WithID (ws .ID .String ()))
107
125
if err == nil {
@@ -121,6 +139,7 @@ func (api *api) workspacesByUser(rw http.ResponseWriter, r *http.Request) {
121
139
122
140
func (api * api ) workspacesByOwner (rw http.ResponseWriter , r * http.Request ) {
123
141
owner := httpmw .UserParam (r )
142
+ roles := httpmw .UserRoles (r )
124
143
workspaces , err := api .Database .GetWorkspacesByOwnerID (r .Context (), database.GetWorkspacesByOwnerIDParams {
125
144
OwnerID : owner .ID ,
126
145
})
@@ -133,7 +152,18 @@ func (api *api) workspacesByOwner(rw http.ResponseWriter, r *http.Request) {
133
152
})
134
153
return
135
154
}
136
- apiWorkspaces , err := convertWorkspaces (r .Context (), api .Database , workspaces )
155
+
156
+ allowedWorkspaces := make ([]database.Workspace , 0 )
157
+ for _ , ws := range workspaces {
158
+ ws := ws
159
+ err = api .Authorizer .ByRoleName (r .Context (), roles .ID .String (), roles .Roles , rbac .ActionRead ,
160
+ rbac .ResourceWorkspace .InOrg (ws .OrganizationID ).WithOwner (ws .OwnerID .String ()).WithID (ws .ID .String ()))
161
+ if err == nil {
162
+ allowedWorkspaces = append (allowedWorkspaces , ws )
163
+ }
164
+ }
165
+
166
+ apiWorkspaces , err := convertWorkspaces (r .Context (), api .Database , allowedWorkspaces )
137
167
if err != nil {
138
168
httpapi .Write (rw , http .StatusInternalServerError , httpapi.Response {
139
169
Message : fmt .Sprintf ("convert workspaces: %s" , err ),
@@ -153,9 +183,8 @@ func (api *api) workspaceByOwnerAndName(rw http.ResponseWriter, r *http.Request)
153
183
Name : workspaceName ,
154
184
})
155
185
if errors .Is (err , sql .ErrNoRows ) {
156
- httpapi .Write (rw , http .StatusNotFound , httpapi.Response {
157
- Message : fmt .Sprintf ("no workspace found by name %q" , workspaceName ),
158
- })
186
+ // Do not leak information if the workspace exists or not
187
+ httpapi .Forbidden (rw )
159
188
return
160
189
}
161
190
if err != nil {
@@ -172,6 +201,11 @@ func (api *api) workspaceByOwnerAndName(rw http.ResponseWriter, r *http.Request)
172
201
return
173
202
}
174
203
204
+ if ! api .Authorize (rw , r , rbac .ActionRead ,
205
+ rbac .ResourceWorkspace .InOrg (workspace .OrganizationID ).WithOwner (workspace .OwnerID .String ()).WithID (workspace .ID .String ())) {
206
+ return
207
+ }
208
+
175
209
build , err := api .Database .GetWorkspaceBuildByWorkspaceIDWithoutAfter (r .Context (), workspace .ID )
176
210
if err != nil {
177
211
httpapi .Write (rw , http .StatusInternalServerError , httpapi.Response {
0 commit comments