Skip to content

Commit 5299687

Browse files
committed
Add v0.9
1 parent ea83e52 commit 5299687

File tree

160 files changed

+12557
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

160 files changed

+12557
-1
lines changed

.idea/.idea.BunqSdkCsharp/.idea/.name

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/.idea.BunqSdkCsharp/.idea/contentModel.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/.idea.BunqSdkCsharp/.idea/modules.xml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/.idea.BunqSdkCsharp/.idea/vcs.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/.idea.BunqSdkCsharp/riderModule.iml

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

BunqSdkCsharp.csproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>netcoreapp1.1</TargetFramework>
5+
<RootNamespace>Bunq.Sdk</RootNamespace>
6+
<LangVersion>5</LangVersion>
7+
</PropertyGroup>
8+
<ItemGroup>
9+
<Folder Include="Http" />
10+
<Folder Include="Model\Generated\Object" />
11+
<Folder Include="Samples\Assets" />
12+
</ItemGroup>
13+
<ItemGroup>
14+
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
15+
</ItemGroup>
16+
</Project>

BunqSdkCsharp.sln

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 2013
4+
VisualStudioVersion = 12.0.0.0
5+
MinimumVisualStudioVersion = 10.0.0.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BunqSdkCsharp", "BunqSdkCsharp.csproj", "{4A5F65F6-41AC-4693-9A91-500A7B8DE1F7}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{4A5F65F6-41AC-4693-9A91-500A7B8DE1F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{4A5F65F6-41AC-4693-9A91-500A7B8DE1F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{4A5F65F6-41AC-4693-9A91-500A7B8DE1F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{4A5F65F6-41AC-4693-9A91-500A7B8DE1F7}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
EndGlobal

CHANGELOG.md

Whitespace-only changes.

Context/ApiContext.cs

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Text;
5+
using Bunq.Sdk.Exception;
6+
using Bunq.Sdk.Json;
7+
using Bunq.Sdk.Model;
8+
using Bunq.Sdk.Model.Generated;
9+
using Bunq.Sdk.Security;
10+
using Newtonsoft.Json;
11+
using DeviceServer = Bunq.Sdk.Model.DeviceServer;
12+
13+
namespace Bunq.Sdk.Context
14+
{
15+
/// <summary>
16+
/// The context to make the API calls in. Consists of:
17+
/// > Environment type (SANDBOX or PRODUCTION)
18+
/// > Bunq API Key for the corresponding environment
19+
/// > Installation context
20+
/// > Session context
21+
/// </summary>
22+
public class ApiContext
23+
{
24+
/// <summary>
25+
/// Error constants.
26+
/// </summary>
27+
private const string ERROR_COULD_NOT_SAVE_API_CONTEXT = "Could not save the API context.";
28+
private const string ERROR_COULD_NOT_RESTORE_API_CONTEXT = "Could not restore the API context.";
29+
30+
/// <summary>
31+
/// Measure of any time unit when none of it is needed.
32+
/// </summary>
33+
private const int TIME_UNIT_COUNT_NONE = 0;
34+
35+
/// <summary>
36+
/// Minimum time to session expiry not requiring session reset.
37+
/// </summary>
38+
private const int TIME_TO_SESSION_EXPIRY_MINIMUM_SECONDS = 30;
39+
40+
/// <summary>
41+
/// Default path to store the serialized context.
42+
/// </summary>
43+
private const string PATH_API_CONTEXT_DEFAULT = "bunq.conf";
44+
45+
/// <summary>
46+
/// Dummy ID to pass to Session endpoint.
47+
/// </summary>
48+
private const int SESSION_ID_DUMMY = 0;
49+
50+
/// <summary>
51+
/// Encoding of the serialized context.
52+
/// </summary>
53+
private static readonly Encoding ENCODING_BUNQ_CONF = Encoding.UTF8;
54+
55+
[JsonProperty(PropertyName = "environment_type")]
56+
public ApiEnvironmentType EnvironmentType { get; private set; }
57+
58+
[JsonProperty(PropertyName = "api_key")]
59+
public string ApiKey { get; private set; }
60+
61+
[JsonProperty(PropertyName = "installation_context")]
62+
public InstallationContext InstallationContext { get; private set; }
63+
64+
[JsonProperty(PropertyName = "session_context")]
65+
public SessionContext SessionContext { get; private set; }
66+
67+
[JsonConstructor]
68+
private ApiContext()
69+
{
70+
}
71+
72+
/// <summary>
73+
/// Create and initialize an API Context with current IP as permitted.
74+
/// </summary>
75+
public static ApiContext Create(ApiEnvironmentType environmentType, string apiKey, string deviceDescription)
76+
{
77+
return Create(environmentType, apiKey, deviceDescription, new List<string>());
78+
}
79+
80+
/// <summary>
81+
/// Create and initialize an API Context.
82+
/// </summary>
83+
public static ApiContext Create(ApiEnvironmentType environmentType, string apiKey, string deviceDescription,
84+
IList<string> permittedIps)
85+
{
86+
var apiContext = new ApiContext
87+
{
88+
ApiKey = apiKey,
89+
EnvironmentType = environmentType,
90+
};
91+
apiContext.Initialize(deviceDescription, permittedIps);
92+
93+
return apiContext;
94+
}
95+
96+
/// <summary>
97+
/// Initializes an API context with Installation, DeviceServer and a SessionServer.
98+
/// </summary>
99+
private void Initialize(string deviceDescription, IList<string> permittedIps)
100+
{
101+
/* The calls below are order-sensitive: to initialize a Device Registration, we need an
102+
* Installation, and to initialize a Session we need a Device Registration. */
103+
InitializeInstallationContext();
104+
RegisterDevice(deviceDescription, permittedIps);
105+
InitializeSessionContext();
106+
}
107+
108+
/// <summary>
109+
/// Create a new installation and store its data in installation context.
110+
/// </summary>
111+
private void InitializeInstallationContext()
112+
{
113+
var keyPairClient = SecurityUtils.GenerateKeyPair();
114+
var publicKeyFormattedString = SecurityUtils.GetPublicKeyFormattedString(keyPairClient);
115+
var installation = Installation.Create(this, publicKeyFormattedString);
116+
InstallationContext = new InstallationContext(installation, keyPairClient);
117+
}
118+
119+
private void RegisterDevice(string deviceDescription, IList<string> permittedIps)
120+
{
121+
DeviceServer.Create(this, deviceDescription, permittedIps);
122+
}
123+
124+
/// <summary>
125+
/// Create a new session and its data in a SessionContext.
126+
/// </summary>
127+
private void InitializeSessionContext()
128+
{
129+
SessionContext = new SessionContext(SessionServer.Create(this));
130+
}
131+
132+
/// <summary>
133+
/// Closes the current session and opens a new one.
134+
/// </summary>
135+
public void ResetSession()
136+
{
137+
DropSessionContext();
138+
InitializeSessionContext();
139+
}
140+
141+
private void DropSessionContext()
142+
{
143+
SessionContext = null;
144+
}
145+
146+
/// <summary>
147+
/// Closes the current session.
148+
/// </summary>
149+
public void CloseSession()
150+
{
151+
DeleteSession();
152+
DropSessionContext();
153+
}
154+
155+
private void DeleteSession()
156+
{
157+
Session.Delete(this, SESSION_ID_DUMMY);
158+
}
159+
160+
/// <summary>
161+
/// Check if current time is too close to the saved session expiry time and reset session if needed.
162+
/// </summary>
163+
public void EnsureSessionActive()
164+
{
165+
if (SessionContext == null) return;
166+
167+
var timeToExpiry = SessionContext.ExpiryTime.Subtract(DateTime.Now);
168+
var timeToExpiryMinimum = new TimeSpan(
169+
TIME_UNIT_COUNT_NONE,
170+
TIME_UNIT_COUNT_NONE,
171+
TIME_TO_SESSION_EXPIRY_MINIMUM_SECONDS
172+
);
173+
174+
if (timeToExpiry < timeToExpiryMinimum)
175+
{
176+
ResetSession();
177+
}
178+
}
179+
180+
/// <summary>
181+
/// Save a JSON representation of the API Context to the default location.
182+
/// </summary>
183+
public void Save()
184+
{
185+
Save(PATH_API_CONTEXT_DEFAULT);
186+
}
187+
188+
/// <summary>
189+
/// Save a JSON representation of the API Context to a given file.
190+
/// </summary>
191+
public void Save(string fileName)
192+
{
193+
try
194+
{
195+
File.WriteAllText(fileName, BunqJsonConvert.SerializeObject(this), ENCODING_BUNQ_CONF);
196+
}
197+
catch (IOException exception)
198+
{
199+
throw new BunqException(ERROR_COULD_NOT_SAVE_API_CONTEXT, exception);
200+
}
201+
}
202+
203+
/// <summary>
204+
/// Restores a context from a default location.
205+
/// </summary>
206+
public static ApiContext Restore()
207+
{
208+
return Restore(PATH_API_CONTEXT_DEFAULT);
209+
}
210+
211+
/// <summary>
212+
/// Restores a context from a given file.
213+
/// </summary>
214+
public static ApiContext Restore(string fileName)
215+
{
216+
try
217+
{
218+
var apiContextJson = File.ReadAllText(fileName, ENCODING_BUNQ_CONF);
219+
220+
return BunqJsonConvert.DeserializeObject<ApiContext>(apiContextJson);
221+
}
222+
catch (IOException exception)
223+
{
224+
throw new BunqException(ERROR_COULD_NOT_RESTORE_API_CONTEXT, exception);
225+
}
226+
}
227+
228+
/// <summary>
229+
/// Returns the base URI of the environment assigned to the API context.
230+
/// </summary>
231+
public string GetBaseUri()
232+
{
233+
return EnvironmentType.BaseUri;
234+
}
235+
236+
/// <returns> The session token, installation token if the session isn't created yet, or null if no installation
237+
/// is created either. </returns>
238+
public string GetSessionToken()
239+
{
240+
if (SessionContext != null) return SessionContext.Token;
241+
242+
return InstallationContext == null ? null : InstallationContext.Token;
243+
}
244+
}
245+
}

Context/ApiEnvironmentType.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System.Collections.Generic;
2+
3+
namespace Bunq.Sdk.Context
4+
{
5+
/// <summary>
6+
/// Class-based Enum for the API environment types and their URIs.
7+
/// </summary>
8+
public sealed class ApiEnvironmentType
9+
{
10+
/// <summary>
11+
/// Mapping of environment type to the base URI.
12+
/// </summary>
13+
private static readonly IDictionary<string, string> NAME_TO_BASE_URI_MAP = new Dictionary<string, string>
14+
{
15+
{ENVIRONMENT_TYPE_PRODUCTION, BASE_URI_PRODUCTION},
16+
{ENVIRONMENT_TYPE_SANDBOX, BASE_URI_SANDBOX}
17+
};
18+
19+
/// <summary>
20+
/// Production environment constants.
21+
/// </summary>
22+
public static readonly ApiEnvironmentType PRODUCTION = new ApiEnvironmentType(ENVIRONMENT_TYPE_PRODUCTION);
23+
private const string ENVIRONMENT_TYPE_PRODUCTION = "PRODUCTION";
24+
private const string BASE_URI_PRODUCTION = "https://public.api.bunq.com/v1/";
25+
26+
/// <summary>
27+
/// Sandbox environment constants.
28+
/// </summary>
29+
public static readonly ApiEnvironmentType SANDBOX = new ApiEnvironmentType(ENVIRONMENT_TYPE_SANDBOX);
30+
private const string ENVIRONMENT_TYPE_SANDBOX = "SANDBOX";
31+
private const string BASE_URI_SANDBOX = "https://sandbox.public.api.bunq.com/v1/";
32+
33+
public string TypeString { get; private set; }
34+
public string BaseUri { get; private set; }
35+
36+
public ApiEnvironmentType(string typeString)
37+
{
38+
TypeString = typeString;
39+
BaseUri = NAME_TO_BASE_URI_MAP[typeString];
40+
}
41+
}
42+
}

0 commit comments

Comments
 (0)