Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions src/SocketLabs/InjectionApi/Core/ApiKeyParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Text;
using SocketLabs.InjectionApi.Core.Enum;
using SocketLabs.InjectionApi.Core.Models;

namespace SocketLabs.InjectionApi.Core
{
/// <summary>
/// Parses a provided api key and provides a result
/// </summary>
public class ApiKeyParser : IApiKeyParser
{
/// <summary>
/// Parses the provided Api key.
/// </summary>
/// <param name="wholeApiKey"></param>
/// <returns>An ApiKeyParseResult with the api key data and result code from the parse.</returns>
public ApiKeyParseResult Parse(string wholeApiKey)
{
var key = new ApiKey { IsValidFormat = false };
if (string.IsNullOrWhiteSpace(wholeApiKey))
return new ApiKeyParseResult { ApiKey = null, ResultCode = ApiKeyParseResultCode.InvalidEmptyOrWhitespace };

//if (!wholeApiKey.StartsWith("SL.", StringComparison.InvariantCulture))
// return new ApiKeyParseResult {ApiKey = null, ResultCode = ApiKeyParseResultCode.InvalidMissingProperPrefix};

//extract public part
var maxCount = Math.Min(50, wholeApiKey.Length);
var publicPartEnd = wholeApiKey.IndexOf('.', startIndex: 0, maxCount); //don't check more than 50 chars
if (publicPartEnd == -1)
return new ApiKeyParseResult { ApiKey = null, ResultCode = ApiKeyParseResultCode.InvalidUnableToExtractPublicPart };
var publicPart = wholeApiKey.Substring(0, publicPartEnd);


//now extract the private part
if (wholeApiKey.Length <= publicPartEnd + 1)
return new ApiKeyParseResult { ApiKey = null, ResultCode = ApiKeyParseResultCode.InvalidUnableToExtractSecretPart };
var privatePart = wholeApiKey.Substring(publicPartEnd + 1);

//success
return new ApiKeyParseResult
{
ApiKey = new ApiKey
{
PublicPart = publicPart,
PrivatePart = privatePart,
IsValidFormat = true,
},
ResultCode = ApiKeyParseResultCode.Success
};
}
}
}
34 changes: 34 additions & 0 deletions src/SocketLabs/InjectionApi/Core/Enum/ApiKeyParseResultCode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace SocketLabs.InjectionApi.Core.Enum
{
/// <summary>
/// A code describing the result of an attempt to parse an Api key.
/// </summary>
public enum ApiKeyParseResultCode
{

/// <summary>
/// No result could be produced.
/// </summary>
None,
/// <summary>
/// The key was found to be blank or invalid.
/// </summary>
InvalidEmptyOrWhitespace,
/// <summary>
/// The public portion of the key was unable to be parsed.
/// </summary>
InvalidUnableToExtractPublicPart,
/// <summary>
/// The secret portion of the key was unable to be parsed.
/// </summary>
InvalidUnableToExtractSecretPart,
/// <summary>
/// Key was successfully parsed.
/// </summary>
Success
}
}
13 changes: 13 additions & 0 deletions src/SocketLabs/InjectionApi/Core/IApiKeyParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using SocketLabs.InjectionApi.Core.Enum;
using SocketLabs.InjectionApi.Core.Models;
using System;
using System.Collections.Generic;
using System.Text;

namespace SocketLabs.InjectionApi.Core
{
public interface IApiKeyParser
{
ApiKeyParseResult Parse(string wholeApiKey);
}
}
27 changes: 27 additions & 0 deletions src/SocketLabs/InjectionApi/Core/Models/ApiKey.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace SocketLabs.InjectionApi.Core.Models
{
/// <summary>
/// A class representing an Api Key
/// </summary>
public class ApiKey
{
/// <summary>
/// The public part of the Api Key.
/// </summary>
public string PublicPart { get; set; } = "";

/// <summary>
/// The private part of the Api Key
/// </summary>
public string PrivatePart { get; set; } = "";

/// <summary>
/// A boolean value describing the validity of the Api Key format
/// </summary>
public bool IsValidFormat { get; set; }
}
}
23 changes: 23 additions & 0 deletions src/SocketLabs/InjectionApi/Core/Models/ApiKeyParseResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using SocketLabs.InjectionApi.Core.Enum;
using System;
using System.Collections.Generic;
using System.Text;

namespace SocketLabs.InjectionApi.Core.Models
{
/// <summary>
/// The result of an Api Key Parse Attempt
/// </summary>
public class ApiKeyParseResult
{
/// <summary>
/// The object representing the parsed Api Key
/// </summary>
public ApiKey ApiKey { get; set; }

/// <summary>
/// A code describing the result of the attempt to parse the Api key.
/// </summary>
public ApiKeyParseResultCode ResultCode { get; set; }
}
}
25 changes: 24 additions & 1 deletion src/SocketLabs/InjectionApi/SocketLabsClient.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Runtime.ExceptionServices;
using System.Threading;
using System.Threading.Tasks;
using SocketLabs.InjectionApi.Core;
using SocketLabs.InjectionApi.Core.Enum;
using SocketLabs.InjectionApi.Message;

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

private readonly int _serverId;
private readonly string _apiKey;
private readonly HttpClient _httpClient;
private string _apiKey;


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

validationResult = validator.ValidateMessage(message);
if (validationResult.Result != SendResult.Success) return validationResult;

var apiKeyParser = new ApiKeyParser();
var parseResult = apiKeyParser.Parse(_apiKey);

if (parseResult.ResultCode == ApiKeyParseResultCode.Success)
{
_httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", _apiKey);
_apiKey = string.Empty;
}

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


var apiKeyParser = new ApiKeyParser();
var parseResult = apiKeyParser.Parse(_apiKey);

if (parseResult.ResultCode == ApiKeyParseResultCode.Success)
{
_httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", _apiKey);
_apiKey = string.Empty;
}

var factory = new InjectionRequestFactory(_serverId, _apiKey);
var injectionRequest = factory.GenerateRequest(message);
var json = injectionRequest.GetAsJson();
Expand Down