Skip to content

Commit 88f0488

Browse files
committed
feature/python-sdk-psd2: ApiContext for PSD2 is now generated and stored.
1 parent 1a7d4d9 commit 88f0488

File tree

2 files changed

+44
-22
lines changed

2 files changed

+44
-22
lines changed

bunq/sdk/context/api_context.py

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from typing import List, Optional
66

77
from Cryptodome.PublicKey import RSA
8-
from Cryptodome.PublicKey.RSA import RsaKey
98

109
from bunq.sdk.context.api_environment_type import ApiEnvironmentType
1110
from bunq.sdk.context.installation_context import InstallationContext
@@ -14,7 +13,7 @@
1413
from bunq.sdk.json import converter
1514
from bunq.sdk.model.core.payment_service_provider_credential_internal import PaymentServiceProviderCredentialInternal
1615
from bunq.sdk.model.generated import endpoint
17-
from bunq.sdk.model.generated.endpoint import UserCredentialPasswordIp
16+
from bunq.sdk.model.generated.endpoint import UserCredentialPasswordIp, UserPaymentServiceProvider
1817
from bunq.sdk.security import security
1918

2019
if typing.TYPE_CHECKING:
@@ -63,9 +62,9 @@ def create(cls,
6362

6463
api_context._api_key = api_key
6564

66-
api_context._initialize_installation()
67-
api_context._register_device(description, all_permitted_ip)
68-
api_context._initialize_session()
65+
api_context.__initialize_installation()
66+
api_context.__register_device(description, all_permitted_ip)
67+
api_context.__initialize_session()
6968

7069
return api_context
7170

@@ -80,21 +79,25 @@ def create_for_psd2(cls,
8079
proxy_url: List[str] = None) -> ApiContext:
8180
api_context = cls(environment_type, proxy_url)
8281

83-
api_context._initialize_installation()
82+
api_context.__initialize_installation()
8483

85-
service_provider_credential = api_context._initialize_psd2_credential(
84+
service_provider_credential = api_context.__initialize_psd2_credential(
8685
certificate,
8786
private_key,
8887
all_chain_certificate)
8988

89+
print(service_provider_credential.token_value)
90+
9091
api_context._api_key = service_provider_credential.token_value
9192

92-
api_context._register_device(description, all_permitted_ip)
93-
api_context._initialize_session()
93+
print(api_context._api_key)
94+
95+
api_context.__register_device(description, all_permitted_ip)
96+
api_context.__initialize_session_for_psd2(service_provider_credential)
9497

9598
return api_context
9699

97-
def _initialize_installation(self) -> None:
100+
def __initialize_installation(self) -> None:
98101
from bunq.sdk.model.core.installation import Installation
99102

100103
private_key_client = security.generate_rsa_private_key()
@@ -114,14 +117,14 @@ def _initialize_installation(self) -> None:
114117
public_key_server
115118
)
116119

117-
def _initialize_psd2_credential(self,
118-
certificate: str,
119-
private_key: str,
120-
all_chain_certificate: List[str], ) -> UserCredentialPasswordIp:
120+
def __initialize_psd2_credential(self,
121+
certificate: str,
122+
private_key: str,
123+
all_chain_certificate: List[str], ) -> UserCredentialPasswordIp:
121124
session_token = self.installation_context.token
122125
client_key_pair = self.installation_context.private_key_client
123126

124-
string_to_sign = security.public_key_to_string(client_key_pair.publickey()) + session_token
127+
string_to_sign = security.public_key_to_string(client_key_pair.publickey()) + "\n" + session_token
125128
encoded_signature = security.generate_signature(string_to_sign, security.rsa_key_from_string(private_key))
126129

127130
payment_response_provider = PaymentServiceProviderCredentialInternal.create_with_api_context(
@@ -133,19 +136,21 @@ def _initialize_psd2_credential(self,
133136

134137
return payment_response_provider
135138

136-
def _register_device(self,
137-
device_description: str,
138-
permitted_ips: List[str]) -> None:
139+
def __register_device(self,
140+
device_description: str,
141+
permitted_ips: List[str]) -> None:
139142
from bunq.sdk.model.core.device_server_internal import DeviceServerInternal
140143

144+
print(self.api_key)
145+
141146
DeviceServerInternal.create(
142147
device_description,
143148
self.api_key,
144149
permitted_ips,
145150
api_context=self
146151
)
147152

148-
def _initialize_session(self) -> None:
153+
def __initialize_session(self) -> None:
149154
from bunq.sdk.model.core.session_server import SessionServer
150155

151156
session_server = SessionServer.create(self).value
@@ -155,6 +160,17 @@ def _initialize_session(self) -> None:
155160

156161
self._session_context = SessionContext(token, expiry_time, user_id)
157162

163+
def _initialize_session_for_psd2(self, user_payment_service_provider: UserPaymentServiceProvider) -> None:
164+
from bunq.sdk.model.core.session_server import SessionServer
165+
166+
session_server = SessionServer.create(self).value
167+
168+
token = session_server.token.token
169+
expiry_time = self._get_expiry_timestamp(session_server)
170+
user_id = session_server.get_referenced_user().id_
171+
172+
self._session_context = SessionContext(token, expiry_time, user_id)
173+
158174
@classmethod
159175
def _get_expiry_timestamp(cls, session_server: SessionServer) -> datetime.datetime:
160176
timeout_seconds = cls._get_session_timeout_seconds(session_server)
@@ -168,6 +184,8 @@ def _get_session_timeout_seconds(cls, session_server: SessionServer) -> int:
168184
return session_server.user_company.session_timeout
169185
elif session_server.user_person is not None:
170186
return session_server.user_person.session_timeout
187+
elif session_server.user_payment_service_provider is not None:
188+
return session_server.user_payment_service_provider.session_timeout
171189
elif session_server.user_api_key is not None:
172190
return session_server \
173191
.user_api_key \
@@ -209,7 +227,7 @@ def reset_session(self) -> None:
209227
"""
210228

211229
self._drop_session_context()
212-
self._initialize_session()
230+
self.__initialize_session()
213231

214232
def _drop_session_context(self) -> None:
215233
self._session_context = None

bunq/sdk/model/core/payment_service_provider_credential_internal.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from __future__ import annotations
22

3+
import json
34
import typing
5+
46
from bunq.sdk.http.api_client import ApiClient
57
from bunq.sdk.json import converter
68
from bunq.sdk.model.generated.endpoint import PaymentServiceProviderCredential, UserCredentialPasswordIp
@@ -10,7 +12,6 @@
1012

1113

1214
class PaymentServiceProviderCredentialInternal(PaymentServiceProviderCredential):
13-
1415
@classmethod
1516
def create_with_api_context(cls,
1617
client_payment_service_provider_certificate: str,
@@ -32,4 +33,7 @@ def create_with_api_context(cls,
3233
endpoint_url = cls._ENDPOINT_URL_CREATE
3334
response_raw = api_client.post(endpoint_url, request_bytes, all_custom_header)
3435

35-
return UserCredentialPasswordIp.from_json(response_raw.body_bytes.decode())
36+
response_body = converter.json_to_class(dict, response_raw.body_bytes.decode())
37+
response_body_dict = converter.deserialize(cls, response_body[cls._FIELD_RESPONSE])[0]
38+
39+
return UserCredentialPasswordIp.from_json(json.dumps(response_body_dict[cls._OBJECT_TYPE_GET]))

0 commit comments

Comments
 (0)