5
5
from typing import List , Optional
6
6
7
7
from Cryptodome .PublicKey import RSA
8
+ from Cryptodome .PublicKey .RSA import RsaKey
8
9
9
10
from bunq .sdk .context .api_environment_type import ApiEnvironmentType
10
11
from bunq .sdk .context .installation_context import InstallationContext
11
12
from bunq .sdk .context .session_context import SessionContext
12
13
from bunq .sdk .exception .bunq_exception import BunqException
13
14
from bunq .sdk .json import converter
15
+ from bunq .sdk .model .core .PaymentServiceProviderCredentialInternal import PaymentServiceProviderCredentialInternal
14
16
from bunq .sdk .model .generated import endpoint
17
+ from bunq .sdk .model .generated .endpoint import UserCredentialPasswordIp
15
18
from bunq .sdk .security import security
16
19
17
20
if typing .TYPE_CHECKING :
21
24
class ApiContext :
22
25
"""
23
26
:type _environment_type: ApiEnvironmentType
24
- :type _api_key: str
25
- :type _session_context: SessionContext
26
- :type _installation_context: InstallationContext
27
+ :type _api_key: str|None
28
+ :type _session_context: SessionContext|None
29
+ :type _installation_context: InstallationContext|None
27
30
:type _proxy_url: str|None
28
31
"""
29
32
@@ -42,26 +45,54 @@ class ApiContext:
42
45
43
46
def __init__ (self ,
44
47
environment_type : ApiEnvironmentType ,
45
- api_key : str ,
46
- device_description : str ,
47
- permitted_ips : List [str ] = None ,
48
48
proxy_url : List [str ] = None ) -> None :
49
- if permitted_ips is None :
50
- permitted_ips = []
51
-
52
49
self ._environment_type = environment_type
53
- self ._api_key = api_key
50
+ self ._proxy_url = proxy_url
51
+ self ._api_key = None
54
52
self ._installation_context = None
55
53
self ._session_context = None
56
- self ._proxy_url = proxy_url
57
- self ._initialize (device_description , permitted_ips )
58
54
59
- def _initialize (self ,
60
- device_description : str ,
61
- permitted_ips : List [str ]) -> None :
62
- self ._initialize_installation ()
63
- self ._register_device (device_description , permitted_ips )
64
- self ._initialize_session ()
55
+ @classmethod
56
+ def create (cls ,
57
+ environment_type : ApiEnvironmentType ,
58
+ api_key : str ,
59
+ description : str ,
60
+ all_permitted_ip : List [str ] = None ,
61
+ proxy_url : List [str ] = None ) -> ApiContext :
62
+ api_context = cls (environment_type , proxy_url )
63
+
64
+ api_context ._api_key = api_key
65
+
66
+ api_context ._initialize_installation ()
67
+ api_context ._register_device (description , all_permitted_ip )
68
+ api_context ._initialize_session ()
69
+
70
+ return api_context
71
+
72
+ @classmethod
73
+ def create_for_psd2 (cls ,
74
+ environment_type : ApiEnvironmentType ,
75
+ certificate : str ,
76
+ private_key : RsaKey ,
77
+ all_chain_certificate : List [str ],
78
+ description : str ,
79
+ all_permitted_ip : List [str ] = None ,
80
+ proxy_url : List [str ] = None ) -> ApiContext :
81
+ api_context = cls (environment_type , proxy_url )
82
+
83
+ api_context ._initialize_installation ()
84
+
85
+ service_provider_credential = api_context ._initialize_psd2_credential (
86
+ certificate ,
87
+ private_key ,
88
+ all_chain_certificate )
89
+
90
+ api_context ._api_key = service_provider_credential .token_value
91
+
92
+ api_context ._register_device (description , all_permitted_ip )
93
+ api_context ._initialize_session ()
94
+
95
+ return api_context
65
96
66
97
def _initialize_installation (self ) -> None :
67
98
from bunq .sdk .model .core .installation import Installation
@@ -83,6 +114,25 @@ def _initialize_installation(self) -> None:
83
114
public_key_server
84
115
)
85
116
117
+ def _initialize_psd2_credential (self ,
118
+ certificate : str ,
119
+ private_key : RsaKey ,
120
+ all_chain_certificate : List [str ], ) -> UserCredentialPasswordIp :
121
+ session_token = self .installation_context .token
122
+ client_key_pair = self .installation_context .private_key_client
123
+
124
+ string_to_sign = security .public_key_to_string (client_key_pair .publickey ()) + session_token
125
+ encoded_signature = security .generate_signature (string_to_sign , private_key )
126
+
127
+ payment_response_provider = PaymentServiceProviderCredentialInternal .create_with_api_context (
128
+ certificate ,
129
+ security .get_certificate_chain_string (all_chain_certificate ),
130
+ encoded_signature ,
131
+ self
132
+ )
133
+
134
+ return payment_response_provider
135
+
86
136
def _register_device (self ,
87
137
device_description : str ,
88
138
permitted_ips : List [str ]) -> None :
0 commit comments