From 480417626979bc69f3319f43f4be2bd1bd13bc0f Mon Sep 17 00:00:00 2001 From: David Svenson Date: Fri, 16 Apr 2021 16:15:18 +0200 Subject: [PATCH 01/11] Add comment about not handling methodNotAllowed --- bankid/exceptions.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bankid/exceptions.py b/bankid/exceptions.py index f8c20ca..b03c7e9 100644 --- a/bankid/exceptions.py +++ b/bankid/exceptions.py @@ -323,6 +323,7 @@ def __init__(self, *args, **kwargs): "alreadyInProgress": AlreadyInProgressError, "unauthorized": UnauthorizedError, "notFound": NotFoundError, + # 'methodNotAllowed': , # This will not be handled here... "requestTimeout": RequestTimeoutError, # 'unsupportedMediaType': , # This will not be handled here... "internalError": InternalError, From 6dd3397f8c430663dc898d17876af67270e61a88 Mon Sep 17 00:00:00 2001 From: David Svenson Date: Fri, 16 Apr 2021 16:17:06 +0200 Subject: [PATCH 02/11] Adjust to RP guidelines that now uses lowercase --- bankid/exceptions.py | 2 +- tests/test_exceptions.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bankid/exceptions.py b/bankid/exceptions.py index b03c7e9..05272e2 100644 --- a/bankid/exceptions.py +++ b/bankid/exceptions.py @@ -327,5 +327,5 @@ def __init__(self, *args, **kwargs): "requestTimeout": RequestTimeoutError, # 'unsupportedMediaType': , # This will not be handled here... "internalError": InternalError, - "Maintenance": MaintenanceError, + "maintenance": MaintenanceError, } diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py index b3272d5..04295d5 100644 --- a/tests/test_exceptions.py +++ b/tests/test_exceptions.py @@ -34,7 +34,7 @@ def test_exceptions(exception_class, rfa): (bankid.exceptions.NotFoundError, "notFound"), (bankid.exceptions.RequestTimeoutError, "requestTimeout"), (bankid.exceptions.InternalError, "internalError"), - (bankid.exceptions.MaintenanceError, "Maintenance"), + (bankid.exceptions.MaintenanceError, "maintenance"), (bankid.exceptions.BankIDError, "Unknown error code"), ], ) From 01debe3cc0a26b509bfb9bbfd417642f75fb5d0a Mon Sep 17 00:00:00 2001 From: David Svenson Date: Fri, 16 Apr 2021 16:18:29 +0200 Subject: [PATCH 03/11] Drop unused function --- bankid/exceptions.py | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/bankid/exceptions.py b/bankid/exceptions.py index 05272e2..742fb20 100644 --- a/bankid/exceptions.py +++ b/bankid/exceptions.py @@ -15,16 +15,6 @@ from __future__ import unicode_literals from __future__ import absolute_import -import six - - -def get_error_class(exc, exception_text): - error_class = _ERROR_CODE_TO_CLASS.get(six.text_type(exc.message)) - if error_class is None: - return BankIDError("{0}: {1}".format(exc, exception_text)) - else: - return error_class(exception_text) - def get_json_error_class(response): data = response.json() @@ -303,21 +293,6 @@ def __init__(self, *args, **kwargs): self.rfa = 5 -_ERROR_CODE_TO_CLASS = { - "INVALID_PARAMETERS": InvalidParametersError, - "ALREADY_IN_PROGRESS": AlreadyInProgressError, - "INTERNAL_ERROR": InternalError, - "RETRY": RetryError, - "ACCESS_DENIED_RP": AccessDeniedRPError, - "CLIENT_ERR": ClientError, - "EXPIRED_TRANSACTION": ExpiredTransactionError, - "CERTIFICATE_ERR": CertificateError, - "USER_CANCEL": UserCancelError, - "CANCELLED": CancelledError, - "START_FAILED": StartFailedError, -} - - _JSON_ERROR_CODE_TO_CLASS = { "invalidParameters": InvalidParametersError, "alreadyInProgress": AlreadyInProgressError, From e265543be9c830f1bf90b61a33a6b7f70bf0cab7 Mon Sep 17 00:00:00 2001 From: David Svenson Date: Fri, 16 Apr 2021 16:28:25 +0200 Subject: [PATCH 04/11] Drop obsolete errors --- bankid/exceptions.py | 154 ------------------------------------------- 1 file changed, 154 deletions(-) diff --git a/bankid/exceptions.py b/bankid/exceptions.py index 742fb20..0fbd67d 100644 --- a/bankid/exceptions.py +++ b/bankid/exceptions.py @@ -101,160 +101,6 @@ def __init__(self, *args, **kwargs): self.rfa = 5 -class RetryError(BankIDError): - """Remote server error, different from InternalError. - - **Code:** ``RETRY`` - - **Reason:** Internal technical error in the BankID system. - - **Action by RP:** RP must not automatically try again. RP must - inform the user that a technical error has - occurred. Message RFA5 should be used. - - """ - - def __init__(self, *args, **kwargs): - super(RetryError, self).__init__(*args, **kwargs) - self.rfa = 5 - - -class AccessDeniedRPError(BankIDError): - """Access permission denied error. - - **Code:** ``ACCESS_DENIED_RP`` - - **Reason:** RP does not have access to the service or - requested operation. - - **Action by RP:** RP must not try the same request again. This is - an internal error within RP's system and must - not be communicated to the user as a BankID-error. - - """ - - -class ClientError(BankIDError): - """Remote technical error. - - **Code:** ``CLIENT_ERR`` - - **Reason:** Internal technical error. It was not possible to - create or verify the transaction. - - **Action by RP:** RP must not automatically try again. RP must - inform the user. Message RFA12. - - """ - - def __init__(self, *args, **kwargs): - super(ClientError, self).__init__(*args, **kwargs) - self.rfa = 12 - - -class ExpiredTransactionError(BankIDError): - """Error due to collecting on an expired order. - - **Code:** ``EXPIRED_TRANSACTION`` - - **Reason:** The order has expired. The BankID security - app/program did not start, the user did not - finalize the signing or the RP called collect - too late. - - **Action by RP:** RP must inform the user. Message RFA8. - - """ - - def __init__(self, *args, **kwargs): - super(ExpiredTransactionError, self).__init__(*args, **kwargs) - self.rfa = 8 - - -class CertificateError(BankIDError): - """Error due to certificate issues. - - **Code:** ``CERTIFICATE_ERR`` - - **Reason:** - This error is returned if: - 1) The user has entered wrong security code - too many times in her mobile device. The - Mobile BankID cannot be used. - 2) The users BankID is revoked. - 3) The users BankID is invalid. - - **Action by RP:** RP must inform the user. Message RFA13. - - """ - - def __init__(self, *args, **kwargs): - super(CertificateError, self).__init__(*args, **kwargs) - self.rfa = 3 - - -class UserCancelError(BankIDError): - """User had issue a cancel on the order. - - **Code:** ``USER_CANCEL`` - - **Reason:** The user decided to cancel the order. - - **Action by RP:** RP must inform the user. Message RFA6. - - """ - - def __init__(self, *args, **kwargs): - super(UserCancelError, self).__init__(*args, **kwargs) - self.rfa = 6 - - -class CancelledError(BankIDError): - """User had issue a cancel on the order. - - **Code:** ``CANCELLED`` - - **Reason:** The order was cancelled. The system - received a new order for the user. - - **Action by RP:** RP must inform the user. Message RFA3. - - """ - - def __init__(self, *args, **kwargs): - super(CancelledError, self).__init__(*args, **kwargs) - self.rfa = 3 - - -class StartFailedError(BankIDError): - """Error handling the order's progression due to RP/user issues. - - **Code:** ``START_FAILED`` - - **Reason:** The user did not provide her ID, or the RP - requires ``autostarttoken`` to be used, but the - client did not start within a certain time limit. - The reason may be: - - 1) RP did not use autoStartToken when starting - BankID security program/app. - 2) The client software was not installed - or other problem with the user’s computer. - - **Action by RP:** - - 1) The RP must use autoStartToken when - starting the client. - 2) The RP must inform the user. Message RFA17. - - """ - - def __init__(self, *args, **kwargs): - super(StartFailedError, self).__init__(*args, **kwargs) - # TODO: Dual cause, in which only one requires RFA. Remove? - self.rfa = 17 - - class UnauthorizedError(BankIDError): """RP does not have access to the service. From e1607f0433ab8afaf70330657b477419270b424c Mon Sep 17 00:00:00 2001 From: David Svenson Date: Fri, 16 Apr 2021 16:30:45 +0200 Subject: [PATCH 05/11] Update/Add error codes --- bankid/exceptions.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/bankid/exceptions.py b/bankid/exceptions.py index 0fbd67d..2372d56 100644 --- a/bankid/exceptions.py +++ b/bankid/exceptions.py @@ -39,7 +39,7 @@ class BankIDWarning(Warning): class InvalidParametersError(BankIDError): """User induced error. - **Code:** ``INVALID_PARAMETERS`` + **Code:** ``invalidParameters`` **Reason:** Invalid parameter. Invalid use of method. @@ -53,7 +53,7 @@ class InvalidParametersError(BankIDError): class AlreadyInProgressError(BankIDError): """Failure to create new order due to one already in progress. - **Code:** ``ALREADY_IN_PROGRESS`` + **Code:** ``alreadyInProgress`` **Reason:** An order for this user is already in progress. The order is aborted. No order is created. @@ -72,7 +72,7 @@ def __init__(self, *args, **kwargs): class InternalError(BankIDError): """Remote server error. - **Code:** ``INTERNAL_ERROR`` + **Code:** ``internalError`` **Reason:** Internal technical error in the BankID system. @@ -90,6 +90,8 @@ def __init__(self, *args, **kwargs): class MaintenanceError(BankIDError): """The service is temporarily out of service. + **Code:** ``maintenance`` + **Action by RP:** RP may try again without informing the user. If this error is returned repeatedly, RP must inform the user. Message RFA5. @@ -104,6 +106,8 @@ def __init__(self, *args, **kwargs): class UnauthorizedError(BankIDError): """RP does not have access to the service. + **Code:** ``unauthorized`` + **Action by RP:** RP must not try the same request again. This is an internal error within RP's system and must not be ' communicated to the user as a BankID error. @@ -116,6 +120,8 @@ class UnauthorizedError(BankIDError): class NotFoundError(BankIDError): """An erroneously URL path was used. + **Code:** ``notFound`` + **Action by RP:** RP must not try the same request again. This is an internal error within RP's system and must not be ' communicated to the user as a BankID error. @@ -128,6 +134,8 @@ class NotFoundError(BankIDError): class RequestTimeoutError(BankIDError): """It took too long time to transmit the request. + **Code:** ``requestTimeout`` + **Action by RP:** RP must not automatically try again. This error may occur if the processing at RP or the communication is too slow. RP must inform the user. Message RFA5 From a674bbb45497f63196d7c9fde751eb6c660599fb Mon Sep 17 00:00:00 2001 From: David Svenson Date: Fri, 16 Apr 2021 16:34:47 +0200 Subject: [PATCH 06/11] Drop some SOAP leftovers --- docs/soapclient.rst | 73 --------------------------------------------- setup.py | 4 +-- 2 files changed, 2 insertions(+), 75 deletions(-) delete mode 100644 docs/soapclient.rst diff --git a/docs/soapclient.rst b/docs/soapclient.rst deleted file mode 100644 index 913a715..0000000 --- a/docs/soapclient.rst +++ /dev/null @@ -1,73 +0,0 @@ -.. _soapclient: - -BankID SOAP Client -================== - -The Relying Party client using the ``v4`` SOAP API. - -**This client will be deprecated in February 2020. Prior to this a** -:exc:`PendingDeprecationWarning` **will be issued on using.** - -Usage ------ - -First, create a ``BankIDClient``: - -.. code-block:: python - - >>> from bankid import BankIDClient - >>> client = BankIDClient(certificates=('path/to/certificate.pem', - ... 'path/to/key.pem')) - -Connection to production server is the default in the client. If test -server is desired, send in the ``test_server=True`` keyword in the init -of the client. - -A sign order is then placed by - -.. code-block:: python - - >>> client.sign(user_visible_data="The information to sign.", - ... personal_number="YYYYMMDDXXXX") - {'autoStartToken': '798c1ea1-e67a-4df6-a2f6-164ac223fd52', - 'orderRef': 'a9b791c3-459f-492b-bf61-23027876140b'} - -and an authentication order is initiated by - -.. code-block:: python - - >>> client.authenticate(personal_number="YYYYMMDDXXXX") - {'autoStartToken': '798c1ea1-e67a-4df6-a2f6-164ac223fd52', - 'orderRef': 'a9b791c3-459f-492b-bf61-23027876140b'} - -The status of an order can then be studied by polling -with the ``collect`` method using the received ``orderRef``: - -.. code-block:: python - - >>> client.collect(order_ref="a9b791c3-459f-492b-bf61-23027876140b") - {'progressStatus': 'OUTSTANDING_TRANSACTION'} - >>> client.collect(order_ref="a9b791c3-459f-492b-bf61-23027876140b") - {'progressStatus': 'USER_SIGN'} - >>> client.collect(order_ref="a9b791c3-459f-492b-bf61-23027876140b") - {'ocspResponse': 'MIIHfgoBAKCCB3cw[...]', - 'progressStatus': 'COMPLETE', - 'signature': 'PD94bWwgdmVyc2lvbj0[...]', - 'userInfo': {'givenName': 'Namn', - 'ipAddress': '195.84.248.212', - 'name': 'Namn Namnsson', - 'notAfter': datetime.datetime(2016, 9, 9, 22, 59, 59), - 'notBefore': datetime.datetime(2014, 9, 9, 23, 0), - 'personalNumber': 'YYYYMMDDXXXX', - 'surname': 'Namnsson'}} - -Please note that the ``collect`` method should be used sparingly: in the -`BankID Relying Party Guidelines `_. -it states that *"collect should be called every two seconds and must not be -called more frequent than once per second"*. - -API ---- - -.. automodule:: bankid.client - :members: diff --git a/setup.py b/setup.py index beb4b9a..e6b21da 100644 --- a/setup.py +++ b/setup.py @@ -6,8 +6,8 @@ PyBankID is a client for performing BankID signing. -The Swedish BankID solution for digital signing uses a SOAP -connection solution, and this module aims at providing a simplifying +The Swedish BankID solution for digital signing utilizes a +JSON API, and this module aims at providing a simplifying client for making authentication, signing and collect requests to the BankID servers. From 1950431a1b25a2298b69f48caa0243655e8c42fd Mon Sep 17 00:00:00 2001 From: David Svenson Date: Fri, 16 Apr 2021 16:39:16 +0200 Subject: [PATCH 07/11] Drop zeep reference --- docs/get_started.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/get_started.rst b/docs/get_started.rst index 89ac66b..c0ba9b4 100644 --- a/docs/get_started.rst +++ b/docs/get_started.rst @@ -38,7 +38,6 @@ Dependencies PyBankID makes use of the following external packages: * `requests>=2.7.0 `_ -* `zeep>=1.3.0 `_ * `six>=1.9.0 `_ From 33214662d216c331458dd6bf6e56b20246ba0a9b Mon Sep 17 00:00:00 2001 From: David Svenson Date: Fri, 16 Apr 2021 16:53:01 +0200 Subject: [PATCH 08/11] Add pytest as a requirement for development --- requirements-dev.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 requirements-dev.txt diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..55b033e --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1 @@ +pytest \ No newline at end of file From 7b57c0c7f8be9635b2e3794d990e77d77c3d6614 Mon Sep 17 00:00:00 2001 From: David Svenson Date: Fri, 16 Apr 2021 16:53:20 +0200 Subject: [PATCH 09/11] Drop tests dir from test command --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 0d5a725..b6bff14 100644 --- a/README.rst +++ b/README.rst @@ -199,4 +199,4 @@ The PyBankID solution can be tested with `pytest `_: .. code-block:: bash - py.test tests/ + py.test From 4dcd914e37f8dd8d47448f015c61a6015aae2066 Mon Sep 17 00:00:00 2001 From: Henrik Blidh Date: Tue, 20 Apr 2021 10:11:57 +0200 Subject: [PATCH 10/11] Update __version__.py --- bankid/__version__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bankid/__version__.py b/bankid/__version__.py index f4377e0..897cde7 100644 --- a/bankid/__version__.py +++ b/bankid/__version__.py @@ -8,5 +8,5 @@ from __future__ import print_function from __future__ import absolute_import -__version__ = "0.10.4" +__version__ = "0.11.0" version = __version__ # backwards compatibility name From da4305df488bc6b6a30e70b0df1bbe54d51e4cda Mon Sep 17 00:00:00 2001 From: Henrik Blidh Date: Tue, 20 Apr 2021 10:13:34 +0200 Subject: [PATCH 11/11] Update build_and_test.yml Added python 3.9 as a version to test --- .github/workflows/build_and_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 1a2ae78..decd5ff 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -18,7 +18,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] - python-version: [2.7, 3.5, 3.6, 3.7, 3.8] + python-version: [2.7, 3.5, 3.6, 3.7, 3.8, 3.9] steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }}