diff --git a/account_ebics/README.rst b/account_ebics/README.rst index f054250..9f939ab 100644 --- a/account_ebics/README.rst +++ b/account_ebics/README.rst @@ -187,9 +187,18 @@ You can also find this information in the doc folder of this module (file EBICS_ | +Electronic Distributed Signature (EDS) +-------------------------------------- + +This is supported via external signing apps, e.g. BankingVEU: + + https://play.google.com/store/apps/details?id=subsembly.bankingveu + https://apps.apple.com/de/app/bankingveu/id1578694190 + + Known Issues / Roadmap ====================== - Add support to import externally generated keys & certificates (currently only 3SKey signature certificate). -- Electronic Distributed Signature (EDS) is not supported in the current version of this module. +- Add support for SWIFT 3SKey signing javascript lib (SConnect, cf https://www2.swift.com/3skey/help/sconnect.html). 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..79ff9f1 100644 --- a/account_ebics/models/ebics_userid.py +++ b/account_ebics/models/ebics_userid.py @@ -72,7 +72,7 @@ class EbicsUserID(models.Model): help="Users who are allowed to use this EBICS UserID for " " bank transactions.", ) - # Currently only a singe signature class per user is supported + # Currently only a single signature class per user is supported # Classes A and B are not yet supported. signature_class = fields.Selection( selection=[("E", "Single signature"), ("T", "Transport signature")], @@ -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/static/description/index.html b/account_ebics/static/description/index.html index dc19440..61ac626 100644 --- a/account_ebics/static/description/index.html +++ b/account_ebics/static/description/index.html @@ -538,12 +538,19 @@ You can also find this information in the doc folder of this module (file EBICS_

+
+

Electronic Distributed Signature (EDS)

+

This is supported via external signing apps, e.g. BankingVEU:

+
+https://play.google.com/store/apps/details?id=subsembly.bankingveu +https://apps.apple.com/de/app/bankingveu/id1578694190
+

Known Issues / Roadmap

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 - -
- - - - - -
-
-
-
-
+