예제 #1
0
    def test_update_group(self, logger_mock):
        with self.subTest("Successful"):
            self.sync_service.update_group(
                "new_group",
                GSuiteSyncService.GroupData(
                    "new_group",
                    "some description",
                    False,
                    ["alias2"],
                    [f"test2@{settings.GSUITE_DOMAIN}"],
                ),
            )

            self.directory_api.groups().update.assert_called_once_with(
                body={
                    "email": f"new_group@{settings.GSUITE_DOMAIN}",
                    "name": "new_group",
                    "description": "some description",
                },
                groupKey=f"new_group@{settings.GSUITE_DOMAIN}",
            )

            self.settings_api.groups().update.assert_called_once_with(
                groupUniqueId=f"new_group@{settings.GSUITE_DOMAIN}",
                body=self.sync_service._group_settings(False),
            )

            self.directory_api.members().list.assert_called()
            self.directory_api.groups().aliases().list.assert_called()

        self.settings_api.reset_mock()
        self.directory_api.reset_mock()

        with self.subTest("Failure"):
            self.directory_api.groups().update(
            ).execute.side_effect = HttpError(Response({"status": 500}),
                                              bytes())

            self.sync_service.update_group(
                "new_group",
                GSuiteSyncService.GroupData(
                    "new_group",
                    "some description",
                    False,
                    ["alias2"],
                    [f"test2@{settings.GSUITE_DOMAIN}"],
                ),
            )

            self.directory_api.members().list.assert_not_called()
            self.directory_api.groups().aliases().list.assert_not_called()

            logger_mock.error.assert_called_once_with(
                "Could not update list %s: %s", "new_group", bytes())
예제 #2
0
 def test_mailinglist_to_group(self):
     group = GSuiteSyncService.mailinglist_to_group(self.mailinglist)
     self.assertEqual(
         group,
         GSuiteSyncService.GroupData(
             "new_group",
             "some description",
             False,
             ["alias2"],
             [f"test2@{settings.GSUITE_DOMAIN}"],
         ),
     )
예제 #3
0
def pre_mailinglist_save(instance, **kwargs):
    sync_service = GSuiteSyncService()
    group = sync_service.mailinglist_to_group(instance)
    old_list = MailingList.objects.filter(pk=instance.pk).first()
    try:
        if old_list is None:
            sync_service.create_group(group)
        else:
            sync_service.update_group(old_list.name, group)
    except HttpError:
        # Cannot do direct create or update, do full sync for list
        sync_service.sync_mailinglists([group])
예제 #4
0
def pre_mailinglist_save(instance, **kwargs):
    if settings.GSUITE_ADMIN_CREDENTIALS == {}:
        logger.warning(
            "Cannot sync mailinglists because there are no GSuite credentials available"
        )
        return
    sync_service = GSuiteSyncService()
    group = sync_service.mailinglist_to_group(instance)
    old_list = MailingList.objects.filter(pk=instance.pk).first()
    try:
        if old_list is None:
            sync_service.create_group(group)
        else:
            sync_service.update_group(old_list.name, group)
    except HttpError:
        # Cannot do direct create or update, do full sync for list
        sync_service.sync_mailinglists([group])
예제 #5
0
 def test_automatic_to_group(self):
     group = GSuiteSyncService._automatic_to_group({
         "moderated":
         False,
         "name":
         "new_group",
         "description":
         "some description",
         "aliases": ["alias1"],
         "addresses": [f"test1@{settings.GSUITE_DOMAIN}"],
     })
     self.assertEqual(
         group,
         GSuiteSyncService.GroupData(
             "new_group",
             "some description",
             False,
             ["alias1"],
             [f"test1@{settings.GSUITE_DOMAIN}"],
         ),
     )
예제 #6
0
    def setUpTestData(cls):
        cls.settings_api = MagicMock()
        cls.directory_api = MagicMock()

        cls.sync_service = GSuiteSyncService(cls.settings_api,
                                             cls.directory_api)
        cls.mailinglist = MailingList.objects.create(
            name="new_group", description="some description", moderated=False)
        ListAlias.objects.create(mailinglist=cls.mailinglist, alias="alias2")
        VerbatimAddress.objects.create(
            mailinglist=cls.mailinglist,
            address=f"test2@{settings.GSUITE_DOMAIN}")
예제 #7
0
 def handle(self, *args, **options):
     """Sync all mailing lists"""
     sync_service = GSuiteSyncService()
     sync_service.sync_mailinglists()
예제 #8
0
    def test_sync_mailinglists(self, logger_mock):
        original_create = self.sync_service.create_group
        original_update = self.sync_service.update_group
        original_delete = self.sync_service.delete_group

        self.sync_service.create_group = MagicMock()
        self.sync_service.update_group = MagicMock()
        self.sync_service.delete_group = MagicMock()

        with self.subTest("Error getting existing list"):
            self.directory_api.groups().list().execute.side_effect = HttpError(
                Response({"status": 500}), bytes())
            self.sync_service.sync_mailinglists()

            logger_mock.error.assert_called_once_with(
                "Could not get the existing groups: %s", bytes())

        self.directory_api.reset_mock()

        with self.subTest("Successful"):
            existing_groups = [
                {
                    "name": "deleteme",
                    "directMembersCount": "3"
                },
                {
                    "name": "already_synced",
                    "directMembersCount": "2"
                },
                {
                    "name": "ignore",
                    "directMembersCount": "0"
                },
            ]

            self.directory_api.groups().list().execute.side_effect = [
                {
                    "groups": existing_groups[:1],
                    "nextPageToken": "some_token"
                },
                {
                    "groups": existing_groups[1:]
                },
            ]

            self.sync_service.sync_mailinglists([
                GSuiteSyncService.GroupData(name="syncme",
                                            addresses=["someone"]),
                GSuiteSyncService.GroupData(name="already_synced",
                                            addresses=["someone"]),
                GSuiteSyncService.GroupData(name="ignore2", addresses=[]),
            ])

            self.sync_service.create_group.assert_called_with(
                GSuiteSyncService.GroupData(name="syncme",
                                            addresses=["someone"]))

            self.sync_service.update_group.assert_called_with(
                "already_synced",
                GSuiteSyncService.GroupData(name="already_synced",
                                            addresses=["someone"]),
            )

            self.sync_service.delete_group.assert_called_with("deleteme")

            self.sync_service.create_group.assert_not_called_with(
                GSuiteSyncService.GroupData(name="ignore2", addresses=[]))
            self.sync_service.update_group.assert_not_called_with(
                "ignore2",
                GSuiteSyncService.GroupData(name="ignore2", addresses=[]))
            self.sync_service.delete_group.assert_not_called_with("ignore2")

        self.sync_service.create_group = original_create
        self.sync_service.update_group = original_update
        self.sync_service.delete_group = original_delete
