Skip to content

Commit

Permalink
Merge develop into master (#79)
Browse files Browse the repository at this point in the history
* Update README.rst

Corrected typo in examples

* Update __init__.py

Fix breakage with urllib 2.0.x

* Github Action fixes

* Version bump

* Bump reqs for example

* Bundle the BankID Test certificate

The BankID pages now returns a captcha instead of the actual certificate when fetching with requests. The actual cert is now bundled instead of fetched each time.

* Failure detection in openssl test cert conversion

* Add possibility to provide p12 test cert through existing file

* Bundle the BankID Test certificate in pem format

Bundle pem formats as well.

* Python 2.7 compat. fix

* Rmoving certutils test for the time being

* Remove Python 2.7 support

* Remove six dependency

* Async client using httpx (#55)

* Test against Python 3.12

* Install setuptools after testing

* Swap out pkg_resources for importlib

* Downgrade importlib-resources to 5.12.0

* Always use compat package

* Read required packages in setup.py from requirements.txt

* Drop unused six and update docs

* Async client

* Tidy up async wrapper

* Install requirements-dev.txt on CI

* Add two more packages to requirements-dev.txt from CI

* Update bankid/jsonclient.py

Co-authored-by: David Svenson <[email protected]>

* Update bankid/jsonclient.py

Co-authored-by: David Svenson <[email protected]>

* Drop unused TypeVar

* Update bankid/jsonclient.py

Co-authored-by: David Svenson <[email protected]>

---------

Co-authored-by: David Svenson <[email protected]>

* Add support for RP v6.0

* First draft of v6 clients

Sync and Async clients
Implementing parts of v6 API
Removing all v5 and v5.1 API implementations
Lacking documentation rewrite

Builds on #53, #54, #56, #57, #58

* Corrected the example app to work with v1.0.0

* Documentation update

* Cleanup before PR

Documentation fixes
Renaming and docstring fixes
Demo app modifications
Version bump

* Remove .vscode folder

* Minor doc change

* Updated README.rst

* CI changes

Removed testing in windows and macos
Also removed 3.7 and 3.8 from test matrix.

* Upgrading CI action versions

* Implemented phone/auth and phone/sign

* Update certutils.py

Make it even easier to retrieve the test certificate by writing it into the current directory if no path is supplied.

* Expose QR code helper explicitly.

This simplifies making use of it without having access to a client instance.

* Update README.rst - use pytest instead of py.test

pytest is the "new" name :)

* Version 1.0.1 - Docfix and QR method separate

* Cache ip addresses in test suite.

Also, only keep a sync version of the ip_address fixture.

This avoids httpbin flakyness/unrelibility since the ip address fetch
only needs to happen once.

* Use builtin importlib.resources.

Supporting Python >=3.9 does not require using the backport.

Also, use joinpath() to simplify the retrival of the path+return
pathlib.Path instead of str.

* Documentation updates

* Dropping use of httpbin for external ip

* Fix for async test

* Add mypy to dev deps.

* mypy --install-types

* Drop duplicate method.

* Fix type errors and add type annotations.

* Add type checking to CI.

* Add CONTRIBUTING.md

* Attempted fix of importlib

* Removed walrus operator

* Fix for mypy in 3.7 and 3.8

* Another attempt to fix mypy

* Another attempt to fix mypy number 2

* Update test certificates

* Using new test certs and removing old ones

* Fixed pem cert and key

The old exporting functions did not work any more apparently.
Exported them from FPTestcert5_20240610.pem instead of p12.

* Version bump

* Update requirements.txt

Newer version of httpx causes SSL error in authenticate()
See #74

* Update requirements.txt

Newer version of httpx causes SSL error in authenticate()

* Version bump

* Add type annotations for BankID API responses (#78)

* Add TypedDict implementations of API responses.

* Set asyncio_default_fixture_loop_scope.

This will silence a deprecation warning from pytest-asyncio.

pytest-dev/pytest-asyncio#924

* Use session scope for cert_and_key fixture.

* Version bump

---------

Co-authored-by: Simon Olofsson <[email protected]>
Co-authored-by: Colin 't Hart <[email protected]>
Co-authored-by: Stefan Berg <[email protected]>
Co-authored-by: William Tisäter <[email protected]>
Co-authored-by: David Svenson <[email protected]>
Co-authored-by: Amin Solhizadeh <[email protected]>
Co-authored-by: Andreas Pelme <[email protected]>
Co-authored-by: Emil <[email protected]>
  • Loading branch information
9 people authored Jan 23, 2025
1 parent 7ae62a0 commit 5f36326
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 33 deletions.
2 changes: 1 addition & 1 deletion bankid/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
Version info
"""

__version__ = "1.4.1"
__version__ = "1.5.0"
version = __version__ # backwards compatibility name
39 changes: 24 additions & 15 deletions bankid/asyncclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@

from bankid.baseclient import BankIDClientBaseclass
from bankid.exceptions import get_json_error_class
from bankid.responses import (
AuthenticateResponse,
CollectCompleteResponse,
CollectFailedResponse,
CollectPendingResponse,
PhoneAuthenticateResponse,
PhoneSignResponse,
SignResponse,
)


class BankIDAsyncClient(BankIDClientBaseclass[httpx.AsyncClient]):
Expand Down Expand Up @@ -32,7 +41,7 @@ async def authenticate(
user_visible_data: Union[str, None] = None,
user_non_visible_data: Union[str, None] = None,
user_visible_data_format: Union[str, None] = None,
) -> Dict[str, str]:
) -> AuthenticateResponse:
"""Request an authentication order. The :py:meth:`collect` method
is used to query the status of the order.
Expand Down Expand Up @@ -62,8 +71,8 @@ async def authenticate(
this parameter indicates that userVisibleData holds formatting characters which
potentially make for a more pleasant user experience.
:type user_visible_data_format: str
:return: The order response.
:rtype: dict
:return: The order response parsed as a dict.
:rtype: AuthenticateResponse
:raises BankIDError: raises a subclass of this error
when error has been returned from server.
Expand Down Expand Up @@ -91,7 +100,7 @@ async def phone_authenticate(
user_visible_data: Union[str, None] = None,
user_non_visible_data: Union[str, None] = None,
user_visible_data_format: Union[str, None] = None,
) -> Dict[str, str]:
) -> PhoneAuthenticateResponse:
"""Initiates an authentication order when the user is talking
to the RP over the phone. The :py:meth:`collect` method
is used to query the status of the order.
Expand Down Expand Up @@ -123,8 +132,8 @@ async def phone_authenticate(
this parameter indicates that userVisibleData holds formatting characters which
potentially make for a more pleasant user experience.
:type user_visible_data_format: str
:return: The order response.
:rtype: dict
:return: The order response parsed as a dict.
:rtype: PhoneAuthenticateResponse
:raises BankIDError: raises a subclass of this error
when error has been returned from server.
Expand Down Expand Up @@ -155,7 +164,7 @@ async def sign(
requirement: Union[Dict[str, Any], None] = None,
user_non_visible_data: Union[str, None] = None,
user_visible_data_format: Union[str, None] = None,
) -> Dict[str, str]:
) -> SignResponse:
"""Request a signing order. The :py:meth:`collect` method
is used to query the status of the order.
Expand Down Expand Up @@ -183,8 +192,8 @@ async def sign(
this parameter indicates that userVisibleData holds formatting characters which
potentially make for a more pleasant user experience.
:type user_visible_data_format: str
:return: The order response.
:rtype: dict
:return: The order response parsed as a dict.
:rtype: SignResponse
:raises BankIDError: raises a subclass of this error
when error has been returned from server.
Expand Down Expand Up @@ -212,7 +221,7 @@ async def phone_sign(
requirement: Union[Dict[str, Any], None] = None,
user_non_visible_data: Union[str, None] = None,
user_visible_data_format: Union[str, None] = None,
) -> Dict[str, str]:
) -> PhoneSignResponse:
"""Initiates an authentication order when the user is talking to
the RP over the phone. The :py:meth:`collect` method
is used to query the status of the order.
Expand Down Expand Up @@ -242,8 +251,8 @@ async def phone_sign(
this parameter indicates that userVisibleData holds formatting characters which
potentially make for a more pleasant user experience.
:type user_visible_data_format: str
:return: The order response.
:rtype: dict
:return: The order response parsed as a dict.
:rtype: PhoneSignResponse
:raises BankIDError: raises a subclass of this error
when error has been returned from server.
Expand All @@ -267,7 +276,7 @@ async def phone_sign(
else:
raise get_json_error_class(response)

async def collect(self, order_ref: str) -> dict:
async def collect(self, order_ref: str) -> Union[CollectPendingResponse, CollectCompleteResponse, CollectFailedResponse]:
"""Collects the result of a sign or auth order using the
``orderRef`` as reference.
Expand Down Expand Up @@ -326,8 +335,8 @@ async def collect(self, order_ref: str) -> dict:
:param order_ref: The ``orderRef`` UUID returned from auth or sign.
:type order_ref: str
:return: The CollectResponse parsed to a dictionary.
:rtype: dict
:return: The order response parsed to a dict.
:rtype: Union[CollectPendingResponse, CollectCompleteResponse, CollectFailedResponse]
:raises BankIDError: raises a subclass of this error
when error has been returned from server.
Expand Down
2 changes: 1 addition & 1 deletion bankid/baseclient.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import base64
import ssl
from datetime import datetime
from typing import Tuple, Dict, Any, Union, TypeVar, Generic
from typing import Any, Dict, Generic, Tuple, TypeVar, Union
from urllib.parse import urljoin

from bankid.qr import generate_qr_code_content
Expand Down
67 changes: 67 additions & 0 deletions bankid/responses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from typing_extensions import Literal, NotRequired, TypedDict

class SignResponse(TypedDict):
orderRef: str
autoStartToken: str
qrStartToken: str
qrStartSecret: str


class PhoneSignResponse(TypedDict):
orderRef: str


class AuthenticateResponse(TypedDict):
orderRef: str
autoStartToken: str
qrStartToken: str
qrStartSecret: str


class PhoneAuthenticateResponse(TypedDict):
orderRef: str


class Device(TypedDict):
ipAddress: str
uhi: str


class StepUp(TypedDict):
mrtd: bool


class User(TypedDict):
personalNumber: str
name: str
givenName: str
surname: str


class CompletionData(TypedDict):
user: User
device: Device
stepUp: StepUp
bankIdIssueDate: str
signature: str
ocspResponse: str
risk: NotRequired[str]


class _CollectResponse(TypedDict):
orderRef: str


class CollectPendingResponse(_CollectResponse):
status: Literal["pending"]
hintCode: str


class CollectCompleteResponse(_CollectResponse):
status: Literal["complete"]
completionData: CompletionData


class CollectFailedResponse(_CollectResponse):
status: Literal["failed"]
hintCode: str
39 changes: 24 additions & 15 deletions bankid/syncclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@

from bankid.baseclient import BankIDClientBaseclass
from bankid.exceptions import get_json_error_class
from bankid.responses import (
AuthenticateResponse,
CollectCompleteResponse,
CollectFailedResponse,
CollectPendingResponse,
PhoneAuthenticateResponse,
PhoneSignResponse,
SignResponse,
)


class BankIDClient(BankIDClientBaseclass[httpx.Client]):
Expand Down Expand Up @@ -32,7 +41,7 @@ def authenticate(
user_visible_data: Union[str, None] = None,
user_non_visible_data: Union[str, None] = None,
user_visible_data_format: Union[str, None] = None,
) -> Dict[str, str]:
) -> AuthenticateResponse:
"""Request an authentication order. The :py:meth:`collect` method
is used to query the status of the order.
Expand Down Expand Up @@ -62,8 +71,8 @@ def authenticate(
this parameter indicates that userVisibleData holds formatting characters which
potentially make for a more pleasant user experience.
:type user_visible_data_format: str
:return: The order response.
:rtype: dict
:return: The order response parsed to a dict.
:rtype: AuthenticateResponse
:raises BankIDError: raises a subclass of this error
when error has been returned from server.
Expand Down Expand Up @@ -91,7 +100,7 @@ def phone_authenticate(
user_visible_data: Union[str, None] = None,
user_non_visible_data: Union[str, None] = None,
user_visible_data_format: Union[str, None] = None,
) -> Dict[str, str]:
) -> PhoneAuthenticateResponse:
"""Initiates an authentication order when the user is talking
to the RP over the phone. The :py:meth:`collect` method
is used to query the status of the order.
Expand Down Expand Up @@ -123,8 +132,8 @@ def phone_authenticate(
this parameter indicates that userVisibleData holds formatting characters which
potentially make for a more pleasant user experience.
:type user_visible_data_format: str
:return: The order response.
:rtype: dict
:return: The order response parsed to a dict.
:rtype: PhoneAuthenticateResponse
:raises BankIDError: raises a subclass of this error
when error has been returned from server.
Expand Down Expand Up @@ -155,7 +164,7 @@ def sign(
requirement: Union[Dict[str, Any], None] = None,
user_non_visible_data: Union[str, None] = None,
user_visible_data_format: Union[str, None] = None,
) -> Dict[str, str]:
) -> SignResponse:
"""Request a signing order. The :py:meth:`collect` method
is used to query the status of the order.
Expand Down Expand Up @@ -183,8 +192,8 @@ def sign(
this parameter indicates that userVisibleData holds formatting characters which
potentially make for a more pleasant user experience.
:type user_visible_data_format: str
:return: The order response.
:rtype: dict
:return: The order response parsed to a dict.
:rtype: SignResponse
:raises BankIDError: raises a subclass of this error
when error has been returned from server.
Expand All @@ -211,7 +220,7 @@ def phone_sign(
requirement: Union[Dict[str, Any], None] = None,
user_non_visible_data: Union[str, None] = None,
user_visible_data_format: Union[str, None] = None,
) -> Dict[str, str]:
) -> PhoneSignResponse:
"""Initiates an authentication order when the user is talking to
the RP over the phone. The :py:meth:`collect` method
is used to query the status of the order.
Expand Down Expand Up @@ -241,8 +250,8 @@ def phone_sign(
this parameter indicates that userVisibleData holds formatting characters which
potentially make for a more pleasant user experience.
:type user_visible_data_format: str
:return: The order response.
:rtype: dict
:return: The order response parsed to a dict.
:rtype: PhoneSignResponse
:raises BankIDError: raises a subclass of this error
when error has been returned from server.
Expand All @@ -266,7 +275,7 @@ def phone_sign(
else:
raise get_json_error_class(response)

def collect(self, order_ref: str) -> dict:
def collect(self, order_ref: str) -> Union[CollectPendingResponse, CollectCompleteResponse, CollectFailedResponse]:
"""Collects the result of a sign or auth order using the
``orderRef`` as reference.
Expand Down Expand Up @@ -325,8 +334,8 @@ def collect(self, order_ref: str) -> dict:
:param order_ref: The ``orderRef`` UUID returned from auth or sign.
:type order_ref: str
:return: The CollectResponse parsed to a dictionary.
:rtype: dict
:return: The order response parsed to a dict.
:rtype: Union[CollectPendingResponse, CollectCompleteResponse, CollectFailedResponse]
:raises BankIDError: raises a subclass of this error
when error has been returned from server.
Expand Down
3 changes: 3 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
[wheel]
universal=1

[tool:pytest]
asyncio_default_fixture_loop_scope = session
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def ip_address() -> str:
return "127.0.0.1"


@pytest.fixture()
@pytest.fixture(scope="session")
def cert_and_key() -> Tuple[str, str]:
cert, key = get_test_cert_and_key()
return str(cert), str(key)
Expand Down

0 comments on commit 5f36326

Please sign in to comment.