From c1b35bd16f54e8e1ee6a56bbb8d579a269089607 Mon Sep 17 00:00:00 2001 From: Luc De Meyer Date: Sat, 9 Dec 2023 11:22:17 +0100 Subject: [PATCH 1/2] [FIX]fix handling of non-stored passphrases module: account_ebics 16.0 The non-stored passphrases (passphrase, sig_passphrase) were incorrectly handled during the INIT cycle: - setting 'ebics_passphrase_store' during INIT cycle didn't work - setting the 'ebics_sig_passphrase' during INIT cycle didn't work --- account_ebics/__manifest__.py | 2 +- account_ebics/models/ebics_userid.py | 84 ++++++++++++------- .../wizards/ebics_change_passphrase.py | 8 +- 3 files changed, 64 insertions(+), 30 deletions(-) diff --git a/account_ebics/__manifest__.py b/account_ebics/__manifest__.py index 4556b4e..c737c4b 100644 --- a/account_ebics/__manifest__.py +++ b/account_ebics/__manifest__.py @@ -3,7 +3,7 @@ { "name": "EBICS banking protocol", - "version": "16.0.1.7.1", + "version": "16.0.1.8.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 79ff9f1..97caf0f 100644 --- a/account_ebics/models/ebics_userid.py +++ b/account_ebics/models/ebics_userid.py @@ -117,7 +117,6 @@ class EbicsUserID(models.Model): ) 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 " @@ -228,10 +227,12 @@ class EbicsUserID(models.Model): @api.depends("state", "ebics_passphrase") def _compute_ebics_passphrase_view_modifiers(self): for rec in self: + rec.ebics_passphrase_invisible = False if rec.state == "draft": rec.ebics_passphrase_required = True - rec.ebics_passphrase_invisible = False - elif rec.state == "get_bank_keys": + elif rec.state == "init": + rec.ebics_passphrase_invisible = True + elif rec.state in ("get_bank_keys", "to_verify"): rec.ebics_passphrase_required = not rec.ebics_passphrase rec.ebics_passphrase_invisible = rec.ebics_passphrase else: @@ -253,11 +254,19 @@ class EbicsUserID(models.Model): 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", "ebics_sig_passphrase") + @api.constrains("ebics_passphrase") def _check_ebics_passphrase(self): for rec in self: if rec.ebics_passphrase and len(rec.ebics_passphrase) < 8: - raise UserError(_("The passphrase must be at least 8 characters long")) + raise UserError(_("The Passphrase must be at least 8 characters long")) + + @api.constrains("ebics_sig_passphrase") + def _check_ebics_sig_passphrase(self): + for rec in self: + if rec.ebics_sig_passphrase and len(rec.ebics_sig_passphrase) < 8: + raise UserError( + _("The Signature Passphrase must be at least 8 characters long") + ) @api.onchange("ebics_version") def _onchange_ebics_version(self): @@ -271,7 +280,7 @@ class EbicsUserID(models.Model): @api.onchange("ebics_passphrase_store") def _onchange_ebics_passphrase_store(self): - if not self.ebics_passphrase_store: + if not self.ebics_passphrase_store and self.state == "active_keys": self.ebics_passphrase = False @api.onchange("swift_3skey") @@ -320,7 +329,7 @@ class EbicsUserID(models.Model): "passphrase": self.ebics_passphrase, } if self.ebics_sig_passphrase: - keyring_params["ebics_sig_passphrase"] = self.ebics_sig_passphrase + keyring_params["sig_passphrase"] = self.ebics_sig_passphrase keyring = EbicsKeyRing(**keyring_params) bank = EbicsBank( keyring=keyring, @@ -457,24 +466,35 @@ class EbicsUserID(models.Model): fn_date = fields.Date.today().isoformat() fn = "_".join([self.ebics_config_id.ebics_host, "ini_letter", fn_date]) + ".pdf" letter = user.create_ini_letter(bankname=ebics_config_bank.name, lang=lang) - self.write( - { - "ebics_ini_letter": base64.encodebytes(letter), - "ebics_ini_letter_fn": fn, - } - ) - - return self.write({"state": "init"}) + vals = { + "ebics_ini_letter": base64.encodebytes(letter), + "ebics_ini_letter_fn": fn, + "state": "init", + } + # remove non-stored passphrases from db after successfull init_1 + if not self.ebics_passphrase_store: + vals.update["ebics_passphrase"] = False + if self.ebics_sig_passphrase: + vals.update["ebics_sig_passphrase"] = False + return self.write(vals) def ebics_init_2(self): """ Initialization of bank keys - Step 2: Activation of the account by the bank. """ + self.ensure_one() if self.state != "init": raise UserError(_("Set state to 'Initialisation'.")) - self.ensure_one() - return self.write({"state": "get_bank_keys"}) + vals = {"state": "get_bank_keys"} + # remove non-stored passphrases from db + # remark: this code is here for extra safety but shouldn't + # have any effect since passphrases are invisible in state "init" + if not self.ebics_passphrase_store: + vals.update["ebics_passphrase"] = False + if self.ebics_sig_passphrase: + vals.update["ebics_sig_passphrase"] = False + return self.write(vals) def ebics_init_3(self): """ @@ -527,21 +547,23 @@ class EbicsUserID(models.Model): "_".join([self.ebics_config_id.ebics_host, "public_bank_keys", fn_date]) + ".txt" ) - self.write( - { - "ebics_public_bank_keys": base64.encodebytes(public_bank_keys), - "ebics_public_bank_keys_fn": fn, - "state": "to_verify", - } - ) - - return True + vals = { + "ebics_public_bank_keys": base64.encodebytes(public_bank_keys), + "ebics_public_bank_keys_fn": fn, + "state": "to_verify", + } + # remove non-stored passphrases from db + if not self.ebics_passphrase_store: + vals.update["ebics_passphrase"] = False + if self.ebics_sig_passphrase: + vals.update["ebics_sig_passphrase"] = False + return self.write(vals) def ebics_init_4(self): """ Initialization of bank keys - Step 2: Confirm Verification of the public bank keys - and activate the bank keyu. + and activate the bank keys. """ self.ensure_one() if self.state != "to_verify": @@ -556,7 +578,13 @@ class EbicsUserID(models.Model): url=self.ebics_config_id.ebics_url, ) bank.activate_keys() - return self.write({"state": "active_keys"}) + vals = {"state": "active_keys"} + # remove non-stored passphrases from db + if not self.ebics_passphrase_store: + vals.update["ebics_passphrase"] = False + if self.ebics_sig_passphrase: + vals.update["ebics_sig_passphrase"] = False + return self.write(vals) def change_passphrase(self): self.ensure_one() diff --git a/account_ebics/wizards/ebics_change_passphrase.py b/account_ebics/wizards/ebics_change_passphrase.py index 92561b9..b4b206d 100644 --- a/account_ebics/wizards/ebics_change_passphrase.py +++ b/account_ebics/wizards/ebics_change_passphrase.py @@ -89,9 +89,15 @@ class EbicsChangePassphrase(models.TransientModel): raise UserError(str(err)) from err if self.new_pass: - self.ebics_userid_id.ebics_passphrase = self.new_pass + self.ebics_userid_id.ebics_passphrase = ( + self.ebics_userid_id.ebics_passphrase_store and self.new_pass + ) self.note += "The EBICS Passphrase has been changed." if self.new_sig_pass: + # removing ebics_sig_passphrase from db should not be required + # but we do it for double safety + if self.ebics_userid_id.ebics_sig_passphrase: + self.ebics_userid_id.ebics_sig_passphrase = False self.note += "The EBICS Signature Passphrase has been changed." module = __name__.split("addons.")[1].split(".")[0] From 752c0cd2d4e3e659c1ef3f569b6a994abb0fbbcc Mon Sep 17 00:00:00 2001 From: Luc De Meyer Date: Sat, 9 Dec 2023 12:06:40 +0100 Subject: [PATCH 2/2] [IMP]account_ebics - update documentation --- account_ebics/README.rst | 15 +++++++++++++-- account_ebics/models/ebics_userid.py | 4 ---- account_ebics/static/description/index.html | 17 ++++++++++++++--- account_ebics/wizards/ebics_xfer.py | 7 ------- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/account_ebics/README.rst b/account_ebics/README.rst index 9f939ab..1d86f00 100644 --- a/account_ebics/README.rst +++ b/account_ebics/README.rst @@ -174,6 +174,16 @@ Go to **Accounting > Bank and Cash > EBICS Processing** | +Diagnostics +=========== + +Add the following to your Odoo config file in order to diagnose +issues with the EBICS connection with your bank: + +log_handler = fintech.ebics:DEBUG + +| + EBICS Return Codes ------------------ @@ -192,13 +202,14 @@ 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 +- https://play.google.com/store/apps/details?id=subsembly.bankingveu +- https://apps.apple.com/de/app/bankingveu/id1578694190 Known Issues / Roadmap ====================== +- The end user is currently not able to change his passphrases (only the users with 'EBICS Manager' rights can do so). - Add support to import externally generated keys & certificates (currently only 3SKey signature certificate). - Add support for SWIFT 3SKey signing javascript lib (SConnect, cf https://www2.swift.com/3skey/help/sconnect.html). diff --git a/account_ebics/models/ebics_userid.py b/account_ebics/models/ebics_userid.py index 97caf0f..d8e8ad1 100644 --- a/account_ebics/models/ebics_userid.py +++ b/account_ebics/models/ebics_userid.py @@ -13,10 +13,6 @@ from odoo.exceptions import UserError _logger = logging.getLogger(__name__) -# logging.basicConfig( -# level=logging.DEBUG, -# format='[%(asctime)s] %(levelname)s - %(name)s: %(message)s') - try: import fintech from fintech.ebics import ( diff --git a/account_ebics/static/description/index.html b/account_ebics/static/description/index.html index 61ac626..5122f07 100644 --- a/account_ebics/static/description/index.html +++ b/account_ebics/static/description/index.html @@ -527,6 +527,15 @@ fintech_register_keycode = AB1CD-E2FG-3H-IJ4K-5L

