From 3ae3e5c55b1e1d20784dbb76380462d149fd74c5 Mon Sep 17 00:00:00 2001 From: apiyo Date: Tue, 25 Jul 2023 14:09:18 +0300 Subject: [PATCH] Ensure PROJECT_INVITATION_URL setting works for multipe domains --- docs/projects.rst | 2 +- .../tests/viewsets/test_project_viewset.py | 39 +++++++++++++++++-- onadata/libs/tests/utils/test_email.py | 22 +++++++++-- onadata/libs/utils/email.py | 7 +++- 4 files changed, 61 insertions(+), 9 deletions(-) diff --git a/docs/projects.rst b/docs/projects.rst index 677f76ae1e..f25f20d941 100644 --- a/docs/projects.rst +++ b/docs/projects.rst @@ -650,7 +650,7 @@ adding the setting ``PROJECT_INVITATION_URL`` :: - PROJECT_INVITATION_URL = 'https://example.com/register' + PROJECT_INVITATION_URL = {'*': 'https://example.com/register'} Update a project invitation diff --git a/onadata/apps/api/tests/viewsets/test_project_viewset.py b/onadata/apps/api/tests/viewsets/test_project_viewset.py index 7bea96d600..0e00a3c0eb 100644 --- a/onadata/apps/api/tests/viewsets/test_project_viewset.py +++ b/onadata/apps/api/tests/viewsets/test_project_viewset.py @@ -2841,7 +2841,13 @@ def test_only_admins_allowed(self, mock_send_mail): else: self.assertEqual(response.status_code, 403) - @override_settings(PROJECT_INVITATION_URL="https://example.com/register") + @override_settings( + PROJECT_INVITATION_URL={ + "*": "https://example.com/register", + "onadata.com": "https://onadata.com/register", + } + ) + @override_settings(ALLOWED_HOSTS=["*"]) def test_create_invitation(self, mock_send_mail): """Project invitation can be created""" post_data = { @@ -2882,6 +2888,31 @@ def test_create_invitation(self, mock_send_mail): response = self.view(request, pk=self.project.pk) self.assertEqual(response.status_code, 400) + # Project invitations are created for non-default host + request = self.factory.post( + "/", + data=json.dumps(post_data), + content_type="application/json", + **self.extra, + ) + request.META["HTTP_HOST"] = "onadata.com" + response = self.view(request, pk=self.project.pk) + self.assertEqual(response.status_code, 200) + self.assertEqual(self.project.invitations.count(), 1) + invitation = self.project.invitations.first() + self.assertEqual( + response.data, + { + "id": invitation.pk, + "email": "janedoe@example.com", + "role": "editor", + "status": 1, + }, + ) + mock_send_mail.assert_called_once_with( + invitation.pk, "https://example.com/register" + ) + def test_email_required(self, mock_send_mail): """email is required""" # blank string @@ -3073,7 +3104,7 @@ def test_only_admins_allowed(self, mock_send_mail): else: self.assertEqual(response.status_code, 403) - @override_settings(PROJECT_INVITATION_URL="https://example.com/register") + @override_settings(PROJECT_INVITATION_URL={"*": "https://example.com/register"}) def test_update(self, mock_send_mail): """We can update an invitation""" payload = { @@ -3133,7 +3164,7 @@ def test_update_role_only(self, mock_send_mail): ) mock_send_mail.assert_not_called() - @override_settings(PROJECT_INVITATION_URL="https://example.com/register") + @override_settings(PROJECT_INVITATION_URL={"*": "https://example.com/register"}) def test_update_email_only(self, mock_send_mail): """We can update email only""" payload = { @@ -3351,7 +3382,7 @@ def test_only_admins_allowed(self, mock_send_mail): mock_send_mail.assert_not_called() - @override_settings(PROJECT_INVITATION_URL="https://example.com/register") + @override_settings(PROJECT_INVITATION_URL={"*": "https://example.com/register"}) def test_resend_invite(self, mock_send_mail): """Invitation is revoked""" invitation = self.project.invitations.create( diff --git a/onadata/libs/tests/utils/test_email.py b/onadata/libs/tests/utils/test_email.py index 12cc55c9e5..81a9e94e28 100644 --- a/onadata/libs/tests/utils/test_email.py +++ b/onadata/libs/tests/utils/test_email.py @@ -26,7 +26,7 @@ def setUp(self): @override_settings( VERIFICATION_URL={ - "stage-testserver": 'https://stage-testserver/email-verification-confirmation', + "stage-testserver": "https://stage-testserver/email-verification-confirmation", "*": None, } ) @@ -89,7 +89,10 @@ def test_get_verification_url(self): self.assertEqual( verification_url, - ("https://stage-testserver/email-verification-confirmation?%s" % string_query_params) + ( + "https://stage-testserver/email-verification-confirmation?%s" + % string_query_params + ), ) def _get_email_data(self, include_redirect_url=False): @@ -215,12 +218,25 @@ def setUp(self): self.custom_request = RequestFactory().get("/path", data={"name": "test"}) - @override_settings(PROJECT_INVITATION_URL="https://example.com/register") + @override_settings(PROJECT_INVITATION_URL={"*": "https://example.com/register"}) def test_url_configured(self): """settings.PROJECT_INVITATION_URL is set""" url = get_project_invitation_url(self.custom_request) self.assertEqual(url, "https://example.com/register") + @override_settings( + PROJECT_INVITATION_URL={ + "*": "https://example.com/register", + "new-domain.com": "https://new-domain.com/register", + } + ) + @override_settings(ALLOWED_HOSTS=["*"]) + def test_url_configured(self): + """settings.PROJECT_INVITATION_URL is set""" + self.custom_request.META["HTTP_HOST"] = "new-domain.com" + url = get_project_invitation_url(self.custom_request) + self.assertEqual(url, "https://new-domain.com/register") + def test_url_not_configured(self): """settings.PROJECT_INVITATION_URL not set""" url = get_project_invitation_url(self.custom_request) diff --git a/onadata/libs/utils/email.py b/onadata/libs/utils/email.py index 559d3c699d..0a4fb035bc 100644 --- a/onadata/libs/utils/email.py +++ b/onadata/libs/utils/email.py @@ -95,7 +95,12 @@ def send_generic_email(email, message_txt, subject): def get_project_invitation_url(request: HttpRequest): """Get project invitation url""" - url: str = getattr(settings, "PROJECT_INVITATION_URL", "") + invitation_url_setting: dict = getattr(settings, "PROJECT_INVITATION_URL", {}) + + site_domain = request.get_host() + url = ( + site_domain in invitation_url_setting and invitation_url_setting[site_domain] + ) or ("*" in invitation_url_setting and invitation_url_setting["*"]) if not url: url = reverse("userprofile-list", request=request)