mirror of
https://github.com/JKorf/CryptoExchange.Net
synced 2025-06-09 17:06:19 +00:00
Moved PrivateKey to ApiCredentials, ApiCredentials use SecureString, Refactored array param string building
This commit is contained in:
parent
b0cf1a899e
commit
ed14082b9a
@ -1,27 +1,82 @@
|
||||
using System;
|
||||
using System.Security;
|
||||
|
||||
namespace CryptoExchange.Net.Authentication
|
||||
{
|
||||
public class ApiCredentials
|
||||
public class ApiCredentials: IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The api key
|
||||
/// The api key to authenticate requests
|
||||
/// </summary>
|
||||
public string Key { get; }
|
||||
public SecureString Key { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The api secret
|
||||
/// The api secret to authenticate requests
|
||||
/// </summary>
|
||||
public string Secret { get; }
|
||||
public SecureString Secret { get; }
|
||||
|
||||
public ApiCredentials() { }
|
||||
/// <summary>
|
||||
/// The private key to authenticate requests
|
||||
/// </summary>
|
||||
public SecureString PrivateKey { get; }
|
||||
|
||||
public ApiCredentials(string key, string secret)
|
||||
/// <summary>
|
||||
/// Create Api credentials providing a private key for authenication
|
||||
/// </summary>
|
||||
/// <param name="privateKey">The private key used for signing</param>
|
||||
public ApiCredentials(SecureString privateKey)
|
||||
{
|
||||
if(string.IsNullOrEmpty(key) || string.IsNullOrEmpty(secret))
|
||||
throw new ArgumentException("Apikey or apisecret not provided");
|
||||
PrivateKey = Key;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create Api credentials providing a private key for authenication
|
||||
/// </summary>
|
||||
/// <param name="privateKey">The private key used for signing</param>
|
||||
public ApiCredentials(string privateKey)
|
||||
{
|
||||
var securePrivateKey = new SecureString();
|
||||
foreach (var c in privateKey)
|
||||
securePrivateKey.AppendChar(c);
|
||||
securePrivateKey.MakeReadOnly();
|
||||
PrivateKey = securePrivateKey;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create Api credentials providing a api key and secret for authenciation
|
||||
/// </summary>
|
||||
/// <param name="key">The api key used for identification</param>
|
||||
/// <param name="secret">The api secret used for signing</param>
|
||||
public ApiCredentials(SecureString key, SecureString secret)
|
||||
{
|
||||
Key = key;
|
||||
Secret = secret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create Api credentials providing a private key for authenication
|
||||
/// </summary>
|
||||
/// <param name="privateKey">The private key used for signing</param>
|
||||
public ApiCredentials(string key, string secret)
|
||||
{
|
||||
var secureApiKey = new SecureString();
|
||||
foreach (var c in key)
|
||||
secureApiKey.AppendChar(c);
|
||||
secureApiKey.MakeReadOnly();
|
||||
Key = secureApiKey;
|
||||
|
||||
var secureApiSecret = new SecureString();
|
||||
foreach (var c in secret)
|
||||
secureApiSecret.AppendChar(c);
|
||||
secureApiSecret.MakeReadOnly();
|
||||
Secret = secureApiSecret;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Key?.Dispose();
|
||||
Secret?.Dispose();
|
||||
PrivateKey?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
using CryptoExchange.Net.Interfaces;
|
||||
using System.Security;
|
||||
|
||||
namespace CryptoExchange.Net.Authentication
|
||||
{
|
||||
@ -7,18 +6,11 @@ namespace CryptoExchange.Net.Authentication
|
||||
{
|
||||
public ApiCredentials Credentials { get; }
|
||||
|
||||
public SecureString PrivateKey { get; }
|
||||
|
||||
protected AuthenticationProvider(ApiCredentials credentials)
|
||||
{
|
||||
Credentials = credentials;
|
||||
}
|
||||
|
||||
protected AuthenticationProvider(SecureString privateKey)
|
||||
{
|
||||
PrivateKey = privateKey;
|
||||
}
|
||||
|
||||
public virtual string AddAuthenticationToUriString(string uri, bool signed)
|
||||
{
|
||||
return uri;
|
||||
|
@ -106,23 +106,12 @@ namespace CryptoExchange.Net
|
||||
string paramString = null;
|
||||
if (parameters != null)
|
||||
{
|
||||
paramString = "with parameters ";
|
||||
int paramCount = 1;
|
||||
paramString = "with parameters";
|
||||
|
||||
foreach (var param in parameters)
|
||||
{
|
||||
string paramValue = param.Value.ToString();
|
||||
if (param.Value.GetType().IsArray)
|
||||
paramValue = string.Format("[{0}]", string.Join(", ", ((object[])param.Value).Select(p => p.ToString())));
|
||||
paramString += $" {param.Key}={(param.Value.GetType().IsArray ? $"[{string.Join(", ", ((object[])param.Value).Select(p => p.ToString()))}]": param.Value )},";
|
||||
|
||||
paramString += $"{param.Key}={paramValue}";
|
||||
|
||||
if (paramCount < parameters.Count)
|
||||
paramString += ", ";
|
||||
else
|
||||
paramString += ".";
|
||||
|
||||
paramCount++;
|
||||
}
|
||||
paramString = paramString.Trim(',');
|
||||
}
|
||||
|
||||
log.Write(LogVerbosity.Debug, $"Sending {(signed ? "signed" : "")} request to {request.Uri} {(paramString ?? "")}");
|
||||
@ -140,25 +129,13 @@ namespace CryptoExchange.Net
|
||||
uriString += "?";
|
||||
|
||||
var arraysParameters = parameters.Where(p => p.Value.GetType().IsArray).ToList();
|
||||
if (arraysParameters != null && arraysParameters.Count() > 0)
|
||||
foreach(var arrayEntry in arraysParameters)
|
||||
{
|
||||
bool isFirstEntry = true;
|
||||
arraysParameters.ForEach((arrayEntry) =>
|
||||
{
|
||||
if (!isFirstEntry)
|
||||
uriString += "&";
|
||||
|
||||
List<object> values = ((object[])arrayEntry.Value).ToList();
|
||||
uriString += $"{string.Join("&", values.Select(v => $"{arrayEntry.Key}[]={v}"))}";
|
||||
|
||||
isFirstEntry = false;
|
||||
});
|
||||
|
||||
if (parameters.Count - arraysParameters.Count > 0)
|
||||
uriString += "&";
|
||||
uriString += $"{string.Join("&", ((object[])arrayEntry.Value).Select(v => $"{arrayEntry.Key}[]={v}"))}&";
|
||||
}
|
||||
|
||||
uriString += $"{string.Join("&", parameters.Where(p => !p.Value.GetType().IsArray).Select(s => $"{s.Key}={s.Value}"))}";
|
||||
uriString = uriString.TrimEnd('&');
|
||||
}
|
||||
|
||||
if (authProvider != null)
|
||||
@ -272,6 +249,10 @@ namespace CryptoExchange.Net
|
||||
|
||||
private void CheckObject(Type type, JObject obj)
|
||||
{
|
||||
if (type.GetCustomAttribute<JsonConverterAttribute>(true) != null)
|
||||
// If type has a custom JsonConverter we assume this will handle property mapping
|
||||
return;
|
||||
|
||||
bool isDif = false;
|
||||
var properties = new List<string>();
|
||||
var props = type.GetProperties();
|
||||
@ -292,11 +273,7 @@ namespace CryptoExchange.Net
|
||||
d = properties.SingleOrDefault(p => p.ToLower() == token.Key.ToLower());
|
||||
if (d == null && !(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>)))
|
||||
{
|
||||
// Checking if missing properties is voluntary
|
||||
// True : If entire class is handled by a JsonConveter
|
||||
bool isManuallyDeserialized = type.GetCustomAttribute<JsonConverterAttribute>(true) != null;
|
||||
if (!isManuallyDeserialized)
|
||||
log.Write(LogVerbosity.Warning, $"Didn't find property `{token.Key}` in object of type `{type.Name}`");
|
||||
log.Write(LogVerbosity.Warning, $"Didn't find property `{token.Key}` in object of type `{type.Name}`");
|
||||
isDif = true;
|
||||
continue;
|
||||
}
|
||||
@ -359,6 +336,7 @@ namespace CryptoExchange.Net
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
authProvider?.Credentials?.Dispose();
|
||||
log.Write(LogVerbosity.Debug, "Disposing exchange client");
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
using CryptoExchange.Net.Authentication;
|
||||
using CryptoExchange.Net.Logging;
|
||||
using CryptoExchange.Net.RateLimiter;
|
||||
@ -18,11 +17,6 @@ namespace CryptoExchange.Net
|
||||
/// </summary>
|
||||
public ApiCredentials ApiCredentials { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The private key instead of api credentials
|
||||
/// </summary>
|
||||
public SecureString PrivateKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Proxy to use
|
||||
/// </summary>
|
||||
|
@ -1,4 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
|
||||
namespace CryptoExchange.Net
|
||||
{
|
||||
@ -25,5 +28,30 @@ namespace CryptoExchange.Net
|
||||
if (value != null)
|
||||
parameters.Add(key, value);
|
||||
}
|
||||
|
||||
public static string GetString(this SecureString source)
|
||||
{
|
||||
string result = null;
|
||||
int length = source.Length;
|
||||
IntPtr pointer = IntPtr.Zero;
|
||||
char[] chars = new char[length];
|
||||
|
||||
try
|
||||
{
|
||||
pointer = Marshal.SecureStringToBSTR(source);
|
||||
Marshal.Copy(pointer, chars, 0, length);
|
||||
|
||||
result = string.Join("", chars);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (pointer != IntPtr.Zero)
|
||||
{
|
||||
Marshal.ZeroFreeBSTR(pointer);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user