Skip to content

Commit fdc5500

Browse files
authored
Merge pull request #40 from socketlabs/usr/mike.boshuyzen/api-key-parser
Added api key parser
2 parents 5729214 + 81bd12d commit fdc5500

File tree

6 files changed

+175
-1
lines changed

6 files changed

+175
-1
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using SocketLabs.InjectionApi.Core.Enum;
5+
using SocketLabs.InjectionApi.Core.Models;
6+
7+
namespace SocketLabs.InjectionApi.Core
8+
{
9+
/// <summary>
10+
/// Parses a provided api key and provides a result
11+
/// </summary>
12+
public class ApiKeyParser : IApiKeyParser
13+
{
14+
/// <summary>
15+
/// Parses the provided Api key.
16+
/// </summary>
17+
/// <param name="wholeApiKey"></param>
18+
/// <returns>An ApiKeyParseResult with the api key data and result code from the parse.</returns>
19+
public ApiKeyParseResult Parse(string wholeApiKey)
20+
{
21+
var key = new ApiKey { IsValidFormat = false };
22+
if (string.IsNullOrWhiteSpace(wholeApiKey))
23+
return new ApiKeyParseResult { ApiKey = null, ResultCode = ApiKeyParseResultCode.InvalidEmptyOrWhitespace };
24+
25+
//if (!wholeApiKey.StartsWith("SL.", StringComparison.InvariantCulture))
26+
// return new ApiKeyParseResult {ApiKey = null, ResultCode = ApiKeyParseResultCode.InvalidMissingProperPrefix};
27+
28+
//extract public part
29+
var maxCount = Math.Min(50, wholeApiKey.Length);
30+
var publicPartEnd = wholeApiKey.IndexOf('.', startIndex: 0, maxCount); //don't check more than 50 chars
31+
if (publicPartEnd == -1)
32+
return new ApiKeyParseResult { ApiKey = null, ResultCode = ApiKeyParseResultCode.InvalidUnableToExtractPublicPart };
33+
var publicPart = wholeApiKey.Substring(0, publicPartEnd);
34+
35+
36+
//now extract the private part
37+
if (wholeApiKey.Length <= publicPartEnd + 1)
38+
return new ApiKeyParseResult { ApiKey = null, ResultCode = ApiKeyParseResultCode.InvalidUnableToExtractSecretPart };
39+
var privatePart = wholeApiKey.Substring(publicPartEnd + 1);
40+
41+
//success
42+
return new ApiKeyParseResult
43+
{
44+
ApiKey = new ApiKey
45+
{
46+
PublicPart = publicPart,
47+
PrivatePart = privatePart,
48+
IsValidFormat = true,
49+
},
50+
ResultCode = ApiKeyParseResultCode.Success
51+
};
52+
}
53+
}
54+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace SocketLabs.InjectionApi.Core.Enum
6+
{
7+
/// <summary>
8+
/// A code describing the result of an attempt to parse an Api key.
9+
/// </summary>
10+
public enum ApiKeyParseResultCode
11+
{
12+
13+
/// <summary>
14+
/// No result could be produced.
15+
/// </summary>
16+
None,
17+
/// <summary>
18+
/// The key was found to be blank or invalid.
19+
/// </summary>
20+
InvalidEmptyOrWhitespace,
21+
/// <summary>
22+
/// The public portion of the key was unable to be parsed.
23+
/// </summary>
24+
InvalidUnableToExtractPublicPart,
25+
/// <summary>
26+
/// The secret portion of the key was unable to be parsed.
27+
/// </summary>
28+
InvalidUnableToExtractSecretPart,
29+
/// <summary>
30+
/// Key was successfully parsed.
31+
/// </summary>
32+
Success
33+
}
34+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using SocketLabs.InjectionApi.Core.Enum;
2+
using SocketLabs.InjectionApi.Core.Models;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Text;
6+
7+
namespace SocketLabs.InjectionApi.Core
8+
{
9+
public interface IApiKeyParser
10+
{
11+
ApiKeyParseResult Parse(string wholeApiKey);
12+
}
13+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace SocketLabs.InjectionApi.Core.Models
6+
{
7+
/// <summary>
8+
/// A class representing an Api Key
9+
/// </summary>
10+
public class ApiKey
11+
{
12+
/// <summary>
13+
/// The public part of the Api Key.
14+
/// </summary>
15+
public string PublicPart { get; set; } = "";
16+
17+
/// <summary>
18+
/// The private part of the Api Key
19+
/// </summary>
20+
public string PrivatePart { get; set; } = "";
21+
22+
/// <summary>
23+
/// A boolean value describing the validity of the Api Key format
24+
/// </summary>
25+
public bool IsValidFormat { get; set; }
26+
}
27+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using SocketLabs.InjectionApi.Core.Enum;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Text;
5+
6+
namespace SocketLabs.InjectionApi.Core.Models
7+
{
8+
/// <summary>
9+
/// The result of an Api Key Parse Attempt
10+
/// </summary>
11+
public class ApiKeyParseResult
12+
{
13+
/// <summary>
14+
/// The object representing the parsed Api Key
15+
/// </summary>
16+
public ApiKey ApiKey { get; set; }
17+
18+
/// <summary>
19+
/// A code describing the result of the attempt to parse the Api key.
20+
/// </summary>
21+
public ApiKeyParseResultCode ResultCode { get; set; }
22+
}
23+
}

src/SocketLabs/InjectionApi/SocketLabsClient.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
using System;
22
using System.Net;
33
using System.Net.Http;
4+
using System.Net.Http.Headers;
45
using System.Reflection;
56
using System.Runtime.ExceptionServices;
67
using System.Threading;
78
using System.Threading.Tasks;
89
using SocketLabs.InjectionApi.Core;
10+
using SocketLabs.InjectionApi.Core.Enum;
911
using SocketLabs.InjectionApi.Message;
1012

1113
namespace SocketLabs.InjectionApi
@@ -35,8 +37,8 @@ public class SocketLabsClient : ISocketLabsClient, IDisposable
3537
private string UserAgent { get; } = $"SocketLabs-csharp/{typeof(SocketLabsClient).GetTypeInfo().Assembly.GetName().Version}";
3638

3739
private readonly int _serverId;
38-
private readonly string _apiKey;
3940
private readonly HttpClient _httpClient;
41+
private string _apiKey;
4042

4143

4244
/// <summary>
@@ -228,6 +230,16 @@ public async Task<SendResponse> SendAsync(IBasicMessage message, CancellationTok
228230

229231
validationResult = validator.ValidateMessage(message);
230232
if (validationResult.Result != SendResult.Success) return validationResult;
233+
234+
var apiKeyParser = new ApiKeyParser();
235+
var parseResult = apiKeyParser.Parse(_apiKey);
236+
237+
if (parseResult.ResultCode == ApiKeyParseResultCode.Success)
238+
{
239+
_httpClient.DefaultRequestHeaders.Authorization =
240+
new AuthenticationHeaderValue("Bearer", _apiKey);
241+
_apiKey = string.Empty;
242+
}
231243

232244
var factory = new InjectionRequestFactory(_serverId, _apiKey);
233245
var injectionRequest = factory.GenerateRequest(message);
@@ -282,6 +294,17 @@ public async Task<SendResponse> SendAsync(IBulkMessage message, CancellationToke
282294
validationResult = validator.ValidateMessage(message);
283295
if (validationResult.Result != SendResult.Success) return validationResult;
284296

297+
298+
var apiKeyParser = new ApiKeyParser();
299+
var parseResult = apiKeyParser.Parse(_apiKey);
300+
301+
if (parseResult.ResultCode == ApiKeyParseResultCode.Success)
302+
{
303+
_httpClient.DefaultRequestHeaders.Authorization =
304+
new AuthenticationHeaderValue("Bearer", _apiKey);
305+
_apiKey = string.Empty;
306+
}
307+
285308
var factory = new InjectionRequestFactory(_serverId, _apiKey);
286309
var injectionRequest = factory.GenerateRequest(message);
287310
var json = injectionRequest.GetAsJson();

0 commit comments

Comments
 (0)