forked from Mapan/odoo17e
88 lines
4.4 KiB
Python
88 lines
4.4 KiB
Python
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
from odoo import fields, models, _
|
|
from odoo.exceptions import UserError, RedirectWarning
|
|
from cryptography.hazmat.primitives import serialization
|
|
from cryptography import x509
|
|
from datetime import datetime
|
|
from requests.exceptions import HTTPError
|
|
import base64
|
|
import requests
|
|
|
|
class ResCompany(models.Model):
|
|
|
|
_inherit = "res.company"
|
|
|
|
l10n_nl_reports_sbr_cert = fields.Binary(
|
|
'PKI Certificate',
|
|
groups="base.group_system",
|
|
help="Upload here the certificate file that will be used to connect to the Digipoort infrastructure. "
|
|
"The private key from this file will be used, if there is one included.",
|
|
)
|
|
l10n_nl_reports_sbr_key = fields.Binary(
|
|
'PKI Private Key',
|
|
groups="base.group_system",
|
|
help="A private key is required in order for the Digipoort services to identify you. "
|
|
"No need to upload a key if it is already included in the certificate file.",
|
|
)
|
|
l10n_nl_reports_sbr_cert_filename = fields.Char('Certificate File Name')
|
|
l10n_nl_reports_sbr_key_filename = fields.Char('Private Key File Name')
|
|
l10n_nl_reports_sbr_server_root_cert = fields.Binary(
|
|
'SBR Root Certificate',
|
|
help="The SBR Tax Service Server Root Certificate is used to verifiy the connection with the Tax services server of the SBR."
|
|
"It is used in order to make the connection library trust the server."
|
|
)
|
|
l10n_nl_reports_sbr_last_sent_date_to = fields.Date(
|
|
'Last Date Sent',
|
|
help="Stores the date of the end of the last period submitted to the Tax Services",
|
|
readonly=True
|
|
)
|
|
|
|
def _l10n_nl_get_certificate_and_key_bytes(self, password=None):
|
|
""" Return the tuple (certificate, private key), each in the form of unencrypted PEM encoded bytes.
|
|
Parameter password must be a bytes object or None.
|
|
Throws a UserError if there is a misconfiguration.
|
|
"""
|
|
self.ensure_one()
|
|
|
|
if not self.l10n_nl_reports_sbr_cert or not self.l10n_nl_reports_sbr_key:
|
|
raise RedirectWarning(
|
|
_("The certificate or the private key is missing. Please upload it in the Accounting Settings first."),
|
|
self.env.ref('account.action_account_config').id,
|
|
_("Go to the Accounting Settings"),
|
|
)
|
|
stored_certificate = base64.b64decode(self.l10n_nl_reports_sbr_cert)
|
|
stored_key = base64.b64decode(self.l10n_nl_reports_sbr_key)
|
|
|
|
try:
|
|
cert_obj, pkey_obj = (x509.load_pem_x509_certificate(stored_certificate), serialization.load_pem_private_key(stored_key, password or None))
|
|
except TypeError:
|
|
raise UserError(_('The certificate or private key you uploaded is encrypted. Please specify your password.'))
|
|
except ValueError:
|
|
raise UserError(_('An error occurred while decrypting your certificate or private key. Please verify your password.'))
|
|
|
|
cert_bytes = cert_obj.public_bytes(serialization.Encoding.PEM)
|
|
pkey_bytes = pkey_obj.private_bytes(
|
|
encoding=serialization.Encoding.PEM,
|
|
format=serialization.PrivateFormat.PKCS8,
|
|
encryption_algorithm=serialization.NoEncryption()
|
|
)
|
|
return (cert_bytes, pkey_bytes)
|
|
|
|
def _l10n_nl_get_server_root_certificate_bytes(self):
|
|
""" Return the tax service server root certificate as PEM encoded bytes.
|
|
Throws a UserError if the services are not reachable.
|
|
"""
|
|
cert_root_bytes = base64.b64decode(self.l10n_nl_reports_sbr_server_root_cert or '')
|
|
if not cert_root_bytes or x509.load_pem_x509_certificate(cert_root_bytes).not_valid_after < datetime.now():
|
|
try:
|
|
req_root = requests.get('https://cert.pkioverheid.nl/PrivateRootCA-G1.cer', timeout=30)
|
|
req_root.raise_for_status()
|
|
|
|
# This certificate is a .cer and is in DER format, we need to change it to PEM format for the libraries
|
|
der_root_obj = x509.load_der_x509_certificate(req_root.content)
|
|
cert_root_bytes = der_root_obj.public_bytes(serialization.Encoding.PEM)
|
|
self.l10n_nl_reports_sbr_server_root_cert = base64.b64encode(cert_root_bytes)
|
|
except HTTPError:
|
|
raise UserError(_("The server root certificate is not accessible at the moment. Please try again later."))
|
|
return cert_root_bytes
|