@@ -8,11 +8,13 @@ import (
8
8
"net/http"
9
9
"testing"
10
10
11
+ "github.com/golang-jwt/jwt/v4"
11
12
"github.com/stretchr/testify/assert"
12
13
"github.com/stretchr/testify/require"
13
14
14
15
"github.com/coder/coder/v2/coderd/audit"
15
16
"github.com/coder/coder/v2/coderd/coderdtest"
17
+ "github.com/coder/coder/v2/coderd/coderdtest/oidctest"
16
18
"github.com/coder/coder/v2/coderd/database"
17
19
"github.com/coder/coder/v2/codersdk"
18
20
"github.com/coder/coder/v2/cryptorand"
@@ -364,5 +366,82 @@ func TestScim(t *testing.T) {
364
366
require .Len (t , userRes .Users , 1 )
365
367
assert .Equal (t , codersdk .UserStatusSuspended , userRes .Users [0 ].Status )
366
368
})
369
+
370
+ // Create a user via SCIM, which starts as dormant.
371
+ // Log in as the user, making them active.
372
+ // Then patch the user again and the user should still be active.
373
+ t .Run ("ActiveIsActive" , func (t * testing.T ) {
374
+ t .Parallel ()
375
+
376
+ ctx , cancel := context .WithTimeout (context .Background (), testutil .WaitLong )
377
+ defer cancel ()
378
+
379
+ scimAPIKey := []byte ("hi" )
380
+
381
+ mockAudit := audit .NewMock ()
382
+ fake := oidctest .NewFakeIDP (t , oidctest .WithServing ())
383
+ client , _ := coderdenttest .New (t , & coderdenttest.Options {
384
+ Options : & coderdtest.Options {
385
+ Auditor : mockAudit ,
386
+ OIDCConfig : fake .OIDCConfig (t , []string {}),
387
+ },
388
+ SCIMAPIKey : scimAPIKey ,
389
+ AuditLogging : true ,
390
+ LicenseOptions : & coderdenttest.LicenseOptions {
391
+ AccountID : "coolin" ,
392
+ Features : license.Features {
393
+ codersdk .FeatureSCIM : 1 ,
394
+ codersdk .FeatureAuditLog : 1 ,
395
+ },
396
+ },
397
+ })
398
+ mockAudit .ResetLogs ()
399
+
400
+ // User is dormant on create
401
+ sUser := makeScimUser (t )
402
+ res , err := client .Request (ctx , "POST" , "/scim/v2/Users" , sUser , setScimAuth (scimAPIKey ))
403
+ require .NoError (t , err )
404
+ defer res .Body .Close ()
405
+ assert .Equal (t , http .StatusOK , res .StatusCode )
406
+
407
+ err = json .NewDecoder (res .Body ).Decode (& sUser )
408
+ require .NoError (t , err )
409
+
410
+ // Check the audit log
411
+ aLogs := mockAudit .AuditLogs ()
412
+ require .Len (t , aLogs , 1 )
413
+ assert .Equal (t , database .AuditActionCreate , aLogs [0 ].Action )
414
+
415
+ // Verify the user is dormant
416
+ scimUser , err := client .User (ctx , sUser .UserName )
417
+ require .NoError (t , err )
418
+ require .Equal (t , codersdk .UserStatusDormant , scimUser .Status , "user starts as dormant" )
419
+
420
+ // Log in as the user, making them active
421
+ //nolint:bodyclose
422
+ scimUserClient , _ := fake .Login (t , client , jwt.MapClaims {
423
+ "email" : sUser .Emails [0 ].Value ,
424
+ })
425
+ scimUser , err = scimUserClient .User (ctx , codersdk .Me )
426
+ require .NoError (t , err )
427
+ require .Equal (t , codersdk .UserStatusActive , scimUser .Status , "user should now be active" )
428
+
429
+ // Patch the user
430
+ mockAudit .ResetLogs ()
431
+ res , err = client .Request (ctx , "PATCH" , "/scim/v2/Users/" + sUser .ID , sUser , setScimAuth (scimAPIKey ))
432
+ require .NoError (t , err )
433
+ _ , _ = io .Copy (io .Discard , res .Body )
434
+ _ = res .Body .Close ()
435
+ assert .Equal (t , http .StatusOK , res .StatusCode )
436
+
437
+ // Should be no audit logs since there is no diff
438
+ aLogs = mockAudit .AuditLogs ()
439
+ require .Len (t , aLogs , 0 )
440
+
441
+ // Verify the user is still active.
442
+ scimUser , err = client .User (ctx , sUser .UserName )
443
+ require .NoError (t , err )
444
+ require .Equal (t , codersdk .UserStatusActive , scimUser .Status , "user is still active" )
445
+ })
367
446
})
368
447
}
0 commit comments