commit da0fc95292a7993c7e0dcf38747e008264543ca7
Author: Stanislav Král <stanislav.kral3@gmail.com>
Date:   Sat May 8 08:37:55 2021 +0200

    Added a global error handler for CryptographyException errors.
    Added a dependency ony pytest-mock library in order to be able to mock method calls in tests.
    Covered the added global CryptographyException error handler in a test.

diff --git a/app.py b/app.py
index 4534460..04b0d12 100644
--- a/app.py
+++ b/app.py
@@ -90,6 +90,11 @@ def generate_certificate_pkcs_identity(id, certificate_controller: CertControlle
     return certificate_controller.generate_certificate_pkcs_identity(id)
 
 
+@app.errorhandler(CryptographyException)
+def cryptography_error(e, certificate_controller: CertController):
+    return certificate_controller.handle_cryptography_error(e)
+
+
 def initialize_app(application) -> bool:
     """
     Initializes the application
diff --git a/requirements.txt b/requirements.txt
index c89e905..4613239 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,3 +4,4 @@ injector==0.18.4
 Flask-Injector==0.12.3
 pytest-cov==2.11.1
 six==1.15.0
+pytest-mock==3.6.1
\ No newline at end of file
diff --git a/src/controllers/certificates_controller.py b/src/controllers/certificates_controller.py
index 36018dc..4261b9c 100644
--- a/src/controllers/certificates_controller.py
+++ b/src/controllers/certificates_controller.py
@@ -65,6 +65,8 @@ E_IDENTITY_PASSWORD_NOT_SPECIFIED = {"success": False, "data": "Invalid request,
 E_INVALID_EXTENSIONS = {"success": False, "data": "Error occurred while creating a certificate. "
                                                   "It may be caused by wrong format of extensions."}
 
+E_UNHANDLED_CRYPTOGRAPHY_ERROR = {"success": False, "data": "An unknown error has happened in the cryptography library."}
+
 
 class CertController:
     USAGE_KEY_MAP = {'CA': CA_ID, 'SSL': SSL_ID, 'digitalSignature': SIGNATURE_ID, 'authentication': AUTHENTICATION_ID}
@@ -768,3 +770,8 @@ class CertController:
                                                                                           identity_name,
                                                                                           identity_password)
                     return Response(identity_byte_array, mimetype='application/x-pkcs12')
+
+    @staticmethod
+    def handle_cryptography_error(e):
+        Logger.error(f"An unhandled CryptographyException has been raised: {str(e)}")
+        return E_UNHANDLED_CRYPTOGRAPHY_ERROR, C_INTERNAL_SERVER_ERROR
diff --git a/src/services/cryptography.py b/src/services/cryptography.py
index 4366bba..a8265ed 100644
--- a/src/services/cryptography.py
+++ b/src/services/cryptography.py
@@ -520,6 +520,7 @@ class CryptographyException(Exception):
 
     def __str__(self):
         # TODO check log is valid here
+        # TODO Standa does not think so...
         msg = f"""
         EXECUTABLE: {self.executable}
         ARGS: {self.args}
diff --git a/tests/integration_tests/rest_api/certificates_test.py b/tests/integration_tests/rest_api/certificates_test.py
index 0e03876..85de176 100644
--- a/tests/integration_tests/rest_api/certificates_test.py
+++ b/tests/integration_tests/rest_api/certificates_test.py
@@ -3,7 +3,8 @@
 # 2->3->4->5->6->7
 # 2->8->9
 from src.controllers.certificates_controller import E_IDENTITY_NAME_NOT_SPECIFIED, E_IDENTITY_PASSWORD_NOT_SPECIFIED, \
-    E_NO_CERTIFICATES_FOUND
+    E_NO_CERTIFICATES_FOUND, E_UNHANDLED_CRYPTOGRAPHY_ERROR
+from src.services.cryptography import CryptographyException
 
 
 def make_root_ca(server, title="Root CA s.r.o."):
@@ -1295,3 +1296,18 @@ def test_generate_identity_non_well_formed(server):
                                json={"password": "foopass", "name": "Foo"})
     assert identity_ret.status_code == 404
     assert identity_ret.json == E_NO_CERTIFICATES_FOUND
+
+
+def test_cryptography_error_handler(server, mocker):
+    def mock_raises_cryptography_error(self, subject, key, config="", extensions="", key_pass=None, days=30, sn: int = None):
+        raise CryptographyException("openssl", ["x509", "-faulty"], "Faulty openssl call")
+
+    mocker.patch(
+        # patch create_sscrt in such way that a CryptographyException is raised
+        'src.services.cryptography.CryptographyService.create_sscrt',
+        mock_raises_cryptography_error
+    )
+
+    ret = make_root_ca(server)
+    assert ret.status_code == 500
+    assert ret.json == E_UNHANDLED_CRYPTOGRAPHY_ERROR
