def test_activate_user(database): """Test creating inactive users and activating them.""" # -- Test creating an inactive user --------------------------------------- username = '******' password = '******' with database.session() as session: users = UserManager(session) user = users.register_user(username, password, verify=True) user_id = user.user_id # Attempt to login will raise error with pytest.raises(err.UnknownUserError): users.login_user(username, password) # -- Test activate user --------------------------------------------------- with database.session() as session: # After activating the user login should succeed. users = UserManager(session) auth = OpenAccessAuth(session) active_user = users.activate_user(user_id) assert active_user.user_id == user_id assert active_user.name == username assert active_user.api_key is None user = users.login_user(username, password) assert user.name == username assert user.api_key is not None assert auth.authenticate(user.api_key.value).user_id == user_id # Activate the same user twice should not raise an error active_user = users.activate_user(user_id) assert active_user.user_id == user_id assert active_user.name == username assert active_user.api_key is not None
def test_reset_password(database): """Test resetting a user password.""" # -- Setup ---------------------------------------------------------------- # # Create one active user. username = '******' password = '******' with database.session() as session: # After a reset request has been send the previous password should # still be valid. users = UserManager(session) auth = OpenAccessAuth(session) user_id = users.register_user(username, password).user_id # -- Test reset password -------------------------------------------------- with database.session() as session: users = UserManager(session) auth = OpenAccessAuth(session) # Ensure login works prior to reset request. token = users.login_user(username, password).api_key.value assert auth.authenticate(token).user_id == user_id request_id = users.request_password_reset(username) password = '******' user = users.reset_password(request_id=request_id, password=password) assert user.user_id == user_id # After resetting the password the previous API key for the user is # invalid with pytest.raises(err.UnauthenticatedAccessError): auth.authenticate(token) token = users.login_user('*****@*****.**', 'mypwd').api_key.value assert auth.authenticate(token).user_id == user_id # -- Test login after request --------------------------------------------- with database.session() as session: # After a reset request has been send the previous password should # still be valid. users = UserManager(session) auth = OpenAccessAuth(session) users.request_password_reset(username) token = users.login_user(username, password).api_key.value assert auth.authenticate(token).user_id == user_id # -- Test request reset for unknown user ---------------------------------- with database.session() as session: users = UserManager(session) assert users.request_password_reset('*****@*****.**') is not None # --Error cases ----------------------------------------------------------- with database.session() as session: # An error is raised when (i) trying to use a request for an unknown # user, (ii) a previously completed reset request, or (iii) an unknown # request identifier to reset a user password users = UserManager(session) with pytest.raises(err.UnknownRequestError): users.reset_password(request_id=request_id, password=password) with pytest.raises(err.UnknownRequestError): users.reset_password(request_id='UNKNOWN', password=password) with pytest.raises(err.UnknownRequestError): users.reset_password(request_id='unknown', password=password)
def test_login_after_timeout(database, authcls): """Test login after key expired.""" # -- Setup ---------------------------------------------------------------- # # Create a database with a single active user. with database.session() as session: user_1 = model.create_user(session, active=True) # Test login after timeout ----------------------------------------- with database.session() as session: # Create user manager with TTL for login tokens of 1 sec. users = UserManager(session, token_timeout=1) # Authenticate user 1. Then sleep for 1.5 sec. When logging in again an # new api-key is generated. api_key = users.login_user(user_1, user_1).api_key.value time.sleep(1.5) assert users.login_user(user_1, user_1).api_key.value != api_key
def test_register_user(database): """Test registering a new user.""" # -- Test creating an active user ----------------------------------------- with database.session() as session: users = UserManager(session) auth = OpenAccessAuth(session) reg_user = users.register_user('*****@*****.**', 'pwd1') assert reg_user.api_key is None user_1 = users.login_user('*****@*****.**', 'pwd1') assert user_1.name == '*****@*****.**' user_id_1 = auth.authenticate(user_1.api_key.value).user_id assert user_1.user_id == user_id_1 # -- Error cases ---------------------------------------------------------- with database.session() as session: users = UserManager(session) # Register user with existing email address raises error with pytest.raises(err.DuplicateUserError): users.register_user('*****@*****.**', 'pwd1') # Providing invalid email or password will raise error with pytest.raises(err.ConstraintViolationError): users.register_user(None, 'pwd1') with pytest.raises(err.ConstraintViolationError): users.register_user(' \t', 'pwd1') with pytest.raises(err.ConstraintViolationError): users.register_user('a' * 513, 'pwd1') with pytest.raises(err.ConstraintViolationError): users.register_user('*****@*****.**', ' ')
def test_user_handle_serialization(database): """Test serialization of user handles.""" schema = validator('User') view = UserSerializer() with database.session() as session: manager = UserManager(session) user = manager.register_user('alice', 'mypwd') doc = view.user(user) schema.validate(doc) assert doc[labels.USER_NAME] == 'alice' assert labels.USER_TOKEN not in doc user = manager.login_user('alice', 'mypwd') doc = view.user(user, include_token=True) schema.validate(doc) assert doc[labels.USER_NAME] == 'alice' assert labels.USER_TOKEN in doc
def test_authenticate_after_timeout(database, authcls): """Test authentication after key expired.""" # -- Setup ---------------------------------------------------------------- # # Create a database with a single active user. with database.session() as session: user_1 = model.create_user(session, active=True) # Test authenticate after timeout ----------------------------------------- with database.session() as session: # Create user manager with TTL for login tokens of 1 sec. users = UserManager(session, token_timeout=1) auth = authcls(session) # Authenticate user 1. Then sleep for 1.5 sec. Trying to authenticate # the user after the sleep period should raise an error. api_key = users.login_user(user_1, user_1).api_key.value time.sleep(1.5) with pytest.raises(err.UnauthenticatedAccessError): auth.authenticate(api_key)
def test_authenticate_user(database, authcls): """Test user login and logout. Uses a database with two active and one inactive user to validate that active users can login and logout while inactive users cannot login. """ # -- Setup ---------------------------------------------------------------- # # Create a database with two active and one inactive users. with database.session() as session: user_1 = model.create_user(session, active=True) user_2 = model.create_user(session, active=True) user_3 = model.create_user(session, active=False) # -- Test login ----------------------------------------------------------- with database.session() as session: users = UserManager(session) token_1 = users.login_user(user_1, user_1).api_key.value token_2 = users.login_user(user_2, user_2).api_key.value # -- Test authentication -------------------------------------------------- with database.session() as session: auth = authcls(session) # Authentication of logged-in users using the API key should return the # respective user identifier. assert auth.authenticate(token_1).user_id == user_1 assert auth.authenticate(token_2).user_id == user_2 # -- Test logout ---------------------------------------------------------- with database.session() as session: # Logout user 1. User 2 should still be able to authenticate while a # user that is logged out cannot. users = UserManager(session) auth = authcls(session) assert users.logout_user(token_1).user_id == user_1 # Authenticating user 1 will raise exception. with pytest.raises(err.UnauthenticatedAccessError): auth.authenticate(token_1) # Logging out a user that is not logged in will not raise error> assert users.logout_user(token_1) is None # User 2 can still authenticate. assert auth.authenticate(token_2).user_id == user_2 # -- Test re-login -------------------------------------------------------- with database.session() as session: # Login user 1 again. users = UserManager(session) auth = authcls(session) token_1 = users.login_user(user_1, user_1).api_key.value # User 1 and 2 can now be authenticated again. assert auth.authenticate(token_1).user_id == user_1 assert auth.authenticate(token_2).user_id == user_2 # If a logged in user logs in the previous key does not become invalid. token_3 = users.login_user(user_1, user_1).api_key.value assert auth.authenticate(token_1).user_id == user_1 assert auth.authenticate(token_3).user_id == user_1 # -- Error cases ---------------------------------------------------------- with database.session() as session: users = UserManager(session) auth = authcls(session) # Attempt to authenticate unknown user raises error with pytest.raises(err.UnknownUserError): users.login_user('unknown', user_1) # Attempt to authenticate with invalid password will raises error with pytest.raises(err.UnknownUserError): users.login_user(user_1, user_2) # Inactive user 3 should not be able to login. with pytest.raises(err.UnknownUserError): users.login_user(user_3, user_3) # An error is raised when using an invalid API key. with pytest.raises(err.UnauthenticatedAccessError): assert auth.authenticate('UNKNOWN')