diff --git a/notifications_routing/authorization_service.py b/notifications_routing/authorization_service.py index 8db4213e8492f9dd25606faa873191b3a9e8bad8..5810e10fa1c1008623a9074f7e35141cb9504910 100644 --- a/notifications_routing/authorization_service.py +++ b/notifications_routing/authorization_service.py @@ -26,10 +26,26 @@ def get_group_users_api(group_id: str): token = get_auth_access_token() headers = {"Authorization": "Bearer {}".format(token)} - url = os.path.join(config.Config.CERN_GROUP_URL, group_id, config.Config.CERN_GROUP_QUERY) - response = requests.get(url, headers=headers) + def _get_group_users(url: str = None): + if not url: + url = os.path.join( + config.Config.CERN_AUTH_SERVICE_URL, + config.Config.CERN_GROUP_URL, + group_id, + config.Config.CERN_GROUP_QUERY, + ) - if response.status_code != requests.codes.ok: - raise BadResponseCodeError(url, status_code=response.status_code) + r = requests.get(url, headers=headers) + if r.status_code != requests.codes.ok: + raise BadResponseCodeError(url, status_code=r.status_code) - return json.loads(response.content) + return json.loads(r.content) + + response = _get_group_users() + data = response["data"] + + while response.get("pagination").get("next"): + response = _get_group_users(response["pagination"]["next"]) + data.extend(response["data"]) + + return data diff --git a/notifications_routing/config.py b/notifications_routing/config.py index 90d773e7fa34cf9e096f8fcdf03e8af604ac1d86..dc52ba5e8c95cca90d86a8f4ad6302176b7b3fb5 100644 --- a/notifications_routing/config.py +++ b/notifications_routing/config.py @@ -29,7 +29,8 @@ class Config: f"grant_type=client_credentials&client_id={CERN_OIDC_CLIENT_ID}" f"&client_secret={CERN_OIDC_CLIENT_SECRET}&audience=authorization-service-api", ) - CERN_GROUP_URL = os.getenv("CERN_GROUP_URL", "https://authorization-service-api.web.cern.ch/api/v1.0/Group") + CERN_AUTH_SERVICE_URL = "https://authorization-service-api.web.cern.ch" + CERN_GROUP_URL = os.getenv("CERN_GROUP_URL", "/api/v1.0/Group") CERN_GROUP_QUERY = os.getenv( "CERN_GROUP_QUERY", "memberidentities/precomputed?field=upn&field=primaryAccountEmail" "&field=unconfirmed&field=unconfirmedEmail", diff --git a/notifications_routing/data_source/postgres/postgres_data_source.py b/notifications_routing/data_source/postgres/postgres_data_source.py index 8e5fd6fd2257efafa8741c6e518ce468b076bc0a..14f9264d720ead1640e11b3df4e11a37d6162237 100644 --- a/notifications_routing/data_source/postgres/postgres_data_source.py +++ b/notifications_routing/data_source/postgres/postgres_data_source.py @@ -171,9 +171,7 @@ class PostgresDataSource(DataSource): """ group_users = [] - content = get_group_users_api(group_id) - members = content["data"] - + members = get_group_users_api(group_id) for member in members: if member["unconfirmed"]: user = {DataSource.USERNAME: member["unconfirmedEmail"], DataSource.EMAIL: member["unconfirmedEmail"]} diff --git a/tests/unit/test_authorization_service.py b/tests/unit/test_authorization_service.py new file mode 100644 index 0000000000000000000000000000000000000000..f72d8266d918213fc95966d02baf0796d1d043b9 --- /dev/null +++ b/tests/unit/test_authorization_service.py @@ -0,0 +1,82 @@ +"""Unit Tests for the Auth service.""" +import json +from unittest import mock +from unittest.mock import call + +import pytest +import requests + +from notifications_routing.authorization_service import get_group_users_api + + +class MockResponse: + """Mock class for requests responses.""" + + def __init__(self, json_data, status_code): + """Initialize the class.""" + self.json_data = json_data + self.status_code = status_code + + @property + def content(self): + """Mock content property.""" + return json.dumps(self.json_data) + + +@pytest.fixture(scope="function") +def auth_user_1(): + """Auth user dict.""" + return { + "primaryAccountEmail": "user1@cern.ch", + "upn": "user1", + "unconfirmed": False, + "unconfirmedEmail": None, + "id": "dcb3e437-a27e-4193-a2b9-ba4eea55f315", + } + + +@pytest.fixture(scope="function") +def auth_user_2(): + """Auth user dict.""" + return { + "primaryAccountEmail": "user2@cern.ch", + "upn": "user2", + "unconfirmed": False, + "unconfirmedEmail": None, + "id": "dcb3e437-a27e-4193-a2b9-ba4eea55f315", + } + + +@pytest.fixture(scope="function") +def auth_user_3(): + """Auth user dict.""" + return { + "primaryAccountEmail": "user3@cern.ch", + "upn": "user3", + "unconfirmed": False, + "unconfirmedEmail": None, + "id": "dcb3e437-a27e-4193-a2b9-ba4eea55f315", + } + + +@mock.patch("notifications_routing.authorization_service.get_auth_access_token") +@mock.patch.object(requests, "get") +def test_process_users(mock_get, mock_get_token, appctx, auth_user_1, auth_user_2, auth_user_3): + """Test process users for normal.""" + mock_get_token.return_value = "jwt" + mock_get.side_effect = [ + MockResponse({"pagination": {"next": "next/url/page"}, "data": [auth_user_1, auth_user_2]}, 200), + MockResponse({"pagination": {"next": None}, "data": [auth_user_3]}, 200), + ] + + result = get_group_users_api("group_id") + assert result == [auth_user_1, auth_user_2, auth_user_3] + mock_get_token.assert_called_once() + expected_first_call_url = ( + "/api/v1.0/Group/group_id/memberidentities/precomputed?field=upn&field" + "=primaryAccountEmail&field=unconfirmed&field=unconfirmedEmail" + ) + expected_headers = {"Authorization": "Bearer jwt"} + mock_get.assert_has_calls( + [call(expected_first_call_url, headers=expected_headers), call("next/url/page", headers=expected_headers)] + ) diff --git a/tests/unit/test_postgres_data_source.py b/tests/unit/test_postgres_data_source.py index a6c03eb16be6d74f9baf087a35b15789fd869682..c7f70fd29b1018d1fa134bd3f27b9c024b9c3c4e 100644 --- a/tests/unit/test_postgres_data_source.py +++ b/tests/unit/test_postgres_data_source.py @@ -135,22 +135,21 @@ def test_get_channel_unsubscribed_users_(mock_get_scalar, db_mock, channel): @mock.patch("notifications_routing.data_source.postgres.postgres_data_source.get_group_users_api") def test_get_group_users(mock_get_group_users_api, db_mock): """Test get group users.""" - mock_get_group_users_api.return_value = { - "data": [ - { - "upn": "testuser", - "primaryAccountEmail": "testuser@cern.ch", - "unconfirmed": False, - "unconfirmedEmail": None, - }, - { - "upn": None, - "primaryAccountEmail": None, - "unconfirmed": True, - "unconfirmedEmail": "unconfirmedEmail@mail.ch", - }, - ] - } + mock_get_group_users_api.return_value = [ + { + "upn": "testuser", + "primaryAccountEmail": "testuser@cern.ch", + "unconfirmed": False, + "unconfirmedEmail": None, + }, + { + "upn": None, + "primaryAccountEmail": None, + "unconfirmed": True, + "unconfirmedEmail": "unconfirmedEmail@mail.ch", + }, + ] + assert db_mock.get_group_users("186d8dfc-2774-43a8-91b5-a887fcb6ba4a") == [ {"username": "testuser", "email": "testuser@cern.ch"}, {"username": "unconfirmedEmail@mail.ch", "email": "unconfirmedEmail@mail.ch"},