Include conflicts in admin reports

This commit is contained in:
s3lph 2022-04-23 00:18:03 +02:00
parent 58070a1505
commit f0c666540f
4 changed files with 43 additions and 9 deletions

View file

@ -9,6 +9,7 @@ Bugfix release
<!-- BEGIN CHANGES 0.1.3 --> <!-- BEGIN CHANGES 0.1.3 -->
- RFC 3156 compliance: Don't base64-encode encrypted reports - RFC 3156 compliance: Don't base64-encode encrypted reports
- Include conflicts in admin reports
<!-- END CHANGES 0.1.3 --> <!-- END CHANGES 0.1.3 -->
<!-- END RELEASE v0.1.3 --> <!-- END RELEASE v0.1.3 -->

View file

@ -1,11 +1,6 @@
from typing import Dict, List, Optional, Tuple 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 hashlib
import json import json
import logging import logging

View file

@ -86,7 +86,8 @@ class MultiList:
for admin in target_admins: for admin in target_admins:
report = AdminReport(self._target, admin.email, self._mail_from, report = AdminReport(self._target, admin.email, self._mail_from,
admin.key.blob if admin.key is not None else None, 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) self._reporter.add_message(report)
logging.info(f'Finished processing: {self._target}') logging.info(f'Finished processing: {self._target}')

View file

@ -118,6 +118,7 @@ class KeyConflictMessage(Message):
self._chosen: SchleuderSubscriber = chosen self._chosen: SchleuderSubscriber = chosen
self._affected: List[SchleuderSubscriber] = affected self._affected: List[SchleuderSubscriber] = affected
self._template: str = template self._template: str = template
self._sourcemap: Dict[int, str] = sourcemap
super().__init__( super().__init__(
schleuder=schleuder, schleuder=schleuder,
mail_from=mail_from, mail_from=mail_from,
@ -128,6 +129,16 @@ class KeyConflictMessage(Message):
self.mime['Subject'] = f'MultiSchleuder {self._schleuder} - Key Conflict' self.mime['Subject'] = f'MultiSchleuder {self._schleuder} - Key Conflict'
self.mime['X-MultiSchleuder-Digest'] = digest 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): class UserConflictMessage(Message):
@ -157,6 +168,7 @@ class UserConflictMessage(Message):
self._chosen: SchleuderSubscriber = chosen self._chosen: SchleuderSubscriber = chosen
self._affected: List[SchleuderSubscriber] = affected self._affected: List[SchleuderSubscriber] = affected
self._template: str = template self._template: str = template
self._sourcemap: Dict[int, str] = sourcemap
super().__init__( super().__init__(
schleuder=schleuder, schleuder=schleuder,
mail_from=mail_from, mail_from=mail_from,
@ -167,6 +179,15 @@ class UserConflictMessage(Message):
self.mime['Subject'] = f'MultiSchleuder {self._schleuder} - Subscriber Conflict' self.mime['Subject'] = f'MultiSchleuder {self._schleuder} - Subscriber Conflict'
self.mime['X-MultiSchleuder-Digest'] = digest 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): class AdminReport(Message):
@ -179,10 +200,13 @@ class AdminReport(Message):
unsubscribed: Set[SchleuderSubscriber], unsubscribed: Set[SchleuderSubscriber],
updated: Set[SchleuderSubscriber], updated: Set[SchleuderSubscriber],
added: Set[SchleuderKey], added: Set[SchleuderKey],
removed: Set[SchleuderKey]): removed: Set[SchleuderKey],
if len(subscribed) == 0 and len(unsubscribed) == 0 and \ conflicts: List[Optional[Message]]):
len(removed) == 0 and len(added) == 0 and len(updated) == 0: 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') 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''' content = f'''
== Admin Report for MultiSchleuder {schleuder} == == Admin Report for MultiSchleuder {schleuder} ==
''' '''
@ -219,6 +243,19 @@ class AdminReport(Message):
''' '''
for k in removed: for k in removed:
content += f'{k.fingerprint} ({k.email})\n' 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__( super().__init__(
schleuder=schleuder, schleuder=schleuder,
mail_from=mail_from, mail_from=mail_from,