def test_save_emits_event(self): """ Saving a user emits event """ user = User(email='*****@*****.**', password='******') with user_events.disconnect_receivers(): spy = mock.Mock() events.user_save_event.connect(spy, weak=False) user_service.save(user) spy.assert_called_with(user)
def test_force_login_fails_if_locked(self): """ Abort force login if locked """ with user_events.disconnect_receivers(): user = self.create_user() user.lock_account() user_service.save(user) with self.app.test_request_context(): with self.assertRaises(x.AccountLocked): user_service.force_login(user)
def test_force_login_drops_counter_on_success(self): """ Drop failed login counter on force login """ with user_events.disconnect_receivers(): user = self.create_user() user.failed_logins = 5 user_service.save(user) with self.app.test_request_context(): user_service.force_login(user) self.assertEqual(0, user.failed_logins)
def test_default_token_user_loader_fails_if_account_locked(self): """ Default token user loader fails if account locked """ with user_events.disconnect_receivers(): user = self.create_user() user.lock_account(minutes=1) user_service.save(user) token = user_service.default_token_implementation(user.id) with self.assertRaises(x.AccountLocked): user_service.default_token_user_loader(token)
def create_user(self, confirm_email=True): """ A shortcut to quickly create and return a user """ with user_events.disconnect_receivers(): user = user_service.create(email='*****@*****.**', password='******') if confirm_email: user.confirm_email() user_service.save(user) return user
def test_login_locks_on_reaching_limit(self): """ Lock account on reaching failed logins limit """ with user_events.disconnect_receivers(): user = self.create_user() user.failed_logins = 10 user_service.save(user) with self.app.test_request_context(): user_service.login(user.email, 'BAD!') self.assertEqual(0, user.failed_logins) self.assertTrue(user.is_locked())
def test_email_confirm_raises_on_expired_link(self): """ Raise if initially confirming with expired link """ user = self.create_user() with events.events.disconnect_receivers(): user.email = '*****@*****.**' user.email_link_expires = datetime.utcnow() - timedelta(hours=12) self.assertFalse(user.email_confirmed) user_service.save(user) with self.assertRaises(x.EmailLinkExpired): user_service.confirm_email_with_link(user.email_link)
def test_email_confirm_emits_event(self): """ Initial email confirmation emits event """ user = self.create_user() with events.events.disconnect_receivers(): user.email = '*****@*****.**' spy = mock.Mock() events.email_confirmed_event.connect(spy, weak=False) user_service.save(user) with self.app.test_request_context(): user_service.confirm_email_with_link(user.email_link) spy.assert_called_with(user)
def test_email_confirm_possible(self): """ Doing initial email confirmation""" user = self.create_user() with events.events.disconnect_receivers(): user.email = '*****@*****.**' user_service.save(user) with self.app.test_request_context(): res = user_service.confirm_email_with_link(user.email_link) self.assertTrue(res) self.assertTrue(user.email_confirmed) self.assertIsNone(user.email_link)
def test_default_implemnetation_returns_token_on_file_if_got_one(self): """ Return token from user model if it's still valid""" with user_events.disconnect_receivers(): user = self.create_user(confirm_email=True) from_now = timedelta(seconds=user_service.jwt_lifetime) expires = datetime.utcnow() + from_now data = dict(exp=expires, user_id=user.id) token = jwt.encode(data, user_service.jwt_secret, algorithm=user_service.jwt_algo) user._token = token user_service.save(user) token = user_service.get_token(user.id) self.assertEquals(user._token, token)
def test_default_implementation_regenerates_token_if_expired(self): """ Regenerate user token if the one on file expired""" with user_events.disconnect_receivers(): user = self.create_user(confirm_email=True) from_now = timedelta(seconds=-20) expires = datetime.utcnow() + from_now data = dict(exp=expires, user_id=user.id) token = jwt.encode(data, user_service.jwt_secret, algorithm=user_service.jwt_algo) user._token = token user_service.save(user) token = user_service.get_token(user.id) self.assertEquals(token, user._token)
def test_send_password_message(self): """ Sending confirmation message to change password """ with events.events.disconnect_receivers(): user = self.create_user() user.generate_password_link() user_service.save(user) with mail.record_messages() as out: with self.app.test_request_context(): url = 'http://my.confirm.url/' user_service.send_password_change_message(user, url) msg = out[0] self.assertTrue('change your password' in msg.html.lower()) self.assertTrue('change your password' in msg.body.lower()) self.assertTrue(user.password_link in msg.html) self.assertTrue(user.password_link in msg.body)
def test_register_password_can_be_verified(self): """ REGRESSION: Password provided at registration can be verified """ user_data = dict(email='*****@*****.**', password='******') with user_events.disconnect_receivers(): user = user_service.register(user_data=user_data, send_welcome=False) verified = user.verify_password(user_data['password']) self.assertTrue(verified) password = 222222 user.password = password user_service.save(user) verified = user.verify_password(password) self.assertTrue(verified)
def dispatch_request(self, id=None): user = user_service.get_or_404(id) myself = self.is_myself(id) form = self.form(schema=self.schema(), context=user) params = dict(form=form, user=user, myself=myself) # is this a request to cancel change? if myself and 'cancel_change' in request.args: user.cancel_email_change() user_service.save(user) if self.flash: flash(self.cancel_message) return render_template(self.template, **params) # otherwise change cfg = current_app.config base_confirm_url = cfg.get('USER_BASE_EMAIL_CONFIRM_URL') if not base_confirm_url: base_confirm_url = url_for( 'user.confirm.email.request', _external=True ) if form.validate_on_submit(): ok = user_service.change_email( user=user, new_email=form.email.data, base_confirm_url=base_confirm_url ) if ok: if self.flash: flash(self.ok_message, 'success') return render_template(self.template, **params) else: if self.flash: flash(self.exception_message, 'danger') elif form.is_submitted(): if self.flash: flash(self.invalid_message, 'danger') return render_template(self.template, **params)
def create(email, password): """ Creates a new user record """ with get_app().app_context(): user = User(email=email, password=password) result = user_service.save(user) if not isinstance(result, User): print_validation_errors(result) return click.echo(green('\nUser created:')) click.echo(green('-' * 40)) click.echo(str(user) + '\n')
def change_email(*_, user_id=None, new_email=None): """ Change email for a user """ click.echo(green('\nChange email:')) click.echo(green('-' * 40)) with get_app().app_context(): user = find_user(dict(id=user_id)) if not user: click.echo(red('User not found\n')) return user.email = new_email result = user_service.save(user) if not isinstance(result, User): print_validation_errors(result) return user.confirm_email() user_service.save(user) msg = 'Change email for user {} to {} \n' click.echo(green(msg.format(user.email, new_email)))
def create_user(self): """ Create a user for testing""" with events.events.disconnect_receivers(): user = User(email='*****@*****.**', password=123) user_service.save(user) return user
def test_save_returns_validation_errors(self): """ Saving returns validation error on bad data """ result = user_service.save(User()) self.assertFalse(result) self.assertIsInstance(result, Result)
def test_save(self): """ Persisting user """ user = User(email='*****@*****.**', password='******') with user_events.disconnect_receivers(): user_service.save(user) self.assertEqual(1, user.id)