예제 #1
0
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}
예제 #2
0
def authenticate_user(request, username, password):
    """Chooses the right authentication mechanism based on the
    configuration and calls it.
    """

    settings = request.registry.settings
    if settings and asbool(settings.get('simpleauth.allow_email_login', False)):
        return model.authenticate_allow_email(username, password)
    else:
        return model.authenticate(username, password)
예제 #3
0
def authenticate_user(request, username, password):
    """Chooses the right authentication mechanism based on the
    configuration and calls it.
    """

    settings = request.registry.settings
    if settings and asbool(settings.get('simpleauth.allow_email_login',
                                        False)):
        return model.authenticate_allow_email(username, password)
    else:
        return model.authenticate(username, password)
예제 #4
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}
예제 #5
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}
예제 #6
0
def login(request):
    """Render login form.  If posted a ``username`` and ``password``, attempt
      to authenticate the user using the credentials provided.  If
      authentication if successful, redirect the user whence they came.

      Setup::

          >>> from mock import Mock, MagicMock
          >>> from pyramid.testing import DummyRequest
          >>> from pyramid import security
          >>> from pyramid_simpleauth import model, view
          >>> _authenticate = model.authenticate
          >>> model.authenticate = Mock()

      If it's not a POST, renders the form::

          >>> dummy_request = DummyRequest()
          >>> dummy_request.registry.settings = {}
          >>> return_value = login(dummy_request)
          >>> return_value['renderer'].data
          {'failed': False}

      Otherwise validates the request::

          >>> dummy_request = DummyRequest(post={'foo': 'bar'})
          >>> dummy_request.registry.settings = {}
          >>> return_value = login(dummy_request)
          >>> return_value['renderer'].data['failed']
          True

      Otherwise tries to authenticate the credentials::

          >>> model.authenticate.return_value = None
          >>> valid_post = {
          ...     'username': '******',
          ...     'password': '******'
          ... }
          >>> dummy_request = DummyRequest(post=valid_post)
          >>> dummy_request.registry.settings = {}
          >>> return_value = login(dummy_request)
          >>> model.authenticate.assert_called_with('thruflo', 'password')

      If they don't match::

          >>> return_value['renderer'].data['failed']
          True

      If they do, redirects with the user's canonical id remembered::

          >>> mock_user = Mock()
          >>> mock_user.canonical_id = 'abc'
          >>> model.authenticate.return_value = mock_user
          >>> dummy_request = DummyRequest(post=valid_post)
          >>> dummy_request.registry.settings = {}
          >>> return_value = login(dummy_request)
          >>> isinstance(return_value, HTTPFound)
          True
          >>> return_value.location
          '/'

      Redirecting to ``next`` if provided::

          >>> data = {
          ...     'username': '******',
          ...     'password': '******',
          ...     'next': '/foo/bar'
          ... }
          >>> dummy_request = DummyRequest(post=data)
          >>> dummy_request.registry.settings = {}
          >>> return_value = login(dummy_request)
          >>> return_value.location
          '/foo/bar'

      n.b.: If ``next`` is invalid, it defaults to '/' rather than failing::

          >>> data['next'] = '$do.evil(h4x);'
          >>> dummy_request = DummyRequest(post=data)
          >>> return_value = login(dummy_request)
          >>> return_value.location
          '/'

      Teardown::

          >>> model.authenticate = _authenticate

    """

    next_ = validate_next_param(request)
    username_param = validate_username_param(request)
    defaults = {'failed': False}
    if username_param:
        defaults['username'] = username_param
    # Validate the rest of the user input.
    form = Form(request, schema=schema.Login, defaults=defaults)
    if request.method == 'POST':
        if form.validate():
            d = form.data
            user = model.authenticate(d['username'], d['password'])
            if user:
                # Remember the logged in user.
                headers = remember(request, user.canonical_id)
                # Work out where to redirect to next.
                location = get_redirect_location(request, user,
                        route_name='index', view_name=None)
                # Fire a ``UserLoggedIn`` event.
                request.registry.notify(events.UserLoggedIn(request, user))
                # Redirect.
                return HTTPFound(location=location, headers=headers)
        form.data['failed'] = True
    # Set ``next`` no matter what.
    if next_:
        form.data['next'] = next_
    return {'renderer': FormRenderer(form)}
