@@ -2,6 +2,7 @@ package coderd_test
2
2
3
3
import (
4
4
"context"
5
+ "io"
5
6
"net/http"
6
7
"strings"
7
8
"testing"
@@ -48,13 +49,18 @@ func TestAuthorizeAllEndpoints(t *testing.T) {
48
49
coderdtest .AwaitTemplateVersionJob (t ,client ,version .ID )
49
50
template := coderdtest .CreateTemplate (t ,client ,admin .OrganizationID ,version .ID )
50
51
workspace := coderdtest .CreateWorkspace (t ,client ,admin .OrganizationID ,template .ID )
52
+ coderdtest .AwaitWorkspaceBuildJob (t ,client ,workspace .LatestBuild .ID )
51
53
52
54
// Always fail auth from this point forward
53
55
authorizer .AlwaysReturn = rbac .ForbiddenWithInternal (xerrors .New ("fake implementation" ),nil ,nil )
54
56
57
+ // Some quick reused objects
58
+ workspaceRBACObj := rbac .ResourceWorkspace .InOrg (organization .ID ).WithID (workspace .ID .String ()).WithOwner (workspace .OwnerID .String ())
59
+
55
60
// skipRoutes allows skipping routes from being checked.
56
61
type routeCheck struct {
57
62
NoAuthorize bool
63
+ AssertAction rbac.Action
58
64
AssertObject rbac.Object
59
65
StatusCode int
60
66
}
@@ -84,13 +90,7 @@ func TestAuthorizeAllEndpoints(t *testing.T) {
84
90
"GET:/api/v2/workspaceagents/{workspaceagent}/turn" : {NoAuthorize :true },
85
91
86
92
// TODO: @emyrk these need to be fixed by adding authorize calls
87
- "GET:/api/v2/workspaceresources/{workspaceresource}" : {NoAuthorize :true },
88
- "GET:/api/v2/workspacebuilds/{workspacebuild}" : {NoAuthorize :true },
89
- "GET:/api/v2/workspacebuilds/{workspacebuild}/logs" : {NoAuthorize :true },
90
- "GET:/api/v2/workspacebuilds/{workspacebuild}/resources" : {NoAuthorize :true },
91
- "GET:/api/v2/workspacebuilds/{workspacebuild}/state" : {NoAuthorize :true },
92
- "PATCH:/api/v2/workspacebuilds/{workspacebuild}/cancel" : {NoAuthorize :true },
93
- "GET:/api/v2/workspaces/{workspace}/builds/{workspacebuildname}" : {NoAuthorize :true },
93
+ "GET:/api/v2/workspaceresources/{workspaceresource}" : {NoAuthorize :true },
94
94
95
95
"GET:/api/v2/users/oauth2/github/callback" : {NoAuthorize :true },
96
96
@@ -123,15 +123,9 @@ func TestAuthorizeAllEndpoints(t *testing.T) {
123
123
124
124
"POST:/api/v2/users/{user}/organizations" : {NoAuthorize :true },
125
125
126
- "GET:/api/v2/workspaces/{workspace}" : {NoAuthorize :true },
127
- "PUT:/api/v2/workspaces/{workspace}/autostart" : {NoAuthorize :true },
128
- "PUT:/api/v2/workspaces/{workspace}/autostop" : {NoAuthorize :true },
129
- "GET:/api/v2/workspaces/{workspace}/builds" : {NoAuthorize :true },
130
- "POST:/api/v2/workspaces/{workspace}/builds" : {NoAuthorize :true },
131
- "GET:/api/v2/workspaces/{workspace}/watch" : {NoAuthorize :true },
132
-
133
- "POST:/api/v2/files" : {NoAuthorize :true },
134
- "GET:/api/v2/files/{hash}" : {NoAuthorize :true },
126
+ "POST:/api/v2/files" : {NoAuthorize :true },
127
+ "GET:/api/v2/files/{hash}" : {NoAuthorize :true },
128
+ "GET:/api/v2/workspaces/{workspace}/watch" : {NoAuthorize :true },
135
129
136
130
// These endpoints have more assertions. This is good, add more endpoints to assert if you can!
137
131
"GET:/api/v2/organizations/{organization}" : {AssertObject :rbac .ResourceOrganization .InOrg (admin .OrganizationID )},
@@ -141,11 +135,60 @@ func TestAuthorizeAllEndpoints(t *testing.T) {
141
135
"GET:/api/v2/organizations/{organization}/workspaces/{user}/{workspace}" : {
142
136
AssertObject :rbac .ResourceWorkspace .InOrg (organization .ID ).WithID (workspace .ID .String ()).WithOwner (workspace .OwnerID .String ()),
143
137
},
138
+ "GET:/api/v2/workspaces/{workspace}/builds/{workspacebuildname}" : {
139
+ AssertAction :rbac .ActionRead ,
140
+ AssertObject :workspaceRBACObj ,
141
+ },
142
+ "GET:/api/v2/organizations/{organization}/workspaces/{user}/{workspacename}" : {
143
+ AssertAction :rbac .ActionRead ,
144
+ AssertObject :workspaceRBACObj ,
145
+ },
144
146
"GET:/api/v2/organizations/{organization}/workspaces" : {StatusCode :http .StatusOK ,AssertObject :rbac .ResourceWorkspace },
145
- "GET:/api/v2/workspaces" : {StatusCode :http .StatusOK ,AssertObject :rbac .ResourceWorkspace },
147
+ "GET:/api/v2/workspacebuilds/{workspacebuild}" : {
148
+ AssertAction :rbac .ActionRead ,
149
+ AssertObject :workspaceRBACObj ,
150
+ },
151
+ "GET:/api/v2/workspacebuilds/{workspacebuild}/logs" : {
152
+ AssertAction :rbac .ActionRead ,
153
+ AssertObject :workspaceRBACObj ,
154
+ },
155
+ "GET:/api/v2/workspaces/{workspace}/builds" : {
156
+ AssertAction :rbac .ActionRead ,
157
+ AssertObject :workspaceRBACObj ,
158
+ },
159
+ "GET:/api/v2/workspaces/{workspace}" : {
160
+ AssertAction :rbac .ActionRead ,
161
+ AssertObject :workspaceRBACObj ,
162
+ },
163
+ "PUT:/api/v2/workspaces/{workspace}/autostart" : {
164
+ AssertAction :rbac .ActionUpdate ,
165
+ AssertObject :workspaceRBACObj ,
166
+ },
167
+ "PUT:/api/v2/workspaces/{workspace}/autostop" : {
168
+ AssertAction :rbac .ActionUpdate ,
169
+ AssertObject :workspaceRBACObj ,
170
+ },
171
+ "PATCH:/api/v2/workspacebuilds/{workspacebuild}/cancel" : {
172
+ AssertAction :rbac .ActionUpdate ,
173
+ AssertObject :workspaceRBACObj ,
174
+ },
175
+ "GET:/api/v2/workspacebuilds/{workspacebuild}/resources" : {
176
+ AssertAction :rbac .ActionRead ,
177
+ AssertObject :workspaceRBACObj ,
178
+ },
179
+ "GET:/api/v2/workspacebuilds/{workspacebuild}/state" : {
180
+ AssertAction :rbac .ActionRead ,
181
+ AssertObject :workspaceRBACObj ,
182
+ },
183
+ "GET:/api/v2/workspaces/" : {
184
+ StatusCode :http .StatusOK ,
185
+ AssertAction :rbac .ActionRead ,
186
+ AssertObject :workspaceRBACObj ,
187
+ },
146
188
147
- // These endpoints need payloads to get to the auth part.
148
- "PUT:/api/v2/users/{user}/roles" : {StatusCode :http .StatusBadRequest ,NoAuthorize :true },
189
+ // These endpoints need payloads to get to the auth part. Payloads will be required
190
+ "PUT:/api/v2/users/{user}/roles" : {StatusCode :http .StatusBadRequest ,NoAuthorize :true },
191
+ "POST:/api/v2/workspaces/{workspace}/builds" : {StatusCode :http .StatusBadRequest ,NoAuthorize :true },
149
192
}
150
193
151
194
for k ,v := range assertRoute {
@@ -175,16 +218,24 @@ func TestAuthorizeAllEndpoints(t *testing.T) {
175
218
route = strings .ReplaceAll (route ,"{organization}" ,admin .OrganizationID .String ())
176
219
route = strings .ReplaceAll (route ,"{user}" ,admin .UserID .String ())
177
220
route = strings .ReplaceAll (route ,"{organizationname}" ,organization .Name )
178
- route = strings .ReplaceAll (route ,"{workspace}" ,workspace .Name )
221
+ route = strings .ReplaceAll (route ,"{workspace}" ,workspace .ID .String ())
222
+ route = strings .ReplaceAll (route ,"{workspacebuild}" ,workspace .LatestBuild .ID .String ())
223
+ route = strings .ReplaceAll (route ,"{workspacename}" ,workspace .Name )
224
+ route = strings .ReplaceAll (route ,"{workspacebuildname}" ,workspace .LatestBuild .Name )
179
225
180
226
resp ,err := client .Request (context .Background (),method ,route ,nil )
181
227
require .NoError (t ,err ,"do req" )
228
+ body ,_ := io .ReadAll (resp .Body )
229
+ t .Logf ("Response Body: %q" ,string (body ))
182
230
_ = resp .Body .Close ()
183
231
184
232
if ! routeAssertions .NoAuthorize {
185
233
assert .NotNil (t ,authorizer .Called ,"authorizer expected" )
186
234
assert .Equal (t ,routeAssertions .StatusCode ,resp .StatusCode ,"expect unauthorized" )
187
235
if authorizer .Called != nil {
236
+ if routeAssertions .AssertAction != "" {
237
+ assert .Equal (t ,routeAssertions .AssertAction ,authorizer .Called .Action ,"resource action" )
238
+ }
188
239
if routeAssertions .AssertObject .Type != "" {
189
240
assert .Equal (t ,routeAssertions .AssertObject .Type ,authorizer .Called .Object .Type ,"resource type" )
190
241
}