def test_success(self): "Set preferred email address" # Create user with email address user = self.makeUserWithEmail() # Add another one user.emails.append( model.Email(address=u'*****@*****.**', is_preferred=True)) model.save(user) transaction.commit() Session.add(user) email1, email2 = user.emails # Sanity check self.assertNotEquals(user.preferred_email, email1) self.assertEquals(user.preferred_email, email2) # Attempt to make the address primary self.authenticate() self.app.post('/auth/prefer_email', {'email_address': email1.address}) # Verify that email is not the user's preferred email Session.add(email1) Session.refresh(email1) self.assertEquals(user.preferred_email, email1) self.assertNotEquals(user.preferred_email, email2)
def change_password(request): """Change user password.""" # Unpack. user = request.user notify = request.registry.notify # Validate the request. form = Form(request, schema=schema.ChangePassword, defaults={'failed': False}) location = get_redirect_location(request) if request.method == 'POST': if form.validate(): d = form.data user = authenticate_user(request, user.username, d['old_password']) if user: # Save new password to the db. user.password = model.encrypt(d['new_password']) model.save(user) # Notify that the password changed. notify(events.UserChangedPassword(request, user)) # Log the user out, so that a change of password will lock out # someone who has compromised the existing password. headers = forget(request) # Notify that the user is logged out. notify(events.UserLoggedOut(request, request.user)) # Redirect. return HTTPFound(location=location, headers=headers) else: form.errors['old_password'] = '******' form.data['next'] = location return {'renderer': FormRenderer(form), 'user': request.user}
def change_password(request): """Change user password.""" # Unpack. user = request.user notify = request.registry.notify # Validate the request. form = Form(request, schema=schema.ChangePassword, defaults={'failed': False}) location = get_redirect_location(request) if request.method == 'POST': if form.validate(): d = form.data user = model.authenticate(user.username, d['old_password']) if user: # Save new password to the db. user.password = model.encrypt(d['new_password']) model.save(user) # Notify that the password changed. notify(events.UserChangedPassword(request, user)) # Log the user out, so that a change of password will lock out # someone who has compromised the existing password. headers = forget(request) # Notify that the user is logged out. notify(events.UserLoggedOut(request, request.user)) # Redirect. return HTTPFound(location=location, headers=headers) else: form.errors['old_password'] = '******' form.data['next'] = location return {'renderer': FormRenderer(form), 'user': request.user}
def test_success(self): "Set preferred email address" # Create user with email address user = self.makeUserWithEmail() # Add another one user.emails.append(model.Email(address=u'*****@*****.**', is_preferred=True)) model.save(user) transaction.commit() Session.add(user) email1, email2 = user.emails # Sanity check self.assertNotEquals(user.preferred_email, email1) self.assertEquals(user.preferred_email, email2) # Attempt to make the address primary self.authenticate() self.app.post('/auth/prefer_email', { 'email_address': email1.address }) # Verify that email is not the user's preferred email Session.add(email1) Session.refresh(email1) self.assertEquals(user.preferred_email, email1) self.assertNotEquals(user.preferred_email, email2)
def makeUser(self, username, password): """Create and save a user with the credentials provided.""" user = model.User() user.username = unicode(username) user.password = model.encrypt(password) model.save(user) transaction.commit() Session.add(user) return user
def makeUser(self, username, password): """Create and save a user with the credentials provided.""" user = model.User() user.username = username user.password = model.encrypt(password) model.save(user) transaction.commit() Session.add(user) return user
def test_preferred_if_only_one(self): "If user has only one email, consider it as preferred email" # Create user without any email address user = self.makeUser('bob', '123') # Directly set new email as preferred email email = model.Email(address=u'*****@*****.**') user.emails.append(email) model.save(user) transaction.commit() # Verify that the new email is now the preferred email Session.add(user) self.assertEquals(user.preferred_email.address, u'*****@*****.**')
def test_prefer_non_persisted_email(self): "Set non-persisted email object as new preferred email" # Create user without any email address user = self.makeUser('bob', '123') # Directly set new email as preferred email email = model.Email(address=u'*****@*****.**') user.preferred_email = email model.save(user) transaction.commit() # Verify that the new email is now the preferred email Session.add(user) self.assertEquals(user.preferred_email.address, u'*****@*****.**')
def change_username(request): "Change username" form = Form(request, schema=schema.ChangeUsername) user = request.user if request.method == 'POST': if form.validate(): user.username = form.data['username'] model.save(user) request.registry.notify(events.UserChangedUsername(request, user)) # Get location based on new username location = get_redirect_location(request) return HTTPFound(location=location) # Get location based on unchanged username location = get_redirect_location(request) form.data['next'] = location return {'renderer': FormRenderer(form), 'user': user}
def prefer_email(request): user = request.user validator = schema.Email() try: email_address = validator.to_python(request.POST.get('email_address')) email = model.get_existing_email(email_address, user_id=user.id) if email: user.preferred_email = email model.save(user) event = events.EmailPreferred(request, user, data={'email': email}) request.registry.notify(event) else: pass except Invalid: pass location = get_redirect_location(request) return HTTPFound(location=location)
def confirm_email(request): """Confirm email address using a confirmation link""" try: encoded_id, confirmation_hash = request.matchdict["traverse"][1:] email_id = urlsafe_b64decode(encoded_id.encode("utf-8")) except (ValueError, TypeError): return {} email = model.Email.query.filter_by(id=email_id, confirmation_hash=confirmation_hash).first() if email: email.is_confirmed = True model.save(email) user = email.user event = events.EmailAddressConfirmed(request, user, data={"email": email}) request.registry.notify(event) location = get_redirect_location(request, user) return HTTPFound(location=location) else: return {}
def test_other_user(self): "Non-admin user cannot delete other user" self.add_user_root() # User to delete self.makeUser('alice', 'Password') # Login as other user bob = self.makeUser('bob', 'Password') model.save(bob) transaction.commit() self.authenticate(username='******', password='******') # Try to delete user res = self.app.post('/users/alice/delete_user', status=403) # Verify that the user has not been deleted self.assertTrue(get_existing_user(username='******') is not None) # User should still be logged in self.assertTrue(len(res.headers['Set-Cookie']) > 250)
def test_admin(self): "Admin should be allowed to delete any user" self.add_user_root() # User to delete self.makeUser('alice', 'Password') # Login as admin admin = self.makeUser('admin', 'Password') admin.roles.append(model.Role(name='admin')) model.save(admin) transaction.commit() self.authenticate(username='******', password='******') # Delete user res = self.app.post('/users/alice/delete_user') # Verify that user has been successfully deleted self.assertTrue(get_existing_user(username='******') is None) # Admin should still be logged in self.assertTrue(len(res.headers['Set-Cookie']) > 250)
def confirm_email(request): """Confirm email address using a confirmation link""" try: encoded_id, confirmation_hash = request.matchdict['traverse'][1:] email_id = urlsafe_b64decode(encoded_id.encode('utf-8')) except (ValueError, TypeError): return {} email = model.Email.query.filter_by( id=email_id, confirmation_hash=confirmation_hash).first() if email: email.is_confirmed = True model.save(email) user = email.user event = events.EmailAddressConfirmed(request, user, data={'email': email}) request.registry.notify(event) location = get_redirect_location(request, user) return HTTPFound(location=location) else: return {}
def change_password(request): """Change user password.""" form = Form(request, schema=schema.ChangePassword, defaults={'failed': False}) user = request.user location = get_redirect_location(request) if request.method == 'POST': if form.validate(): d = form.data user = model.authenticate(user.username, d['old_password']) if user: # Save new password to the db user.password = model.encrypt(d['new_password']) model.save(user) request.registry.notify( events.UserChangedPassword(request, user)) return HTTPFound(location=location) else: form.errors['old_password'] = '******' form.data['next'] = location return {'renderer': FormRenderer(form), 'user': request.user}
def signup_view(request): """Render and handle signup form. Setup:: >>> from mock import Mock >>> from pyramid.testing import DummyRequest >>> from pyramid_simpleauth import model, view >>> _get_existing_email = model.get_existing_email >>> _get_existing_user = model.get_existing_user >>> _save = model.save >>> _remember = view.remember >>> view.remember = Mock() >>> model.save = Mock() >>> model.get_existing_user = Mock() >>> model.get_existing_user.return_value = None >>> model.get_existing_email = Mock() >>> model.get_existing_email.return_value = None If it's not a POST, renders the form:: >>> dummy_request = DummyRequest() >>> return_value = signup_view(dummy_request) >>> return_value['renderer'].data {'failed': False} Otherwise it validates the request data against ``schema.Signup``:: >>> dummy_request = DummyRequest(post={'foo': 'bar'}) >>> return_value = signup_view(dummy_request) >>> return_value['renderer'].data {'failed': True, 'foo': 'bar'} If provided with valid data, it saves a ``User`` with related ``Email``, logs them in by calling ``remember`` and redirects to the user's profile:: >>> valid_post = { ... 'username': '******', ... 'email': '*****@*****.**', ... 'password': '******', ... 'confirm': 'password' ... } >>> dummy_request = DummyRequest(post=valid_post) >>> dummy_request.registry.settings = {} >>> dummy_request.route_url = Mock() >>> return_value = signup_view(dummy_request) >>> model.save.called True >>> view.remember.called True >>> isinstance(return_value, HTTPFound) True Teardown:: >>> view.remember = _remember >>> model.save = _save >>> model.get_existing_user = _get_existing_user >>> model.get_existing_email = _get_existing_email """ form = Form(request, schema=schema.Signup, defaults={'failed': False}) if request.method == 'POST': if form.validate(): d = form.data # Determine whether to skip confirmation. s = request.registry.settings should_skip_confirmation = s.get('auth.skip_confirmation', False) # Instantiate the email instance. email = model.Email() email.address = d['email'] email.is_confirmed = should_skip_confirmation # Instantiate the user instance. user = model.User() user.username = d['username'] user.password = model.encrypt(d['password']) user.emails = [email] # Save the user and email to the db. model.save(user) # Log the user in. remember(request, user.canonical_id) # Fire a ``UserSignedUp`` event. request.registry.notify(events.UserSignedUp(request, user)) # Redirect to the user's profile url. settings = request.registry.settings route_name = settings.get('simpleauth.after_signup_route', 'users') try: location = request.route_url(route_name, traverse=(user.username, )) except (KeyError, ComponentLookupError): location = '/' return HTTPFound(location=location) form.data['failed'] = True return {'renderer': FormRenderer(form)}
def signup_view(request): """Render and handle signup form. Setup:: >>> from mock import Mock >>> from pyramid.testing import DummyRequest >>> from pyramid_simpleauth import model, view >>> _get_existing_email = model.get_existing_email >>> _get_existing_user = model.get_existing_user >>> _save = model.save >>> _remember = view.remember >>> view.remember = Mock() >>> model.save = Mock() >>> model.get_existing_user = Mock() >>> model.get_existing_user.return_value = None >>> model.get_existing_email = Mock() >>> model.get_existing_email.return_value = None If it's not a POST, renders the form:: >>> dummy_request = DummyRequest() >>> return_value = signup_view(dummy_request) >>> return_value['renderer'].data {'failed': False} Otherwise it validates the request data against ``schema.Signup``:: >>> dummy_request = DummyRequest(post={'foo': 'bar'}) >>> return_value = signup_view(dummy_request) >>> return_value['renderer'].data {'failed': True, 'foo': 'bar'} If provided with valid data, it saves a ``User`` with related ``Email``, logs them in by calling ``remember`` and redirects to the user's profile:: >>> valid_post = { ... 'username': '******', ... 'email': '*****@*****.**', ... 'password': '******', ... 'confirm': 'password' ... } >>> dummy_request = DummyRequest(post=valid_post) >>> dummy_request.registry.settings = {} >>> dummy_request.route_url = Mock() >>> return_value = signup_view(dummy_request) >>> model.save.called True >>> view.remember.called True >>> isinstance(return_value, HTTPFound) True Teardown:: >>> view.remember = _remember >>> model.save = _save >>> model.get_existing_user = _get_existing_user >>> model.get_existing_email = _get_existing_email """ form = Form(request, schema=schema.Signup, defaults={'failed': False}) if request.method == 'POST': if form.validate(): d = form.data # Determine whether to skip confirmation. s = request.registry.settings should_skip_confirmation = s.get('auth.skip_confirmation', False) # Instantiate the email instance. email = model.Email() email.address = d['email'] email.is_confirmed = should_skip_confirmation # Instantiate the user instance. user = model.User() user.username = d['username'] user.password = model.encrypt(d['password']) user.emails = [email] # Save the user and email to the db. model.save(user) # Log the user in. remember(request, user.canonical_id) # Fire a ``UserSignedUp`` event. request.registry.notify(events.UserSignedUp(request, user)) # Redirect to the user's profile url. settings = request.registry.settings route_name = settings.get('simpleauth.after_signup_route', 'users') try: location = request.route_url(route_name, traverse=(user.username,)) except (KeyError, ComponentLookupError): location = '/' return HTTPFound(location=location) form.data['failed'] = True return {'renderer': FormRenderer(form)}