Skip to content

Commit 5f36326

Browse files
hbldhdotchettercthart1sfbtiwilliam
authored
Merge develop into master (#79)
* 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 <davidsvenson@outlook.com> * Update bankid/jsonclient.py Co-authored-by: David Svenson <davidsvenson@outlook.com> * Drop unused TypeVar * Update bankid/jsonclient.py Co-authored-by: David Svenson <davidsvenson@outlook.com> --------- Co-authored-by: David Svenson <davidsvenson@outlook.com> * 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 <36161882+dotchetter@users.noreply.github.com> Co-authored-by: Colin 't Hart <colinthart@gmail.com> Co-authored-by: Stefan Berg <sfb@consultron.com> Co-authored-by: William Tisäter <william@defunct.cc> Co-authored-by: David Svenson <davidsvenson@outlook.com> Co-authored-by: Amin Solhizadeh <amin.solhizadeh@oneflow.com> Co-authored-by: Andreas Pelme <andreas@pelme.se> Co-authored-by: Emil <emil@personalkollen.se>
1 parent 7ae62a0 commit 5f36326

File tree

7 files changed

+121
-33
lines changed

7 files changed

+121
-33
lines changed

bankid/__version__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
Version info
44
"""
55

6-
__version__ = "1.4.1"
6+
__version__ = "1.5.0"
77
version = __version__ # backwards compatibility name

bankid/asyncclient.py

+24-15
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44

55
from bankid.baseclient import BankIDClientBaseclass
66
from bankid.exceptions import get_json_error_class
7+
from bankid.responses import (
8+
AuthenticateResponse,
9+
CollectCompleteResponse,
10+
CollectFailedResponse,
11+
CollectPendingResponse,
12+
PhoneAuthenticateResponse,
13+
PhoneSignResponse,
14+
SignResponse,
15+
)
716

817

918
class BankIDAsyncClient(BankIDClientBaseclass[httpx.AsyncClient]):
@@ -32,7 +41,7 @@ async def authenticate(
3241
user_visible_data: Union[str, None] = None,
3342
user_non_visible_data: Union[str, None] = None,
3443
user_visible_data_format: Union[str, None] = None,
35-
) -> Dict[str, str]:
44+
) -> AuthenticateResponse:
3645
"""Request an authentication order. The :py:meth:`collect` method
3746
is used to query the status of the order.
3847
@@ -62,8 +71,8 @@ async def authenticate(
6271
this parameter indicates that userVisibleData holds formatting characters which
6372
potentially make for a more pleasant user experience.
6473
:type user_visible_data_format: str
65-
:return: The order response.
66-
:rtype: dict
74+
:return: The order response parsed as a dict.
75+
:rtype: AuthenticateResponse
6776
:raises BankIDError: raises a subclass of this error
6877
when error has been returned from server.
6978
@@ -91,7 +100,7 @@ async def phone_authenticate(
91100
user_visible_data: Union[str, None] = None,
92101
user_non_visible_data: Union[str, None] = None,
93102
user_visible_data_format: Union[str, None] = None,
94-
) -> Dict[str, str]:
103+
) -> PhoneAuthenticateResponse:
95104
"""Initiates an authentication order when the user is talking
96105
to the RP over the phone. The :py:meth:`collect` method
97106
is used to query the status of the order.
@@ -123,8 +132,8 @@ async def phone_authenticate(
123132
this parameter indicates that userVisibleData holds formatting characters which
124133
potentially make for a more pleasant user experience.
125134
:type user_visible_data_format: str
126-
:return: The order response.
127-
:rtype: dict
135+
:return: The order response parsed as a dict.
136+
:rtype: PhoneAuthenticateResponse
128137
:raises BankIDError: raises a subclass of this error
129138
when error has been returned from server.
130139
@@ -155,7 +164,7 @@ async def sign(
155164
requirement: Union[Dict[str, Any], None] = None,
156165
user_non_visible_data: Union[str, None] = None,
157166
user_visible_data_format: Union[str, None] = None,
158-
) -> Dict[str, str]:
167+
) -> SignResponse:
159168
"""Request a signing order. The :py:meth:`collect` method
160169
is used to query the status of the order.
161170
@@ -183,8 +192,8 @@ async def sign(
183192
this parameter indicates that userVisibleData holds formatting characters which
184193
potentially make for a more pleasant user experience.
185194
:type user_visible_data_format: str
186-
:return: The order response.
187-
:rtype: dict
195+
:return: The order response parsed as a dict.
196+
:rtype: SignResponse
188197
:raises BankIDError: raises a subclass of this error
189198
when error has been returned from server.
190199
@@ -212,7 +221,7 @@ async def phone_sign(
212221
requirement: Union[Dict[str, Any], None] = None,
213222
user_non_visible_data: Union[str, None] = None,
214223
user_visible_data_format: Union[str, None] = None,
215-
) -> Dict[str, str]:
224+
) -> PhoneSignResponse:
216225
"""Initiates an authentication order when the user is talking to
217226
the RP over the phone. The :py:meth:`collect` method
218227
is used to query the status of the order.
@@ -242,8 +251,8 @@ async def phone_sign(
242251
this parameter indicates that userVisibleData holds formatting characters which
243252
potentially make for a more pleasant user experience.
244253
:type user_visible_data_format: str
245-
:return: The order response.
246-
:rtype: dict
254+
:return: The order response parsed as a dict.
255+
:rtype: PhoneSignResponse
247256
:raises BankIDError: raises a subclass of this error
248257
when error has been returned from server.
249258
@@ -267,7 +276,7 @@ async def phone_sign(
267276
else:
268277
raise get_json_error_class(response)
269278

270-
async def collect(self, order_ref: str) -> dict:
279+
async def collect(self, order_ref: str) -> Union[CollectPendingResponse, CollectCompleteResponse, CollectFailedResponse]:
271280
"""Collects the result of a sign or auth order using the
272281
``orderRef`` as reference.
273282
@@ -326,8 +335,8 @@ async def collect(self, order_ref: str) -> dict:
326335
327336
:param order_ref: The ``orderRef`` UUID returned from auth or sign.
328337
:type order_ref: str
329-
:return: The CollectResponse parsed to a dictionary.
330-
:rtype: dict
338+
:return: The order response parsed to a dict.
339+
:rtype: Union[CollectPendingResponse, CollectCompleteResponse, CollectFailedResponse]
331340
:raises BankIDError: raises a subclass of this error
332341
when error has been returned from server.
333342

bankid/baseclient.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import base64
22
import ssl
33
from datetime import datetime
4-
from typing import Tuple, Dict, Any, Union, TypeVar, Generic
4+
from typing import Any, Dict, Generic, Tuple, TypeVar, Union
55
from urllib.parse import urljoin
66

77
from bankid.qr import generate_qr_code_content

bankid/responses.py

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
from typing_extensions import Literal, NotRequired, TypedDict
2+
3+
class SignResponse(TypedDict):
4+
orderRef: str
5+
autoStartToken: str
6+
qrStartToken: str
7+
qrStartSecret: str
8+
9+
10+
class PhoneSignResponse(TypedDict):
11+
orderRef: str
12+
13+
14+
class AuthenticateResponse(TypedDict):
15+
orderRef: str
16+
autoStartToken: str
17+
qrStartToken: str
18+
qrStartSecret: str
19+
20+
21+
class PhoneAuthenticateResponse(TypedDict):
22+
orderRef: str
23+
24+
25+
class Device(TypedDict):
26+
ipAddress: str
27+
uhi: str
28+
29+
30+
class StepUp(TypedDict):
31+
mrtd: bool
32+
33+
34+
class User(TypedDict):
35+
personalNumber: str
36+
name: str
37+
givenName: str
38+
surname: str
39+
40+
41+
class CompletionData(TypedDict):
42+
user: User
43+
device: Device
44+
stepUp: StepUp
45+
bankIdIssueDate: str
46+
signature: str
47+
ocspResponse: str
48+
risk: NotRequired[str]
49+
50+
51+
class _CollectResponse(TypedDict):
52+
orderRef: str
53+
54+
55+
class CollectPendingResponse(_CollectResponse):
56+
status: Literal["pending"]
57+
hintCode: str
58+
59+
60+
class CollectCompleteResponse(_CollectResponse):
61+
status: Literal["complete"]
62+
completionData: CompletionData
63+
64+
65+
class CollectFailedResponse(_CollectResponse):
66+
status: Literal["failed"]
67+
hintCode: str

bankid/syncclient.py

+24-15
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44

55
from bankid.baseclient import BankIDClientBaseclass
66
from bankid.exceptions import get_json_error_class
7+
from bankid.responses import (
8+
AuthenticateResponse,
9+
CollectCompleteResponse,
10+
CollectFailedResponse,
11+
CollectPendingResponse,
12+
PhoneAuthenticateResponse,
13+
PhoneSignResponse,
14+
SignResponse,
15+
)
716

817

918
class BankIDClient(BankIDClientBaseclass[httpx.Client]):
@@ -32,7 +41,7 @@ def authenticate(
3241
user_visible_data: Union[str, None] = None,
3342
user_non_visible_data: Union[str, None] = None,
3443
user_visible_data_format: Union[str, None] = None,
35-
) -> Dict[str, str]:
44+
) -> AuthenticateResponse:
3645
"""Request an authentication order. The :py:meth:`collect` method
3746
is used to query the status of the order.
3847
@@ -62,8 +71,8 @@ def authenticate(
6271
this parameter indicates that userVisibleData holds formatting characters which
6372
potentially make for a more pleasant user experience.
6473
:type user_visible_data_format: str
65-
:return: The order response.
66-
:rtype: dict
74+
:return: The order response parsed to a dict.
75+
:rtype: AuthenticateResponse
6776
:raises BankIDError: raises a subclass of this error
6877
when error has been returned from server.
6978
@@ -91,7 +100,7 @@ def phone_authenticate(
91100
user_visible_data: Union[str, None] = None,
92101
user_non_visible_data: Union[str, None] = None,
93102
user_visible_data_format: Union[str, None] = None,
94-
) -> Dict[str, str]:
103+
) -> PhoneAuthenticateResponse:
95104
"""Initiates an authentication order when the user is talking
96105
to the RP over the phone. The :py:meth:`collect` method
97106
is used to query the status of the order.
@@ -123,8 +132,8 @@ def phone_authenticate(
123132
this parameter indicates that userVisibleData holds formatting characters which
124133
potentially make for a more pleasant user experience.
125134
:type user_visible_data_format: str
126-
:return: The order response.
127-
:rtype: dict
135+
:return: The order response parsed to a dict.
136+
:rtype: PhoneAuthenticateResponse
128137
:raises BankIDError: raises a subclass of this error
129138
when error has been returned from server.
130139
@@ -155,7 +164,7 @@ def sign(
155164
requirement: Union[Dict[str, Any], None] = None,
156165
user_non_visible_data: Union[str, None] = None,
157166
user_visible_data_format: Union[str, None] = None,
158-
) -> Dict[str, str]:
167+
) -> SignResponse:
159168
"""Request a signing order. The :py:meth:`collect` method
160169
is used to query the status of the order.
161170
@@ -183,8 +192,8 @@ def sign(
183192
this parameter indicates that userVisibleData holds formatting characters which
184193
potentially make for a more pleasant user experience.
185194
:type user_visible_data_format: str
186-
:return: The order response.
187-
:rtype: dict
195+
:return: The order response parsed to a dict.
196+
:rtype: SignResponse
188197
:raises BankIDError: raises a subclass of this error
189198
when error has been returned from server.
190199
@@ -211,7 +220,7 @@ def phone_sign(
211220
requirement: Union[Dict[str, Any], None] = None,
212221
user_non_visible_data: Union[str, None] = None,
213222
user_visible_data_format: Union[str, None] = None,
214-
) -> Dict[str, str]:
223+
) -> PhoneSignResponse:
215224
"""Initiates an authentication order when the user is talking to
216225
the RP over the phone. The :py:meth:`collect` method
217226
is used to query the status of the order.
@@ -241,8 +250,8 @@ def phone_sign(
241250
this parameter indicates that userVisibleData holds formatting characters which
242251
potentially make for a more pleasant user experience.
243252
:type user_visible_data_format: str
244-
:return: The order response.
245-
:rtype: dict
253+
:return: The order response parsed to a dict.
254+
:rtype: PhoneSignResponse
246255
:raises BankIDError: raises a subclass of this error
247256
when error has been returned from server.
248257
@@ -266,7 +275,7 @@ def phone_sign(
266275
else:
267276
raise get_json_error_class(response)
268277

269-
def collect(self, order_ref: str) -> dict:
278+
def collect(self, order_ref: str) -> Union[CollectPendingResponse, CollectCompleteResponse, CollectFailedResponse]:
270279
"""Collects the result of a sign or auth order using the
271280
``orderRef`` as reference.
272281
@@ -325,8 +334,8 @@ def collect(self, order_ref: str) -> dict:
325334
326335
:param order_ref: The ``orderRef`` UUID returned from auth or sign.
327336
:type order_ref: str
328-
:return: The CollectResponse parsed to a dictionary.
329-
:rtype: dict
337+
:return: The order response parsed to a dict.
338+
:rtype: Union[CollectPendingResponse, CollectCompleteResponse, CollectFailedResponse]
330339
:raises BankIDError: raises a subclass of this error
331340
when error has been returned from server.
332341

setup.cfg

+3
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
[wheel]
22
universal=1
3+
4+
[tool:pytest]
5+
asyncio_default_fixture_loop_scope = session

tests/conftest.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def ip_address() -> str:
1111
return "127.0.0.1"
1212

1313

14-
@pytest.fixture()
14+
@pytest.fixture(scope="session")
1515
def cert_and_key() -> Tuple[str, str]:
1616
cert, key = get_test_cert_and_key()
1717
return str(cert), str(key)

0 commit comments

Comments
 (0)