예제 #7
0
def authenticate_view(request):
    """If posted a ``username`` and ``password``, attempt to authenticate the
      user using the credentials provided.  If authentication if successful,
      return the JSON representation of the authenticated user.

      Setup::

          >>> from mock import Mock, MagicMock
          >>> from pyramid.testing import DummyRequest
          >>> from pyramid import security
          >>> from pyramid_simpleauth import model, view
          >>> _authenticate = model.authenticate
          >>> _remember = view.remember
          >>> view.remember = Mock()
          >>> model.authenticate = Mock()

      If the request doesn't validate, returns an empty dict::

          >>> dummy_request = DummyRequest(post={'foo': 'bar'})
          >>> authenticate_view(dummy_request)
          {}

      Otherwise tries to authenticate the credentials::

          >>> model.authenticate.return_value = None
          >>> valid_post = {
          ...     'username': '******',
          ...     'password': '******'
          ... }
          >>> dummy_request = DummyRequest(post=valid_post)
          >>> return_value = authenticate_view(dummy_request)
          >>> model.authenticate.assert_called_with('thruflo', 'password')

      If they don't match, returns an empty dict::

          >>> authenticate_view(dummy_request)
          {}

      If they do, remembers the user and returns the user as a dict::

          >>> mock_user = Mock()
          >>> mock_user.canonical_id = 'abc'
          >>> def __json__(*args):
          ...     return '<user as dict>'
          >>> mock_user.__json__ = __json__
          >>> model.authenticate.return_value = mock_user
          >>> dummy_request = DummyRequest(post=valid_post)
          >>> return_value = authenticate_view(dummy_request)
          >>> view.remember.assert_called_with(dummy_request, 'abc')
          >>> return_value
          '<user as dict>'

      Teardown::

          >>> view.remember = _remember
          >>> model.authenticate = _authenticate

    """

    form = Form(request, schema=schema.Authenticate)
    if form.validate():
        d = form.data
        user = model.authenticate(d['username'], d['password'])
        if user:
            # Remember the logged in user.
            remember(request, user.canonical_id)
            # Fire a ``UserLoggedIn`` event.
            request.registry.notify(events.UserLoggedIn(request, user))
            # Return the user's public data.
            return user.__json__()
    return {}
