[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,10 +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/>.
from __future__ import annotations
from typing import Any
from typing import TYPE_CHECKING
import logging
from collections.abc import Callable
from pathlib import Path
from gi.repository import Gdk
from gi.repository import GLib
from gi.repository import Gtk
from nbxmpp import JID
from nbxmpp.namespaces import Namespace
@@ -25,7 +32,11 @@ from nbxmpp.namespaces import Namespace
from gajim.common import app
from gajim.common import configpaths
from gajim.common import ged
from gajim.common.client import Client
from gajim.common.const import CSSPriority
from gajim.common.events import SignedIn
from gajim.common.structs import OutgoingMessage
from gajim.gtk.control import ChatControl
from gajim.gtk.dialogs import SimpleDialog
from gajim.plugins import GajimPlugin
from gajim.plugins.plugins_i18n import _
@@ -35,18 +46,21 @@ from openpgp.modules.util import ENCRYPTION_NAME
try:
from openpgp.modules import openpgp
except (ImportError, OSError) as e:
ERROR_MSG = str(e)
error_msg = str(e)
else:
ERROR_MSG = None
error_msg = None
if TYPE_CHECKING:
from openpgp.modules.openpgp import OpenPGP
log = logging.getLogger("gajim.p.openpgp")
class OpenPGPPlugin(GajimPlugin):
def init(self):
if ERROR_MSG:
if error_msg:
self.activatable = False
self.available_text = ERROR_MSG
self.available_text = error_msg
self.config_dialog = None
return
@@ -76,7 +90,11 @@ class OpenPGPPlugin(GajimPlugin):
self._create_paths()
self._load_css()
def _load_css(self):
@staticmethod
def get_openpgp_module(account: str) -> OpenPGP:
return app.get_client(account).get_module("OpenPGP") # pyright: ignore
def _load_css(self) -> None:
path = Path(__file__).parent / "gtk" / "style.css"
try:
with path.open("r") as f:
@@ -85,59 +103,63 @@ class OpenPGPPlugin(GajimPlugin):
log.error("Error loading css: %s", exc)
return
display = Gdk.Display.get_default()
assert display is not None
try:
provider = Gtk.CssProvider()
provider.load_from_data(bytes(css.encode("utf-8")))
Gtk.StyleContext.add_provider_for_screen(
Gdk.Screen.get_default(), provider, CSSPriority.DEFAULT_THEME
provider.load_from_bytes(GLib.Bytes.new(css.encode("utf-8")))
Gtk.StyleContext.add_provider_for_display(
display, provider, CSSPriority.DEFAULT_THEME
)
except Exception:
log.exception("Error loading application css")
@staticmethod
def _create_paths():
def _create_paths() -> None:
keyring_path = Path(configpaths.get("MY_DATA")) / "openpgp"
if not keyring_path.exists():
keyring_path.mkdir()
def signed_in(self, event):
client = app.get_client(event.account)
if client.get_module("OpenPGP").secret_key_available:
def signed_in(self, event: SignedIn) -> None:
openpgp = self.get_openpgp_module(event.account)
if openpgp.secret_key_available:
log.info(
"%s => Publish keylist and public key after sign in", event.account
)
client.get_module("OpenPGP").request_keylist()
client.get_module("OpenPGP").set_public_key()
openpgp.request_keylist()
openpgp.set_public_key()
def activate(self):
def activate(self) -> None:
for account in app.settings.get_active_accounts():
client = app.get_client(account)
client.get_module("Caps").update_caps()
if app.account_is_connected(account):
if client.get_module("OpenPGP").secret_key_available:
openpgp = self.get_openpgp_module(account)
if openpgp.secret_key_available:
log.info(
"%s => Publish keylist and public key "
"after plugin activation",
account,
)
client.get_module("OpenPGP").request_keylist()
client.get_module("OpenPGP").set_public_key()
openpgp.request_keylist()
openpgp.set_public_key()
def deactivate(self):
def deactivate(self) -> None:
pass
@staticmethod
def _update_caps(_account, features):
def _update_caps(_account: str, features: list[str]) -> None:
features.append("%s+notify" % Namespace.OPENPGP_PK)
def activate_encryption(self, chat_control):
def activate_encryption(self, chat_control: ChatControl) -> bool:
account = chat_control.account
jid = chat_control.contact.jid
client = app.get_client(account)
if client.get_module("OpenPGP").secret_key_available:
keys = client.get_module("OpenPGP").get_keys(jid, only_trusted=False)
openpgp = self.get_openpgp_module(account)
if openpgp.secret_key_available:
keys = openpgp.get_keys(jid, only_trusted=False)
if not keys:
client.get_module("OpenPGP").request_keylist(JID.from_string(jid))
openpgp.request_keylist(JID.from_string(jid))
return True
from openpgp.gtk.wizard import KeyWizard
@@ -146,12 +168,12 @@ class OpenPGPPlugin(GajimPlugin):
return False
@staticmethod
def encryption_state(_chat_control, state):
def encryption_state(_chat_control: ChatControl, state: dict[str, Any]) -> None:
state["authenticated"] = True
state["visible"] = True
@staticmethod
def on_encryption_button_clicked(chat_control):
def on_encryption_button_clicked(chat_control: ChatControl) -> None:
account = chat_control.account
jid = chat_control.contact.jid
@@ -159,26 +181,31 @@ class OpenPGPPlugin(GajimPlugin):
KeyDialog(account, jid, app.window)
def _before_sendmessage(self, chat_control):
def _before_sendmessage(self, chat_control: ChatControl) -> None:
account = chat_control.account
jid = chat_control.contact.jid
client = app.get_client(account)
openpgp = self.get_openpgp_module(account)
if not client.get_module("OpenPGP").secret_key_available:
if not openpgp.secret_key_available:
from openpgp.gtk.wizard import KeyWizard
KeyWizard(self, account, chat_control)
return
keys = client.get_module("OpenPGP").get_keys(jid)
keys = openpgp.get_keys(jid)
if not keys:
SimpleDialog(
_("Not Trusted"), _("There was no trusted and active key found")
)
chat_control.sendmessage = False
@staticmethod
def _encrypt_message(client, obj, callback):
if not client.get_module("OpenPGP").secret_key_available:
def _encrypt_message(
self,
client: Client,
message: OutgoingMessage,
callback: Callable[[OutgoingMessage], None],
) -> None:
openpgp = self.get_openpgp_module(client.account)
if not openpgp.secret_key_available:
return
client.get_module("OpenPGP").encrypt_message(obj, callback)
openpgp.encrypt_message(message, callback)