@@ -22,6 +22,7 @@ import (
22
22
"github.com/prometheus/client_golang/prometheus"
23
23
"github.com/stretchr/testify/assert"
24
24
"github.com/stretchr/testify/require"
25
+ "go.uber.org/atomic"
25
26
"golang.org/x/oauth2"
26
27
"golang.org/x/xerrors"
27
28
@@ -254,37 +255,64 @@ func TestUserOAuth2Github(t *testing.T) {
254
255
})
255
256
t .Run ("BlockSignups" ,func (t * testing.T ) {
256
257
t .Parallel ()
258
+
259
+ db ,ps := dbtestutil .NewDB (t )
260
+
261
+ id := atomic .NewInt64 (100 )
262
+ login := atomic .NewString ("testuser" )
263
+ email := atomic .NewString ("testuser@coder.com" )
264
+
257
265
client := coderdtest .New (t ,& coderdtest.Options {
266
+ Database :db ,
267
+ Pubsub :ps ,
258
268
GithubOAuth2Config :& coderd.GithubOAuth2Config {
259
269
OAuth2Config :& testutil.OAuth2Config {},
260
270
AllowOrganizations : []string {"coder" },
261
- ListOrganizationMemberships :func (ctx context.Context ,client * http.Client ) ([]* github.Membership ,error ) {
271
+ ListOrganizationMemberships :func (_ context.Context ,_ * http.Client ) ([]* github.Membership ,error ) {
262
272
return []* github.Membership {{
263
273
State :& stateActive ,
264
274
Organization :& github.Organization {
265
275
Login :github .String ("coder" ),
266
276
},
267
277
}},nil
268
278
},
269
- AuthenticatedUser :func (ctx context.Context ,client * http.Client ) (* github.User ,error ) {
279
+ AuthenticatedUser :func (_ context.Context ,_ * http.Client ) (* github.User ,error ) {
280
+ id := id .Load ()
281
+ login := login .Load ()
270
282
return & github.User {
271
- ID :github . Int64 ( 100 ) ,
272
- Login :github . String ( "testuser" ) ,
283
+ ID :& id ,
284
+ Login :& login ,
273
285
Name :github .String ("The Right Honorable Sir Test McUser" ),
274
286
},nil
275
287
},
276
- ListEmails :func (ctx context.Context ,client * http.Client ) ([]* github.UserEmail ,error ) {
288
+ ListEmails :func (_ context.Context ,_ * http.Client ) ([]* github.UserEmail ,error ) {
289
+ email := email .Load ()
277
290
return []* github.UserEmail {{
278
- Email :github . String ( "testuser@coder.com" ) ,
291
+ Email :& email ,
279
292
Verified :github .Bool (true ),
280
293
Primary :github .Bool (true ),
281
294
}},nil
282
295
},
283
296
},
284
297
})
285
298
299
+ // The first user in a deployment with signups disabled will be allowed to sign up,
300
+ // but all the other users will not.
286
301
resp := oauth2Callback (t ,client )
302
+ require .Equal (t ,http .StatusTemporaryRedirect ,resp .StatusCode )
303
+
304
+ ctx := testutil .Context (t ,testutil .WaitLong )
305
+
306
+ // nolint:gocritic // Unit test
307
+ count ,err := db .GetUserCount (dbauthz .AsSystemRestricted (ctx ))
308
+ require .NoError (t ,err )
309
+ require .Equal (t ,int64 (1 ),count )
310
+
311
+ id .Store (101 )
312
+ email .Store ("someotheruser@coder.com" )
313
+ login .Store ("someotheruser" )
287
314
315
+ resp = oauth2Callback (t ,client )
288
316
require .Equal (t ,http .StatusForbidden ,resp .StatusCode )
289
317
})
290
318
t .Run ("MultiLoginNotAllowed" ,func (t * testing.T ) {
@@ -986,6 +1014,7 @@ func TestUserOIDC(t *testing.T) {
986
1014
AssertResponse func (t testing.TB ,resp * http.Response )
987
1015
IgnoreEmailVerified bool
988
1016
IgnoreUserInfo bool
1017
+ PrecreateFirstUser bool
989
1018
}{
990
1019
{
991
1020
Name :"NoSub" ,
@@ -1122,7 +1151,17 @@ func TestUserOIDC(t *testing.T) {
1122
1151
"email_verified" :true ,
1123
1152
"sub" :uuid .NewString (),
1124
1153
},
1125
- StatusCode :http .StatusForbidden ,
1154
+ StatusCode :http .StatusForbidden ,
1155
+ PrecreateFirstUser :true ,
1156
+ },
1157
+ {
1158
+ Name :"FirstSignup" ,
1159
+ IDTokenClaims : jwt.MapClaims {
1160
+ "email" :"kyle@kwc.io" ,
1161
+ "email_verified" :true ,
1162
+ "sub" :uuid .NewString (),
1163
+ },
1164
+ StatusCode :http .StatusOK ,
1126
1165
},
1127
1166
{
1128
1167
Name :"UsernameFromEmail" ,
@@ -1401,15 +1440,22 @@ func TestUserOIDC(t *testing.T) {
1401
1440
})
1402
1441
numLogs := len (auditor .AuditLogs ())
1403
1442
1443
+ ctx := testutil .Context (t ,testutil .WaitShort )
1444
+ if tc .PrecreateFirstUser {
1445
+ owner .CreateFirstUser (ctx , codersdk.CreateFirstUserRequest {
1446
+ Email :"precreated@coder.com" ,
1447
+ Username :"precreated" ,
1448
+ Password :"SomeSecurePassword!" ,
1449
+ })
1450
+ }
1451
+
1404
1452
client ,resp := fake .AttemptLogin (t ,owner ,tc .IDTokenClaims )
1405
1453
numLogs ++ // add an audit log for login
1406
1454
require .Equal (t ,tc .StatusCode ,resp .StatusCode )
1407
1455
if tc .AssertResponse != nil {
1408
1456
tc .AssertResponse (t ,resp )
1409
1457
}
1410
1458
1411
- ctx := testutil .Context (t ,testutil .WaitShort )
1412
-
1413
1459
if tc .AssertUser != nil {
1414
1460
user ,err := client .User (ctx ,"me" )
1415
1461
require .NoError (t ,err )