예제 #8
0
def login(request):
    """Render login form.  If posted a ``username`` and ``password``, attempt
      to authenticate the user using the credentials provided.  If
      authentication if successful, redirect the user whence they came.

      Setup::

          >>> from mock import Mock, MagicMock
          >>> from pyramid.testing import DummyRequest
          >>> from pyramid import security
          >>> from pyramid_simpleauth import model, view
          >>> _authenticate = model.authenticate
          >>> model.authenticate = Mock()

      If it's not a POST, renders the form::

          >>> dummy_request = DummyRequest()
          >>> dummy_request.registry.settings = {}
          >>> return_value = login(dummy_request)
          >>> return_value['renderer'].data
          {'failed': False}

      Otherwise validates the request::

          >>> dummy_request = DummyRequest(post={'foo': 'bar'})
          >>> dummy_request.registry.settings = {}
          >>> return_value = login(dummy_request)
          >>> return_value['renderer'].data['failed']
          True

      Otherwise tries to authenticate the credentials::

          >>> model.authenticate.return_value = None
          >>> valid_post = {
          ...     'username': '******',
          ...     'password': '******'
          ... }
          >>> dummy_request = DummyRequest(post=valid_post)
          >>> dummy_request.registry.settings = {}
          >>> return_value = login(dummy_request)
          >>> model.authenticate.assert_called_with('thruflo', 'password')

      If they don't match::

          >>> return_value['renderer'].data['failed']
          True

      If they do, redirects with the user's canonical id remembered::

          >>> mock_user = Mock()
          >>> mock_user.canonical_id = 'abc'
          >>> model.authenticate.return_value = mock_user
          >>> dummy_request = DummyRequest(post=valid_post)
          >>> dummy_request.registry.settings = {}
          >>> return_value = login(dummy_request)
          >>> isinstance(return_value, HTTPFound)
          True
          >>> return_value.location
          '/'

      Redirecting to ``next`` if provided::

          >>> data = {
          ...     'username': '******',
          ...     'password': '******',
          ...     'next': '/foo/bar'
          ... }
          >>> dummy_request = DummyRequest(post=data)
          >>> dummy_request.registry.settings = {}
          >>> return_value = login(dummy_request)
          >>> return_value.location
          '/foo/bar'

      n.b.: If ``next`` is invalid, it defaults to '/' rather than failing::

          >>> data['next'] = '$do.evil(h4x);'
          >>> dummy_request = DummyRequest(post=data)
          >>> return_value = login(dummy_request)
          >>> return_value.location
          '/'

      Teardown::

          >>> model.authenticate = _authenticate

    """

    next_ = validate_next_param(request)
    # Validate the rest of the user input.
    form = Form(request, schema=schema.Login, defaults={'failed': False})
    if request.method == 'POST':
        if form.validate():
            d = form.data
            user = model.authenticate(d['username'], d['password'])
            if user:
                # Remember the logged in user.
                headers = remember(request, user.canonical_id)
                # Work out where to redirect to next.
                location = get_redirect_location(request,
                                                 user,
                                                 route_name='index',
                                                 view_name=None)
                # Fire a ``UserLoggedIn`` event.
                request.registry.notify(events.UserLoggedIn(request, user))
                # Redirect.
                return HTTPFound(location=location, headers=headers)
        form.data['failed'] = True
    # Set ``next`` no matter what.
    if next_:
        form.data['next'] = next_
    return {'renderer': FormRenderer(form)}
예제 #9
0
def authenticate_view(request):
    """If posted a ``username`` and ``password``, attempt to authenticate the
      user using the credentials provided.  If authentication if successful,
      return the JSON representation of the authenticated user.

      Setup::

          >>> from mock import Mock, MagicMock
          >>> from pyramid.testing import DummyRequest
          >>> from pyramid import security
          >>> from pyramid_simpleauth import model, view
          >>> _authenticate = model.authenticate
          >>> _remember = view.remember
          >>> view.remember = Mock()
          >>> model.authenticate = Mock()

      If the request doesn't validate, returns an empty dict::

          >>> dummy_request = DummyRequest(post={'foo': 'bar'})
          >>> authenticate_view(dummy_request)
          {}

      Otherwise tries to authenticate the credentials::

          >>> model.authenticate.return_value = None
          >>> valid_post = {
          ...     'username': '******',
          ...     'password': '******'
          ... }
          >>> dummy_request = DummyRequest(post=valid_post)
          >>> return_value = authenticate_view(dummy_request)
          >>> model.authenticate.assert_called_with('thruflo', 'password')

      If they don't match, returns an empty dict::

          >>> authenticate_view(dummy_request)
          {}

      If they do, remembers the user and returns the user as a dict::

          >>> mock_user = Mock()
          >>> mock_user.canonical_id = 'abc'
          >>> def __json__(*args):
          ...     return '<user as dict>'
          >>> mock_user.__json__ = __json__
          >>> model.authenticate.return_value = mock_user
          >>> dummy_request = DummyRequest(post=valid_post)
          >>> return_value = authenticate_view(dummy_request)
          >>> view.remember.assert_called_with(dummy_request, 'abc')
          >>> return_value
          '<user as dict>'

      Teardown::

          >>> view.remember = _remember
          >>> model.authenticate = _authenticate

    """

    form = Form(request, schema=schema.Authenticate)
    if form.validate():
        d = form.data
        user = model.authenticate(d['username'], d['password'])
        if user:
            # Remember the logged in user.
            remember(request, user.canonical_id)
            # Fire a ``UserLoggedIn`` event.
            request.registry.notify(events.UserLoggedIn(request, user))
            # Return the user's public data.
            return user.__json__()
    return {}