def test_change_password_ldap_backend(self) -> None: ldap_user_attr_map = {'full_name': 'fn', 'short_name': 'sn'} ldap_patcher = patch('django_auth_ldap.config.ldap.initialize') mock_initialize = ldap_patcher.start() mock_ldap = MockLDAP() mock_initialize.return_value = mock_ldap mock_ldap.directory = { 'uid=hamlet,ou=users,dc=zulip,dc=com': { 'userPassword': ['ldappassword', ], 'fn': ['New LDAP fullname'] } } self.login(self.example_email("hamlet")) with self.settings(LDAP_APPEND_DOMAIN="zulip.com", AUTH_LDAP_USER_ATTR_MAP=ldap_user_attr_map): result = self.client_patch( "/json/settings", dict( old_password=initial_password(self.example_email("hamlet")), new_password="******", )) self.assert_json_error(result, "Your Zulip password is managed in LDAP") result = self.client_patch( "/json/settings", dict( old_password='******', new_password="******", )) self.assert_json_error(result, "Your Zulip password is managed in LDAP") with self.settings(LDAP_APPEND_DOMAIN="example.com", AUTH_LDAP_USER_ATTR_MAP=ldap_user_attr_map): result = self.client_patch( "/json/settings", dict( old_password=initial_password(self.example_email("hamlet")), new_password="******", )) self.assert_json_success(result) with self.settings(LDAP_APPEND_DOMAIN=None, AUTH_LDAP_USER_ATTR_MAP=ldap_user_attr_map): result = self.client_patch( "/json/settings", dict( old_password=initial_password(self.example_email("hamlet")), new_password="******", )) self.assert_json_error(result, "Your Zulip password is managed in LDAP")
def test_password_auth_disabled(self): # type: () -> None with mock.patch('zproject.backends.password_auth_enabled', return_value=False): result = self.client_post("/api/v1/fetch_api_key", dict(username=self.email, password=initial_password(self.email))) self.assert_json_error_contains(result, "Password auth is disabled", 403)
def test_inactive_user(self): # type: () -> None do_deactivate_user(self.user_profile) result = self.client_post("/api/v1/fetch_api_key", dict(username=self.email, password=initial_password(self.email))) self.assert_json_error_contains(result, "Your account has been disabled", 403)
def test_fetch_api_key_success(self): # type: () -> None email = self.example_email("cordelia") self.login(email) result = self.client_post("/json/fetch_api_key", {"password": initial_password(email)}) self.assert_json_success(result)
def login_with_return(self, email: Text, password: Optional[Text]=None, **kwargs: Any) -> HttpResponse: if password is None: password = initial_password(email) return self.client_post('/accounts/login/', {'username': email, 'password': password}, **kwargs)
def login(self, email, password=None, fails=False): if password is None: password = initial_password(email) if not fails: self.assertTrue(self.client.login(username=email, password=password)) else: self.assertFalse(self.client.login(username=email, password=password))
def test_deactivated_realm(self): # type: () -> None do_deactivate_realm(self.user_profile.realm) result = self.client_post("/api/v1/fetch_api_key", dict(username=self.email, password=initial_password(self.email))) self.assert_json_error_contains(result, "Your realm has been deactivated", 403)
def test_wrong_old_password_rate_limiter(self) -> None: self.login(self.example_email("hamlet")) with self.settings(RATE_LIMITING_AUTHENTICATE=True): add_ratelimit_rule(10, 2, domain='authenticate_by_username') start_time = time.time() with mock.patch('time.time', return_value=start_time): result = self.client_patch( "/json/settings", dict( old_password='******', new_password="******", )) self.assert_json_error(result, "Wrong password!") result = self.client_patch( "/json/settings", dict( old_password='******', new_password="******", )) self.assert_json_error(result, "Wrong password!") # We're over the limit, so we'll get blocked even with the correct password. result = self.client_patch( "/json/settings", dict( old_password=initial_password( self.example_email("hamlet")), new_password="******", )) self.assert_json_error( result, "You're making too many attempts! Try again in 10 seconds." ) # After time passes, we should be able to succeed if we give the correct password. with mock.patch('time.time', return_value=start_time + 11): json_result = self.client_patch( "/json/settings", dict( old_password=initial_password( self.example_email("hamlet")), new_password='******', )) self.assert_json_success(json_result) remove_ratelimit_rule(10, 2, domain='authenticate_by_username')
def login_user(self, user_profile: UserProfile) -> None: email = user_profile.delivery_email realm = user_profile.realm password = initial_password(email) request = HttpRequest() request.session = self.client.session self.assertTrue(self.client.login(request=request, username=email, password=password, realm=realm))
def fetch_api_key() -> Dict[str, object]: email = helpers.example_email("iago") password = initial_password(email) return { "username": email, "password": password, }
def login_with_return(self, email, password=None): # type: (Text, Optional[Text]) -> HttpResponse if password is None: password = initial_password(email) return self.client_post('/accounts/login/', { 'username': email, 'password': password })
def handle(self, *args: Any, **options: str) -> None: realm = self.get_realm(options) print(self.fmt % ('email', 'password', 'API key')) for email in options['emails']: if '@' not in email: print('ERROR: %s does not look like an email address' % (email,)) continue print(self.fmt % (email, initial_password(email), self.get_user(email, realm).api_key))
def login(self, email, password=None, fails=False): # type: (Text, Optional[Text], bool) -> HttpResponse if password is None: password = initial_password(email) if not fails: self.assertTrue(self.client.login(username=email, password=password)) else: self.assertFalse(self.client.login(username=email, password=password))
def login(self, email, password=None): # type: (text_type, Optional[text_type]) -> HttpResponse if password is None: password = initial_password(email) return self.client.post('/accounts/login/', { 'username': email, 'password': password })
def handle(self, *args, **options): # type: (*Any, **str) -> None print(self.fmt % ('email', 'password', 'API key')) for email in options['emails']: if '@' not in email: print('ERROR: %s does not look like an email address' % (email,)) continue print(self.fmt % (email, initial_password(email), get_user_profile_by_email(email).api_key))
def login(self, email, password=None, fails=False): # type: (text_type, Optional[text_type], bool) -> HttpResponse if password is None: password = initial_password(email) if not fails: self.assertTrue(self.client.login(username=email, password=password)) else: self.assertFalse(self.client.login(username=email, password=password))
def test_send_login_emails_if_send_login_email_setting_is_true( self) -> None: with self.settings(SEND_LOGIN_EMAILS=True): self.assertTrue(settings.SEND_LOGIN_EMAILS) # we don't use the self.login method since we spoof the user-agent utc = get_timezone('utc') mock_time = datetime.datetime(year=2018, month=1, day=1, tzinfo=utc) user = self.example_user('hamlet') user.timezone = 'US/Pacific' user.twenty_four_hour_time = False user.date_joined = mock_time - datetime.timedelta( seconds=JUST_CREATED_THRESHOLD + 1) user.save() password = initial_password(user.email) firefox_windows = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0" user_tz = get_timezone(user.timezone) mock_time = datetime.datetime(year=2018, month=1, day=1, tzinfo=utc) reference_time = mock_time.astimezone(user_tz).strftime( '%A, %B %d, %Y at %I:%M%p %Z') with mock.patch('zerver.signals.timezone_now', return_value=mock_time): self.client_post("/accounts/login/", info={ "username": user.email, "password": password }, HTTP_USER_AGENT=firefox_windows) # email is sent and correct subject self.assertEqual(len(mail.outbox), 1) subject = 'New login from Firefox on Windows' self.assertEqual(mail.outbox[0].subject, subject) # local time is correct and in email's body self.assertIn(reference_time, mail.outbox[0].body) # Try again with the 24h time format setting enabled for this user self.logout() # We just logged in, we'd be redirected without this user.twenty_four_hour_time = True user.save() with mock.patch('zerver.signals.timezone_now', return_value=mock_time): self.client_post("/accounts/login/", info={ "username": user.email, "password": password }, HTTP_USER_AGENT=firefox_windows) reference_time = mock_time.astimezone(user_tz).strftime( '%A, %B %d, %Y at %H:%M %Z') self.assertIn(reference_time, mail.outbox[1].body)
def handle(self, *args: Any, **options: str) -> None: realm = self.get_realm(options) print(self.fmt % ('email', 'password', 'API key')) for email in options['emails']: if '@' not in email: print(f'ERROR: {email} does not look like an email address') continue user = self.get_user(email, realm) print(self.fmt % (email, initial_password(email), get_api_key(user)))
def login_with_return(self, email: str, password: Optional[str]=None, **kwargs: Any) -> HttpResponse: if password is None: password = initial_password(email) result = self.client_post('/accounts/login/', {'username': email, 'password': password}, **kwargs) self.assertNotEqual(result.status_code, 500) return result
def login(self, email, password=None, fails=False): if password is None: password = initial_password(email) if not fails: self.assertTrue( self.client.login(username=email, password=password)) else: self.assertFalse( self.client.login(username=email, password=password))
def fetch_api_key() -> Dict[str, object]: email = helpers.example_email("iago") password = initial_password(email) assert password is not None return { "username": email, "password": urllib.parse.quote(password), }
def login_with_return(self, email: str, password: Optional[str]=None, **kwargs: Any) -> HttpResponse: if password is None: password = initial_password(email) result = self.client_post('/accounts/login/', {'username': email, 'password': password}, **kwargs) self.assertNotEqual(result.status_code, 500) return result
def bulk_create_users(realm: Realm, users_raw: Set[Tuple[str, str, str, bool]], bot_type: Optional[int]=None, bot_owner: Optional[UserProfile]=None, tos_version: Optional[str]=None, timezone: str="") -> None: """ Creates and saves a UserProfile with the given email. Has some code based off of UserManage.create_user, but doesn't .save() """ existing_users = frozenset(UserProfile.objects.filter( realm=realm).values_list('email', flat=True)) users = sorted([user_raw for user_raw in users_raw if user_raw[0] not in existing_users]) # If we have a different email_address_visibility mode, the code # below doesn't have the logic to set user_profile.email properly. assert realm.email_address_visibility == Realm.EMAIL_ADDRESS_VISIBILITY_EVERYONE # Now create user_profiles profiles_to_create = [] # type: List[UserProfile] for (email, full_name, short_name, active) in users: profile = create_user_profile(realm, email, initial_password(email), active, bot_type, full_name, short_name, bot_owner, False, tos_version, timezone, tutorial_status=UserProfile.TUTORIAL_FINISHED, enter_sends=True) profiles_to_create.append(profile) UserProfile.objects.bulk_create(profiles_to_create) RealmAuditLog.objects.bulk_create( [RealmAuditLog(realm=realm, modified_user=profile_, event_type=RealmAuditLog.USER_CREATED, event_time=profile_.date_joined) for profile_ in profiles_to_create]) profiles_by_email = {} # type: Dict[str, UserProfile] profiles_by_id = {} # type: Dict[int, UserProfile] for profile in UserProfile.objects.select_related().filter(realm=realm): profiles_by_email[profile.email] = profile profiles_by_id[profile.id] = profile recipients_to_create = [] # type: List[Recipient] for (email, full_name, short_name, active) in users: recipients_to_create.append(Recipient(type_id=profiles_by_email[email].id, type=Recipient.PERSONAL)) Recipient.objects.bulk_create(recipients_to_create) recipients_by_email = {} # type: Dict[str, Recipient] for recipient in recipients_to_create: recipients_by_email[profiles_by_id[recipient.type_id].email] = recipient subscriptions_to_create = [] # type: List[Subscription] for (email, full_name, short_name, active) in users: subscriptions_to_create.append( Subscription(user_profile_id=profiles_by_email[email].id, recipient=recipients_by_email[email])) Subscription.objects.bulk_create(subscriptions_to_create)
def test_change_password_ldap_backend(self) -> None: self.init_default_ldap_database() ldap_user_attr_map = {'full_name': 'cn', 'short_name': 'sn'} self.login('hamlet') with self.settings(LDAP_APPEND_DOMAIN="zulip.com", AUTH_LDAP_USER_ATTR_MAP=ldap_user_attr_map): result = self.client_patch( "/json/settings", dict( old_password=initial_password(self.example_email("hamlet")), new_password="******", )) self.assert_json_error(result, "Your Zulip password is managed in LDAP") result = self.client_patch( "/json/settings", dict( old_password=self.ldap_password("hamlet"), # hamlet's password in ldap new_password="******", )) self.assert_json_error(result, "Your Zulip password is managed in LDAP") with self.settings(LDAP_APPEND_DOMAIN="example.com", AUTH_LDAP_USER_ATTR_MAP=ldap_user_attr_map): result = self.client_patch( "/json/settings", dict( old_password=initial_password(self.example_email("hamlet")), new_password="******", )) self.assert_json_success(result) with self.settings(LDAP_APPEND_DOMAIN=None, AUTH_LDAP_USER_ATTR_MAP=ldap_user_attr_map): result = self.client_patch( "/json/settings", dict( old_password=initial_password(self.example_email("hamlet")), new_password="******", )) self.assert_json_error(result, "Your Zulip password is managed in LDAP")
def handle(self, *args: Any, **options: str) -> None: realm = self.get_realm(options) print(self.fmt % ("email", "password", "API key")) for email in options["emails"]: if "@" not in email: print(f"ERROR: {email} does not look like an email address") continue user = self.get_user(email, realm) print(self.fmt % (email, initial_password(email), get_api_key(user)))
def login_with_return(self, email: Text, password: Optional[Text] = None, **kwargs: Any) -> HttpResponse: if password is None: password = initial_password(email) return self.client_post('/accounts/login/', { 'username': email, 'password': password }, **kwargs)
def handle(self, *args, **options): # type: (*Any, **str) -> None realm = self.get_realm(options) print(self.fmt % ('email', 'password', 'API key')) for email in options['emails']: if '@' not in email: print('ERROR: %s does not look like an email address' % (email, )) continue print(self.fmt % (email, initial_password(email), self.get_user(email, realm).api_key))
def test_password_change_check_strength(self) -> None: self.login('hamlet') with self.settings(PASSWORD_MIN_LENGTH=3, PASSWORD_MIN_GUESSES=1000): json_result = self.client_patch( "/json/settings", dict( full_name='Foo Bar', old_password=initial_password(self.example_email("hamlet")), new_password='******', )) self.assert_json_error(json_result, "New password is too weak!") json_result = self.client_patch( "/json/settings", dict( full_name='Foo Bar', old_password=initial_password(self.example_email("hamlet")), new_password='******', )) self.assert_json_success(json_result)
def login(self, email: Text, password: Optional[Text]=None, fails: bool=False, realm: Optional[Realm]=None) -> HttpResponse: if realm is None: realm = get_realm("zulip") if password is None: password = initial_password(email) if not fails: self.assertTrue(self.client.login(username=email, password=password, realm=realm)) else: self.assertFalse(self.client.login(username=email, password=password, realm=realm))
def bulk_create_users(realm, users_raw, bot_type=None, tos_version=None): # type: (Realm, Set[Tuple[Text, Text, Text, bool]], Optional[int], Optional[Text]) -> None """ Creates and saves a UserProfile with the given email. Has some code based off of UserManage.create_user, but doesn't .save() """ existing_users = frozenset( UserProfile.objects.values_list('email', flat=True)) users = sorted([ user_raw for user_raw in users_raw if user_raw[0] not in existing_users ]) # Now create user_profiles profiles_to_create = [] # type: List[UserProfile] for (email, full_name, short_name, active) in users: profile = create_user_profile(realm, email, initial_password(email), active, bot_type, full_name, short_name, None, False, tos_version) profiles_to_create.append(profile) UserProfile.objects.bulk_create(profiles_to_create) RealmAuditLog.objects.bulk_create([ RealmAuditLog(realm=profile_.realm, modified_user=profile_, event_type='user_created', event_time=profile_.date_joined) for profile_ in profiles_to_create ]) profiles_by_email = {} # type: Dict[Text, UserProfile] profiles_by_id = {} # type: Dict[int, UserProfile] for profile in UserProfile.objects.select_related().all(): profiles_by_email[profile.email] = profile profiles_by_id[profile.id] = profile recipients_to_create = [] # type: List[Recipient] for (email, full_name, short_name, active) in users: recipients_to_create.append( Recipient(type_id=profiles_by_email[email].id, type=Recipient.PERSONAL)) Recipient.objects.bulk_create(recipients_to_create) recipients_by_email = {} # type: Dict[Text, Recipient] for recipient in Recipient.objects.filter(type=Recipient.PERSONAL): recipients_by_email[profiles_by_id[ recipient.type_id].email] = recipient subscriptions_to_create = [] # type: List[Subscription] for (email, full_name, short_name, active) in users: subscriptions_to_create.append( Subscription(user_profile_id=profiles_by_email[email].id, recipient=recipients_by_email[email])) Subscription.objects.bulk_create(subscriptions_to_create)
def login(self, email: str, password: Optional[str]=None, fails: bool=False, realm: Optional[Realm]=None) -> HttpResponse: if realm is None: realm = get_realm("zulip") if password is None: password = initial_password(email) if not fails: self.assertTrue(self.client.login(username=email, password=password, realm=realm)) else: self.assertFalse(self.client.login(username=email, password=password, realm=realm))
def handle(self, *args: Any, **options: Any) -> None: if not options["tos"]: raise CommandError( """You must confirm that this user has accepted the Terms of Service by passing --this-user-has-accepted-the-tos.""" ) realm = self.get_realm(options) assert realm is not None # Should be ensured by parser try: email = options["email"] full_name = options["full_name"] try: validators.validate_email(email) except ValidationError: raise CommandError("Invalid email address.") except KeyError: if "email" in options or "full_name" in options: raise CommandError( """Either specify an email and full name as two parameters, or specify no parameters for interactive user creation.""" ) else: while True: email = input("Email: ") try: validators.validate_email(email) break except ValidationError: print("Invalid email address.", file=sys.stderr) full_name = input("Full name: ") try: if options["password_file"] is not None: with open(options["password_file"]) as f: pw = f.read().strip() elif options["password"] is not None: pw = options["password"] else: user_initial_password = initial_password(email) if user_initial_password is None: raise CommandError("Password is unusable.") pw = user_initial_password do_create_user( email, pw, realm, full_name, acting_user=None, ) except IntegrityError: raise CommandError("User already exists.")
def bulk_create_users(realm: Realm, users_raw: Set[Tuple[str, str, str, bool]], bot_type: Optional[int]=None, bot_owner: Optional[UserProfile]=None, tos_version: Optional[str]=None, timezone: str="") -> None: """ Creates and saves a UserProfile with the given email. Has some code based off of UserManage.create_user, but doesn't .save() """ existing_users = frozenset(UserProfile.objects.filter( realm=realm).values_list('email', flat=True)) users = sorted([user_raw for user_raw in users_raw if user_raw[0] not in existing_users]) # Now create user_profiles profiles_to_create = [] # type: List[UserProfile] for (email, full_name, short_name, active) in users: profile = create_user_profile(realm, email, initial_password(email), active, bot_type, full_name, short_name, bot_owner, False, tos_version, timezone, tutorial_status=UserProfile.TUTORIAL_FINISHED, enter_sends=True) profiles_to_create.append(profile) UserProfile.objects.bulk_create(profiles_to_create) RealmAuditLog.objects.bulk_create( [RealmAuditLog(realm=realm, modified_user=profile_, event_type=RealmAuditLog.USER_CREATED, event_time=profile_.date_joined) for profile_ in profiles_to_create]) profiles_by_email = {} # type: Dict[str, UserProfile] profiles_by_id = {} # type: Dict[int, UserProfile] for profile in UserProfile.objects.select_related().filter(realm=realm): profiles_by_email[profile.email] = profile profiles_by_id[profile.id] = profile recipients_to_create = [] # type: List[Recipient] for (email, full_name, short_name, active) in users: recipients_to_create.append(Recipient(type_id=profiles_by_email[email].id, type=Recipient.PERSONAL)) Recipient.objects.bulk_create(recipients_to_create) recipients_by_email = {} # type: Dict[str, Recipient] for recipient in recipients_to_create: recipients_by_email[profiles_by_id[recipient.type_id].email] = recipient subscriptions_to_create = [] # type: List[Subscription] for (email, full_name, short_name, active) in users: subscriptions_to_create.append( Subscription(user_profile_id=profiles_by_email[email].id, recipient=recipients_by_email[email])) Subscription.objects.bulk_create(subscriptions_to_create)
def bulk_create_users(realms, users_raw, bot_type=None, tos_version=None): # type: (Mapping[text_type, Realm], Set[Tuple[text_type, text_type, text_type, bool]], Optional[int], Optional[text_type]) -> None """ Creates and saves a UserProfile with the given email. Has some code based off of UserManage.create_user, but doesn't .save() """ users = [] # type: List[Tuple[text_type, text_type, text_type, bool]] existing_users = set( u.email for u in UserProfile.objects.all()) # type: Set[text_type] for (email, full_name, short_name, active) in users_raw: if email in existing_users: continue users.append((email, full_name, short_name, active)) existing_users.add(email) users = sorted(users) # Now create user_profiles profiles_to_create = [] # type: List[UserProfile] for (email, full_name, short_name, active) in users: domain = email_to_domain(email) profile = create_user_profile(realms[domain], email, initial_password(email), active, bot_type, full_name, short_name, None, False, tos_version) profiles_to_create.append(profile) UserProfile.objects.bulk_create(profiles_to_create) profiles_by_email = {} # type: Dict[text_type, UserProfile] profiles_by_id = {} # type: Dict[int, UserProfile] for profile in UserProfile.objects.select_related().all(): profiles_by_email[profile.email] = profile profiles_by_id[profile.id] = profile recipients_to_create = [] # type: List[Recipient] for (email, full_name, short_name, active) in users: recipients_to_create.append( Recipient(type_id=profiles_by_email[email].id, type=Recipient.PERSONAL)) Recipient.objects.bulk_create(recipients_to_create) recipients_by_email = {} # type: Dict[text_type, Recipient] for recipient in Recipient.objects.filter(type=Recipient.PERSONAL): recipients_by_email[profiles_by_id[ recipient.type_id].email] = recipient subscriptions_to_create = [] # type: List[Subscription] for (email, full_name, short_name, active) in users: subscriptions_to_create.append( Subscription(user_profile_id=profiles_by_email[email].id, recipient=recipients_by_email[email])) Subscription.objects.bulk_create(subscriptions_to_create)
def handle(self, *args, **options): # type: (*Any, **Any) -> None if not options["tos"]: raise CommandError( """You must confirm that this user has accepted the Terms of Service by passing --this-user-has-accepted-the-tos.""") if not options["string_id"]: raise CommandError( """Please specify a realm by passing --realm.""") try: realm = get_realm(options["string_id"]) except Realm.DoesNotExist: raise CommandError("Realm does not exist.") try: email = options['email'] full_name = options['full_name'] try: validators.validate_email(email) except ValidationError: raise CommandError("Invalid email address.") except KeyError: if 'email' in options or 'full_name' in options: raise CommandError( """Either specify an email and full name as two parameters, or specify no parameters for interactive user creation.""") else: while True: email = input("Email: ") try: validators.validate_email(email) break except ValidationError: print("Invalid email address.", file=sys.stderr) full_name = input("Full name: ") try: if 'password' in options: pw = options['password'] if 'password_file' in options: pw = open(options['password_file'], 'r').read() else: pw = initial_password(email).encode() notify_new_user(do_create_user(email, pw, realm, full_name, email_to_username(email)), internal=True) except IntegrityError: raise CommandError("User already exists.")
def test_send_login_emails_if_send_login_email_setting_is_true(self) -> None: with self.settings(SEND_LOGIN_EMAILS=True): self.assertTrue(settings.SEND_LOGIN_EMAILS) # we don't use the self.login method since we spoof the user-agent email = self.example_email('hamlet') password = initial_password(email) firefox_windows = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0" self.client_post("/accounts/login/", info={"username": email, "password": password}, HTTP_USER_AGENT=firefox_windows) # email is sent and correct subject self.assertEqual(len(mail.outbox), 1) subject = 'New login from Firefox on Windows' self.assertEqual(mail.outbox[0].subject, subject)
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") # Password reset email client.post('/accounts/password/reset/', {'email': registered_email}) # Confirm account email client.post('/accounts/home/', {'email': unregistered_email_1}) # Find account email client.post('/accounts/find/', {'emails': registered_email}) # New login email password = initial_password(registered_email) client.login(username=registered_email, password=password) # New user invite and reminder emails client.post( "/json/invites", { "invitee_emails": unregistered_email_2, "stream": ["Denmark"], "custom_body": "" }) # Verification for new email client.patch('/json/settings', urllib.parse.urlencode({'email': '*****@*****.**'})) # 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 get_create_user_params( self, options: Dict[str, Any]) -> CreateUserParameters: # nocoverage """ Parses parameters for user creation defined in add_create_user_args. """ if options["email"] is None: email = input("Email: ") else: email = options["email"] try: validators.validate_email(email) except ValidationError: raise CommandError("Invalid email address.") if options["full_name"] is None: full_name = input("Full name: ") else: full_name = options["full_name"] if options["password_file"] is not None: with open(options["password_file"]) as f: password: Optional[str] = f.read().strip() elif options["password"] is not None: logging.warning( "Passing password on the command line is insecure; prefer --password-file." ) password = options["password"] else: # initial_password will return a random password that # is a salted hash of the email address in a # development environment, and None in a production # environment. user_initial_password = initial_password(email) if user_initial_password is None: logging.info("User will be created with a disabled password.") else: assert settings.DEVELOPMENT logging.info( "Password will be available via `./manage.py print_initial_password`." ) password = user_initial_password return CreateUserParameters( email=email, full_name=full_name, password=password, )
def bulk_create_users(realms, users_raw, bot=False): """ Creates and saves a UserProfile with the given email. Has some code based off of UserManage.create_user, but doesn't .save() """ users = [] existing_users = set(u.email for u in UserProfile.objects.all()) for (email, full_name, short_name, active) in users_raw: if email in existing_users: continue users.append((email, full_name, short_name, active)) existing_users.add(email) users = sorted(users) # Now create user_profiles profiles_to_create = [] for (email, full_name, short_name, active) in users: domain = resolve_email_to_domain(email) profile = create_user_profile(realms[domain], email, initial_password(email), active, bot, full_name, short_name, None, False) profiles_to_create.append(profile) UserProfile.objects.bulk_create(profiles_to_create) profiles_by_email = {} profiles_by_id = {} for profile in UserProfile.objects.select_related().all(): profiles_by_email[profile.email] = profile profiles_by_id[profile.id] = profile recipients_to_create = [] for (email, _, _, _) in users: recipients_to_create.append( Recipient(type_id=profiles_by_email[email].id, type=Recipient.PERSONAL)) Recipient.objects.bulk_create(recipients_to_create) recipients_by_email = {} for recipient in Recipient.objects.filter(type=Recipient.PERSONAL): recipients_by_email[profiles_by_id[ recipient.type_id].email] = recipient subscriptions_to_create = [] for (email, _, _, _) in users: subscriptions_to_create.append( Subscription(user_profile_id=profiles_by_email[email].id, recipient=recipients_by_email[email])) Subscription.objects.bulk_create(subscriptions_to_create)
def test_password_reset(self): # type: () -> None email = '*****@*****.**' old_password = initial_password(email) self.login(email) # start the password reset process by supplying an email address result = self.client_post('/accounts/password/reset/', {'email': email}) # check the redirect link telling you to check mail for password reset link self.assertEquals(result.status_code, 302) self.assertTrue(result["Location"].endswith( "/accounts/password/reset/done/")) result = self.client_get(result["Location"]) self.assert_in_response("Check your email to finish the process.", result) # visit password reset link from django.core.mail import outbox for message in reversed(outbox): if email in message.to: password_reset_pattern = re.compile(settings.EXTERNAL_HOST + "(\S+)") password_reset_url = password_reset_pattern.search( message.body).groups()[0] break else: raise ValueError("Couldn't find a password reset email.") result = self.client_get(password_reset_url) self.assertEquals(result.status_code, 200) # Reset your password result = self.client_post(password_reset_url, {'new_password1': 'new_password', 'new_password2': 'new_password'}) # password reset succeeded self.assertEquals(result.status_code, 302) self.assertTrue(result["Location"].endswith("/password/done/")) # log back in with new password self.login(email, password='******') user_profile = get_user_profile_by_email('*****@*****.**') self.assertEqual(get_session_dict_user(self.client.session), user_profile.id) # make sure old password no longer works self.login(email, password=old_password, fails=True)
def login(self, email, password=None, fails=False, realm=None): # type: (Text, Optional[Text], bool, Optional[Realm]) -> HttpResponse if realm is None: realm = get_realm("zulip") if password is None: password = initial_password(email) if not fails: self.assertTrue( self.client.login(username=email, password=password, realm_subdomain=realm.subdomain)) else: self.assertFalse( self.client.login(username=email, password=password, realm_subdomain=realm.subdomain))
def bulk_create_users(realms, users_raw, bot_type=None): # type: (Mapping[text_type, Realm], Set[Tuple[text_type, text_type, text_type, bool]], Optional[int]) -> None """ Creates and saves a UserProfile with the given email. Has some code based off of UserManage.create_user, but doesn't .save() """ users = [] # type: List[Tuple[text_type, text_type, text_type, bool]] existing_users = set(u.email for u in UserProfile.objects.all()) # type: Set[text_type] for (email, full_name, short_name, active) in users_raw: if email in existing_users: continue users.append((email, full_name, short_name, active)) existing_users.add(email) users = sorted(users) # Now create user_profiles profiles_to_create = [] # type: List[UserProfile] for (email, full_name, short_name, active) in users: domain = resolve_email_to_domain(email) profile = create_user_profile(realms[domain], email, initial_password(email), active, bot_type, full_name, short_name, None, False) profiles_to_create.append(profile) UserProfile.objects.bulk_create(profiles_to_create) profiles_by_email = {} # type: Dict[text_type, UserProfile] profiles_by_id = {} # type: Dict[int, UserProfile] for profile in UserProfile.objects.select_related().all(): profiles_by_email[profile.email] = profile profiles_by_id[profile.id] = profile recipients_to_create = [] # type: List[Recipient] for (email, full_name, short_name, active) in users: recipients_to_create.append(Recipient(type_id=profiles_by_email[email].id, type=Recipient.PERSONAL)) Recipient.objects.bulk_create(recipients_to_create) recipients_by_email = {} # type: Dict[text_type, Recipient] for recipient in Recipient.objects.filter(type=Recipient.PERSONAL): recipients_by_email[profiles_by_id[recipient.type_id].email] = recipient subscriptions_to_create = [] # type: List[Subscription] for (email, full_name, short_name, active) in users: subscriptions_to_create.append( Subscription(user_profile_id=profiles_by_email[email].id, recipient=recipients_by_email[email])) Subscription.objects.bulk_create(subscriptions_to_create)
def bulk_create_users(realm, users_raw, bot_type=None, tos_version=None, timezone=u""): # type: (Realm, Set[Tuple[Text, Text, Text, bool]], Optional[int], Optional[Text], Text) -> None """ Creates and saves a UserProfile with the given email. Has some code based off of UserManage.create_user, but doesn't .save() """ existing_users = frozenset(UserProfile.objects.values_list('email', flat=True)) users = sorted([user_raw for user_raw in users_raw if user_raw[0] not in existing_users]) # Now create user_profiles profiles_to_create = [] # type: List[UserProfile] for (email, full_name, short_name, active) in users: profile = create_user_profile(realm, email, initial_password(email), active, bot_type, full_name, short_name, None, False, tos_version, timezone, tutorial_status=UserProfile.TUTORIAL_FINISHED, enter_sends=True) profiles_to_create.append(profile) UserProfile.objects.bulk_create(profiles_to_create) RealmAuditLog.objects.bulk_create( [RealmAuditLog(realm=profile_.realm, modified_user=profile_, event_type='user_created', event_time=profile_.date_joined) for profile_ in profiles_to_create]) profiles_by_email = {} # type: Dict[Text, UserProfile] profiles_by_id = {} # type: Dict[int, UserProfile] for profile in UserProfile.objects.select_related().all(): profiles_by_email[profile.email] = profile profiles_by_id[profile.id] = profile recipients_to_create = [] # type: List[Recipient] for (email, full_name, short_name, active) in users: recipients_to_create.append(Recipient(type_id=profiles_by_email[email].id, type=Recipient.PERSONAL)) Recipient.objects.bulk_create(recipients_to_create) recipients_by_email = {} # type: Dict[Text, Recipient] for recipient in Recipient.objects.filter(type=Recipient.PERSONAL): recipients_by_email[profiles_by_id[recipient.type_id].email] = recipient subscriptions_to_create = [] # type: List[Subscription] for (email, full_name, short_name, active) in users: subscriptions_to_create.append( Subscription(user_profile_id=profiles_by_email[email].id, recipient=recipients_by_email[email])) Subscription.objects.bulk_create(subscriptions_to_create)
def bulk_create_users(realms, users_raw, bot=False): """ Creates and saves a UserProfile with the given email. Has some code based off of UserManage.create_user, but doesn't .save() """ users = [] existing_users = set(u.email for u in UserProfile.objects.all()) for (email, full_name, short_name, active) in users_raw: if email in existing_users: continue users.append((email, full_name, short_name, active)) existing_users.add(email) # Now create user_profiles profiles_to_create = [] for (email, full_name, short_name, active) in users: domain = resolve_email_to_domain(email) profile = create_user_profile(realms[domain], email, initial_password(email), active, bot, full_name, short_name, None, False) profiles_to_create.append(profile) UserProfile.objects.bulk_create(profiles_to_create) profiles_by_email = {} profiles_by_id = {} for profile in UserProfile.objects.select_related().all(): profiles_by_email[profile.email] = profile profiles_by_id[profile.id] = profile recipients_to_create = [] for (email, _, _, _) in users: recipients_to_create.append(Recipient(type_id=profiles_by_email[email].id, type=Recipient.PERSONAL)) Recipient.objects.bulk_create(recipients_to_create) recipients_by_email = {} for recipient in Recipient.objects.filter(type=Recipient.PERSONAL): recipients_by_email[profiles_by_id[recipient.type_id].email] = recipient subscriptions_to_create = [] for (email, _, _, _) in users: subscriptions_to_create.append( Subscription(user_profile_id=profiles_by_email[email].id, recipient=recipients_by_email[email])) Subscription.objects.bulk_create(subscriptions_to_create)
def handle(self, *args: Any, **options: Any) -> None: if not options["tos"]: raise CommandError( """You must confirm that this user has accepted the Terms of Service by passing --this-user-has-accepted-the-tos.""") realm = self.get_realm(options) assert realm is not None # Should be ensured by parser try: email = options['email'] full_name = options['full_name'] try: validators.validate_email(email) except ValidationError: raise CommandError("Invalid email address.") except KeyError: if 'email' in options or 'full_name' in options: raise CommandError( """Either specify an email and full name as two parameters, or specify no parameters for interactive user creation.""") else: while True: email = input("Email: ") try: validators.validate_email(email) break except ValidationError: print("Invalid email address.", file=sys.stderr) full_name = input("Full name: ") try: if 'password' in options: pw = options['password'] if 'password_file' in options: pw = open(options['password_file'], 'r').read() else: user_initial_password = initial_password(email) if user_initial_password is None: raise CommandError("Password is unusable.") pw = user_initial_password.encode() notify_new_user(do_create_user(email, pw, realm, full_name, email_to_username(email)), internal=True) except IntegrityError: raise CommandError("User already exists.")
def handle(self, *args, **options): if not options["tos"]: raise CommandError( """You must confirm that this user has accepted the Terms of Service by passing --this-user-has-accepted-the-tos.""") if not options["domain"]: raise CommandError( """Please specify a realm by passing --domain.""") try: realm = get_realm(options["domain"]) except Realm.DoesNotExist: raise CommandError("Realm does not exist.") try: email = options['email'] full_name = options['full_name'] try: validators.validate_email(email) except ValidationError: raise CommandError("Invalid email address.") except KeyError: if 'email' in options or 'full_name' in options: raise CommandError( """Either specify an email and full name as two parameters, or specify no parameters for interactive user creation.""") else: while True: email = raw_input("Email: ") try: validators.validate_email(email) break except ValidationError: print >> sys.stderr, "Invalid email address." full_name = raw_input("Full name: ") try: notify_new_user(do_create_user(email, initial_password(email), realm, full_name, email_to_username(email)), internal=True) except IntegrityError: raise CommandError("User already exists.")
def handle(self, *args: Any, **options: Any) -> None: if not options["tos"]: raise CommandError("""You must confirm that this user has accepted the Terms of Service by passing --this-user-has-accepted-the-tos.""") realm = self.get_realm(options) assert realm is not None # Should be ensured by parser try: email = options['email'] full_name = options['full_name'] try: validators.validate_email(email) except ValidationError: raise CommandError("Invalid email address.") except KeyError: if 'email' in options or 'full_name' in options: raise CommandError("""Either specify an email and full name as two parameters, or specify no parameters for interactive user creation.""") else: while True: email = input("Email: ") try: validators.validate_email(email) break except ValidationError: print("Invalid email address.", file=sys.stderr) full_name = input("Full name: ") try: if 'password' in options: pw = options['password'] if 'password_file' in options: pw = open(options['password_file'], 'r').read() else: user_initial_password = initial_password(email) if user_initial_password is None: raise CommandError("Password is unusable.") pw = user_initial_password.encode() notify_new_user(do_create_user(email, pw, realm, full_name, email_to_username(email)), internal=True) except IntegrityError: raise CommandError("User already exists.")
def test_send_login_emails_if_send_login_email_setting_is_true( self) -> None: with self.settings(SEND_LOGIN_EMAILS=True): self.assertTrue(settings.SEND_LOGIN_EMAILS) # we don't use the self.login method since we spoof the user-agent email = self.example_email('hamlet') password = initial_password(email) firefox_windows = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0" self.client_post("/accounts/login/", info={ "username": email, "password": password }, HTTP_USER_AGENT=firefox_windows) # email is sent and correct subject self.assertEqual(len(mail.outbox), 1) subject = 'New login from Firefox on Windows' self.assertEqual(mail.outbox[0].subject, subject)
def test_login_deactivated_mirror_dummy(self): # type: () -> None """ logging in fails with an inactive user """ user_profile = self.example_user('hamlet') user_profile.is_mirror_dummy = True user_profile.save() password = initial_password(user_profile.email) request = mock.MagicMock() request.get_host.return_value = 'zulip.testserver' # Test a mirror-dummy active user. form = OurAuthenticationForm(request, data={'username': user_profile.email, 'password': password}) with self.settings(AUTHENTICATION_BACKENDS=('zproject.backends.EmailAuthBackend',)): self.assertTrue(form.is_valid()) # Test a mirror-dummy deactivated user. do_deactivate_user(user_profile) user_profile.save() form = OurAuthenticationForm(request, data={'username': user_profile.email, 'password': password}) with self.settings(AUTHENTICATION_BACKENDS=('zproject.backends.EmailAuthBackend',)): self.assertFalse(form.is_valid()) self.assertIn("Please enter a correct email", str(form.errors)) # Test a non-mirror-dummy deactivated user. user_profile.is_mirror_dummy = False user_profile.save() form = OurAuthenticationForm(request, data={'username': user_profile.email, 'password': password}) with self.settings(AUTHENTICATION_BACKENDS=('zproject.backends.EmailAuthBackend',)): self.assertFalse(form.is_valid()) self.assertIn("your account has been deactivated", str(form.errors))
def test_login_deactivated_mirror_dummy(self): # type: () -> None """ logging in fails with an inactive user """ user_profile = self.example_user('hamlet') user_profile.is_mirror_dummy = True user_profile.save() password = initial_password(user_profile.email) request = mock.MagicMock() request.get_host.return_value = 'zulip.testserver' # Test a mirror-dummy active user. form = OurAuthenticationForm(request, data={'username': user_profile.email, 'password': password}) with self.settings(AUTHENTICATION_BACKENDS=('zproject.backends.EmailAuthBackend',)): self.assertTrue(form.is_valid()) # Test a mirror-dummy deactivated user. do_deactivate_user(user_profile) user_profile.save() form = OurAuthenticationForm(request, data={'username': user_profile.email, 'password': password}) with self.settings(AUTHENTICATION_BACKENDS=('zproject.backends.EmailAuthBackend',)): self.assertFalse(form.is_valid()) self.assertIn("Please enter a correct email", str(form.errors)) # Test a non-mirror-dummy deactivated user. user_profile.is_mirror_dummy = False user_profile.save() form = OurAuthenticationForm(request, data={'username': user_profile.email, 'password': password}) with self.settings(AUTHENTICATION_BACKENDS=('zproject.backends.EmailAuthBackend',)): self.assertFalse(form.is_valid()) self.assertIn("your account has been deactivated", str(form.errors))
def handle(self, *args, **options): # type: (*Any, **Any) -> None if not options["tos"]: raise CommandError("""You must confirm that this user has accepted the Terms of Service by passing --this-user-has-accepted-the-tos.""") if not options["string_id"]: raise CommandError("""Please specify a realm by passing --realm.""") try: realm = get_realm(options["string_id"]) except Realm.DoesNotExist: raise CommandError("Realm does not exist.") try: email = options['email'] full_name = options['full_name'] try: validators.validate_email(email) except ValidationError: raise CommandError("Invalid email address.") except KeyError: if 'email' in options or 'full_name' in options: raise CommandError("""Either specify an email and full name as two parameters, or specify no parameters for interactive user creation.""") else: while True: email = input("Email: ") try: validators.validate_email(email) break except ValidationError: print("Invalid email address.", file=sys.stderr) full_name = input("Full name: ") try: pw = options.get('password', initial_password(email)) notify_new_user(do_create_user(email, pw, realm, full_name, email_to_username(email)), internal=True) except IntegrityError: raise CommandError("User already exists.")
def bulk_create_users(realm, users_raw, bot_type=None, tos_version=None): # type: (Realm, Set[Tuple[text_type, text_type, text_type, bool]], Optional[int], Optional[text_type]) -> None """ Creates and saves a UserProfile with the given email. Has some code based off of UserManage.create_user, but doesn't .save() """ existing_users = frozenset(UserProfile.objects.values_list('email', flat=True)) users = sorted([user_raw for user_raw in users_raw if user_raw[0] not in existing_users]) # Now create user_profiles profiles_to_create = [] # type: List[UserProfile] for (email, full_name, short_name, active) in users: profile = create_user_profile(realm, email, initial_password(email), active, bot_type, full_name, short_name, None, False, tos_version) profiles_to_create.append(profile) UserProfile.objects.bulk_create(profiles_to_create) profiles_by_email = {} # type: Dict[text_type, UserProfile] profiles_by_id = {} # type: Dict[int, UserProfile] for profile in UserProfile.objects.select_related().all(): profiles_by_email[profile.email] = profile profiles_by_id[profile.id] = profile recipients_to_create = [] # type: List[Recipient] for (email, full_name, short_name, active) in users: recipients_to_create.append(Recipient(type_id=profiles_by_email[email].id, type=Recipient.PERSONAL)) Recipient.objects.bulk_create(recipients_to_create) recipients_by_email = {} # type: Dict[text_type, Recipient] for recipient in Recipient.objects.filter(type=Recipient.PERSONAL): recipients_by_email[profiles_by_id[recipient.type_id].email] = recipient subscriptions_to_create = [] # type: List[Subscription] for (email, full_name, short_name, active) in users: subscriptions_to_create.append( Subscription(user_profile_id=profiles_by_email[email].id, recipient=recipients_by_email[email])) Subscription.objects.bulk_create(subscriptions_to_create)
def test_successful_change_settings(self) -> None: """ A call to /json/settings with valid parameters changes the user's settings correctly and returns correct values. """ self.login(self.example_email("hamlet")) json_result = self.client_patch( "/json/settings", dict( full_name='Foo Bar', old_password=initial_password(self.example_email("hamlet")), new_password='******', )) self.assert_json_success(json_result) result = ujson.loads(json_result.content) self.check_well_formed_change_settings_response(result) self.assertEqual(self.example_user('hamlet'). full_name, "Foo Bar") self.logout() self.login(self.example_email("hamlet"), "foobar1") user_profile = self.example_user('hamlet') self.assertEqual(get_session_dict_user(self.client.session), user_profile.id)
def test_send_login_emails_if_send_login_email_setting_is_true(self) -> None: with self.settings(SEND_LOGIN_EMAILS=True): self.assertTrue(settings.SEND_LOGIN_EMAILS) # we don't use the self.login method since we spoof the user-agent utc = get_timezone('utc') mock_time = datetime.datetime(year=2018, month=1, day=1, tzinfo=utc) user = self.example_user('hamlet') user.timezone = 'US/Pacific' user.twenty_four_hour_time = False user.date_joined = mock_time - datetime.timedelta(seconds=JUST_CREATED_THRESHOLD + 1) user.save() password = initial_password(user.email) firefox_windows = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0" user_tz = get_timezone(user.timezone) mock_time = datetime.datetime(year=2018, month=1, day=1, tzinfo=utc) reference_time = mock_time.astimezone(user_tz).strftime('%A, %B %d, %Y at %I:%M%p %Z') with mock.patch('zerver.signals.timezone_now', return_value=mock_time): self.client_post("/accounts/login/", info={"username": user.email, "password": password}, HTTP_USER_AGENT=firefox_windows) # email is sent and correct subject self.assertEqual(len(mail.outbox), 1) subject = 'New login from Firefox on Windows' self.assertEqual(mail.outbox[0].subject, subject) # local time is correct and in email's body self.assertIn(reference_time, mail.outbox[0].body) # Try again with the 24h time format setting enabled for this user self.logout() # We just logged in, we'd be redirected without this user.twenty_four_hour_time = True user.save() with mock.patch('zerver.signals.timezone_now', return_value=mock_time): self.client_post("/accounts/login/", info={"username": user.email, "password": password}, HTTP_USER_AGENT=firefox_windows) reference_time = mock_time.astimezone(user_tz).strftime('%A, %B %d, %Y at %H:%M %Z') self.assertIn(reference_time, mail.outbox[1].body)
def test_send_login_emails_if_send_login_email_setting_is_true(self) -> None: with self.settings(SEND_LOGIN_EMAILS=True): self.assertTrue(settings.SEND_LOGIN_EMAILS) # we don't use the self.login method since we spoof the user-agent user = self.example_user('hamlet') user.timezone = 'US/Pacific' user.save() password = initial_password(user.email) firefox_windows = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0" utc = get_timezone('utc') user_tz = get_timezone(user.timezone) mock_time = datetime.datetime(year=2018, month=1, day=1, tzinfo=utc) reference_time = mock_time.astimezone(user_tz).strftime('%A, %B %d, %Y at %I:%M%p ') + user.timezone with mock.patch('zerver.signals.timezone_now', return_value=mock_time): self.client_post("/accounts/login/", info={"username": user.email, "password": password}, HTTP_USER_AGENT=firefox_windows) # email is sent and correct subject self.assertEqual(len(mail.outbox), 1) subject = 'New login from Firefox on Windows' self.assertEqual(mail.outbox[0].subject, subject) # local time is correct and in email's body self.assertIn(reference_time, mail.outbox[0].body)
def login(self, email, password=None): if password is None: password = initial_password(email) return self.client.post('/accounts/login/', {'username': email, 'password': password})
def login_with_return(self, email, password=None): # type: (Text, Optional[Text]) -> HttpResponse if password is None: password = initial_password(email) return self.client_post('/accounts/login/', {'username': email, 'password': password})
def test_success(self): # type: () -> None result = self.client_post("/api/v1/fetch_api_key", dict(username=self.email, password=initial_password(self.email))) self.assert_json_success(result)
def test_fetch_api_key_success(self): email = "*****@*****.**" self.login(email) result = self.client_post("/json/fetch_api_key", {"password": initial_password(email)}) self.assert_json_success(result)
def login(self, email, password=None): # type: (text_type, Optional[text_type]) -> HttpResponse if password is None: password = initial_password(email) return self.client.post('/accounts/login/', {'username': email, 'password': password})