def test_login_with_api_key_inactive_user(self): """Inactive user logging in with API key.""" db = connect_to_db() email = '*****@*****.**' password = '******' full_name = 'Test user login' ip_address = '1.2.3.4' add_user( db=db, new_user=NewUser( email=email, full_name=full_name, notes='Test test test', role_ids=[1], active=False, password=password, password_repeat=password, activation_url='https://activate.com/activate', ), ) user = user_info(db=db, email=email) assert user global_api_key = user.global_api_key() with pytest.raises(McAuthLoginException) as ex: login_with_api_key(db=db, api_key=global_api_key, ip_address=ip_address) # Make sure the error message explicitly states that login failed due to user not being active assert 'not active' in str(ex)
def test_login_with_email_password_inactive_user(self): """Inactive user logging in with username and password.""" db = connect_to_db() email = '*****@*****.**' password = '******' full_name = 'Test user login' # Inactive user add_user( db=db, new_user=NewUser( email=email, full_name=full_name, has_consented=True, notes='Test test test', role_ids=[1], active=False, password=password, password_repeat=password, activation_url='https://activate.com/activate', ), ) with pytest.raises(McAuthLoginException) as ex: login_with_email_password(db=db, email=email, password=password) # Make sure the error message explicitly states that login failed due to user not being active assert 'not active' in str(ex)
def test_send_password_reset_token(self): db = connect_to_db() email = '*****@*****.**' password = '******' password_reset_link = 'http://password-reset.com/' add_user( db=db, new_user=NewUser( email=email, full_name='Test user login', has_consented=True, notes='Test test test', role_ids=[1], active=True, password=password, password_repeat=password, activation_url='', # user is active, no need for activation URL ), ) # Existing user send_password_reset_token(db=db, email=email, password_reset_link=password_reset_link) # Nonexisting user (call shouldn't fail because we don't want to reveal which users are in the system so we # pretend that we've sent the email) send_password_reset_token(db=db, email='*****@*****.**', password_reset_link=password_reset_link)
def test_regenerate_api_key(self): db = connect_to_db() email = '*****@*****.**' password = '******' full_name = 'Test user login' ip_address = '1.2.3.4' add_user( db=db, new_user=NewUser( email=email, full_name=full_name, has_consented=True, notes='Test test test', role_ids=[1], active=True, password=password, password_repeat=password, activation_url='', # user is active, no need for activation URL ), ) # Get sample API keys user = login_with_email_password(db=db, email=email, password=password, ip_address=ip_address) assert user before_global_api_key = user.global_api_key() assert before_global_api_key before_per_ip_api_key = user.api_key_for_ip_address( ip_address=ip_address) assert before_per_ip_api_key assert before_global_api_key != before_per_ip_api_key # Regenerate API key, purge per-IP API keys regenerate_api_key(db=db, email=email) # Get sample API keys again user = login_with_email_password(db=db, email=email, password=password, ip_address=ip_address) assert user after_global_api_key = user.global_api_key() assert after_global_api_key after_per_ip_api_key = user.api_key_for_ip_address( ip_address=ip_address) assert after_per_ip_api_key # Make sure API keys are different assert before_global_api_key != after_global_api_key assert before_per_ip_api_key != after_per_ip_api_key
def test_login_with_api_key(): db = connect_to_db() email = '*****@*****.**' password = '******' full_name = 'Test user login' ip_address = '1.2.3.4' add_user( db=db, new_user=NewUser( email=email, full_name=full_name, notes='Test test test', role_ids=[1], active=True, password=password, password_repeat=password, activation_url='', # user is active, no need for activation URL ), ) # Get sample API keys user = login_with_email_password(db=db, email=email, password=password, ip_address=ip_address) assert user global_api_key = user.global_api_key() assert global_api_key per_ip_api_key = user.api_key_for_ip_address(ip_address=ip_address) assert per_ip_api_key assert global_api_key != per_ip_api_key # Non-existent API key with pytest.raises(McAuthLoginException): login_with_api_key(db=db, api_key='Non-existent API key', ip_address=ip_address) # Global API key user = login_with_api_key(db=db, api_key=global_api_key, ip_address=ip_address) assert user assert user.email() == email assert user.global_api_key() == global_api_key # Per-IP API key user = login_with_api_key(db=db, api_key=per_ip_api_key, ip_address=ip_address) assert user assert user.email() == email
def test_all_users(): db = connect_to_db() email = '*****@*****.**' full_name = 'Test user info' notes = 'Test test test' weekly_requests_limit = 123 weekly_requested_items_limit = 456 max_topic_stories = 789 add_user( db=db, new_user=NewUser( email=email, full_name=full_name, has_consented=True, notes=notes, role_ids=[1], active=True, password='******', password_repeat='user_info', activation_url='', # user is active, no need for activation URL resource_limits=Resources( weekly_requests=weekly_requests_limit, weekly_requested_items=weekly_requested_items_limit, max_topic_stories=max_topic_stories, ), ), ) users = all_users(db=db) assert len(users) == 1 user = users[0] assert isinstance(user, CurrentUser) assert user.user_id() assert user.email() == email assert user.full_name() == full_name assert user.notes() == notes assert user.resource_limits() assert user.resource_limits().weekly_requests() == weekly_requests_limit assert user.resource_limits().weekly_requested_items( ) == weekly_requested_items_limit assert user.resource_limits().max_topic_stories() == max_topic_stories assert user.active() assert user.has_consented() assert user.global_api_key() assert user.password_hash() assert user.has_role('admin')
def test_login_with_email_password(): db = connect_to_db() email = '*****@*****.**' password = '******' full_name = 'Test user login' add_user( db=db, new_user=NewUser( email=email, full_name=full_name, has_consented=True, notes='Test test test', role_ids=[1], active=True, password=password, password_repeat=password, activation_url='', # user is active, no need for activation URL ), ) # Successful login user = login_with_email_password(db=db, email=email, password=password) assert user assert isinstance(user, CurrentUser) assert user.email() == email assert user.full_name() == full_name # Unsuccessful login with pytest.raises(McAuthLoginException): login_with_email_password(db=db, email=email, password='******') # Subsequent login attempt after a failed one should be delayed by 1 second with pytest.raises(McAuthLoginException): login_with_email_password(db=db, email=email, password=password) # Successful login after waiting out the delay time.sleep(2) user = login_with_email_password(db=db, email=email, password=password) assert user assert isinstance(user, CurrentUser) assert user.email() == email assert user.full_name() == full_name
def test_send_user_activation_token(self): db = connect_to_db() email = '*****@*****.**' password = '******' activation_url = 'http://activate.com/' subscribe_to_newsletter = True add_user( db=db, new_user=NewUser( email=email, full_name='Test user login', notes='Test test test', role_ids=[1], active=True, password=password, password_repeat=password, activation_url='', # user is active, no need for activation URL subscribe_to_newsletter=subscribe_to_newsletter, ), ) # Existing user send_user_activation_token( db=db, email=email, activation_link=activation_url, subscribe_to_newsletter=subscribe_to_newsletter, ) # Nonexistent user (call shouldn't fail because we don't want to reveal which users are in the system so we # pretend that we've sent the email) send_user_activation_token( db=db, email='*****@*****.**', activation_link=activation_url, subscribe_to_newsletter=subscribe_to_newsletter, )
def test_user_info(): db = connect_to_db() email = '*****@*****.**' full_name = 'Test user info' notes = 'Test test test' weekly_requests_limit = 123 weekly_requested_items_limit = 456 add_user( db=db, new_user=NewUser( email=email, full_name=full_name, notes=notes, role_ids=[1], active=True, password='******', password_repeat='user_info', activation_url='', # user is active, no need for activation URL weekly_requests_limit=weekly_requests_limit, weekly_requested_items_limit=weekly_requested_items_limit, ), ) user = user_info(db=db, email=email) assert isinstance(user, CurrentUser) assert user.email() == email assert user.full_name() == full_name assert user.notes() == notes assert user.weekly_requests_limit() == weekly_requests_limit assert user.weekly_requested_items_limit() == weekly_requested_items_limit assert user.active() assert user.created_date() assert __looks_like_iso8601_date(user.created_date()) assert user.global_api_key() assert user.password_hash() assert user.has_role('admin')
def test_add_user(self): db = connect_to_db() email = '*****@*****.**' password = '******' full_name = 'Test user login' new_user = NewUser( email=email, full_name=full_name, has_consented=True, notes='Test test test', role_ids=[1], active=True, password=password, password_repeat=password, activation_url='', # user is active, no need for activation URL ) # Add user add_user(db=db, new_user=new_user) # Test logging in user = login_with_email_password(db=db, email=email, password=password) assert user assert isinstance(user, CurrentUser) assert user.email() == email assert user.full_name() == full_name # Faulty input with pytest.raises(McAuthRegisterException): # noinspection PyTypeChecker add_user(db=db, new_user=None) # Existing user with pytest.raises(McAuthRegisterException): add_user(db=db, new_user=new_user) # Existing user with uppercase email with pytest.raises(McAuthRegisterException): add_user( db=db, new_user=NewUser( email=email.upper(), full_name=full_name, has_consented=True, notes='Test test test', role_ids=[1], active=True, password=password, password_repeat=password, activation_url= '', # user is active, no need for activation URL ), ) # Invalid password with pytest.raises(McAuthUserException): add_user( db=db, new_user=NewUser( email='*****@*****.**', full_name=full_name, has_consented=True, notes='Test test test', role_ids=[1], active=True, password='******', password_repeat='def', activation_url= '', # user is active, no need for activation URL ), ) # Nonexistent roles with pytest.raises(McAuthRegisterException): add_user( db=db, new_user=NewUser( email='*****@*****.**', full_name=full_name, has_consented=True, notes='Test test test', role_ids=[42], active=True, password=password, password_repeat=password, activation_url= '', # user is active, no need for activation URL ), ) # Both the user is set as active and the activation URL is set with pytest.raises(McAuthUserException): add_user( db=db, new_user=NewUser( email='*****@*****.**', full_name=full_name, has_consented=True, notes='Test test test', role_ids=[1], active=True, password=password, password_repeat=password, activation_url='https://activate-user.com/activate', ), ) # User is neither active not the activation URL is set with pytest.raises(McAuthUserException): add_user( db=db, new_user=NewUser( email='*****@*****.**', full_name=full_name, has_consented=True, notes='Test test test', role_ids=[1], active=False, password=password, password_repeat=password, activation_url='', ), )
def test_change_password_with_reset_token(self): # FIXME test changing password for user A using reset token from user B db = connect_to_db() email = '*****@*****.**' password = '******' full_name = 'Test user login' add_user( db=db, new_user=NewUser( email=email, full_name=full_name, notes='Test test test', role_ids=[1], active=True, password=password, password_repeat=password, activation_url='', # user is active, no need for activation URL ), ) # Successful login user = login_with_email_password(db=db, email=email, password=password) assert user assert isinstance(user, CurrentUser) assert user.email() == email assert user.full_name() == full_name # Make sure password reset token is not set password_reset_token_hash = db.query(""" SELECT password_reset_token_hash FROM auth_users WHERE email = %(email)s """, {'email': email}).flat() assert password_reset_token_hash[0] is None # Send password reset link password_reset_url = 'https://reset-password.com/reset' final_password_reset_url = _generate_password_reset_token( db=db, email=email, password_reset_link=password_reset_url, ) assert final_password_reset_url assert password_reset_url in final_password_reset_url final_password_reset_uri = furl(final_password_reset_url) assert final_password_reset_uri.args['email'] assert final_password_reset_uri.args['password_reset_token'] # Make sure password reset token is set password_reset_token_hash = db.query(""" SELECT password_reset_token_hash FROM auth_users WHERE email = %(email)s """, {'email': email}).flat() assert password_reset_token_hash[0] is not None # Change password new_password = '******' change_password_with_reset_token( db=db, email=email, password_reset_token=final_password_reset_uri.args['password_reset_token'], new_password=new_password, new_password_repeat=new_password, ) # Make sure password reset token has been reset after changing password password_reset_token_hash = db.query(""" SELECT password_reset_token_hash FROM auth_users WHERE email = %(email)s """, {'email': email}).flat() assert password_reset_token_hash[0] is None # Unsuccessful login with old password with pytest.raises(McAuthLoginException): login_with_email_password(db=db, email=email, password=password) # Imposed delay after unsuccessful login time.sleep(2) # Successful login with new password user = login_with_email_password(db=db, email=email, password=new_password) assert user assert isinstance(user, CurrentUser) assert user.email() == email assert user.full_name() == full_name # Incorrect password reset token _generate_password_reset_token( db=db, email=email, password_reset_link=password_reset_url, ) with pytest.raises(McAuthChangePasswordException): change_password_with_reset_token( db=db, email=email, password_reset_token='incorrect password reset token', new_password=new_password, new_password_repeat=new_password, ) # Changing for nonexistent user final_password_reset_url = _generate_password_reset_token( db=db, email=email, password_reset_link=password_reset_url, ) with pytest.raises(McAuthChangePasswordException): change_password_with_reset_token( db=db, email='*****@*****.**', password_reset_token=furl(final_password_reset_url).args['password_reset_token'], new_password=new_password, new_password_repeat=new_password, ) # Passwords don't match final_password_reset_url = _generate_password_reset_token( db=db, email=email, password_reset_link=password_reset_url, ) with pytest.raises(McAuthChangePasswordException): change_password_with_reset_token( db=db, email=email, password_reset_token=furl(final_password_reset_url).args['password_reset_token'], new_password='******', new_password_repeat='not match', )
def test_change_password(): db = connect_to_db() email = '*****@*****.**' password = '******' full_name = 'Test user login' add_user( db=db, new_user=NewUser( email=email, full_name=full_name, has_consented=True, notes='Test test test', role_ids=[1], active=True, password=password, password_repeat=password, activation_url='', # user is active, no need for activation URL ), ) # Successful login user = login_with_email_password(db=db, email=email, password=password) assert user assert isinstance(user, CurrentUser) assert user.email() == email assert user.full_name() == full_name # Change password new_password = '******' change_password( db=db, email=email, new_password=new_password, new_password_repeat=new_password, do_not_inform_via_email=True, ) # Unsuccessful login with old password with pytest.raises(McAuthLoginException): login_with_email_password(db=db, email=email, password=password) # Imposed delay after unsuccessful login time.sleep(2) # Successful login with new password user = login_with_email_password(db=db, email=email, password=new_password) assert user assert isinstance(user, CurrentUser) assert user.email() == email assert user.full_name() == full_name # Changing for nonexistent user with pytest.raises(McAuthChangePasswordException): change_password( db=db, email='*****@*****.**', new_password=new_password, new_password_repeat=new_password, do_not_inform_via_email=True, ) # Passwords don't match with pytest.raises(McAuthChangePasswordException): change_password( db=db, email=email, new_password='******', new_password_repeat='not match', do_not_inform_via_email=True, )
def test_activate_user_via_token(self): db = connect_to_db() email = '*****@*****.**' password = '******' full_name = 'Test user login' activation_url = 'https://activate.com/activate' # Add inactive user add_user( db=db, new_user=NewUser( email=email, full_name=full_name, notes='Test test test', role_ids=[1], active=False, # not active, needs to be activated password=password, password_repeat=password, activation_url=activation_url, ), ) # Test logging in with pytest.raises(McAuthLoginException) as ex: login_with_email_password(db=db, email=email, password=password) # Make sure the error message explicitly states that login failed due to user not being active assert 'not active' in str(ex) # Make sure activation token is set activation_token_hash = db.query( """ SELECT password_reset_token_hash FROM auth_users WHERE email = %(email)s """, { 'email': email }).flat() assert activation_token_hash assert len(activation_token_hash) == 1 assert len(activation_token_hash[0]) > 0 # Send password reset link final_activation_url = _generate_user_activation_token( db=db, email=email, activation_link=activation_url, ) final_activation_uri = furl(final_activation_url) assert final_activation_uri.args['email'] activation_token = final_activation_uri.args['activation_token'] assert activation_token # Make sure activation token is (still) set activation_token_hash = db.query( """ SELECT password_reset_token_hash FROM auth_users WHERE email = %(email)s """, { 'email': email }).flat() assert activation_token_hash assert len(activation_token_hash) == 1 assert len(activation_token_hash[0]) > 0 # Activate user activate_user_via_token(db=db, email=email, activation_token=activation_token) # Imposed delay after unsuccessful login time.sleep(2) # Test logging in user = login_with_email_password(db=db, email=email, password=password) assert user assert isinstance(user, CurrentUser) assert user.email() == email assert user.full_name() == full_name # Make sure activation token is not set anymore activation_token_hash = db.query( """ SELECT password_reset_token_hash FROM auth_users WHERE email = %(email)s """, { 'email': email }).flat() assert activation_token_hash assert len(activation_token_hash) == 1 assert activation_token_hash[0] is None # Incorrect activation token _generate_user_activation_token(db=db, email=email, activation_link=activation_url) with pytest.raises(McAuthRegisterException): activate_user_via_token( db=db, email=email, activation_token='incorrect activation token') # Activating nonexistent user final_activation_url = _generate_user_activation_token( db=db, email=email, activation_link=activation_url, ) final_activation_uri = furl(final_activation_url) activation_token = final_activation_uri.args['activation_token'] with pytest.raises(McAuthRegisterException): activate_user_via_token(db=db, email='*****@*****.**', activation_token=activation_token)