def get_user_and_hashed_pass(request): """Similar to the `user_loader`, except it also return the hashed_pass :param request: flask's request :return: Return a tuple with a user object (or None) and its hashed pass """ auth = request.authorization if auth: user = user_datastore.get_user(auth.username) hashed_pass = md5(auth.password) else: token_auth_header = current_app.config[ 'SECURITY_TOKEN_AUTHENTICATION_HEADER'] token = request.headers.get(token_auth_header) if not token: return None, None user, hashed_pass = _get_user_from_token(token) if user: db = current_app.extensions['sqlalchemy'].db # This hack makes sure the roles are actually loaded from the DB _ = user.roles # NOQA # This is necessary to allow access after the SQLA session has closed db.make_transient(user) return user, hashed_pass
def _authenticate_token(self, token): """Make sure that the token passed exists, is valid, is not expired, and that the user contained within it exists in the DB :param token: An authentication token :return: A tuple: (A user object, its hashed password) """ self.logger.debug('Authenticating token') expired, invalid, user, data, error = \ user_handler.get_token_status(token) if expired: raise_unauthorized_user_error('Token is expired') elif invalid or (not isinstance(data, list) or len(data) != 2): raise_unauthorized_user_error( 'Authentication token is invalid:\n{0}'.format(error) ) elif not user: raise_unauthorized_user_error('No authentication info provided') elif md5(user.password) != data[1]: raise_unauthorized_user_error( 'Authentication failed for {0}'.format(user) ) return user
def generate_unsubscribe_token(user): """Generates a unique unsubscription token for the specified user. :param user: The user to work with """ data = [str(user.id), md5(user.password)] return get_serializer(TOKEN_SERIALIZER_NAME).dumps(data)
def generate_reset_password_token(user): """Generate a unique reset password token for the specified user. :param user: The user to work with :type user: User """ data = [str(user.id), md5(user.password)] return get_serializer("reset").dumps(data)
def generate_reset_password_token(user): """Generates a unique reset password token for the specified user. :param user: The user to work with :type user: User """ data = [str(user.id), md5(user.password)] return get_serializer("reset").dumps(data)
def _basic_http_authenticate(user, hashed_pass): """Assert that `user` exists and that its stored password matches the one passed :param user: A valid user object, or None :param hashed_pass: md5 hashed password, or None """ if not user or md5(user.password) != hashed_pass: unauthorized_user_handler('HTTP authentication failed') # Reloading the user from the datastore, because the current user # object is detached from a session return user_datastore.get_user(user.username)
def token_loader(token, max_age=settings.MAX_TOKEN_AGE): """ Used to patch flask-security to expire tokens after a time limit. """ from flask_security.core import AnonymousUser try: data = app.extensions['security'].remember_token_serializer.loads(token, max_age=max_age) user = app.extensions['security'].datastore.find_user(id=data[0]) if user and md5(user.password) == data[1]: return user except Exception: pass return AnonymousUser()
def token_loader(token, max_age=settings.MAX_TOKEN_AGE): """ Used to patch flask-security to expire tokens after a time limit. """ from flask_security.core import AnonymousUser try: data = app.extensions['security'].remember_token_serializer.loads( token, max_age=max_age) user = app.extensions['security'].datastore.find_user(id=data[0]) if user and md5(user.password) == data[1]: return user except Exception: pass return AnonymousUser()
def get_user_and_hashed_pass(request): """Similar to the `user_loader`, except it also return the hashed_pass :param request: flask's request :return: Return a tuple with a user object (or None) and its hashed pass """ auth = request.authorization if auth: user = user_datastore.get_user(auth.username) hashed_pass = md5(auth.password) else: token_auth_header = current_app.config[ 'SECURITY_TOKEN_AUTHENTICATION_HEADER'] token = request.headers.get(token_auth_header) if not token: return None, None user, hashed_pass = _get_user_from_token(token) return user, hashed_pass
def test_md5(): data = md5(b'hello') assert isinstance(data, string_types) data = md5(u'hellö') assert isinstance(data, string_types)
def test_user_registration_and_login(live_server, env_browser): """E2E user registration and login test.""" browser = env_browser # 1. Go to user registration page browser.get(flask.url_for('security.register', _external=True)) e2e_assert_url(browser, 'security.register') # 2. Input user data signup_form = browser.find_element_by_name('register_user_form') input_email = signup_form.find_element_by_name('email') input_password = signup_form.find_element_by_name('password') # input w/ name "email" # input w/ name "password" user_email = '*****@*****.**' user_password = '******' input_email.send_keys(user_email) input_password.send_keys(user_password) # 3. submit form signup_form.submit() # ...and get a message saying to expect an email success_element = browser.find_element_by_css_selector('.alert-success') assert (success_element is not None) assert ( success_element.text == 'Thank you. Confirmation instructions have been sent to [email protected].' ) # 3.5: After registering we should not yet be logged in. e2e_assert(browser, not testutils.webdriver_authenticated(browser), 'Should not be authenticated') # 4. go to login-form browser.get(flask.url_for('security.login', _external=True)) e2e_assert_url(browser, 'security.login') login_form = browser.find_element_by_name('login_user_form') # 5. input registered info login_form.find_element_by_name('email').send_keys(user_email) login_form.find_element_by_name('password').send_keys(user_password) # 6. Submit! login_form.submit() # 7. We should not yet be able to log in as we haven't confirmed the email error_element = browser.find_element_by_css_selector('.alert-danger') assert (error_element is not None) assert ('Email requires confirmation.' in error_element.text) e2e_assert(browser, not testutils.webdriver_authenticated(browser), 'Should not be authenticated') # 8. Check that the resend confirmation link works browser.get(flask.url_for('security.send_confirmation', _external=True)) e2e_assert_url(browser, 'security.send_confirmation') email_confirm_form = browser.find_element_by_name('send_confirmation_form') # 8a. input registered info email_confirm_form.find_element_by_name('email').send_keys(user_email) # 8b. Submit! email_confirm_form.submit() info_element = browser.find_element_by_css_selector('.alert-info') assert (info_element is not None) assert ('Confirmation instructions have been sent to %s.' % user_email in info_element.text) # 9a Generate a confirmation token (this is how it's done in flask_security) data = ['2', utils.md5(user_email)] serializer = URLSafeTimedSerializer(secret_key="CHANGE_ME", salt="CHANGE_ME") token = serializer.dumps(data) # 9b Go to the confirmation URL with our token browser.get( flask.url_for('security.confirm_email', token=token, _external=True)) # 9c Check that we're on the dashboard and we've got a success message e2e_assert_url(browser, 'hep_dashboard.dashboard') success_element = browser.find_element_by_css_selector('.alert-success') assert (success_element is not None) assert ('Thank you. Your email has been confirmed.' in success_element.text) # 9d We should now be logged in e2e_assert(browser, testutils.webdriver_authenticated(browser), 'Should be authenticated') # 10. logout. browser.get(flask.url_for('security.logout', _external=True)) e2e_assert(browser, not testutils.webdriver_authenticated(browser), 'Should not be authenticated') # 11. go back to login-form browser.get(flask.url_for('security.login', _external=True)) e2e_assert_url(browser, 'security.login') login_form = browser.find_element_by_name('login_user_form') # 11a. input registered info login_form.find_element_by_name('email').send_keys(user_email) login_form.find_element_by_name('password').send_keys(user_password) # 11b. Submit! # check if authenticated at `flask.url_for('security.change_password')` login_form.submit() e2e_assert(browser, testutils.webdriver_authenticated(browser)) # 12. check we can access the change password screen browser.get(flask.url_for('security.change_password', _external=True)) e2e_assert_url(browser, 'security.change_password') # 13. logout. browser.get(flask.url_for('security.logout', _external=True)) e2e_assert(browser, not testutils.webdriver_authenticated(browser), 'Should not be authenticated')