def test_blocked_user(mocker: pytest_mock.MockFixture, client: testing.FlaskClient): mocker.patch("app.auth.routes.oauth.google.authorize_access_token") mocker.patch("app.auth.routes.oauth.google.parse_id_token") oauth.google.authorize_access_token.return_value = { "access_token": "TOKEN" } oauth.google.parse_id_token.return_value = UserInfo(blocked_user_info()) resp = client.get("/auth/authorized") assert resp.status_code == 302 assert resp.headers.get("Location") == "http://localhost/" oauth.google.authorize_access_token.assert_called_once() oauth.google.parse_id_token.assert_called_once_with( {"access_token": "TOKEN"}) with client.session_transaction() as session: assert "user_info" in session resp = client.get("/") assert resp.status_code == 200 with client.session_transaction() as session: assert "user_info" not in session
def test_superadmin_callback( client: FlaskClient, org_id: str, # pylint: disable=unused-argument ): with patch.object(auth0_sa, "authorize_access_token", return_value=None): mock_response = Mock() mock_response.json = MagicMock(return_value={"email": SA_EMAIL}) with patch.object(auth0_sa, "get", return_value=mock_response): rv = client.get("/auth/superadmin/callback?code=foobar") assert rv.status_code == 302 assert urlparse(rv.location).path == "/superadmin/" with client.session_transaction() as session: # type: ignore assert session["_superadmin"] is True assert_is_date(session["_created_at"]) assert datetime.now(timezone.utc) - datetime.fromisoformat( session["_created_at"]) < timedelta(seconds=1) assert_is_date(session["_last_request_at"]) assert datetime.now(timezone.utc) - datetime.fromisoformat( session["_last_request_at"]) < timedelta(seconds=1) assert list(session.keys()) == [ "_created_at", "_last_request_at", "_superadmin", ] assert auth0_sa.authorize_access_token.called assert auth0_sa.get.called
def set_logged_in_user( client: FlaskClient, user_type: UserType, user_key=DEFAULT_AA_EMAIL, from_superadmin=False, ): with client.session_transaction() as session: # type: ignore auth_lib.set_loggedin_user(session, user_type, user_key, from_superadmin)
def as_user(client: testing.FlaskClient): ui = regular_user_info() with client.session_transaction() as session: session["user_info"] = ui user = User(full_name=ui["name"], login=ui["email"], profile_picture=ui["picture"]) user.roles = [ Role(name=PredefinedRoles.USER), ] return user
def store_user_id_in_session(client: FlaskClient, user: ci_demo.User) -> None: """ Stores the id of the given user in the session to emulate a logged in user. :param client: The client that holds the session. :param user: The user to be stored in the session. :return: Nothing. """ with client.session_transaction() as sess: sess['user_id'] = user.id
def test_logout(client: FlaskClient, aa_email: str): set_logged_in_user(client, UserType.AUDIT_ADMIN, aa_email) set_superadmin(client) with client.session_transaction() as session: # type: ignore previous_session = session.copy() rv = client.get("/auth/logout") assert rv.status_code == 302 with client.session_transaction() as session: # type: ignore assert session["_user"] is None assert "_superadmin" not in session.keys() assert session["_created_at"] == previous_session["_created_at"] assert (datetime.fromisoformat(session["_last_request_at"]) - datetime.fromisoformat(previous_session["_last_request_at"]) ) < timedelta(seconds=1) # logging out a second time should not cause an error rv = client.get("/auth/logout") assert rv.status_code == 302
def test_audit_board_log_in( client: FlaskClient, election_id: str, audit_board_id: str, ): audit_board = AuditBoard.query.get(audit_board_id) rv = client.get(f"/auditboard/{audit_board.passphrase}") assert rv.status_code == 302 location = urlparse(rv.location) assert location.path == f"/election/{election_id}/audit-board/{audit_board.id}" with client.session_transaction() as session: # type: ignore assert session["_user"]["type"] == UserType.AUDIT_BOARD assert session["_user"]["key"] == audit_board.id
def as_user(client: testing.FlaskClient): ui = regular_user_info() with client.session_transaction() as session: session['user_info'] = ui user = User(full_name=ui['name'], email=ui['email'], profile_picture=ui['picture']) user.roles = [ Role(name=PredefinedRoles.USER), ] return user
def test_logout(client: FlaskClient, aa_email: str): set_logged_in_user(client, UserType.AUDIT_ADMIN, aa_email) set_superadmin(client) rv = client.get("/auth/logout") assert rv.status_code == 302 with client.session_transaction() as session: # type: ignore assert session["_user"] is None assert "_superadmin" not in session.keys() # logging out a second time should not cause an error rv = client.get("/auth/logout") assert rv.status_code == 302
def as_admin(client: testing.FlaskClient): ui = admin_user_info() with client.session_transaction() as session: session['user_info'] = ui session['google_token'] = 'testing-admin' user = User(full_name=ui['name'], email=ui['email'], profile_picture=ui['picture']) user.roles = [ Role(name=PredefinedRoles.ADMIN), Role(name=PredefinedRoles.REVIEWER), Role(name=PredefinedRoles.USER), ] return user
def test_jurisdictionadmin_callback(client: FlaskClient, ja_email: str): with patch.object(auth0_ja, "authorize_access_token", return_value=None): mock_response = Mock() mock_response.json = MagicMock(return_value={"email": ja_email}) with patch.object(auth0_ja, "get", return_value=mock_response): rv = client.get("/auth/jurisdictionadmin/callback?code=foobar") assert rv.status_code == 302 with client.session_transaction() as session: # type: ignore assert session["_user"]["type"] == UserType.JURISDICTION_ADMIN assert session["_user"]["key"] == ja_email assert auth0_ja.authorize_access_token.called assert auth0_ja.get.called
def test_auditadmin_callback(client: FlaskClient, aa_email: str): auth0_aa.authorize_access_token = MagicMock(return_value=None) mock_response = Mock() mock_response.json = MagicMock(return_value={"email": aa_email}) auth0_aa.get = Mock(return_value=mock_response) rv = client.get("/auth/auditadmin/callback?code=foobar") assert rv.status_code == 302 with client.session_transaction() as session: # type: ignore assert session["_user"]["type"] == UserType.AUDIT_ADMIN assert session["_user"]["key"] == aa_email assert auth0_aa.authorize_access_token.called assert auth0_aa.get.called
def test_superadmin_callback( client: FlaskClient, org_id: str, # pylint: disable=unused-argument ): with patch.object(auth0_sa, "authorize_access_token", return_value=None): mock_response = Mock() mock_response.json = MagicMock(return_value={"email": SA_EMAIL}) with patch.object(auth0_sa, "get", return_value=mock_response): rv = client.get("/auth/superadmin/callback?code=foobar") assert rv.status_code == 302 assert urlparse(rv.location).path == "/superadmin/" with client.session_transaction() as session: # type: ignore assert session["_superadmin"] assert list(session.keys()) == ["_superadmin"] assert auth0_sa.authorize_access_token.called assert auth0_sa.get.called
def test_superadmin_callback_rejected( client: FlaskClient, org_id: str, # pylint: disable=unused-argument ): bad_user_infos: List[Optional[JSONDict]] = [None, {}, {"email": AA_EMAIL}] for bad_user_info in bad_user_infos: with patch.object(auth0_sa, "authorize_access_token", return_value=None): mock_response = Mock() mock_response.json = MagicMock(return_value=bad_user_info) with patch.object(auth0_sa, "get", return_value=mock_response): rv = client.get("/auth/superadmin/callback?code=foobar") assert rv.status_code == 302 assert urlparse(rv.location).path == "/" with client.session_transaction() as session: # type: ignore assert "_superadmin" not in session assert auth0_sa.authorize_access_token.called assert auth0_sa.get.called
def test_audit_board_log_in( client: FlaskClient, election_id: str, audit_board_id: str, ): audit_board = AuditBoard.query.get(audit_board_id) rv = client.get(f"/auditboard/{audit_board.passphrase}") assert rv.status_code == 302 location = urlparse(rv.location) assert location.path == f"/election/{election_id}/audit-board/{audit_board.id}" with client.session_transaction() as session: # type: ignore assert session["_user"]["type"] == UserType.AUDIT_BOARD assert session["_user"]["key"] == audit_board.id assert_is_date(session["_created_at"]) assert (datetime.now(timezone.utc) - datetime.fromisoformat( session["_created_at"])) < timedelta(seconds=1) assert_is_date(session["_last_request_at"]) assert (datetime.now(timezone.utc) - datetime.fromisoformat( session["_last_request_at"])) < timedelta(seconds=1)
def test_jurisdictionadmin_callback(client: FlaskClient, ja_email: str): with patch.object(auth0_ja, "authorize_access_token", return_value=None): mock_response = Mock() mock_response.json = MagicMock(return_value={"email": ja_email}) with patch.object(auth0_ja, "get", return_value=mock_response): rv = client.get("/auth/jurisdictionadmin/callback?code=foobar") assert rv.status_code == 302 with client.session_transaction() as session: # type: ignore assert session["_user"]["type"] == UserType.JURISDICTION_ADMIN assert session["_user"]["key"] == ja_email assert_is_date(session["_created_at"]) assert (datetime.now(timezone.utc) - datetime.fromisoformat( session["_created_at"])) < timedelta(seconds=1) assert_is_date(session["_last_request_at"]) assert (datetime.now(timezone.utc) - datetime.fromisoformat( session["_last_request_at"])) < timedelta(seconds=1) assert auth0_ja.authorize_access_token.called assert auth0_ja.get.called
def set_superadmin(client: FlaskClient): with client.session_transaction() as session: # type: ignore session[_SUPERADMIN] = True
def clear_superadmin(client: FlaskClient): with client.session_transaction() as session: # type: ignore if _SUPERADMIN in session: del session[_SUPERADMIN]
def set_logged_in_user( client: FlaskClient, user_type: UserType, user_key=DEFAULT_AA_EMAIL ): with client.session_transaction() as session: # type: ignore session[_USER] = {"type": user_type, "key": user_key}
def clear_logged_in_user(client: FlaskClient): with client.session_transaction() as session: # type: ignore session[_USER] = None
def clear_superadmin(client: FlaskClient): with client.session_transaction() as session: # type: ignore auth_lib.clear_superadmin(session)
def clear_logged_in_user(client: FlaskClient): with client.session_transaction() as session: # type: ignore auth_lib.clear_loggedin_user(session)
def login_admin(admin_user: User, client: FlaskClient) -> User: with client.session_transaction() as session: session["_user_id"] = admin_user.id return admin_user
def login_admin(admin_user: User, client: FlaskClient) -> User: # pyre-fixme[16]: Optional type has no attribute `__enter__`. with client.session_transaction() as session: session["user_id"] = admin_user.id return admin_user
def logged_in_user(create_remove_user: str, client: testing.FlaskClient) -> None: with client.session_transaction() as session: # type: ignore session["user_id"] = create_remove_user session["_fresh"] = True
class TestHome(unittest.TestCase): """ Test base Flask application Home. """ def setUp(self): app.testing = True self.client = FlaskClient(app, response_wrapper=FormWrapper) def tearDown(self): pass def test_000_page_index_get(self): """ 200, OK: GET / """ result = self.client.get('/') self.assertEqual(result.status_code, 200) def test_000_page_index_post(self): """ 405, Method not allowed: POST / """ result = self.client.post('/') self.assertEqual(result.status_code, 405) def test_001_page_login_get(self): """ 200, OK: GET /login """ result = self.client.get('/login') self.assertEqual(result.status_code, 200) def test_001_page_login_post(self): """ 405, Method not allowed: POST /login """ result = self.client.post('/login') self.assertEqual(result.status_code, 405) def test_002_page_login_get(self): """ 200, OK: GET /login (with session transaction) """ with self.client.session_transaction(): result = self.client.get('/login') self.assertTrue('Set-Cookie' in result.headers) self.assertEqual(result.status_code, 200) def test_002_page_login_post(self): """ 405, Method not allowed: POST /login (with session transaction) """ with self.client.session_transaction(): result = self.client.post('/login') self.assertEqual(result.status_code, 405) def test_003_page_login_email_get(self): """ 200, OK: GET /login/email (with session transaction) """ with self.client.session_transaction(): result = self.client.get('/login/email') self.assertTrue('Set-Cookie' in result.headers) self.assertEqual(result.status_code, 200) def test_004_page_login_otp(self): """ 302, Found: GET /login/otp """ result = self.client.get('/login/otp') self.assertEqual(result.status_code, 302) def test_004_page_login_otp_get(self): """ 302, Found: GET /login/otp (with session transaction) """ with self.client.session_transaction(): result = self.client.get('/login/otp') self.assertEqual(result.status_code, 302) def test_005_page_login_complete(self): """ 403, Access denied: GET /login/complete """ with self.client.session_transaction(): result = self.client.get('/login/complete') self.assertEqual(result.status_code, 403) def test_006_page_login_wait(self): """ 403, Access denied: GET /login/wait """ with self.client.session_transaction(): result = self.client.get('/login/wait') self.assertEqual(result.status_code, 403) def test_007_login_sequence_csrf(self): """ Verify a fixture's login sequence without csrf fails. """ with self.client.session_transaction(): result = self.client.get('/login') self.assertEqual(result.status_code, 200) result = self.client.get('/login/email') self.assertEqual(result.status_code, 200) result.form.fields['email_address'] = '*****@*****.**' result.form.fields['password'] = '******' result.form.fields['csrf_token'] = "invalid" result = result.form.submit(self.client, path='/login/email', method='POST') self.assertEqual(result.status_code, 302) self.assertEqual(result.headers['Location'], "http://localhost/login") def test_007_login_sequence_uuid(self): """ Verify a fixture's login sequence with invalid UUID fails. """ with self.client.session_transaction(): result = self.client.get('/login') self.assertEqual(result.status_code, 200) result = self.client.get('/login/email') self.assertEqual(result.status_code, 200) result.form.fields['email_address'] = '*****@*****.**' result.form.fields['password'] = '******' result.form.fields['uuid'] = "invalid" result = result.form.submit(self.client, path='/login/email', method='POST') self.assertEqual(result.status_code, 403) def test_007_login_sequence_invalid(self): """ Verify a fixture's login sequence with false password. """ with self.client.session_transaction(): result = self.client.get('/login') self.assertEqual(result.status_code, 200) result = self.client.get('/login/email') self.assertEqual(result.status_code, 200) result.form.fields['email_address'] = '*****@*****.**' result.form.fields['password'] = '******' result = result.form.submit(self.client, path='/login/email', method='POST') self.assertEqual(result.status_code, 302) self.assertEqual(result.headers['Location'], "http://localhost/login/wait") result = self.client.get('/login/wait') self.assertEqual(result.status_code, 200) def test_007_login_sequence_valid(self): """ Verify a fixture's login sequence. """ with self.client.session_transaction(): result = self.client.get('/login') self.assertEqual(result.status_code, 200, '/login') result = self.client.get('/login/email') self.assertEqual(result.status_code, 200, '/login/email') result.form.fields['email_address'] = '*****@*****.**' result.form.fields['password'] = '******' result = result.form.submit(self.client, path='/login/email', method='POST') self.assertEqual(result.status_code, 302) self.assertEqual(result.headers['Location'], "http://localhost/login/wait") result = self.client.get('/login/wait') self.assertEqual(result.status_code, 200)
def login_admin(admin_user: User, client: FlaskClient) -> User: with client.session_transaction() as session: session["user_id"] = admin_user.id return admin_user