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 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)
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 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)}
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 {}
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)}