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}
Exemple #4
0
    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'*****@*****.**')
Exemple #8
0
    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'*****@*****.**')
Exemple #9
0
    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 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 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)
Exemple #15
0
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 {}
Exemple #16
0
    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_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)
Exemple #18
0
    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 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)
Exemple #21
0
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}
Exemple #22
0
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)}