From e5953a1f4b2d58c0dc02cf25c1d14a679f80aa3b Mon Sep 17 00:00:00 2001 From: Luc De Meyer Date: Sat, 2 Dec 2023 18:35:04 +0100 Subject: [PATCH] [IMP]add support for signature passphrase --- account_ebics/__manifest__.py | 2 +- account_ebics/models/ebics_userid.py | 34 ++++++- account_ebics/views/ebics_userid_views.xml | 6 ++ .../wizards/ebics_change_passphrase.py | 72 +++++++++++---- .../wizards/ebics_change_passphrase.xml | 91 ++++++++++++------- account_ebics/wizards/ebics_xfer.py | 30 ++++-- account_ebics/wizards/ebics_xfer.xml | 6 ++ 7 files changed, 178 insertions(+), 63 deletions(-) diff --git a/account_ebics/__manifest__.py b/account_ebics/__manifest__.py index aa0643b..8f66b60 100644 --- a/account_ebics/__manifest__.py +++ b/account_ebics/__manifest__.py @@ -3,7 +3,7 @@ { "name": "EBICS banking protocol", - "version": "16.0.1.6.2", + "version": "16.0.1.7.0", "license": "LGPL-3", "author": "Noviat", "website": "https://www.noviat.com/", diff --git a/account_ebics/models/ebics_userid.py b/account_ebics/models/ebics_userid.py index ef2dc13..62e9a0d 100644 --- a/account_ebics/models/ebics_userid.py +++ b/account_ebics/models/ebics_userid.py @@ -115,6 +115,17 @@ class EbicsUserID(models.Model): ebics_passphrase_invisible = fields.Boolean( compute="_compute_ebics_passphrase_view_modifiers" ) + ebics_sig_passphrase = fields.Char( + string="EBICS Signature Passphrase", + store=False, + help="You can set here a different passphrase for the EBICS " + "signing key. This passphrase will never be stored hence " + "you'll need to specify your passphrase for each transaction that " + "requires a digital signature.", + ) + ebics_sig_passphrase_invisible = fields.Boolean( + compute="_compute_ebics_sig_passphrase_invisible" + ) ebics_ini_letter = fields.Binary( string="EBICS INI Letter", readonly=True, @@ -227,13 +238,22 @@ class EbicsUserID(models.Model): rec.ebics_passphrase_required = False rec.ebics_passphrase_invisible = True + @api.depends("state") + def _compute_ebics_sig_passphrase_invisible(self): + for rec in self: + rec.ebics_sig_passphrase_invisible = True + if fintech.__version_info__ < (7, 3, 1): + continue + if rec.transaction_rights != "down" and rec.state == "draft": + rec.ebics_sig_passphrase_invisible = False + @api.constrains("ebics_key_x509") def _check_ebics_key_x509(self): for cfg in self: if cfg.ebics_version == "H005" and not cfg.ebics_key_x509: raise UserError(_("X.509 certificates must be used with EBICS 3.0.")) - @api.constrains("ebics_passphrase") + @api.constrains("ebics_passphrase", "ebics_sig_passphrase") def _check_ebics_passphrase(self): for rec in self: if rec.ebics_passphrase and len(rec.ebics_passphrase) < 8: @@ -295,9 +315,13 @@ class EbicsUserID(models.Model): ebics_version = self.ebics_config_id.ebics_version try: - keyring = EbicsKeyRing( - keys=self.ebics_keys_fn, passphrase=self.ebics_passphrase - ) + keyring_params = { + "keys": self.ebics_keys_fn, + "passphrase": self.ebics_passphrase, + } + if self.ebics_sig_passphrase: + keyring_params["ebics_sig_passphrase"] = self.ebics_sig_passphrase + keyring = EbicsKeyRing(**keyring_params) bank = EbicsBank( keyring=keyring, hostid=self.ebics_config_id.ebics_host, @@ -536,7 +560,7 @@ class EbicsUserID(models.Model): def change_passphrase(self): self.ensure_one() - ctx = dict(self._context, default_ebics_userid_id=self.id) + ctx = dict(self.env.context, default_ebics_userid_id=self.id) module = __name__.split("addons.")[1].split(".")[0] view = self.env.ref("%s.ebics_change_passphrase_view_form" % module) return { diff --git a/account_ebics/views/ebics_userid_views.xml b/account_ebics/views/ebics_userid_views.xml index e4d9fd5..76c5021 100644 --- a/account_ebics/views/ebics_userid_views.xml +++ b/account_ebics/views/ebics_userid_views.xml @@ -88,6 +88,7 @@ + + diff --git a/account_ebics/wizards/ebics_change_passphrase.py b/account_ebics/wizards/ebics_change_passphrase.py index 38e689c..92561b9 100644 --- a/account_ebics/wizards/ebics_change_passphrase.py +++ b/account_ebics/wizards/ebics_change_passphrase.py @@ -24,37 +24,75 @@ class EbicsChangePassphrase(models.TransientModel): ebics_userid_id = fields.Many2one( comodel_name="ebics.userid", string="EBICS UserID", readonly=True ) - old_pass = fields.Char(string="Old Passphrase", required=True) - new_pass = fields.Char(string="New Passphrase", required=True) - new_pass_check = fields.Char(string="New Passphrase (verification)", required=True) + old_pass = fields.Char(string="Old Passphrase") + new_pass = fields.Char(string="New Passphrase") + new_pass_check = fields.Char(string="New Passphrase (verification)") + old_sig_pass = fields.Char(string="Old Signature Passphrase") + new_sig_pass = fields.Char(string="New Signature Passphrase") + new_sig_pass_check = fields.Char(string="New Signature Passphrase (verification)") + ebics_sig_passphrase_invisible = fields.Boolean( + compute="_compute_ebics_sig_passphrase_invisible" + ) note = fields.Text(string="Notes", readonly=True) + def _compute_ebics_sig_passphrase_invisible(self): + for rec in self: + if fintech.__version_info__ < (7, 3, 1): + rec.ebics_sig_passphrase_invisible = True + else: + rec.ebics_sig_passphrase_invisible = False + def change_passphrase(self): self.ensure_one() + self.note = "" if ( self.ebics_userid_id.ebics_passphrase_store + and self.old_pass and self.old_pass != self.ebics_userid_id.ebics_passphrase ): raise UserError(_("Incorrect old passphrase.")) if self.new_pass != self.new_pass_check: raise UserError(_("New passphrase verification error.")) - if self.new_pass == self.ebics_userid_id.ebics_passphrase: + if self.new_pass and self.new_pass == self.ebics_userid_id.ebics_passphrase: raise UserError(_("New passphrase equal to old passphrase.")) + if ( + self.new_sig_pass + and self.old_sig_pass + and self.new_sig_pass == self.old_sig_pass + ): + raise UserError( + _("New signature passphrase equal to old signature passphrase.") + ) + if self.new_sig_pass != self.new_sig_pass_check: + raise UserError(_("New signature passphrase verification error.")) + passphrase = ( + self.ebics_userid_id.ebics_passphrase_store + and self.ebics_userid_id.ebics_passphrase + or self.old_pass + ) try: - passphrase = ( - self.ebics_userid_id.ebics_passphrase_store - and self.ebics_userid_id.ebics_passphrase - or self.old_pass - ) - keyring = EbicsKeyRing( - keys=self.ebics_userid_id.ebics_keys_fn, - passphrase=passphrase, - ) - keyring.change_passphrase(self.new_pass) - except ValueError as err: + keyring_params = { + "keys": self.ebics_userid_id.ebics_keys_fn, + "passphrase": passphrase, + } + if self.new_sig_pass: + keyring_params["sig_passphrase"] = self.old_sig_pass + keyring = EbicsKeyRing(**keyring_params) + change_params = {} + if self.new_pass: + change_params["passphrase"] = self.new_pass + if self.new_sig_pass: + change_params["sig_passphrase"] = self.new_sig_pass + if change_params: + keyring.change_passphrase(**change_params) + except (ValueError, RuntimeError) as err: raise UserError(str(err)) from err - self.ebics_userid_id.ebics_passphrase = self.new_pass - self.note = "The EBICS Passphrase has been changed." + + if self.new_pass: + self.ebics_userid_id.ebics_passphrase = self.new_pass + self.note += "The EBICS Passphrase has been changed." + if self.new_sig_pass: + self.note += "The EBICS Signature Passphrase has been changed." module = __name__.split("addons.")[1].split(".")[0] result_view = self.env.ref( diff --git a/account_ebics/wizards/ebics_change_passphrase.xml b/account_ebics/wizards/ebics_change_passphrase.xml index bb24f0a..17839bd 100644 --- a/account_ebics/wizards/ebics_change_passphrase.xml +++ b/account_ebics/wizards/ebics_change_passphrase.xml @@ -1,44 +1,67 @@ - - EBICS Keys Change Passphrase - ebics.change.passphrase - 1 - -
- - - - - -
-
-
-
-
+