[openpgp] Port to Gtk4

This commit is contained in:
Philipp Hörist
2025-02-08 16:10:31 +01:00
parent 3a5816259c
commit c67e7f341b
19 changed files with 935 additions and 1111 deletions

View File

@@ -14,8 +14,17 @@
# You should have received a copy of the GNU General Public License
# along with OpenPGP Gajim Plugin. If not, see <http://www.gnu.org/licenses/>.
import logging
from __future__ import annotations
import logging
from collections.abc import Iterator
from nbxmpp.protocol import JID
from nbxmpp.structs import PGPKeyMetadata
from openpgp.backend.base import BasePGPBackend
from openpgp.backend.sql import ContactRow
from openpgp.backend.sql import Storage
from openpgp.modules.util import Trust
log = logging.getLogger("gajim.p.openpgp.store")
@@ -26,45 +35,34 @@ class KeyData:
Holds all data related to a certain key
"""
def __init__(self, contact_data):
def __init__(
self,
contact_data: ContactData,
fingerprint: str,
active: bool,
trust: Trust,
timestamp: float,
):
self._contact_data = contact_data
self.fingerprint = None
self.active = False
self._trust = Trust.UNKNOWN
self.timestamp = None
self.fingerprint = fingerprint
self.active = active
self._trust = trust
self.timestamp = timestamp
self.comment = None
self.has_pubkey = False
@property
def trust(self):
def trust(self) -> Trust:
return self._trust
@trust.setter
def trust(self, value):
def trust(self, value: Trust) -> None:
if value not in (Trust.NOT_TRUSTED, Trust.UNKNOWN, Trust.BLIND, Trust.VERIFIED):
raise ValueError("Trust value not allowed: %s" % value)
self._trust = value
self._contact_data.set_trust(self.fingerprint, self._trust)
@classmethod
def from_key(cls, contact_data, key, trust):
keydata = cls(contact_data)
keydata.fingerprint = key.fingerprint
keydata.timestamp = key.date
keydata.active = True
keydata._trust = trust
return keydata
@classmethod
def from_row(cls, contact_data, row):
keydata = cls(contact_data)
keydata.fingerprint = row.fingerprint
keydata.timestamp = row.timestamp
keydata.comment = row.comment
keydata._trust = row.trust
keydata.active = row.active
return keydata
def delete(self):
self._contact_data.delete_key(self.fingerprint)
@@ -74,9 +72,9 @@ class ContactData:
Holds all data related to a contact
"""
def __init__(self, jid, storage, pgp):
def __init__(self, jid: JID, storage: Storage, pgp: BasePGPBackend) -> None:
self.jid = jid
self._key_store = {}
self._key_store: dict[str, KeyData] = {}
self._storage = storage
self._pgp = pgp
@@ -87,13 +85,13 @@ class ContactData:
return "xmpp:%s" % self.jid
@property
def default_trust(self):
def default_trust(self) -> Trust:
for key in self._key_store.values():
if key.trust in (Trust.NOT_TRUSTED, Trust.BLIND):
return Trust.UNKNOWN
return Trust.BLIND
def db_values(self):
def db_values(self) -> Iterator[tuple[JID, str, bool, Trust, float]]:
for key in self._key_store.values():
yield (
self.jid,
@@ -101,28 +99,39 @@ class ContactData:
key.active,
key.trust,
key.timestamp,
key.comment,
)
def add_from_key(self, key):
def add_from_key(self, key: PGPKeyMetadata) -> KeyData:
try:
keydata = self._key_store[key.fingerprint]
except KeyError:
keydata = KeyData.from_key(self, key, self.default_trust)
keydata = KeyData(
self,
key.fingerprint,
True,
self.default_trust,
key.date,
)
self._key_store[key.fingerprint] = keydata
log.info("Add from key: %s %s", self.jid, keydata.fingerprint)
return keydata
def add_from_db(self, row):
def add_from_db(self, row: ContactRow) -> KeyData:
try:
keydata = self._key_store[row.fingerprint]
except KeyError:
keydata = KeyData.from_row(self, row)
keydata = KeyData(
self,
row.fingerprint,
row.active,
row.trust,
row.timestamp,
)
self._key_store[row.fingerprint] = keydata
log.info("Add from row: %s %s", self.jid, row.fingerprint)
return keydata
def process_keylist(self, keylist):
def process_keylist(self, keylist: list[PGPKeyMetadata] | None) -> list[str]:
log.info("Process keylist: %s %s", self.jid, keylist)
if keylist is None:
@@ -131,8 +140,8 @@ class ContactData:
self._storage.save_contact(self.db_values())
return []
missing_pub_keys = []
fingerprints = set([key.fingerprint for key in keylist])
missing_pub_keys: list[str] = []
fingerprints = {key.fingerprint for key in keylist}
if fingerprints == self._key_store.keys():
log.info("No updates found")
for key in self._key_store.values():
@@ -156,7 +165,7 @@ class ContactData:
self._storage.save_contact(self.db_values())
return missing_pub_keys
def set_public_key(self, fingerprint):
def set_public_key(self, fingerprint: str) -> None:
try:
keydata = self._key_store[fingerprint]
except KeyError:
@@ -167,7 +176,7 @@ class ContactData:
keydata.has_pubkey = True
log.info("Set public key: %s %s", self.jid, fingerprint)
def get_keys(self, only_trusted=True):
def get_keys(self, only_trusted: bool = True) -> list[KeyData]:
keys = list(self._key_store.values())
if not only_trusted:
return keys
@@ -175,13 +184,13 @@ class ContactData:
k for k in keys if k.active and k.trust in (Trust.VERIFIED, Trust.BLIND)
]
def get_key(self, fingerprint):
def get_key(self, fingerprint: str) -> KeyData | None:
return self._key_store.get(fingerprint, None)
def set_trust(self, fingerprint, trust):
def set_trust(self, fingerprint: str, trust: Trust) -> None:
self._storage.set_trust(self.jid, fingerprint, trust)
def delete_key(self, fingerprint):
def delete_key(self, fingerprint: str) -> None:
self._storage.delete_key(self.jid, fingerprint)
self._pgp.delete_key(fingerprint)
del self._key_store[fingerprint]
@@ -192,8 +201,8 @@ class PGPContacts:
Holds all contacts available for PGP encryption
"""
def __init__(self, pgp, storage):
self._contacts = {}
def __init__(self, pgp: BasePGPBackend, storage: Storage) -> None:
self._contacts: dict[JID, ContactData] = {}
self._storage = storage
self._pgp = pgp
self._load_from_storage()
@@ -204,14 +213,12 @@ class PGPContacts:
keyring = self._pgp.get_keys()
for key in keyring:
log.info("Found: %s %s", key.jid, key.fingerprint)
assert key.jid is not None
self.set_public_key(key.jid, key.fingerprint)
def _load_from_storage(self):
log.info("Load contacts from storage")
rows = self._storage.load_contacts()
if rows is None:
return
for row in rows:
log.info("Found: %s %s", row.jid, row.fingerprint)
try:
@@ -223,7 +230,9 @@ class PGPContacts:
else:
contact_data.add_from_db(row)
def process_keylist(self, jid, keylist):
def process_keylist(
self, jid: JID, keylist: list[PGPKeyMetadata] | None
) -> list[str]:
try:
contact_data = self._contacts[jid]
except KeyError:
@@ -235,7 +244,7 @@ class PGPContacts:
return missing_pub_keys
def set_public_key(self, jid, fingerprint):
def set_public_key(self, jid: JID, fingerprint: str) -> None:
try:
contact_data = self._contacts[jid]
except KeyError:
@@ -243,14 +252,14 @@ class PGPContacts:
else:
contact_data.set_public_key(fingerprint)
def get_keys(self, jid, only_trusted=True):
def get_keys(self, jid: JID, only_trusted: bool = True) -> list[KeyData]:
try:
contact_data = self._contacts[jid]
return contact_data.get_keys(only_trusted=only_trusted)
except KeyError:
return []
def get_trust(self, jid, fingerprint):
def get_trust(self, jid: JID, fingerprint: str) -> Trust:
contact_data = self._contacts.get(jid, None)
if contact_data is None:
return Trust.UNKNOWN