diff --git a/opwen_email_server/actions.py b/opwen_email_server/actions.py index 81604726..2ef45dee 100644 --- a/opwen_email_server/actions.py +++ b/opwen_email_server/actions.py @@ -118,7 +118,8 @@ def _action(self, resource_id): # type: ignore email = self._email_storage.fetch_object(resource_id) for email_address in self._get_pivot(email): - index = f"{email_address}/{self._folder}/{email['sent_at']}/{resource_id}" + domain = get_domain(email_address) + index = f"{domain}/{email_address}/{self._folder}/{email['sent_at']}/{resource_id}" self._mailbox_storage.store_text(index, 'indexed') self.log_event(events.MAILBOX_EMAIL_INDEXED, {'folder': self._folder}) # noqa: E501 # yapf: disable @@ -400,11 +401,14 @@ def _action(self, domain, **auth_args): # type: ignore class DeleteClient(_Action): def __init__(self, auth: AzureAuth, delete_mailbox: Callable[[str, str], None], - delete_mx_records: Callable[[str], None]): + delete_mx_records: Callable[[str], None], mailbox_storage: AzureTextStorage, + pending_storage: AzureTextStorage): self._auth = auth self._delete_mailbox = delete_mailbox self._delete_mx_records = delete_mx_records + self._mailbox_storage = mailbox_storage + self._pending_storage = pending_storage def _action(self, domain, **auth_args): # type: ignore if not is_lowercase(domain): @@ -419,11 +423,18 @@ def _action(self, domain, **auth_args): # type: ignore self._delete_mailbox(client_id, domain) self._delete_mx_records(domain) + self._delete_index(self._pending_storage, domain) + self._delete_index(self._mailbox_storage, domain) self._auth.delete(client_id, domain) self.log_event(events.CLIENT_DELETED, {'domain': domain}) # noqa: E501 # yapf: disable return 'OK', 200 + @classmethod + def _delete_index(cls, storage: AzureTextStorage, domain: str) -> None: + for prefix in storage.iter(f'{domain}/'): + storage.delete(f'{domain}/{prefix}') + class CalculateNumberOfUsersMetric(_Action): def __init__(self, auth: AzureAuth, user_storage: AzureObjectStorage): diff --git a/opwen_email_server/integration/connexion.py b/opwen_email_server/integration/connexion.py index 5e5bcec1..da3dd977 100644 --- a/opwen_email_server/integration/connexion.py +++ b/opwen_email_server/integration/connexion.py @@ -12,6 +12,7 @@ from opwen_email_server.integration.azure import get_auth from opwen_email_server.integration.azure import get_client_storage from opwen_email_server.integration.azure import get_email_storage +from opwen_email_server.integration.azure import get_mailbox_storage from opwen_email_server.integration.azure import get_pending_storage from opwen_email_server.integration.azure import get_raw_email_storage from opwen_email_server.integration.azure import get_user_storage @@ -62,6 +63,8 @@ secret=config.DNS_SECRET, provider=config.DNS_PROVIDER, ), + mailbox_storage=get_mailbox_storage(), + pending_storage=get_pending_storage(), ) metrics_users = CalculateNumberOfUsersMetric( diff --git a/opwen_email_server/integration/webapp.py b/opwen_email_server/integration/webapp.py index 0c10d4af..685c115b 100644 --- a/opwen_email_server/integration/webapp.py +++ b/opwen_email_server/integration/webapp.py @@ -194,7 +194,8 @@ def sent(self, email_address: str, page: int) -> Iterable[dict]: return self._iter_mailbox(email_address, page, mailbox.SENT_FOLDER) def _iter_mailbox(self, email_address: str, page: int, folder: str) -> Iterable[dict]: - emails = self._mailbox_storage.iter(f'{email_address}/{folder}') + domain = get_domain(email_address) + emails = self._mailbox_storage.iter(f'{domain}/{email_address}/{folder}') for i, resource_ids in enumerate(chunks(emails, AppConfig.EMAILS_PER_PAGE), start=1): if i != page: continue @@ -220,6 +221,8 @@ def num_pending(self) -> int: return 0 def _delete(self, email_address: str, uids: Iterable[str]): + domain = get_domain(email_address) + for uid in uids: email = self.get(uid) if not email: @@ -232,7 +235,7 @@ def _delete(self, email_address: str, uids: Iterable[str]): else: continue - self._mailbox_storage.delete(f"{email_address}/{folder}/{email['sent_at']}/{uid}") + self._mailbox_storage.delete(f"{domain}/{email_address}/{folder}/{email['sent_at']}/{uid}") self._email_storage.delete(uid) def _mark_sent(self, uids: Iterable[str]): diff --git a/tests/opwen_email_server/test_actions.py b/tests/opwen_email_server/test_actions.py index d620ed55..61fbf0c9 100644 --- a/tests/opwen_email_server/test_actions.py +++ b/tests/opwen_email_server/test_actions.py @@ -152,8 +152,10 @@ def test_200(self): self.assertEqual(status, 200) self.email_storage.fetch_object.assert_called_once_with(email_id) - self.mailbox_storage.store_text.assert_any_call('1@bar.lokole.ca/received/2019-10-26 22:47/123', 'indexed') - self.mailbox_storage.store_text.assert_any_call('2@baz.lokole.ca/received/2019-10-26 22:47/123', 'indexed') + self.mailbox_storage.store_text.assert_any_call('bar.lokole.ca/1@bar.lokole.ca/received/2019-10-26 22:47/123', + 'indexed') + self.mailbox_storage.store_text.assert_any_call('baz.lokole.ca/2@baz.lokole.ca/received/2019-10-26 22:47/123', + 'indexed') self.assertEqual(self.mailbox_storage.store_text.call_count, 2) def _execute_action(self, *args, **kwargs): @@ -183,7 +185,7 @@ def test_200(self): self.assertEqual(status, 200) self.email_storage.fetch_object.assert_called_once_with(email_id) - self.mailbox_storage.store_text.assert_called_once_with('foo@foo/sent/2019-10-26 22:47/123', 'indexed') + self.mailbox_storage.store_text.assert_called_once_with('foo/foo@foo/sent/2019-10-26 22:47/123', 'indexed') def _execute_action(self, *args, **kwargs): action = actions.IndexSentEmailForMailbox( @@ -633,6 +635,8 @@ def setUp(self): self.auth = Mock() self.delete_mailbox = MagicMock() self.delete_mx_records = MagicMock() + self.mailbox_storage = Mock() + self.pending_storage = Mock() def test_400(self): domain = 'TEST.com' @@ -674,6 +678,8 @@ def test_200(self): self.auth.client_id_for.return_value = client_id self.auth.is_owner.return_value = True + self.mailbox_storage.iter.return_value = ['1/2/a', '1/2/b'] + self.pending_storage.iter.return_value = ['c', 'd', 'e'] _, status = self._execute_action(domain, user=user) @@ -683,12 +689,23 @@ def test_200(self): self.auth.delete.assert_called_once_with(client_id, domain) self.delete_mailbox.assert_called_once_with(client_id, domain) self.delete_mx_records.assert_called_once_with(domain) + self.mailbox_storage.iter.assert_called_once_with(f'{domain}/') + self.mailbox_storage.delete.assert_any_call(f'{domain}/1/2/a') + self.mailbox_storage.delete.assert_any_call(f'{domain}/1/2/b') + self.assertEqual(self.mailbox_storage.delete.call_count, 2) + self.pending_storage.iter.assert_called_once_with(f'{domain}/') + self.pending_storage.delete.assert_any_call(f'{domain}/c') + self.pending_storage.delete.assert_any_call(f'{domain}/d') + self.pending_storage.delete.assert_any_call(f'{domain}/e') + self.assertEqual(self.pending_storage.delete.call_count, 3) def _execute_action(self, *args, **kwargs): action = actions.DeleteClient( auth=self.auth, delete_mailbox=self.delete_mailbox, delete_mx_records=self.delete_mx_records, + mailbox_storage=self.mailbox_storage, + pending_storage=self.pending_storage, ) return action(*args, **kwargs)