예제 #9
0
    def test_update_group_members(self, logger_mock):
        with self.subTest("Error getting existing list"):
            self.directory_api.members(
            ).list().execute.side_effect = HttpError(Response({"status": 500}),
                                                     bytes())
            self.sync_service._update_group_members(
                GSuiteSyncService.GroupData(name="update_group"))

            logger_mock.error.assert_called_once_with(
                "Could not obtain list member data: %s", bytes())

        self.directory_api.reset_mock()

        with self.subTest("Successful with some errors"):
            group_data = GSuiteSyncService.GroupData(
                name="update_group",
                addresses=[
                    "*****@*****.**",
                    "*****@*****.**",
                    "*****@*****.**",
                ],
            )

            existing_aliases = [
                {
                    "email": "*****@*****.**",
                    "role": "MEMBER"
                },
                {
                    "email": "*****@*****.**",
                    "role": "MEMBER"
                },
                {
                    "email": "*****@*****.**",
                    "role": "MEMBER"
                },
                {
                    "email": "*****@*****.**",
                    "role": "MANAGER"
                },
            ]

            self.directory_api.members().list().execute.side_effect = [
                {
                    "members": existing_aliases[:1],
                    "nextPageToken": "some_token"
                },
                {
                    "members": existing_aliases[1:]
                },
            ]

            self.directory_api.members().insert().execute.side_effect = [
                "success",
                HttpError(Response({"status": 500}), bytes()),
            ]

            self.directory_api.members().delete().execute.side_effect = [
                "success",
                HttpError(Response({"status": 500}), bytes()),
            ]

            self.sync_service._update_group_members(group_data)

            self.directory_api.members().insert.assert_any_call(
                groupKey=f"update_group@{settings.GSUITE_DOMAIN}",
                body={
                    "email": "*****@*****.**",
                    "role": "MEMBER"
                },
            )

            self.directory_api.members().delete.assert_any_call(
                groupKey=f"update_group@{settings.GSUITE_DOMAIN}",
                memberKey="*****@*****.**",
            )

            self.directory_api.members().delete.assert_not_called_with(
                groupKey=f"update_group@{settings.GSUITE_DOMAIN}",
                memberKey="*****@*****.**",
            )

            logger_mock.error.assert_any_call(
                "Could not insert list member %s in %s: %s",
                "*****@*****.**",
                "update_group",
                bytes(),
            )

            logger_mock.error.assert_any_call(
                "Could not remove list member %s from %s: %s",
                "*****@*****.**",
                "update_group",
                bytes(),
            )
예제 #10
0
    def test_update_group_aliases(self, logger_mock):
        with self.subTest("Error getting existing list"):
            self.directory_api.groups().aliases(
            ).list().execute.side_effect = HttpError(Response({"status": 500}),
                                                     bytes())
            self.sync_service._update_group_aliases(
                GSuiteSyncService.GroupData(name="update_group"))

            logger_mock.error.assert_called_once_with(
                "Could not obtain existing aliases for list %s: %s",
                "update_group",
                bytes(),
            )

        self.directory_api.reset_mock()

        with self.subTest("Successful with some errors"):
            group_data = GSuiteSyncService.GroupData(
                name="update_group",
                aliases=["not_synced", "not_synced_error", "already_synced"],
            )

            existing_aliases = [
                {
                    "alias": f"deleteme@{settings.GSUITE_DOMAIN}"
                },
                {
                    "alias": f"deleteme_error@{settings.GSUITE_DOMAIN}"
                },
                {
                    "alias": f"already_synced@{settings.GSUITE_DOMAIN}"
                },
            ]

            self.directory_api.groups().aliases().list(
            ).execute.side_effect = [{
                "aliases": existing_aliases
            }]

            self.directory_api.groups().aliases().insert(
            ).execute.side_effect = [
                "success",
                HttpError(Response({"status": 500}), bytes()),
            ]

            self.directory_api.groups().aliases().delete(
            ).execute.side_effect = [
                "success",
                HttpError(Response({"status": 500}), bytes()),
            ]

            self.sync_service._update_group_aliases(group_data)

            self.directory_api.groups().aliases().insert.assert_any_call(
                groupKey=f"update_group@{settings.GSUITE_DOMAIN}",
                body={"alias": f"not_synced@{settings.GSUITE_DOMAIN}"},
            )

            self.directory_api.groups().aliases().delete.assert_any_call(
                groupKey=f"update_group@{settings.GSUITE_DOMAIN}",
                alias=f"deleteme@{settings.GSUITE_DOMAIN}",
            )

            logger_mock.error.assert_any_call(
                "Could not insert alias %s for list %s: %s",
                f"not_synced_error@{settings.GSUITE_DOMAIN}",
                "update_group",
                bytes(),
            )

            logger_mock.error.assert_any_call(
                "Could not remove alias %s for list %s: %s",
                f"deleteme_error@{settings.GSUITE_DOMAIN}",
                "update_group",
                bytes(),
            )