diff --git a/CHANGELOG.md b/CHANGELOG.md index a46245e..58bfa77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Bugfix release - RFC 3156 compliance: Don't base64-encode encrypted reports +- Include conflicts in admin reports diff --git a/multischleuder/conflict.py b/multischleuder/conflict.py index 9943eea..628065f 100644 --- a/multischleuder/conflict.py +++ b/multischleuder/conflict.py @@ -1,11 +1,6 @@ from typing import Dict, List, Optional, Tuple -import email.mime.base -import email.mime.application -import email.mime.multipart -import email.mime.text -import email.utils import hashlib import json import logging diff --git a/multischleuder/processor.py b/multischleuder/processor.py index eec5271..3e7921d 100644 --- a/multischleuder/processor.py +++ b/multischleuder/processor.py @@ -86,7 +86,8 @@ class MultiList: for admin in target_admins: report = AdminReport(self._target, admin.email, self._mail_from, admin.key.blob if admin.key is not None else None, - to_subscribe, to_unsubscribe, to_update, to_add, to_remove) + to_subscribe, to_unsubscribe, to_update, to_add, to_remove, + conflicts) self._reporter.add_message(report) logging.info(f'Finished processing: {self._target}') diff --git a/multischleuder/reporting.py b/multischleuder/reporting.py index 536c29d..edca363 100644 --- a/multischleuder/reporting.py +++ b/multischleuder/reporting.py @@ -118,6 +118,7 @@ class KeyConflictMessage(Message): self._chosen: SchleuderSubscriber = chosen self._affected: List[SchleuderSubscriber] = affected self._template: str = template + self._sourcemap: Dict[int, str] = sourcemap super().__init__( schleuder=schleuder, mail_from=mail_from, @@ -128,6 +129,16 @@ class KeyConflictMessage(Message): self.mime['Subject'] = f'MultiSchleuder {self._schleuder} - Key Conflict' self.mime['X-MultiSchleuder-Digest'] = digest + @property + def report_str(self) -> str: + fpr = 'no key' if self._chosen.key is None else self._chosen.key.fingerprint + s = f'{self._chosen.email} -> {fpr}\n' + for a in self._affected: + fpr = 'no key' if a.key is None else a.key.fingerprint + aschleuder: str = self._sourcemap.get(a.schleuder, 'unknown') + s += f'- {fpr} ({aschleuder})\n' + return s + class UserConflictMessage(Message): @@ -157,6 +168,7 @@ class UserConflictMessage(Message): self._chosen: SchleuderSubscriber = chosen self._affected: List[SchleuderSubscriber] = affected self._template: str = template + self._sourcemap: Dict[int, str] = sourcemap super().__init__( schleuder=schleuder, mail_from=mail_from, @@ -167,6 +179,15 @@ class UserConflictMessage(Message): self.mime['Subject'] = f'MultiSchleuder {self._schleuder} - Subscriber Conflict' self.mime['X-MultiSchleuder-Digest'] = digest + @property + def report_str(self) -> str: + assert self._chosen.key is not None + s = f'{self._chosen.key.fingerprint} -> {self._chosen.email}\n' + for a in self._affected: + aschleuder: str = self._sourcemap.get(a.schleuder, 'unknown') + s += f'- {a.email} ({aschleuder})\n' + return s + class AdminReport(Message): @@ -179,10 +200,13 @@ class AdminReport(Message): unsubscribed: Set[SchleuderSubscriber], updated: Set[SchleuderSubscriber], added: Set[SchleuderKey], - removed: Set[SchleuderKey]): - if len(subscribed) == 0 and len(unsubscribed) == 0 and \ - len(removed) == 0 and len(added) == 0 and len(updated) == 0: + removed: Set[SchleuderKey], + conflicts: List[Optional[Message]]): + if len(subscribed) == 0 and len(unsubscribed) == 0 and len(removed) == 0 \ + and len(added) == 0 and len(updated) == 0 and len(conflicts) == 0: raise ValueError('No changes, not creating admin report') + key_conflicts = [m for m in conflicts if m is not None and isinstance(m, KeyConflictMessage)] + user_conflicts = [m for m in conflicts if m is not None and isinstance(m, UserConflictMessage)] content = f''' == Admin Report for MultiSchleuder {schleuder} == ''' @@ -219,6 +243,19 @@ class AdminReport(Message): ''' for k in removed: content += f'{k.fingerprint} ({k.email})\n' + if len(key_conflicts) > 0: + content += ''' +>>> Keys conflicts: +''' + for c in key_conflicts: + content += f'{c.report_str}\n' + if len(user_conflicts) > 0: + content += ''' +>>> User conflicts: +''' + for u in user_conflicts: + content += f'{u.report_str}\n' + super().__init__( schleuder=schleuder, mail_from=mail_from,