Skip to content

Commit 2d150a3

Browse files
Implementation of SendSecure SDK
1 parent 6f210bc commit 2d150a3

31 files changed

+1892
-0
lines changed

XMedius.SendSecure/Client.cs

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
using Newtonsoft.Json;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Diagnostics;
5+
using System.Linq;
6+
using System.Net.Http;
7+
using System.Net.Http.Headers;
8+
using System.Text;
9+
using System.Threading;
10+
using System.Threading.Tasks;
11+
12+
namespace XMedius.SendSecure
13+
{
14+
public class Client
15+
{
16+
private static TraceSource TraceSource = new TraceSource("XMedius.SendSecure");
17+
18+
private static readonly Uri DEFAULT_PORTAL_URI = new Uri("https://portal.xmedius.com");
19+
private static readonly string USER_TOKEN_PATH = "api/user_token";
20+
21+
private string EnterpriseAccount;
22+
private string Token;
23+
private Uri EndPoint;
24+
private JsonClient JsonClient;
25+
private string Locale;
26+
27+
public Client(string token, Uri endpoint, string enterpriseAccount, string locale = "en")
28+
{
29+
EnterpriseAccount = enterpriseAccount;
30+
Token = token;
31+
EndPoint = endpoint;
32+
Locale = locale;
33+
JsonClient = new JsonClient(Token, EnterpriseAccount, EndPoint);
34+
}
35+
36+
public static async Task<string> GetUserToken(string enterpriseAccount, string username, string password, string deviceId,
37+
string deviceName, string applicationType = "SendSecure C#", Uri endpoint = null, string oneTimePassword = "",
38+
CancellationToken cancellationToken = default(CancellationToken))
39+
{
40+
if (endpoint == null)
41+
{
42+
endpoint = DEFAULT_PORTAL_URI;
43+
}
44+
45+
try
46+
{
47+
string portalUrl = await Utils.SendSecureUrlUtil.GetPortalUrlForEnterpriseAccount(enterpriseAccount, endpoint, cancellationToken);
48+
49+
Uri resourceAddress = new Uri(new Uri(portalUrl), USER_TOKEN_PATH);
50+
51+
var jsonRequest = new JsonObjects.GetTokenRequest
52+
{
53+
permalink = enterpriseAccount,
54+
username = username,
55+
password = password,
56+
application_type = applicationType,
57+
device_id = deviceId,
58+
device_name = deviceName,
59+
otp = oneTimePassword
60+
};
61+
62+
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, resourceAddress);
63+
StringContent jsonContent = new StringContent(JsonConvert.SerializeObject(jsonRequest), Encoding.UTF8, "application/json");
64+
request.Content = jsonContent;
65+
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
66+
67+
string responseString = await Utils.HttpUtil.MakeRequest(request, cancellationToken);
68+
69+
var ResponseData = JsonConvert.DeserializeObject<JsonObjects.GetTokenResponseSuccess>(responseString);
70+
71+
return ResponseData.Token;
72+
}
73+
catch (Exceptions.MakeRequestException e)
74+
{
75+
if (e.StatusCode > 0)
76+
{
77+
if (!String.IsNullOrEmpty(e.ResponseString))
78+
{
79+
try
80+
{
81+
var responseData = JsonConvert.DeserializeObject<JsonObjects.GetTokenResponseError>(e.ResponseString);
82+
throw new Exceptions.SendSecureException(responseData.Code, e.ResponseString, responseData.Message);
83+
}
84+
catch (JsonException)
85+
{
86+
}
87+
}
88+
89+
throw new Exceptions.SendSecureException((int)e.StatusCode, e.Message);
90+
}
91+
else
92+
{
93+
throw new Exceptions.UnexpectedServerResponseException();
94+
}
95+
96+
}
97+
catch (JsonSerializationException)
98+
{
99+
throw new Exceptions.UnexpectedServerResponseException();
100+
}
101+
catch (TaskCanceledException)
102+
{
103+
TraceSource.TraceEvent(TraceEventType.Information, 0, "GetUserToken Cancelled.");
104+
throw new OperationCanceledException();
105+
}
106+
catch (Exception e)
107+
{
108+
TraceSource.TraceEvent(TraceEventType.Error, 0,
109+
"Unexpected exception in GetToken ({0})", e.Message);
110+
throw new Exceptions.SendSecureException(e.Message);
111+
}
112+
}
113+
114+
public async Task<Helpers.SafeboxResponse> SubmitSafebox(Helpers.Safebox safebox, CancellationToken cancellationToken = default(CancellationToken))
115+
{
116+
await InitializeSafebox(safebox, cancellationToken);
117+
118+
foreach(Helpers.Attachment attachment in safebox.Attachments)
119+
{
120+
await UploadAttachment(safebox, attachment, cancellationToken);
121+
}
122+
123+
if(safebox.SecurityProfile == null)
124+
{
125+
safebox.SecurityProfile = await DefaultSecurityProfile(safebox.UserEmail, cancellationToken);
126+
127+
if(safebox.SecurityProfile == null)
128+
{
129+
throw new Exceptions.SendSecureException();
130+
}
131+
}
132+
133+
return await CommitSafebox(safebox, cancellationToken);
134+
}
135+
136+
public async Task<Helpers.Safebox> InitializeSafebox(Helpers.Safebox safebox, CancellationToken cancellationToken = default(CancellationToken))
137+
{
138+
string jsonResponse = await JsonClient.NewSafebox(safebox.UserEmail, cancellationToken);
139+
140+
var response = JsonConvert.DeserializeObject<JsonObjects.NewSafeboxResponseSuccess>(jsonResponse);
141+
142+
safebox.Guid = response.guid;
143+
safebox.PublicEncryptionKey = response.public_encryption_key;
144+
safebox.UploadUrl = response.upload_url;
145+
146+
return safebox;
147+
}
148+
149+
public async Task<Helpers.Attachment> UploadAttachment(Helpers.Safebox safebox, Helpers.Attachment attachment, CancellationToken cancellationToken = default(CancellationToken))
150+
{
151+
string jsonResponse = await JsonClient.UploadFile(new Uri(safebox.UploadUrl), attachment.Stream, attachment.ContentType, attachment.FileName, attachment.Size, cancellationToken);
152+
153+
var response = JsonConvert.DeserializeObject<JsonObjects.UploadFileResponseSuccess>(jsonResponse);
154+
155+
attachment.Guid = response.temporary_document.document_guid;
156+
157+
return attachment;
158+
}
159+
160+
public async Task<Helpers.SafeboxResponse> CommitSafebox(Helpers.Safebox safebox, CancellationToken cancellationToken = default(CancellationToken))
161+
{
162+
var request = new JsonObjects.CommitSafeboxRequest
163+
{
164+
safebox = new JsonObjects.CommitSafeboxRequest.SafeBox
165+
{
166+
guid = safebox.Guid,
167+
subject = safebox.Subject,
168+
message = safebox.Message,
169+
security_profile_id = safebox.SecurityProfile.Id,
170+
public_encryption_key = safebox.PublicEncryptionKey,
171+
notification_language = Locale,
172+
173+
reply_enabled = safebox.SecurityProfile.ReplyEnabled.Value,
174+
group_replies = safebox.SecurityProfile.GroupReplies.Value,
175+
expiration_value = safebox.SecurityProfile.ExpirationValue.Value,
176+
expiration_unit = safebox.SecurityProfile.ExpirationUnit.Value,
177+
retention_period_type = safebox.SecurityProfile.RetentionPeriodType.Value,
178+
retention_period_value = safebox.SecurityProfile.RetentionPeriodValue.Value,
179+
retention_period_unit = safebox.SecurityProfile.RetentionPeriodUnit.Value,
180+
encrypt_message = safebox.SecurityProfile.ReplyEnabled.Value,
181+
double_encryption = safebox.SecurityProfile.ReplyEnabled.Value,
182+
183+
document_ids = new List<string>(),
184+
recipients = safebox.Recipients
185+
}
186+
};
187+
188+
foreach (var attachment in safebox.Attachments)
189+
{
190+
request.safebox.document_ids.Add(attachment.Guid);
191+
}
192+
193+
string json = JsonConvert.SerializeObject(request);
194+
195+
string jsonResponse = await JsonClient.CommitSafebox(json, cancellationToken);
196+
197+
return JsonConvert.DeserializeObject<Helpers.SafeboxResponse>(jsonResponse);
198+
}
199+
200+
public async Task<List<Helpers.SecurityProfile>> SecurityProfiles(string userEmail, CancellationToken cancellationToken = default(CancellationToken))
201+
{
202+
string jsonResponse = await JsonClient.GetSecurityProfiles(userEmail, cancellationToken);
203+
204+
var response = JsonConvert.DeserializeObject<JsonObjects.GetSecurityProfilesResponseSuccess>(jsonResponse);
205+
206+
return response.SecurityProfiles;
207+
}
208+
209+
public async Task<Helpers.SecurityProfile> DefaultSecurityProfile(string userEmail, CancellationToken cancellationToken = default(CancellationToken))
210+
{
211+
var enterpriseSettings = await EnterpriseSettings(cancellationToken);
212+
var securityProfiles = await SecurityProfiles(userEmail, cancellationToken);
213+
214+
return securityProfiles.Find(x => x.Id == enterpriseSettings.DefaultSecurityProfileId);
215+
}
216+
217+
218+
public async Task<Helpers.EnterpriseSettings> EnterpriseSettings(CancellationToken cancellationToken = default(CancellationToken))
219+
{
220+
string jsonResponse = await JsonClient.GetEnterpriseSettings(cancellationToken);
221+
222+
var response = JsonConvert.DeserializeObject<Helpers.EnterpriseSettings>(jsonResponse);
223+
224+
return response;
225+
}
226+
}
227+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace XMedius.SendSecure.Exceptions
8+
{
9+
internal class MakeRequestException : Exception
10+
{
11+
public MakeRequestException()
12+
: base("MakeRequestException")
13+
{
14+
}
15+
16+
public MakeRequestException(string message)
17+
: base(message)
18+
{
19+
}
20+
21+
public MakeRequestException(string message, Exception inner)
22+
: base(message, inner)
23+
{
24+
}
25+
26+
public MakeRequestException(System.Net.HttpStatusCode statusCode, string reasonPhrase = null, string responseString = null)
27+
: base(reasonPhrase)
28+
{
29+
StatusCode = statusCode;
30+
ReasonPhrase = reasonPhrase;
31+
ResponseString = responseString;
32+
}
33+
34+
public System.Net.HttpStatusCode StatusCode { get; private set; }
35+
public string ReasonPhrase { get; private set; }
36+
public string ResponseString { get; private set; }
37+
38+
}
39+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace XMedius.SendSecure.Exceptions
8+
{
9+
public class SendSecureException : Exception
10+
{
11+
public SendSecureException()
12+
: base("An error occurred within a SendSecure call.")
13+
{
14+
}
15+
16+
public SendSecureException(string message)
17+
: base(message)
18+
{
19+
}
20+
21+
public SendSecureException(string message, Exception inner)
22+
: base(message, inner)
23+
{
24+
}
25+
26+
public SendSecureException(int code, string response, string message)
27+
: base(message)
28+
{
29+
Code = code;
30+
Response = response;
31+
}
32+
33+
public SendSecureException(int code, string message)
34+
: base(message)
35+
{
36+
Code = code;
37+
Response = null;
38+
}
39+
40+
public int Code
41+
{
42+
get; private set;
43+
}
44+
45+
public string Response
46+
{
47+
get; private set;
48+
}
49+
}
50+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace XMedius.SendSecure.Exceptions
8+
{
9+
class UnexpectedServerResponseException : SendSecureException
10+
{
11+
public UnexpectedServerResponseException()
12+
: base(1, "An error occurred within a SendSecure call.")
13+
{
14+
}
15+
}
16+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace XMedius.SendSecure.Helpers
9+
{
10+
public class Attachment
11+
{
12+
public string Guid { get; set; }
13+
14+
public string FileName { get; set; }
15+
public string ContentType { get; set; }
16+
public long Size { get; set; }
17+
18+
internal Stream Stream;
19+
20+
public Attachment(string path, string content_type = "application/octet-stream")
21+
{
22+
Stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
23+
24+
var fileInfo = new FileInfo(path);
25+
FileName = fileInfo.Name;
26+
ContentType = content_type;
27+
Size = fileInfo.Length;
28+
}
29+
30+
public Attachment(Stream stream, string filename, long size, string content_type = "application/octet-stream")
31+
{
32+
Stream = stream;
33+
FileName = filename;
34+
ContentType = content_type;
35+
Size = size;
36+
}
37+
}
38+
}

0 commit comments

Comments
 (0)