diff --git a/CHANGELOG.md b/CHANGELOG.md index b902c95..dbeddd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # MultiSchleuder Changelog + +## Version 0.1.7 + +Bugfix Release + +### Changes + + +- Remove and re-import keys whose expiry date has been changed +- Don't report keys as changed if they appear to differ, but are treated as identical by GnuPG. + + + + ## Version 0.1.6 diff --git a/multischleuder/__init__.py b/multischleuder/__init__.py index 82a4917..1c808d0 100644 --- a/multischleuder/__init__.py +++ b/multischleuder/__init__.py @@ -1,2 +1,2 @@ -__version__ = '0.1.6' +__version__ = '0.1.7' diff --git a/multischleuder/processor.py b/multischleuder/processor.py index 114ec9f..a9eb2a2 100644 --- a/multischleuder/processor.py +++ b/multischleuder/processor.py @@ -63,8 +63,14 @@ class MultiList: to_unsubscribe = current_subs.difference(intended_subs) to_remove = current_keys.difference(intended_keys) to_add = intended_keys.difference(current_keys) + # Already present keys that are being updated have to be removed and re-imported for convergence + to_pre_remove = {k for k in to_add if k.fingerprint in {o.fingerprint for o in to_remove}} + to_remove = {k for k in to_remove if k.fingerprint not in {o.fingerprint for o in to_pre_remove}} to_update = {s for s in intended_subs if s in current_subs and s.key in to_add} # Perform the actual list modifications in an order which avoids race conditions + for key in to_pre_remove: + self._api.delete_key(key, target_list) + logging.info(f'Pre-removed key: {key}') for key in to_add: self._api.post_key(key, target_list) logging.info(f'Added key: {key}') @@ -81,6 +87,23 @@ class MultiList: self._api.delete_key(key, target_list) logging.info(f'Removed key: {key}') + # Workaround for quirky gpg behaviour where some key signatures are exported from a sublist, but dropped on + # import into the target list, leading to a situation where the same key is imported over and over again. + new_subs = set() + # Get the new list of subscribers + for s in self._api.get_subscribers(target_list): + if s.email in self._unmanaged or s.email == self._target: + continue + if s.key is None or s.key.fingerprint == target_list.fingerprint: + continue + new_subs.add(s) + # Compare the key blobs to the ones present before this run + unchanged_subs = {s for s in new_subs if s.key.blob in {o.key.blob for o in current_subs if o.key is not None}} + # Remove the unchanged keys from the changesets so that they are not included in the admin report + to_subscribe = {s for s in to_subscribe if s not in unchanged_subs} + to_update = {s for s in to_update if s not in unchanged_subs} + to_add = {k for k in to_add if k.fingerprint not in {s.key.fingerprint for s in unchanged_subs}} + if len(to_add) + len(to_subscribe) + len(to_unsubscribe) + len(to_remove) == 0: logging.info(f'No changes for {self._target}') else: