1111from bunq .sdk .context .session_context import SessionContext
1212from bunq .sdk .exception .bunq_exception import BunqException
1313from bunq .sdk .json import converter
14+ from bunq .sdk .model .core .payment_service_provider_credential_internal import PaymentServiceProviderCredentialInternal
1415from bunq .sdk .model .generated import endpoint
16+ from bunq .sdk .model .generated .endpoint import UserCredentialPasswordIp , UserPaymentServiceProvider
1517from bunq .sdk .security import security
1618
1719if typing .TYPE_CHECKING :
2123class ApiContext :
2224 """
2325 :type _environment_type: ApiEnvironmentType
24- :type _api_key: str
25- :type _session_context: SessionContext
26- :type _installation_context: InstallationContext
26+ :type _api_key: str|None
27+ :type _session_context: SessionContext|None
28+ :type _installation_context: InstallationContext|None
2729 :type _proxy_url: str|None
2830 """
2931
@@ -42,28 +44,56 @@ class ApiContext:
4244
4345 def __init__ (self ,
4446 environment_type : ApiEnvironmentType ,
45- api_key : str ,
46- device_description : str ,
47- permitted_ips : List [str ] = None ,
4847 proxy_url : List [str ] = None ) -> None :
49- if permitted_ips is None :
50- permitted_ips = []
51-
5248 self ._environment_type = environment_type
53- self ._api_key = api_key
49+ self ._proxy_url = proxy_url
50+ self ._api_key = None
5451 self ._installation_context = None
5552 self ._session_context = None
56- self ._proxy_url = proxy_url
57- self ._initialize (device_description , permitted_ips )
5853
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 ()
54+ @classmethod
55+ def create (cls ,
56+ environment_type : ApiEnvironmentType ,
57+ api_key : str ,
58+ description : str ,
59+ all_permitted_ip : List [str ] = None ,
60+ proxy_url : List [str ] = None ) -> ApiContext :
61+ api_context = cls (environment_type , proxy_url )
62+
63+ api_context ._api_key = api_key
64+
65+ api_context .__initialize_installation ()
66+ api_context .__register_device (description , all_permitted_ip )
67+ api_context .__initialize_session ()
68+
69+ return api_context
70+
71+ @classmethod
72+ def create_for_psd2 (cls ,
73+ environment_type : ApiEnvironmentType ,
74+ certificate : str ,
75+ private_key : str ,
76+ all_chain_certificate : List [str ],
77+ description : str ,
78+ all_permitted_ip : List [str ] = None ,
79+ proxy_url : List [str ] = None ) -> ApiContext :
80+ api_context = cls (environment_type , proxy_url )
81+
82+ api_context .__initialize_installation ()
83+
84+ service_provider_credential = api_context .__initialize_psd2_credential (
85+ certificate ,
86+ private_key ,
87+ all_chain_certificate )
88+
89+ api_context ._api_key = service_provider_credential .token_value
90+
91+ api_context .__register_device (description , all_permitted_ip )
92+ api_context .__initialize_session_for_psd2 (service_provider_credential )
93+
94+ return api_context
6595
66- def _initialize_installation (self ) -> None :
96+ def __initialize_installation (self ) -> None :
6797 from bunq .sdk .model .core .installation import Installation
6898
6999 private_key_client = security .generate_rsa_private_key ()
@@ -83,9 +113,28 @@ def _initialize_installation(self) -> None:
83113 public_key_server
84114 )
85115
86- def _register_device (self ,
87- device_description : str ,
88- permitted_ips : List [str ]) -> None :
116+ def __initialize_psd2_credential (self ,
117+ certificate : str ,
118+ private_key : str ,
119+ all_chain_certificate : List [str ], ) -> UserCredentialPasswordIp :
120+ session_token = self .installation_context .token
121+ client_key_pair = self .installation_context .private_key_client
122+
123+ string_to_sign = security .public_key_to_string (client_key_pair .publickey ()) + "\n " + session_token
124+ encoded_signature = security .generate_signature (string_to_sign , security .rsa_key_from_string (private_key ))
125+
126+ payment_response_provider = PaymentServiceProviderCredentialInternal .create_with_api_context (
127+ certificate ,
128+ security .get_certificate_chain_string (all_chain_certificate ),
129+ encoded_signature ,
130+ self
131+ )
132+
133+ return payment_response_provider
134+
135+ def __register_device (self ,
136+ device_description : str ,
137+ permitted_ips : List [str ]) -> None :
89138 from bunq .sdk .model .core .device_server_internal import DeviceServerInternal
90139
91140 DeviceServerInternal .create (
@@ -95,7 +144,7 @@ def _register_device(self,
95144 api_context = self
96145 )
97146
98- def _initialize_session (self ) -> None :
147+ def __initialize_session (self ) -> None :
99148 from bunq .sdk .model .core .session_server import SessionServer
100149
101150 session_server = SessionServer .create (self ).value
@@ -105,6 +154,17 @@ def _initialize_session(self) -> None:
105154
106155 self ._session_context = SessionContext (token , expiry_time , user_id )
107156
157+ def __initialize_session_for_psd2 (self , user_payment_service_provider : UserPaymentServiceProvider ) -> None :
158+ from bunq .sdk .model .core .session_server import SessionServer
159+
160+ session_server = SessionServer .create (self ).value
161+
162+ token = session_server .token .token
163+ expiry_time = self ._get_expiry_timestamp (session_server )
164+ user_id = session_server .get_referenced_user ().id_
165+
166+ self ._session_context = SessionContext (token , expiry_time , user_id )
167+
108168 @classmethod
109169 def _get_expiry_timestamp (cls , session_server : SessionServer ) -> datetime .datetime :
110170 timeout_seconds = cls ._get_session_timeout_seconds (session_server )
@@ -118,6 +178,8 @@ def _get_session_timeout_seconds(cls, session_server: SessionServer) -> int:
118178 return session_server .user_company .session_timeout
119179 elif session_server .user_person is not None :
120180 return session_server .user_person .session_timeout
181+ elif session_server .user_payment_service_provider is not None :
182+ return session_server .user_payment_service_provider .session_timeout
121183 elif session_server .user_api_key is not None :
122184 return session_server \
123185 .user_api_key \
@@ -159,7 +221,7 @@ def reset_session(self) -> None:
159221 """
160222
161223 self ._drop_session_context ()
162- self ._initialize_session ()
224+ self .__initialize_session ()
163225
164226 def _drop_session_context (self ) -> None :
165227 self ._session_context = None
0 commit comments