+ +
+

Diagnostics

+

Add the following to your Odoo config file in order to diagnose +issues with the EBICS connection with your bank:

+

log_handler = fintech.ebics:DEBUG

+
+

+

EBICS Return Codes

During the processing of your EBICS upload/download, your bank may return an Error Code, e.g.

@@ -541,14 +550,16 @@ You can also find this information in the doc folder of this module (file EBICS_

Known Issues / Roadmap

    +
  • The end user is currently not able to change his passphrases (only the users with 'EBICS Manager' rights can do so).
  • Add support to import externally generated keys & certificates (currently only 3SKey signature certificate).
  • Add support for SWIFT 3SKey signing javascript lib (SConnect, cf https://www2.swift.com/3skey/help/sconnect.html).
diff --git a/account_ebics/wizards/ebics_xfer.py b/account_ebics/wizards/ebics_xfer.py index ed45f93..921d8da 100644 --- a/account_ebics/wizards/ebics_xfer.py +++ b/account_ebics/wizards/ebics_xfer.py @@ -1,13 +1,6 @@ # Copyright 2009-2023 Noviat. # License LGPL-3 or later (http://www.gnu.org/licenses/lgpl). -""" -import logging -logging.basicConfig( - level=logging.DEBUG, - format='[%(asctime)s] %(levelname)s - %(name)s: %(message)s') -""" - import base64 import logging from sys import exc_info