@@ -3,6 +3,7 @@ package workspaceapps_test
3
3
import (
4
4
"context"
5
5
"crypto/rand"
6
+ "database/sql"
6
7
"fmt"
7
8
"io"
8
9
"net"
@@ -24,6 +25,7 @@ import (
24
25
"github.com/coder/coder/v2/coderd/audit"
25
26
"github.com/coder/coder/v2/coderd/coderdtest"
26
27
"github.com/coder/coder/v2/coderd/database"
28
+ "github.com/coder/coder/v2/coderd/database/dbauthz"
27
29
"github.com/coder/coder/v2/coderd/httpmw"
28
30
"github.com/coder/coder/v2/coderd/jwtutils"
29
31
"github.com/coder/coder/v2/coderd/tracing"
@@ -83,6 +85,9 @@ func Test_ResolveRequest(t *testing.T) {
83
85
84
86
auditor := audit .NewMock ()
85
87
t .Cleanup (func () {
88
+ if t .Failed () {
89
+ return
90
+ }
86
91
assert .Len (t ,auditor .AuditLogs (),0 ,"one or more test cases produced unexpected audit logs, did you replace the auditor or forget to call ResetLogs?" )
87
92
})
88
93
client ,closer ,api := coderdtest .NewWithAPI (t ,& coderdtest.Options {
@@ -220,11 +225,24 @@ func Test_ResolveRequest(t *testing.T) {
220
225
for _ ,agnt := range resource .Agents {
221
226
if agnt .Name == agentName {
222
227
agentID = agnt .ID
228
+ break
223
229
}
224
230
}
225
231
}
226
232
require .NotEqual (t ,uuid .Nil ,agentID )
227
233
234
+ //nonlint:gocritic // This is a test, allow dbauthz.AsSystemRestricted.
235
+ agent ,err := api .Database .GetWorkspaceAgentByID (dbauthz .AsSystemRestricted (ctx ),agentID )
236
+ require .NoError (t ,err )
237
+
238
+ //nolint:gocritic // This is a test, allow dbauthz.AsSystemRestricted.
239
+ apps ,err := api .Database .GetWorkspaceAppsByAgentID (dbauthz .AsSystemRestricted (ctx ),agentID )
240
+ require .NoError (t ,err )
241
+ appsBySlug := make (map [string ]database.WorkspaceApp ,len (apps ))
242
+ for _ ,app := range apps {
243
+ appsBySlug [app .Slug ]= app
244
+ }
245
+
228
246
// Reset audit logs so cleanup check can pass.
229
247
auditor .ResetLogs ()
230
248
@@ -268,12 +286,14 @@ func Test_ResolveRequest(t *testing.T) {
268
286
269
287
auditor := audit .NewMock ()
270
288
auditableIP := randomIPv6 (t )
289
+ auditableUA := "Tidua"
271
290
272
291
t .Log ("app" ,app )
273
292
rw := httptest .NewRecorder ()
274
293
r := httptest .NewRequest ("GET" ,"/app" ,nil )
275
294
r .Header .Set (codersdk .SessionTokenHeader ,client .SessionToken ())
276
295
r = requestWithAuditorAndRemoteAddr (r ,auditor ,auditableIP )
296
+ r .Header .Set ("User-Agent" ,auditableUA )
277
297
278
298
// Try resolving the request without a token.
279
299
token ,ok := workspaceappsResolveRequest (t ,rw ,r , workspaceapps.ResolveRequestOptions {
@@ -314,7 +334,12 @@ func Test_ResolveRequest(t *testing.T) {
314
334
315
335
require .True (t ,auditor .Contains (t , database.AuditLog {
316
336
OrganizationID :workspace .OrganizationID ,
337
+ Action :database .AuditActionOpen ,
338
+ ResourceType :audit .ResourceType (appsBySlug [app ]),
339
+ ResourceID :audit .ResourceID (appsBySlug [app ]),
340
+ ResourceTarget :audit .ResourceTarget (appsBySlug [app ]),
317
341
UserID :me .ID ,
342
+ UserAgent : sql.NullString {Valid :true ,String :auditableUA },
318
343
Ip :audit .ParseIP (auditableIP ),
319
344
StatusCode :int32 (w .StatusCode ),//nolint:gosec
320
345
}),"audit log" )
@@ -399,6 +424,10 @@ func Test_ResolveRequest(t *testing.T) {
399
424
400
425
require .True (t ,auditor .Contains (t , database.AuditLog {
401
426
OrganizationID :workspace .OrganizationID ,
427
+ Action :database .AuditActionOpen ,
428
+ ResourceType :audit .ResourceType (appsBySlug [app ]),
429
+ ResourceID :audit .ResourceID (appsBySlug [app ]),
430
+ ResourceTarget :audit .ResourceTarget (appsBySlug [app ]),
402
431
UserID :secondUser .ID ,
403
432
Ip :audit .ParseIP (auditableIP ),
404
433
StatusCode :int32 (w .StatusCode ),//nolint:gosec
@@ -457,6 +486,10 @@ func Test_ResolveRequest(t *testing.T) {
457
486
458
487
require .True (t ,auditor .Contains (t , database.AuditLog {
459
488
OrganizationID :workspace .OrganizationID ,
489
+ ResourceType :audit .ResourceType (appsBySlug [app ]),
490
+ ResourceID :audit .ResourceID (appsBySlug [app ]),
491
+ ResourceTarget :audit .ResourceTarget (appsBySlug [app ]),
492
+ UserID :uuid .Nil ,// Nil is not verified by Contains, see below.
460
493
Ip :audit .ParseIP (auditableIP ),
461
494
StatusCode :int32 (w .StatusCode ),//nolint:gosec
462
495
}),"audit log" )
@@ -587,6 +620,9 @@ func Test_ResolveRequest(t *testing.T) {
587
620
require .Equal (t ,token .AgentID ,agentID )
588
621
require .True (t ,auditor .Contains (t , database.AuditLog {
589
622
OrganizationID :workspace .OrganizationID ,
623
+ ResourceType :audit .ResourceType (appsBySlug [token .AppSlugOrPort ]),
624
+ ResourceID :audit .ResourceID (appsBySlug [token .AppSlugOrPort ]),
625
+ ResourceTarget :audit .ResourceTarget (appsBySlug [token .AppSlugOrPort ]),
590
626
UserID :me .ID ,
591
627
Ip :audit .ParseIP (auditableIP ),
592
628
StatusCode :int32 (w .StatusCode ),//nolint:gosec
@@ -677,6 +713,9 @@ func Test_ResolveRequest(t *testing.T) {
677
713
678
714
require .True (t ,auditor .Contains (t , database.AuditLog {
679
715
OrganizationID :workspace .OrganizationID ,
716
+ ResourceType :audit .ResourceType (appsBySlug [token .AppSlugOrPort ]),
717
+ ResourceID :audit .ResourceID (appsBySlug [token .AppSlugOrPort ]),
718
+ ResourceTarget :audit .ResourceTarget (appsBySlug [token .AppSlugOrPort ]),
680
719
UserID :me .ID ,
681
720
Ip :audit .ParseIP (auditableIP ),
682
721
StatusCode :int32 (w .StatusCode ),//nolint:gosec
@@ -759,10 +798,13 @@ func Test_ResolveRequest(t *testing.T) {
759
798
require .Equal (t ,http .StatusOK ,w .StatusCode )
760
799
require .True (t ,auditor .Contains (t , database.AuditLog {
761
800
OrganizationID :workspace .OrganizationID ,
801
+ ResourceType :audit .ResourceType (agent ),
802
+ ResourceID :audit .ResourceID (agent ),
803
+ ResourceTarget :audit .ResourceTarget (agent ),
762
804
UserID :me .ID ,
763
805
Ip :audit .ParseIP (auditableIP ),
764
806
StatusCode :int32 (w .StatusCode ),//nolint:gosec
765
- }),"audit log" )
807
+ }),"audit log for agent, not app " )
766
808
require .Len (t ,auditor .AuditLogs (),1 ,"single audit log" )
767
809
})
768
810
@@ -839,6 +881,9 @@ func Test_ResolveRequest(t *testing.T) {
839
881
_ = w .Body .Close ()
840
882
require .True (t ,auditor .Contains (t , database.AuditLog {
841
883
OrganizationID :workspace .OrganizationID ,
884
+ ResourceType :audit .ResourceType (appsBySlug [token .AppSlugOrPort ]),
885
+ ResourceID :audit .ResourceID (appsBySlug [token .AppSlugOrPort ]),
886
+ ResourceTarget :audit .ResourceTarget (appsBySlug [token .AppSlugOrPort ]),
842
887
UserID :me .ID ,
843
888
Ip :audit .ParseIP (auditableIP ),
844
889
StatusCode :int32 (w .StatusCode ),//nolint:gosec
@@ -883,10 +928,13 @@ func Test_ResolveRequest(t *testing.T) {
883
928
_ = w .Body .Close ()
884
929
require .True (t ,auditor .Contains (t , database.AuditLog {
885
930
OrganizationID :workspace .OrganizationID ,
931
+ ResourceType :audit .ResourceType (agent ),
932
+ ResourceID :audit .ResourceID (agent ),
933
+ ResourceTarget :audit .ResourceTarget (agent ),
886
934
UserID :me .ID ,
887
935
Ip :audit .ParseIP (auditableIP ),
888
936
StatusCode :int32 (w .StatusCode ),//nolint:gosec
889
- }),"audit log" )
937
+ }),"audit log for agent, not app " )
890
938
require .Len (t ,auditor .AuditLogs (),1 ,"single audit log" )
891
939
})
892
940