From 1bf05cfe5f9929023e550f9cd796ca8cdcfb2582 Mon Sep 17 00:00:00 2001 From: Kipchirchir Sigei Date: Wed, 5 Oct 2022 17:08:15 +0300 Subject: [PATCH 1/3] Ensure org project is shared with members team Signed-off-by: Kipchirchir Sigei --- .../organization_member_serializer.py | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/onadata/libs/serializers/organization_member_serializer.py b/onadata/libs/serializers/organization_member_serializer.py index 3917b22cb8..a92d2d7d3a 100644 --- a/onadata/libs/serializers/organization_member_serializer.py +++ b/onadata/libs/serializers/organization_member_serializer.py @@ -17,9 +17,12 @@ remove_user_from_organization, remove_user_from_team, ) -from onadata.libs.models.share_project import ShareProject +from onadata.apps.api.models.organization_profile import ( + get_organization_members_team, +) from onadata.libs.permissions import ROLES, OwnerRole, is_organization from onadata.libs.serializers.fields.organization_field import OrganizationField +from onadata.libs.serializers.share_project_serializer import ShareProjectSerializer from onadata.settings.common import DEFAULT_FROM_EMAIL, SHARE_ORG_SUBJECT User = get_user_model() @@ -39,17 +42,22 @@ def _set_organization_role_to_user(organization, user, role): role_cls.add(user, organization) owners_team = get_or_create_organization_owners_team(organization) - - # add the owner to owners team - if role == OwnerRole.name: - role_cls.add(user, organization.userprofile_ptr) - add_user_to_team(owners_team, user) - # add user to org projects - for project in organization.user.project_org.all(): - ShareProject(project, user.username, role).save() - - if role != OwnerRole.name: - remove_user_from_team(owners_team, user) + members_team = get_organization_members_team(organization) + current_team = owners_team if role == OwnerRole.name else members_team + + # add user to their respective team + role_cls.add(user, organization.userprofile_ptr) + add_user_to_team(current_team, user) + # add user to org projects + for project in organization.user.project_org.all(): + data = { + "project": project.pk, + "username": user.username, + "role": role + } + serializer = ShareProjectSerializer(data=data) + if serializer.is_valid(): + serializer.save() class OrganizationMemberSerializer(serializers.Serializer): From 27466b2759be2e93fcf59b3f68e52158be5829f2 Mon Sep 17 00:00:00 2001 From: Kipchirchir Sigei Date: Wed, 5 Oct 2022 17:21:52 +0300 Subject: [PATCH 2/3] Add tests Signed-off-by: Kipchirchir Sigei --- .../test_organization_profile_viewset.py | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/onadata/apps/api/tests/viewsets/test_organization_profile_viewset.py b/onadata/apps/api/tests/viewsets/test_organization_profile_viewset.py index 38f7d14837..d52465989d 100644 --- a/onadata/apps/api/tests/viewsets/test_organization_profile_viewset.py +++ b/onadata/apps/api/tests/viewsets/test_organization_profile_viewset.py @@ -23,7 +23,7 @@ from onadata.apps.api.viewsets.project_viewset import ProjectViewSet from onadata.apps.api.viewsets.user_profile_viewset import UserProfileViewSet from onadata.apps.main.models import UserProfile -from onadata.libs.permissions import OwnerRole +from onadata.libs.permissions import OwnerRole, EditorRole # pylint: disable=too-many-public-methods @@ -283,7 +283,6 @@ def test_add_members_to_org(self): request = self.factory.post( "/", data=json.dumps(data), content_type="application/json", **self.extra ) - response = view(request, user="denoinc") self.assertEqual(response.status_code, 201) self.assertEqual(set(response.data), set(["denoinc", "aboy"])) @@ -542,6 +541,38 @@ def test_publish_xls_form_to_organization_project(self): self._publish_xls_form_to_project() self.assertTrue(OwnerRole.user_has_role(self.user, self.xform)) + def test_publish_xls_form_to_organization_project_perms(self): + # create org + self._org_create() + project_data = {"owner": self.company_data["user"]} + + # create project under org + self._project_create(project_data) + self._publish_xls_form_to_project() + + # add member to org + view = OrganizationProfileViewSet.as_view({"post": "members"}) + + # create new user + self.profile_data["username"] = "aboy" + self.profile_data["email"] = "aboy@org.com" + self._create_user_profile() + data = {"username": "aboy", "role": "editor"} + + # add new user as member to org with editor permissions + request = self.factory.post( + "/", data=json.dumps(data), content_type="application/json", **self.extra + ) + response = view(request, user="denoinc") + self.assertEqual(response.status_code, 201) + + member = User.objects.get(username="aboy") + + # Assert that user has xform and project permissions + self.assertTrue(EditorRole.user_has_role(member, self.xform)) + self.assertTrue(EditorRole.user_has_role(member, self.project)) + + def test_put_change_role(self): self._org_create() newname = "aboy" From f5ea169e842938c7136441ba8db47eb02a8ebc1d Mon Sep 17 00:00:00 2001 From: Kipchirchir Sigei Date: Wed, 5 Oct 2022 18:38:03 +0300 Subject: [PATCH 3/3] Cleanup Signed-off-by: Kipchirchir Sigei --- .../test_organization_profile_viewset.py | 63 +++++++++---------- .../organization_member_serializer.py | 52 +++++++++------ 2 files changed, 65 insertions(+), 50 deletions(-) diff --git a/onadata/apps/api/tests/viewsets/test_organization_profile_viewset.py b/onadata/apps/api/tests/viewsets/test_organization_profile_viewset.py index d52465989d..d8eef73394 100644 --- a/onadata/apps/api/tests/viewsets/test_organization_profile_viewset.py +++ b/onadata/apps/api/tests/viewsets/test_organization_profile_viewset.py @@ -541,38 +541,6 @@ def test_publish_xls_form_to_organization_project(self): self._publish_xls_form_to_project() self.assertTrue(OwnerRole.user_has_role(self.user, self.xform)) - def test_publish_xls_form_to_organization_project_perms(self): - # create org - self._org_create() - project_data = {"owner": self.company_data["user"]} - - # create project under org - self._project_create(project_data) - self._publish_xls_form_to_project() - - # add member to org - view = OrganizationProfileViewSet.as_view({"post": "members"}) - - # create new user - self.profile_data["username"] = "aboy" - self.profile_data["email"] = "aboy@org.com" - self._create_user_profile() - data = {"username": "aboy", "role": "editor"} - - # add new user as member to org with editor permissions - request = self.factory.post( - "/", data=json.dumps(data), content_type="application/json", **self.extra - ) - response = view(request, user="denoinc") - self.assertEqual(response.status_code, 201) - - member = User.objects.get(username="aboy") - - # Assert that user has xform and project permissions - self.assertTrue(EditorRole.user_has_role(member, self.xform)) - self.assertTrue(EditorRole.user_has_role(member, self.project)) - - def test_put_change_role(self): self._org_create() newname = "aboy" @@ -843,6 +811,37 @@ def test_org_members_added_to_projects(self): self.assertIn("aboy", users_in_users) self.assertIn("alice", users_in_users) + def test_member_added_to_org_with_correct_perms(self): + # create org + self._org_create() + project_data = {"owner": self.company_data["user"]} + + # create project under org + self._project_create(project_data) + self._publish_xls_form_to_project() + + # add member to org + view = OrganizationProfileViewSet.as_view({"post": "members"}) + + # create new user + self.profile_data["username"] = "aboy" + self.profile_data["email"] = "aboy@org.com" + self._create_user_profile() + data = {"username": "aboy", "role": "editor"} + + # add new user as member to org with editor permissions + request = self.factory.post( + "/", data=json.dumps(data), content_type="application/json", **self.extra + ) + response = view(request, user="denoinc") + self.assertEqual(response.status_code, 201) + + member = User.objects.get(username="aboy") + + # Assert that user has xform and project permissions + self.assertTrue(EditorRole.user_has_role(member, self.xform)) + self.assertTrue(EditorRole.user_has_role(member, self.project)) + def test_put_role_user_none_existent(self): self._org_create() newname = "i-do-no-exist" diff --git a/onadata/libs/serializers/organization_member_serializer.py b/onadata/libs/serializers/organization_member_serializer.py index a92d2d7d3a..077eadecc4 100644 --- a/onadata/libs/serializers/organization_member_serializer.py +++ b/onadata/libs/serializers/organization_member_serializer.py @@ -17,12 +17,13 @@ remove_user_from_organization, remove_user_from_team, ) -from onadata.apps.api.models.organization_profile import ( - get_organization_members_team, +from onadata.libs.permissions import ( + ROLES, OwnerRole, is_organization ) -from onadata.libs.permissions import ROLES, OwnerRole, is_organization from onadata.libs.serializers.fields.organization_field import OrganizationField -from onadata.libs.serializers.share_project_serializer import ShareProjectSerializer +from onadata.libs.serializers.share_project_serializer import ( + ShareProjectSerializer +) from onadata.settings.common import DEFAULT_FROM_EMAIL, SHARE_ORG_SUBJECT User = get_user_model() @@ -42,22 +43,37 @@ def _set_organization_role_to_user(organization, user, role): role_cls.add(user, organization) owners_team = get_or_create_organization_owners_team(organization) - members_team = get_organization_members_team(organization) - current_team = owners_team if role == OwnerRole.name else members_team # add user to their respective team - role_cls.add(user, organization.userprofile_ptr) - add_user_to_team(current_team, user) - # add user to org projects - for project in organization.user.project_org.all(): - data = { - "project": project.pk, - "username": user.username, - "role": role - } - serializer = ShareProjectSerializer(data=data) - if serializer.is_valid(): - serializer.save() + if role == OwnerRole.name: + # add user to owners team + role_cls.add(user, organization.userprofile_ptr) + add_user_to_team(owners_team, user) + # add user to org projects + for project in organization.user.project_org.all(): + data = { + "project": project.pk, + "username": user.username, + "role": role + } + serializer = ShareProjectSerializer(data=data) + if serializer.is_valid(): + serializer.save() + + elif role != OwnerRole.name: + # add user to org projects + for project in organization.user.project_org.all(): + data = { + "project": project.pk, + "username": user.username, + "role": role + } + serializer = ShareProjectSerializer(data=data) + if serializer.is_valid(): + serializer.save() + + # remove user from owners team + remove_user_from_team(owners_team, user) class OrganizationMemberSerializer(serializers.Serializer):