You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ma...@apache.org on 2019/12/12 23:18:46 UTC
[airavata-django-portal] 06/07: AIRAVATA-3243 Send one email when
user added to multiple groups at once
This is an automated email from the ASF dual-hosted git repository.
machristie pushed a commit to branch airavata-3243
in repository https://gitbox.apache.org/repos/asf/airavata-django-portal.git
commit a7452b4261effc99005cfa7990a636c6e8397493
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Thu Dec 12 16:58:06 2019 -0500
AIRAVATA-3243 Send one email when user added to multiple groups at once
---
django_airavata/apps/api/signals.py | 2 +-
django_airavata/apps/api/tests.py | 119 ++++++++++++++++++++-
django_airavata/apps/api/views.py | 21 ++--
.../auth/migrations/0005_auto_20191211_2011.py | 12 +--
django_airavata/apps/auth/signals.py | 4 +-
django_airavata/apps/auth/tests.py | 42 +++++++-
6 files changed, 177 insertions(+), 23 deletions(-)
diff --git a/django_airavata/apps/api/signals.py b/django_airavata/apps/api/signals.py
index e9abfee..f01df92 100644
--- a/django_airavata/apps/api/signals.py
+++ b/django_airavata/apps/api/signals.py
@@ -11,7 +11,7 @@ log = logging.getLogger(__name__)
# Signals
-user_added_to_group = Signal(providing_args=["user", "group", "request"])
+user_added_to_group = Signal(providing_args=["user", "groups", "request"])
# Receivers
diff --git a/django_airavata/apps/api/tests.py b/django_airavata/apps/api/tests.py
index b682ddb..bb52a9f 100644
--- a/django_airavata/apps/api/tests.py
+++ b/django_airavata/apps/api/tests.py
@@ -1,4 +1,4 @@
-from unittest.mock import MagicMock, patch
+from unittest.mock import MagicMock, call, patch
from django.contrib.auth.models import User
from django.test import TestCase, override_settings
@@ -76,7 +76,7 @@ class GroupViewSetTests(TestCase):
self.assertEquals("abc123", response.data['id'])
user_added_to_group_handler.assert_called_once()
args, kwargs = user_added_to_group_handler.call_args
- self.assertEquals("abc123", kwargs["group"].id)
+ self.assertEquals("abc123", kwargs["groups"][0].id)
self.assertIs(user_profile, kwargs["user"])
def test_update_group_sends_user_added_to_group_signal(self):
@@ -159,7 +159,7 @@ class GroupViewSetTests(TestCase):
user_added_to_group_handler.assert_called_once()
args, kwargs = user_added_to_group_handler.call_args
- self.assertEquals("abc123", kwargs["group"].id)
+ self.assertEquals("abc123", kwargs["groups"][0].id)
self.assertIs(user_profile, kwargs["user"])
@@ -271,4 +271,115 @@ class IAMUserViewSetTests(TestCase):
args, kwargs = user_added_to_group_handler.call_args
self.assertEqual(kwargs["sender"], views.IAMUserViewSet)
self.assertEqual(kwargs["user"], user_profile)
- self.assertEqual(kwargs["group"], group)
+ self.assertEqual(kwargs["groups"][0], group)
+
+ @patch("django_airavata.apps.api.views.iam_admin_client")
+ def test_update_that_adds_user_to_multiple_groups(
+ self, iam_admin_client):
+
+ username = "testuser1"
+ url = reverse(
+ 'django_airavata_api:iam-user-profile-detail',
+ kwargs={'user_id': username})
+ data = {
+ "airavataInternalUserId": f"{username}@{GATEWAY_ID}",
+ "userId": username,
+ "gatewayId": GATEWAY_ID,
+ "email": "testuser1@example.com",
+ "firstName": "Test",
+ "lastName": "User1",
+ "airavataUserProfileExists": True,
+ "enabled": True,
+ "emailVerified": True,
+ "groups": [
+ {"id": "group1", "name": "Group 1"},
+ {"id": "group2", "name": "Group 2"},
+ {"id": "group3", "name": "Group 3"},
+ ]
+ }
+ request = self.factory.put(url, data)
+ force_authenticate(request, self.user)
+ request.is_gateway_admin = True
+
+ # Mock api clients
+ iam_user_profile = UserProfile(
+ airavataInternalUserId=f"testuser1@{GATEWAY_ID}",
+ userId="testuser1",
+ firstName="Test",
+ lastName="User1",
+ emails=["testuser1@example.com"]
+ )
+ iam_admin_client.get_user.return_value = iam_user_profile
+ group_manager_mock = MagicMock(name='group_manager')
+ user_profile_mock = MagicMock(name='user_profile')
+ request.profile_service = {
+ 'group_manager': group_manager_mock,
+ 'user_profile': user_profile_mock,
+ }
+ request.authz_token = "dummy"
+ user_profile_mock.doesUserExist.return_value = True
+ user_profile = UserProfile(
+ airavataInternalUserId=f"testuser1@{GATEWAY_ID}",
+ userId="testuser1",
+ firstName="Test",
+ lastName="User1",
+ emails=["testuser1@example.com"]
+ )
+ user_profile_mock.getUserProfileById.return_value = user_profile
+ group_manager_mock.getAllGroupsUserBelongs.return_value = [
+ GroupModel(id="group1")]
+
+ def side_effect(authz_token, group_id):
+ if group_id == "group2":
+ return GroupModel(id="group2", name="Group 2")
+ elif group_id == "group3":
+ return GroupModel(id="group3", name="Group 3")
+ else:
+ raise Exception("Unexpected group id: " + group_id)
+
+ group_manager_mock.getGroup.side_effect = side_effect
+ request.airavata_client = MagicMock(name="airavata_client")
+ request.airavata_client.getGatewayGroups.return_value = GatewayGroups(
+ gatewayId=GATEWAY_ID,
+ adminsGroupId="adminsGroupId",
+ readOnlyAdminsGroupId="readOnlyAdminsGroupId",
+ defaultGatewayUsersGroupId="defaultGatewayUsersGroupId"
+ )
+ request.session = {}
+
+ # Mock signal handler to verify 'user_added_to_group' signal is sent
+ user_added_to_group_handler = MagicMock(
+ name="user_added_to_group_handler")
+ signals.user_added_to_group.connect(
+ user_added_to_group_handler,
+ sender=views.IAMUserViewSet)
+ iam_user_update = views.IAMUserViewSet.as_view({'put': 'update'})
+ response = iam_user_update(request, user_id=username)
+ self.assertEquals(200, response.status_code)
+
+ user_profile_mock.doesUserExist.assert_called_once()
+ group_manager_mock.getAllGroupsUserBelongs.assert_called_once()
+
+ user_profile_mock.getUserProfileById.assert_called_once()
+ args, kwargs = user_profile_mock.getUserProfileById.call_args
+ self.assertSequenceEqual(
+ args, [request.authz_token, "testuser1", GATEWAY_ID])
+
+ group_manager_mock.getGroup.assert_has_calls([
+ call(request.authz_token, "group2"),
+ call(request.authz_token, "group3")
+ ], any_order=True)
+
+ group_manager_mock.addUsersToGroup.assert_has_calls([
+ call(request.authz_token, [f"testuser1@{GATEWAY_ID}"], "group2"),
+ call(request.authz_token, [f"testuser1@{GATEWAY_ID}"], "group3"),
+ ], any_order=True)
+
+ # user_added_to_group signal should only be called once, with both
+ # groups passed to it
+ user_added_to_group_handler.assert_called_once()
+ args, kwargs = user_added_to_group_handler.call_args
+ self.assertEqual(kwargs["sender"], views.IAMUserViewSet)
+ self.assertEqual(kwargs["user"], user_profile)
+ self.assertSetEqual({"group2", "group3"},
+ {g.id for g in kwargs["groups"]})
diff --git a/django_airavata/apps/api/views.py b/django_airavata/apps/api/views.py
index f674139..02d6701 100644
--- a/django_airavata/apps/api/views.py
+++ b/django_airavata/apps/api/views.py
@@ -122,7 +122,7 @@ class GroupViewSet(APIBackedViewSet):
signals.user_added_to_group.send(
sender=self.__class__,
user=user_profile,
- group=group,
+ groups=[group],
request=self.request)
@@ -1613,18 +1613,21 @@ class IAMUserViewSet(mixins.RetrieveModelMixin,
group_manager_client = self.request.profile_service['group_manager']
user_profile_client = self.request.profile_service['user_profile']
user_id = managed_user_profile['airavataInternalUserId']
- username = managed_user_profile['userId']
+ user_profile = user_profile_client.getUserProfileById(
+ self.authz_token,
+ managed_user_profile['userId'],
+ settings.GATEWAY_ID)
+ added_groups = []
for group_id in managed_user_profile['_added_group_ids']:
- user_profile = user_profile_client.getUserProfileById(
- self.authz_token, username, settings.GATEWAY_ID)
group = group_manager_client.getGroup(self.authz_token, group_id)
group_manager_client.addUsersToGroup(
self.authz_token, [user_id], group_id)
- signals.user_added_to_group.send(
- sender=self.__class__,
- user=user_profile,
- group=group,
- request=self.request)
+ added_groups.append(group)
+ signals.user_added_to_group.send(
+ sender=self.__class__,
+ user=user_profile,
+ groups=added_groups,
+ request=self.request)
for group_id in managed_user_profile['_removed_group_ids']:
group_manager_client.removeUsersFromGroup(
self.authz_token, [user_id], group_id)
diff --git a/django_airavata/apps/auth/migrations/0005_auto_20191211_2011.py b/django_airavata/apps/auth/migrations/0005_auto_20191211_2011.py
index c6533dc..eeb4b99 100644
--- a/django_airavata/apps/auth/migrations/0005_auto_20191211_2011.py
+++ b/django_airavata/apps/auth/migrations/0005_auto_20191211_2011.py
@@ -12,22 +12,22 @@ def default_templates(apps, schema_editor):
EmailTemplate = apps.get_model("django_airavata_auth", "EmailTemplate")
user_added_to_group_template = EmailTemplate(
template_type=USER_ADDED_TO_GROUP_TEMPLATE,
- subject="You've been added to group [{{group_name}}] in {{portal_title}}",
+ subject="You've been added to group{{ group_names|length|pluralize }} [{{group_names|join:'] and ['}}] in {{portal_title}}",
body="""
<p>
Dear {{first_name}} {{last_name}},
</p>
<p>
- Your user account (username {{username}}) has been added to the group
- {{group_name}}. {{portal_title}} uses groups to share applications
- and experiments.
+ Your user account (username {{username}}) has been added to the
+ group{{ group_names|length|pluralize }} {{group_names|join:' and '}}.
+ {{portal_title}} uses groups to share applications and experiments.
</p>
<p>
You may have access to additional applications now that you are a
- member of {{group_name}}. To check what applications you have access
- to, please check: <a href="{{dashboard_url}}">{{dashboard_url}}</a>.
+ member of {{group_names|join:' and '}}. To check what applications you
+ have access to, please check: <a href="{{dashboard_url}}">{{dashboard_url}}</a>.
</p>
<p>
diff --git a/django_airavata/apps/auth/signals.py b/django_airavata/apps/auth/signals.py
index 9efe76a..32f3cb0 100644
--- a/django_airavata/apps/auth/signals.py
+++ b/django_airavata/apps/auth/signals.py
@@ -9,7 +9,7 @@ from . import models, utils
@receiver(user_added_to_group, dispatch_uid="auth_email_user_added_to_group")
-def email_user_added_to_group(sender, user, group, request, **kwargs):
+def email_user_added_to_group(sender, user, groups, request, **kwargs):
context = Context({
"email": user.emails[0],
"first_name": user.firstName,
@@ -20,6 +20,6 @@ def email_user_added_to_group(sender, user, group, request, **kwargs):
reverse("django_airavata_workspace:dashboard")),
"experiments_url": request.build_absolute_uri(
reverse("django_airavata_workspace:experiments")),
- "group_name": group.name
+ "group_names": [g.name for g in groups]
})
utils.send_email_to_user(models.USER_ADDED_TO_GROUP_TEMPLATE, context)
diff --git a/django_airavata/apps/auth/tests.py b/django_airavata/apps/auth/tests.py
index 6d7a033..50d4faa 100644
--- a/django_airavata/apps/auth/tests.py
+++ b/django_airavata/apps/auth/tests.py
@@ -31,7 +31,10 @@ class EmailUserAddedToGroupSignalReceiverTests(TestCase):
firstName="Test",
lastName="User")
group = GroupModel(id="abc123", name="Test Group")
- user_added_to_group.send(None, user=user, group=group, request=request)
+ user_added_to_group.send(None,
+ user=user,
+ groups=[group],
+ request=request)
self.assertEqual(len(mail.outbox), 1)
msg = mail.outbox[0]
self.assertEqual(msg.subject,
@@ -50,3 +53,40 @@ class EmailUserAddedToGroupSignalReceiverTests(TestCase):
reverse("django_airavata_workspace:experiments")),
msg.body)
self.assertIn(user.userId, msg.body)
+
+ def test_multiple_groups(self):
+ factory = RequestFactory()
+ request = factory.get("/")
+ user = UserProfile(
+ airavataInternalUserId=f"testuser@{GATEWAY_ID}",
+ userId="testuser",
+ gatewayId=GATEWAY_ID,
+ emails=["testuser@example.com"],
+ firstName="Test",
+ lastName="User")
+ group1 = GroupModel(id="abc123", name="Test Group")
+ group2 = GroupModel(id="group2", name="Group 2")
+ user_added_to_group.send(None,
+ user=user,
+ groups=[group1, group2],
+ request=request)
+ self.assertEqual(len(mail.outbox), 1)
+ msg = mail.outbox[0]
+ self.assertEqual(msg.subject,
+ f"You've been added to groups "
+ f"[{group1.name}] and [{group2.name}] "
+ f"in {PORTAL_TITLE}")
+ self.assertEqual(msg.from_email,
+ f"{PORTAL_TITLE} <{SERVER_EMAIL}>")
+ self.assertSequenceEqual(
+ msg.to, [f"{user.firstName} {user.lastName} <{user.emails[0]}>"])
+ self.assertIn(
+ request.build_absolute_uri(
+ reverse("django_airavata_workspace:dashboard")),
+ msg.body)
+ self.assertIn(
+ request.build_absolute_uri(
+ reverse("django_airavata_workspace:experiments")),
+ msg.body)
+ self.assertIn(user.userId, msg.body)
+ self.assertIn("groups Test Group and Group 2", msg.body)