1
1
from datetime import timedelta
2
+ from uuid import uuid4
2
3
3
4
from django .conf import settings
4
5
from django .db import router
15
16
from sentry .models .organizationmember import InviteStatus , OrganizationMember
16
17
from sentry .models .organizationmembermapping import OrganizationMemberMapping
17
18
from sentry .models .outbox import outbox_context
19
+ from sentry .models .useremail import UserEmail
18
20
from sentry .silo import SiloMode , unguarded_write
19
21
from sentry .testutils .cases import TestCase
20
22
from sentry .testutils .factories import Factories
@@ -117,7 +119,7 @@ def test_not_needs_authentication(self):
117
119
self .login_as (self .user )
118
120
119
121
om = Factories .create_member (
120
- email = "newuser@example.com" , token = "abc" , organization = self .organization
122
+ email = self . user . email , token = "abc" , organization = self .organization
121
123
)
122
124
for path in self ._get_paths ([om .id , om .token ]):
123
125
resp = self .client .get (path )
@@ -131,7 +133,7 @@ def test_user_needs_2fa(self):
131
133
self .login_as (self .user )
132
134
133
135
om = Factories .create_member (
134
- email = "newuser@example.com" , token = "abc" , organization = self .organization
136
+ email = self . user . email , token = "abc" , organization = self .organization
135
137
)
136
138
137
139
for path in self ._get_paths ([om .id , om .token ]):
@@ -165,7 +167,7 @@ def test_multi_region_organizationmember_id(self):
165
167
166
168
with assume_test_silo_mode_of (OrganizationMember ), outbox_context (flush = False ):
167
169
om = OrganizationMember .objects .create (
168
- email = "newuser@example.com" , token = "abc" , organization_id = self .organization .id
170
+ email = self . user . email , token = "abc" , organization_id = self .organization .id
169
171
)
170
172
with unguarded_write (using = router .db_for_write (OrganizationMemberMapping )):
171
173
OrganizationMemberMapping .objects .create (
@@ -211,7 +213,7 @@ def test_user_has_2fa(self):
211
213
self .login_as (self .user )
212
214
213
215
om = Factories .create_member (
214
- email = "newuser@example.com" , token = "abc" , organization = self .organization
216
+ email = self . user . email , token = "abc" , organization = self .organization
215
217
)
216
218
for path in self ._get_paths ([om .id , om .token ]):
217
219
resp = self .client .get (path )
@@ -225,7 +227,7 @@ def test_user_can_use_sso(self):
225
227
self .login_as (self .user )
226
228
227
229
om = Factories .create_member (
228
- email = "newuser@example.com" , token = "abc" , organization = self .organization
230
+ email = self . user . email , token = "abc" , organization = self .organization
229
231
)
230
232
for path in self ._get_paths ([om .id , om .token ]):
231
233
resp = self .client .get (path )
@@ -307,6 +309,61 @@ def test_cannot_accept_unapproved_invite(self):
307
309
assert om .is_pending
308
310
assert om .token
309
311
312
+ def test_cannot_accept_without_matching_verified_email (self ):
313
+ newuser = self .create_user ()
314
+
315
+ newuser_email = UserEmail .objects .get (user = newuser , email = newuser .email )
316
+ newuser_email .is_verified = False
317
+ newuser_email .save ()
318
+
319
+ self .login_as (newuser )
320
+
321
+ assert not newuser_email .is_verified
322
+
323
+ om = Factories .create_member (
324
+ email = newuser .email ,
325
+ role = "member" ,
326
+ token = "abc" ,
327
+ organization = self .organization ,
328
+ invite_status = InviteStatus .APPROVED .value ,
329
+ )
330
+
331
+ for path in self ._get_paths ([om .id , om .token ]):
332
+ resp = self .client .post (path )
333
+ assert resp .status_code == 403 , resp .content
334
+
335
+ with assume_test_silo_mode_of (OrganizationMember ):
336
+ om = OrganizationMember .objects .get (id = om .id )
337
+
338
+ assert om .is_pending
339
+ assert om .token
340
+
341
+ def test_can_accept_with_matching_verified_email (self ):
342
+ urls = self ._get_urls ()
343
+
344
+ for url in urls :
345
+ newuser = self .create_user () # implicitly verifies the email
346
+ self .login_as (newuser )
347
+
348
+ om = Factories .create_member (
349
+ email = newuser .email ,
350
+ role = "member" ,
351
+ token = uuid4 ().hex ,
352
+ organization = self .organization ,
353
+ invite_status = InviteStatus .APPROVED .value ,
354
+ )
355
+
356
+ path = self ._get_path (url , [om .id , om .token ])
357
+ resp = self .client .post (path )
358
+
359
+ assert resp .status_code == 204 , resp .content
360
+
361
+ with assume_test_silo_mode_of (OrganizationMember ):
362
+ om = OrganizationMember .objects .get (id = om .id )
363
+
364
+ assert not om .is_pending
365
+ assert not om .token
366
+
310
367
def test_member_already_exists (self ):
311
368
urls = self ._get_urls ()
312
369
@@ -317,7 +374,7 @@ def test_member_already_exists(self):
317
374
om = Factories .create_member (
318
375
email = user .email ,
319
376
role = "member" ,
320
- token = "abc" ,
377
+ token = uuid4 (). hex ,
321
378
organization = self .organization ,
322
379
)
323
380
path = self ._get_path (url , [om .id , om .token ])
@@ -355,7 +412,7 @@ def test_can_accept_when_user_has_2fa(self):
355
412
self .login_as (user )
356
413
357
414
om = Factories .create_member (
358
- email = "newuser" + str ( i ) + "@example.com" ,
415
+ email = user . email ,
359
416
role = "member" ,
360
417
token = "abc" ,
361
418
organization = self .organization ,
@@ -408,19 +465,19 @@ def test_2fa_cookie_deleted_after_accept(self):
408
465
self .login_as (user )
409
466
410
467
om = Factories .create_member (
411
- email = "newuser" + str ( i ) + "@example.com" ,
468
+ email = user . email ,
412
469
role = "member" ,
413
470
token = "abc" ,
414
471
organization = self .organization ,
415
472
)
416
473
path = self ._get_path (url , [om .id , om .token ])
417
474
resp = self .client .get (path )
418
- assert resp .status_code == 200
475
+ assert resp .status_code == 200 , resp . content
419
476
self ._assert_pending_invite_details_in_session (om )
420
477
421
478
self ._enroll_user_in_2fa (user )
422
479
resp = self .client .post (path )
423
- assert resp .status_code == 204
480
+ assert resp .status_code == 204 , resp . content
424
481
425
482
self ._assert_pending_invite_details_not_in_session (resp )
426
483
0 commit comments