def test_confirm_email_change_with_invalid_key(self) -> None: self.login("hamlet") key = "invalid_key" url = confirmation_url(key, None, Confirmation.EMAIL_CHANGE) response = self.client_get(url) self.assertEqual(response.status_code, 404) self.assert_in_response("Whoops. The confirmation link is malformed.", response)
def test_confirm_email_change_with_non_existent_key(self): # type: () -> None self.login(self.example_email("hamlet")) key = generate_key() url = confirmation_url(key, 'testserver', Confirmation.EMAIL_CHANGE) response = self.client_get(url) self.assert_in_success_response(["Whoops. We couldn't find your confirmation link in the system."], response)
def test_confirm_email_change_with_invalid_key(self): # type: () -> None self.login(self.example_email("hamlet")) key = 'invalid key' url = confirmation_url(key, 'testserver', Confirmation.EMAIL_CHANGE) response = self.client_get(url) self.assert_in_success_response(["Whoops. The confirmation link is malformed."], response)
def test_change_delivery_email_end_to_end_with_admins_visibility(self) -> None: user_profile = self.example_user('hamlet') do_set_realm_property(user_profile.realm, 'email_address_visibility', Realm.EMAIL_ADDRESS_VISIBILITY_ADMINS) self.login_user(user_profile) old_email = user_profile.delivery_email new_email = '*****@*****.**' obj = EmailChangeStatus.objects.create(new_email=new_email, old_email=old_email, user_profile=user_profile, realm=user_profile.realm) key = generate_key() Confirmation.objects.create(content_object=obj, date_sent=now(), confirmation_key=key, type=Confirmation.EMAIL_CHANGE) url = confirmation_url(key, user_profile.realm.host, Confirmation.EMAIL_CHANGE) response = self.client_get(url) self.assertEqual(response.status_code, 200) self.assert_in_success_response(["This confirms that the email address for your Zulip"], response) user_profile = get_user_profile_by_id(user_profile.id) self.assertEqual(user_profile.delivery_email, new_email) self.assertEqual(user_profile.email, f"user{user_profile.id}@zulip.testserver") obj.refresh_from_db() self.assertEqual(obj.status, 1) with self.assertRaises(UserProfile.DoesNotExist): get_user(old_email, user_profile.realm) with self.assertRaises(UserProfile.DoesNotExist): get_user_by_delivery_email(old_email, user_profile.realm) self.assertEqual(get_user_by_delivery_email(new_email, user_profile.realm), user_profile)
def test_change_delivery_email_end_to_end_with_admins_visibility(self) -> None: user_profile = self.example_user('hamlet') do_set_realm_property(user_profile.realm, 'email_address_visibility', Realm.EMAIL_ADDRESS_VISIBILITY_ADMINS) old_email = user_profile.email new_email = '*****@*****.**' self.login(self.example_email('hamlet')) obj = EmailChangeStatus.objects.create(new_email=new_email, old_email=old_email, user_profile=user_profile, realm=user_profile.realm) key = generate_key() Confirmation.objects.create(content_object=obj, date_sent=now(), confirmation_key=key, type=Confirmation.EMAIL_CHANGE) url = confirmation_url(key, user_profile.realm.host, Confirmation.EMAIL_CHANGE) response = self.client_get(url) self.assertEqual(response.status_code, 200) self.assert_in_success_response(["This confirms that the email address for your Zulip"], response) user_profile = get_user_profile_by_id(user_profile.id) self.assertEqual(user_profile.delivery_email, new_email) self.assertEqual(user_profile.email, "*****@*****.**") obj.refresh_from_db() self.assertEqual(obj.status, 1) with self.assertRaises(UserProfile.DoesNotExist): get_user(old_email, user_profile.realm) with self.assertRaises(UserProfile.DoesNotExist): get_user_by_delivery_email(old_email, user_profile.realm) self.assertEqual(get_user_by_delivery_email(new_email, user_profile.realm), user_profile)
def test_confirm_email_change_with_invalid_key(self) -> None: self.login('hamlet') key = 'invalid_key' url = confirmation_url(key, None, Confirmation.EMAIL_CHANGE) response = self.client_get(url) self.assert_in_success_response( ["Whoops. The confirmation link is malformed."], response)
def test_confirm_email_change_when_time_exceeded(self) -> None: user_profile = self.example_user("hamlet") old_email = user_profile.email new_email = "*****@*****.**" self.login("hamlet") obj = EmailChangeStatus.objects.create( new_email=new_email, old_email=old_email, user_profile=user_profile, realm=user_profile.realm, ) key = generate_key() date_sent = now() - datetime.timedelta(days=2) Confirmation.objects.create( content_object=obj, date_sent=date_sent, confirmation_key=key, type=Confirmation.EMAIL_CHANGE, ) url = confirmation_url(key, user_profile.realm, Confirmation.EMAIL_CHANGE) response = self.client_get(url) self.assert_in_success_response( ["The confirmation link has expired or been deactivated."], response)
def test_confirm_email_change(self) -> None: user_profile = self.example_user('hamlet') old_email = user_profile.email new_email = '*****@*****.**' new_realm = get_realm('zulip') self.login(self.example_email('hamlet')) obj = EmailChangeStatus.objects.create(new_email=new_email, old_email=old_email, user_profile=user_profile, realm=user_profile.realm) key = generate_key() Confirmation.objects.create(content_object=obj, date_sent=now(), confirmation_key=key, type=Confirmation.EMAIL_CHANGE) url = confirmation_url(key, user_profile.realm.host, Confirmation.EMAIL_CHANGE) response = self.client_get(url) self.assertEqual(response.status_code, 200) self.assert_in_success_response(["This confirms that the email address for your Zulip"], response) user_profile = get_user(new_email, new_realm) self.assertTrue(bool(user_profile)) obj.refresh_from_db() self.assertEqual(obj.status, 1)
def generate_all_emails(request: HttpRequest) -> HttpResponse: # write fake data for all variables registered_email = "*****@*****.**" unregistered_email_1 = "*****@*****.**" unregistered_email_2 = "*****@*****.**" realm = get_realm("zulip") host_kwargs = {'HTTP_HOST': realm.host} # Password reset email result = client.post('/accounts/password/reset/', {'email': registered_email}, **host_kwargs) assert result.status_code == 302 # Confirm account email result = client.post('/accounts/home/', {'email': unregistered_email_1}, **host_kwargs) assert result.status_code == 302 # Find account email result = client.post('/accounts/find/', {'emails': registered_email}, **host_kwargs) assert result.status_code == 302 # New login email logged_in = client.login(dev_auth_username=registered_email, realm=realm) assert logged_in # New user invite and reminder emails result = client.post( "/json/invites", { "invitee_emails": unregistered_email_2, "stream": ["Denmark"], "custom_body": "" }, **host_kwargs) assert result.status_code == 200 # Verification for new email result = client.patch( '/json/settings', urllib.parse.urlencode({'email': '*****@*****.**'}), **host_kwargs) assert result.status_code == 200 # Email change successful key = Confirmation.objects.filter( type=Confirmation.EMAIL_CHANGE).latest('id').confirmation_key url = confirmation_url(key, realm.host, Confirmation.EMAIL_CHANGE) user_profile = get_user(registered_email, realm) result = client.get(url) assert result.status_code == 200 # Reset the email value so we can run this again user_profile.email = registered_email user_profile.save(update_fields=['email']) # Follow up day1 day2 emails enqueue_welcome_emails(user_profile) return redirect(email_page)
def test_confirm_email_change_with_non_existent_key(self) -> None: self.login('hamlet') key = generate_key() url = confirmation_url(key, None, Confirmation.EMAIL_CHANGE) response = self.client_get(url) self.assert_in_success_response( ["Whoops. We couldn't find your confirmation link in the system."], response)
def test_confirm_email_change_with_invalid_key(self): # type: () -> None self.login(self.example_email("hamlet")) key = 'invalid key' url = confirmation_url(key, 'testserver', Confirmation.EMAIL_CHANGE) response = self.client_get(url) self.assert_in_success_response( ["Whoops. The confirmation link is malformed."], response)
def test_confirm_email_change_with_non_existent_key(self): # type: () -> None self.login(self.example_email("hamlet")) key = generate_key() url = confirmation_url(key, 'testserver', Confirmation.EMAIL_CHANGE) response = self.client_get(url) self.assert_in_success_response( ["Whoops. We couldn't find your confirmation link in the system."], response)
def test_confirm_email_change_with_non_existent_key(self) -> None: self.login("hamlet") key = generate_key() url = confirmation_url(key, None, Confirmation.EMAIL_CHANGE) response = self.client_get(url) self.assertEqual(response.status_code, 404) self.assert_in_response( "Whoops. We couldn't find your confirmation link in the system.", response)
def do_get_invites_controlled_by_user( user_profile: UserProfile) -> List[Dict[str, Any]]: """ Returns a list of dicts representing invitations that can be controlled by user_profile. This isn't necessarily the same as all the invitations generated by the user, as administrators can control also invitations that they did not themselves create. """ if user_profile.is_realm_admin: prereg_users = filter_to_valid_prereg_users( PreregistrationUser.objects.filter( referred_by__realm=user_profile.realm)) else: prereg_users = filter_to_valid_prereg_users( PreregistrationUser.objects.filter(referred_by=user_profile)) invites = [] for invitee in prereg_users: assert invitee.referred_by is not None invites.append( dict( email=invitee.email, invited_by_user_id=invitee.referred_by.id, invited=datetime_to_timestamp(invitee.invited_at), expiry_date=get_invitation_expiry_date( invitee.confirmation.get()), id=invitee.id, invited_as=invitee.invited_as, is_multiuse=False, )) if not user_profile.is_realm_admin: # We do not return multiuse invites to non-admin users. return invites multiuse_confirmation_objs = Confirmation.objects.filter( realm=user_profile.realm, type=Confirmation.MULTIUSE_INVITE).filter( Q(expiry_date__gte=timezone_now()) | Q(expiry_date=None)) for confirmation_obj in multiuse_confirmation_objs: invite = confirmation_obj.content_object assert invite is not None invites.append( dict( invited_by_user_id=invite.referred_by.id, invited=datetime_to_timestamp(confirmation_obj.date_sent), expiry_date=get_invitation_expiry_date(confirmation_obj), id=invite.id, link_url=confirmation_url( confirmation_obj.confirmation_key, user_profile.realm, Confirmation.MULTIUSE_INVITE, ), invited_as=invite.invited_as, is_multiuse=True, )) return invites
def generate_all_emails(request): # type: (HttpRequest) -> HttpResponse # write fake data for all variables registered_email = "*****@*****.**" unregistered_email_1 = "*****@*****.**" unregistered_email_2 = "*****@*****.**" realm = get_realm("zulip") host_kwargs = {'HTTP_HOST': realm.host} # Password reset email client.post('/accounts/password/reset/', {'email': registered_email}, **host_kwargs) # Confirm account email client.post('/accounts/home/', {'email': unregistered_email_1}, **host_kwargs) # Find account email client.post('/accounts/find/', {'emails': registered_email}, **host_kwargs) # New login email client.login(username=registered_email) # New user invite and reminder emails client.post( "/json/invites", { "invitee_emails": unregistered_email_2, "stream": ["Denmark"], "custom_body": "" }, **host_kwargs) # Verification for new email client.patch('/json/settings', urllib.parse.urlencode({'email': '*****@*****.**'}), **host_kwargs) # Email change successful key = Confirmation.objects.filter( type=Confirmation.EMAIL_CHANGE).latest('id').confirmation_key url = confirmation_url(key, realm.host, Confirmation.EMAIL_CHANGE) user_profile = get_user(registered_email, realm) client.get(url) user_profile.emails = "*****@*****.**" user_profile.save() # Follow up day1 day2 emails enqueue_welcome_emails(user_profile) message = ''' Emails generated successfully. Reload this page to generate them again. To clear this log click <a href="/emails/clear">here</a>. ''' return email_page(request, message)
def generate_all_emails(request: HttpRequest) -> HttpResponse: # write fake data for all variables registered_email = "*****@*****.**" unregistered_email_1 = "*****@*****.**" unregistered_email_2 = "*****@*****.**" realm = get_realm("zulip") host_kwargs = {'HTTP_HOST': realm.host} # Password reset email result = client.post('/accounts/password/reset/', {'email': registered_email}, **host_kwargs) assert result.status_code == 302 # Confirm account email result = client.post('/accounts/home/', {'email': unregistered_email_1}, **host_kwargs) assert result.status_code == 302 # Find account email result = client.post('/accounts/find/', {'emails': registered_email}, **host_kwargs) assert result.status_code == 302 # New login email logged_in = client.login(dev_auth_username=registered_email, realm=realm) assert logged_in # New user invite and reminder emails result = client.post("/json/invites", {"invitee_emails": unregistered_email_2, "stream": ["Denmark"]}, **host_kwargs) assert result.status_code == 200 # Verification for new email result = client.patch('/json/settings', urllib.parse.urlencode({'email': '*****@*****.**'}), **host_kwargs) assert result.status_code == 200 # Email change successful key = Confirmation.objects.filter(type=Confirmation.EMAIL_CHANGE).latest('id').confirmation_key url = confirmation_url(key, realm.host, Confirmation.EMAIL_CHANGE) user_profile = get_user(registered_email, realm) result = client.get(url) assert result.status_code == 200 # Reset the email value so we can run this again user_profile.email = registered_email user_profile.save(update_fields=['email']) # Follow up day1 day2 emails enqueue_welcome_emails(user_profile) return redirect(email_page)
def test_confirm_email_change_when_time_exceeded(self) -> None: user_profile = self.example_user('hamlet') old_email = user_profile.email new_email = '*****@*****.**' self.login(self.example_email("hamlet")) obj = EmailChangeStatus.objects.create(new_email=new_email, old_email=old_email, user_profile=user_profile, realm=user_profile.realm) key = generate_key() date_sent = now() - datetime.timedelta(days=2) Confirmation.objects.create(content_object=obj, date_sent=date_sent, confirmation_key=key, type=Confirmation.EMAIL_CHANGE) url = confirmation_url(key, user_profile.realm.host, Confirmation.EMAIL_CHANGE) response = self.client_get(url) self.assert_in_success_response(["The confirmation link has expired or been deactivated."], response)
def get_confirmations( types: List[int], object_ids: List[int], hostname: Optional[str] = None ) -> List[Dict[str, Any]]: lowest_datetime = timezone_now() - timedelta(days=30) confirmations = Confirmation.objects.filter( type__in=types, object_id__in=object_ids, date_sent__gte=lowest_datetime ) confirmation_dicts = [] for confirmation in confirmations: realm = confirmation.realm content_object = confirmation.content_object type = confirmation.type days_to_activate = _properties[type].validity_in_days expiry_date = confirmation.date_sent + timedelta(days=days_to_activate) assert content_object is not None if hasattr(content_object, "status"): if content_object.status == STATUS_ACTIVE: link_status = "Link has been clicked" else: link_status = "Link has never been clicked" else: link_status = "" now = timezone_now() if now < expiry_date: expires_in = timesince(now, expiry_date) else: expires_in = "Expired" url = confirmation_url(confirmation.confirmation_key, realm, type) confirmation_dicts.append( { "object": confirmation.content_object, "url": url, "type": type, "link_status": link_status, "expires_in": expires_in, } ) return confirmation_dicts
def test_confirm_email_change(self) -> None: user_profile = self.example_user("hamlet") do_set_realm_property( user_profile.realm, "email_address_visibility", Realm.EMAIL_ADDRESS_VISIBILITY_EVERYONE, acting_user=None, ) old_email = user_profile.delivery_email new_email = "*****@*****.**" new_realm = get_realm("zulip") self.login("hamlet") obj = EmailChangeStatus.objects.create( new_email=new_email, old_email=old_email, user_profile=user_profile, realm=user_profile.realm, ) key = generate_key() Confirmation.objects.create( content_object=obj, date_sent=now(), confirmation_key=key, type=Confirmation.EMAIL_CHANGE, ) url = confirmation_url(key, user_profile.realm, Confirmation.EMAIL_CHANGE) response = self.client_get(url) self.assertEqual(response.status_code, 200) self.assert_in_success_response( ["This confirms that the email address for your Zulip"], response ) user_profile = get_user_by_delivery_email(new_email, new_realm) self.assertTrue(bool(user_profile)) obj.refresh_from_db() self.assertEqual(obj.status, 1)
def generate_all_emails(request: HttpRequest) -> HttpResponse: if not settings.TEST_SUITE: # nocoverage # It's really convenient to automatically inline the email CSS # here, since that saves a step when testing out changes to # the email CSS. But we don't run this inside the test suite, # because by role, the tests shouldn't be doing a provision-like thing. subprocess.check_call(["./scripts/setup/inline_email_css.py"]) # We import the Django test client inside the view function, # because it isn't needed in production elsewhere, and not # importing it saves ~50ms of unnecessary manage.py startup time. from django.test import Client client = Client() # write fake data for all variables registered_email = "*****@*****.**" unregistered_email_1 = "*****@*****.**" unregistered_email_2 = "*****@*****.**" realm = get_realm("zulip") other_realm = Realm.objects.exclude(string_id='zulip').first() user = get_user_by_delivery_email(registered_email, realm) host_kwargs = {'HTTP_HOST': realm.host} # Password reset emails # active account in realm result = client.post('/accounts/password/reset/', {'email': registered_email}, **host_kwargs) assert result.status_code == 302 # deactivated user user.is_active = False user.save(update_fields=['is_active']) result = client.post('/accounts/password/reset/', {'email': registered_email}, **host_kwargs) assert result.status_code == 302 user.is_active = True user.save(update_fields=['is_active']) # account on different realm result = client.post('/accounts/password/reset/', {'email': registered_email}, HTTP_HOST=other_realm.host) assert result.status_code == 302 # no account anywhere result = client.post('/accounts/password/reset/', {'email': unregistered_email_1}, **host_kwargs) assert result.status_code == 302 # Confirm account email result = client.post('/accounts/home/', {'email': unregistered_email_1}, **host_kwargs) assert result.status_code == 302 # Find account email result = client.post('/accounts/find/', {'emails': registered_email}, **host_kwargs) assert result.status_code == 302 # New login email logged_in = client.login(dev_auth_username=registered_email, realm=realm) assert logged_in # New user invite and reminder emails stream = get_realm_stream("Denmark", user.realm.id) result = client.post( "/json/invites", { "invitee_emails": unregistered_email_2, "stream_ids": ujson.dumps([stream.id]) }, **host_kwargs) assert result.status_code == 200 # Verification for new email result = client.patch( '/json/settings', urllib.parse.urlencode({'email': '*****@*****.**'}), **host_kwargs) assert result.status_code == 200 # Email change successful key = Confirmation.objects.filter( type=Confirmation.EMAIL_CHANGE).latest('id').confirmation_key url = confirmation_url(key, realm.host, Confirmation.EMAIL_CHANGE) user_profile = get_user_by_delivery_email(registered_email, realm) result = client.get(url) assert result.status_code == 200 # Reset the email value so we can run this again do_change_user_delivery_email(user_profile, registered_email) # Follow up day1 day2 emails for normal user enqueue_welcome_emails(user_profile) # Follow up day1 day2 emails for admin user enqueue_welcome_emails(get_user_by_delivery_email("*****@*****.**", realm), realm_creation=True) # Realm reactivation email do_send_realm_reactivation_email(realm) return redirect(email_page)
def generate_all_emails(request: HttpRequest) -> HttpResponse: if not settings.TEST_SUITE: # nocoverage # It's really convenient to automatically inline the email CSS # here, since that saves a step when testing out changes to # the email CSS. But we don't run this inside the test suite, # because by role, the tests shouldn't be doing a provision-like thing. subprocess.check_call(["./tools/inline-email-css"]) # We import the Django test client inside the view function, # because it isn't needed in production elsewhere, and not # importing it saves ~50ms of unnecessary manage.py startup time. from django.test import Client client = Client() # write fake data for all variables registered_email = "*****@*****.**" unregistered_email_1 = "*****@*****.**" unregistered_email_2 = "*****@*****.**" realm = get_realm("zulip") host_kwargs = {'HTTP_HOST': realm.host} # Password reset email result = client.post('/accounts/password/reset/', {'email': registered_email}, **host_kwargs) assert result.status_code == 302 # Confirm account email result = client.post('/accounts/home/', {'email': unregistered_email_1}, **host_kwargs) assert result.status_code == 302 # Find account email result = client.post('/accounts/find/', {'emails': registered_email}, **host_kwargs) assert result.status_code == 302 # New login email logged_in = client.login(dev_auth_username=registered_email, realm=realm) assert logged_in # New user invite and reminder emails result = client.post("/json/invites", { "invitee_emails": unregistered_email_2, "stream": ["Denmark"] }, **host_kwargs) assert result.status_code == 200 # Verification for new email result = client.patch( '/json/settings', urllib.parse.urlencode({'email': '*****@*****.**'}), **host_kwargs) assert result.status_code == 200 # Email change successful key = Confirmation.objects.filter( type=Confirmation.EMAIL_CHANGE).latest('id').confirmation_key url = confirmation_url(key, realm.host, Confirmation.EMAIL_CHANGE) user_profile = get_user(registered_email, realm) result = client.get(url) assert result.status_code == 200 # Reset the email value so we can run this again user_profile.email = registered_email user_profile.save(update_fields=['email']) # Follow up day1 day2 emails enqueue_welcome_emails(user_profile) return redirect(email_page)
def test_email_change_when_not_logging_in(self): # type: () -> None key = generate_key() url = confirmation_url(key, 'testserver', Confirmation.EMAIL_CHANGE) response = self.client_get(url) self.assertEqual(response.status_code, 302)
def generate_all_emails(request: HttpRequest) -> HttpResponse: if not settings.TEST_SUITE: # nocoverage # It's really convenient to automatically inline the email CSS # here, since that saves a step when testing out changes to # the email CSS. But we don't run this inside the test suite, # because by role, the tests shouldn't be doing a provision-like thing. subprocess.check_call(["./tools/inline-email-css"]) # We import the Django test client inside the view function, # because it isn't needed in production elsewhere, and not # importing it saves ~50ms of unnecessary manage.py startup time. from django.test import Client client = Client() # write fake data for all variables registered_email = "*****@*****.**" unregistered_email_1 = "*****@*****.**" unregistered_email_2 = "*****@*****.**" realm = get_realm("zulip") other_realm = Realm.objects.exclude(string_id='zulip').first() user = get_user_by_delivery_email(registered_email, realm) host_kwargs = {'HTTP_HOST': realm.host} # Password reset emails # active account in realm result = client.post('/accounts/password/reset/', {'email': registered_email}, **host_kwargs) assert result.status_code == 302 # deactivated user user.is_active = False user.save(update_fields=['is_active']) result = client.post('/accounts/password/reset/', {'email': registered_email}, **host_kwargs) assert result.status_code == 302 user.is_active = True user.save(update_fields=['is_active']) # account on different realm result = client.post('/accounts/password/reset/', {'email': registered_email}, HTTP_HOST=other_realm.host) assert result.status_code == 302 # no account anywhere result = client.post('/accounts/password/reset/', {'email': unregistered_email_1}, **host_kwargs) assert result.status_code == 302 # Confirm account email result = client.post('/accounts/home/', {'email': unregistered_email_1}, **host_kwargs) assert result.status_code == 302 # Find account email result = client.post('/accounts/find/', {'emails': registered_email}, **host_kwargs) assert result.status_code == 302 # New login email logged_in = client.login(dev_auth_username=registered_email, realm=realm) assert logged_in # New user invite and reminder emails result = client.post("/json/invites", {"invitee_emails": unregistered_email_2, "stream": ["Denmark"]}, **host_kwargs) assert result.status_code == 200 # Verification for new email result = client.patch('/json/settings', urllib.parse.urlencode({'email': '*****@*****.**'}), **host_kwargs) assert result.status_code == 200 # Email change successful key = Confirmation.objects.filter(type=Confirmation.EMAIL_CHANGE).latest('id').confirmation_key url = confirmation_url(key, realm.host, Confirmation.EMAIL_CHANGE) user_profile = get_user_by_delivery_email(registered_email, realm) result = client.get(url) assert result.status_code == 200 # Reset the email value so we can run this again do_change_user_delivery_email(user_profile, registered_email) # Follow up day1 day2 emails for normal user enqueue_welcome_emails(user_profile) # Follow up day1 day2 emails for admin user enqueue_welcome_emails(get_user_by_delivery_email("*****@*****.**", realm), realm_creation=True) # Realm reactivation email do_send_realm_reactivation_email(realm) return redirect(email_page)