mirror of
https://github.com/JKorf/CryptoExchange.Net.git
synced 2026-08-11 16:32:57 +00:00
Authentication update (#275)
Updated API credential logic, exchange implementation are expected to provide their own credentials implementation with ApiCredentials as base class Removed ApiCredentials implementation used by most exchanges Removed ApiCredentialsType Enum Added CredentialSet base class and implementations for defining different API credentials Added optional type param to AuthenticationProvider for the specific API credential type to improve type safety Moved AuthenticationProvider/ApiCredentials from BaseApiClient to RestApiClient/SocketApiClient base classes Added optional type params to RestApiClient/SocketApiClient base class to specify the AuthenticationProvider type and credentials type to improve type safety Moved SetOptions/SetApiCredentials from BaseApiClient to RestApiClient/SocketApiClient Extracted LibraryOptions<TRestOptions, TSocketOptions, TEnvironment> without TApiCredentials for libraries without API credentials Removed ApiCredentials from ApiOptions, credentials can only be configured at library, rest or socket level Added EnvironmentName to RestApiClient/SocketApiClient property Added Unknown enum value to Shared interfaces SharedOrderStatus, SharedTransferStatus and SharedTriggerOrderStatus enums Updated Enum converter to map value to an undefined Enum value instead of the first Enum value Added support for checking for missing fields on RestIntegrationTest Added BytesToHexString and HexToBytesString to ExchangeHelpers static class Fixed bug where WebSocket connections are not reconnected when configuring Proxy with SetUpdates Removed legacy CryptoBaseClient, CryptoRestClient and CryptoSocketClient
This commit is contained in:
@@ -29,7 +29,13 @@ namespace CryptoExchange.Net.UnitTests
|
||||
// act
|
||||
// assert
|
||||
Assert.Throws(typeof(ArgumentException),
|
||||
() => new RestExchangeOptions<TestEnvironment, ApiCredentials>() { ApiCredentials = new ApiCredentials(key, secret) });
|
||||
() => {
|
||||
var opts = new RestExchangeOptions<TestEnvironment, HMACCredential>()
|
||||
{
|
||||
ApiCredentials = new HMACCredential(key, secret)
|
||||
};
|
||||
opts.ApiCredentials.Validate();
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -38,7 +44,7 @@ namespace CryptoExchange.Net.UnitTests
|
||||
// arrange, act
|
||||
var options = new TestClientOptions
|
||||
{
|
||||
ApiCredentials = new ApiCredentials("123", "456"),
|
||||
ApiCredentials = new HMACCredential("123", "456"),
|
||||
ReceiveWindow = TimeSpan.FromSeconds(10)
|
||||
};
|
||||
|
||||
@@ -48,84 +54,9 @@ namespace CryptoExchange.Net.UnitTests
|
||||
Assert.That(options.ApiCredentials.Secret == "456");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestApiOptionsAreSet()
|
||||
{
|
||||
// arrange, act
|
||||
var options = new TestClientOptions();
|
||||
options.Api1Options.ApiCredentials = new ApiCredentials("123", "456");
|
||||
options.Api2Options.ApiCredentials = new ApiCredentials("789", "101");
|
||||
|
||||
// assert
|
||||
Assert.That(options.Api1Options.ApiCredentials.Key == "123");
|
||||
Assert.That(options.Api1Options.ApiCredentials.Secret == "456");
|
||||
Assert.That(options.Api2Options.ApiCredentials.Key == "789");
|
||||
Assert.That(options.Api2Options.ApiCredentials.Secret == "101");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestClientUsesCorrectOptions()
|
||||
{
|
||||
var client = new TestRestClient(options => {
|
||||
options.Api1Options.ApiCredentials = new ApiCredentials("111", "222");
|
||||
options.ApiCredentials = new ApiCredentials("333", "444");
|
||||
});
|
||||
|
||||
var authProvider1 = (TestAuthProvider)client.Api1.AuthenticationProvider;
|
||||
var authProvider2 = (TestAuthProvider)client.Api2.AuthenticationProvider;
|
||||
Assert.That(authProvider1.GetKey() == "111");
|
||||
Assert.That(authProvider1.GetSecret() == "222");
|
||||
Assert.That(authProvider2.GetKey() == "333");
|
||||
Assert.That(authProvider2.GetSecret() == "444");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestClientUsesCorrectOptionsWithDefault()
|
||||
{
|
||||
TestClientOptions.Default.ApiCredentials = new ApiCredentials("123", "456");
|
||||
TestClientOptions.Default.Api1Options.ApiCredentials = new ApiCredentials("111", "222");
|
||||
|
||||
var client = new TestRestClient();
|
||||
|
||||
var authProvider1 = (TestAuthProvider)client.Api1.AuthenticationProvider;
|
||||
var authProvider2 = (TestAuthProvider)client.Api2.AuthenticationProvider;
|
||||
Assert.That(authProvider1.GetKey() == "111");
|
||||
Assert.That(authProvider1.GetSecret() == "222");
|
||||
Assert.That(authProvider2.GetKey() == "123");
|
||||
Assert.That(authProvider2.GetSecret() == "456");
|
||||
|
||||
// Cleanup static values
|
||||
TestClientOptions.Default.ApiCredentials = null;
|
||||
TestClientOptions.Default.Api1Options.ApiCredentials = null;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestClientUsesCorrectOptionsWithOverridingDefault()
|
||||
{
|
||||
TestClientOptions.Default.ApiCredentials = new ApiCredentials("123", "456");
|
||||
TestClientOptions.Default.Api1Options.ApiCredentials = new ApiCredentials("111", "222");
|
||||
|
||||
var client = new TestRestClient(options =>
|
||||
{
|
||||
options.Api1Options.ApiCredentials = new ApiCredentials("333", "444");
|
||||
options.Environment = new TestEnvironment("Test", "https://test.test");
|
||||
});
|
||||
|
||||
var authProvider1 = (TestAuthProvider)client.Api1.AuthenticationProvider;
|
||||
var authProvider2 = (TestAuthProvider)client.Api2.AuthenticationProvider;
|
||||
Assert.That(authProvider1.GetKey() == "333");
|
||||
Assert.That(authProvider1.GetSecret() == "444");
|
||||
Assert.That(authProvider2.GetKey() == "123");
|
||||
Assert.That(authProvider2.GetSecret() == "456");
|
||||
Assert.That(client.Api2.BaseAddress == "https://localhost:123");
|
||||
|
||||
// Cleanup static values
|
||||
TestClientOptions.Default.ApiCredentials = null;
|
||||
TestClientOptions.Default.Api1Options.ApiCredentials = null;
|
||||
}
|
||||
}
|
||||
|
||||
public class TestClientOptions: RestExchangeOptions<TestEnvironment, ApiCredentials>
|
||||
public class TestClientOptions: RestExchangeOptions<TestEnvironment, HMACCredential>
|
||||
{
|
||||
/// <summary>
|
||||
/// Default options for the futures client
|
||||
|
||||
@@ -155,15 +155,22 @@ namespace CryptoExchange.Net.UnitTests
|
||||
[TestCase("three", TestEnum.Three)]
|
||||
[TestCase("Four", TestEnum.Four)]
|
||||
[TestCase("four", TestEnum.Four)]
|
||||
[TestCase("Four1", TestEnum.One)]
|
||||
[TestCase(null, TestEnum.One)]
|
||||
public void TestEnumConverterNotNullableDeserializeTests(string value, TestEnum? expected)
|
||||
[TestCase("Four1", (TestEnum)(-9))]
|
||||
[TestCase(null, (TestEnum)(-9))]
|
||||
public void TestEnumConverterNotNullableDeserializeTests(string value, TestEnum expected)
|
||||
{
|
||||
var val = value == null ? "null" : $"\"{value}\"";
|
||||
var output = JsonSerializer.Deserialize<NotNullableSTJEnumObject>($"{{ \"Value\": {val} }}");
|
||||
Assert.That(output.Value == expected);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEnumConverterMapsUndefinedValueCorrectlyIfDefaultIsDefined()
|
||||
{
|
||||
var output = JsonSerializer.Deserialize<TestEnum2>($"\"TestUndefined\"");
|
||||
Assert.That((int)output == -99);
|
||||
}
|
||||
|
||||
[TestCase("1", TestEnum.One)]
|
||||
[TestCase("2", TestEnum.Two)]
|
||||
[TestCase("3", TestEnum.Three)]
|
||||
@@ -425,6 +432,20 @@ namespace CryptoExchange.Net.UnitTests
|
||||
Four
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(EnumConverter<TestEnum2>))]
|
||||
public enum TestEnum2
|
||||
{
|
||||
[Map("-9")]
|
||||
Minus9 = -9,
|
||||
[Map("1")]
|
||||
One,
|
||||
[Map("2")]
|
||||
Two,
|
||||
[Map("three", "3")]
|
||||
Three,
|
||||
Four
|
||||
}
|
||||
|
||||
[JsonSerializable(typeof(Test))]
|
||||
[JsonSerializable(typeof(Test2))]
|
||||
[JsonSerializable(typeof(Test3))]
|
||||
|
||||
@@ -42,11 +42,11 @@ namespace CryptoExchange.Net.UnitTests
|
||||
}
|
||||
}
|
||||
|
||||
public class TestSubClient : RestApiClient
|
||||
public class TestSubClient : RestApiClient<TestEnvironment, TestAuthProvider, HMACCredential>
|
||||
{
|
||||
protected override IRestMessageHandler MessageHandler => throw new NotImplementedException();
|
||||
|
||||
public TestSubClient(RestExchangeOptions<TestEnvironment> options, RestApiOptions apiOptions) : base(new TraceLogger(), null, "https://localhost:123", options, apiOptions)
|
||||
public TestSubClient(RestExchangeOptions<TestEnvironment, HMACCredential> options, RestApiOptions apiOptions) : base(new TraceLogger(), null, "https://localhost:123", options, apiOptions)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -58,24 +58,22 @@ namespace CryptoExchange.Net.UnitTests
|
||||
/// <inheritdoc />
|
||||
public override string FormatSymbol(string baseAsset, string quoteAsset, TradingMode futuresType, DateTime? deliverDate = null) => $"{baseAsset.ToUpperInvariant()}{quoteAsset.ToUpperInvariant()}";
|
||||
protected override IMessageSerializer CreateSerializer() => new SystemTextJsonMessageSerializer(new System.Text.Json.JsonSerializerOptions());
|
||||
protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) => throw new NotImplementedException();
|
||||
protected override TestAuthProvider CreateAuthenticationProvider(HMACCredential credentials) => throw new NotImplementedException();
|
||||
protected override Task<WebCallResult<DateTime>> GetServerTimestampAsync() => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public class TestAuthProvider : AuthenticationProvider
|
||||
public class TestAuthProvider : AuthenticationProvider<HMACCredential, HMACCredential>
|
||||
{
|
||||
public override ApiCredentialsType[] SupportedCredentialTypes => [ApiCredentialsType.Hmac];
|
||||
|
||||
public TestAuthProvider(ApiCredentials credentials) : base(credentials)
|
||||
public TestAuthProvider(HMACCredential credentials) : base(credentials, credentials)
|
||||
{
|
||||
}
|
||||
|
||||
public override void ProcessRequest(RestApiClient apiClient, RestRequestConfiguration requestConfig)
|
||||
{
|
||||
}
|
||||
|
||||
public string GetKey() => _credentials.Key;
|
||||
public string GetSecret() => _credentials.Secret;
|
||||
|
||||
public string GetKey() => Credential.Key;
|
||||
public string GetSecret() => Credential.Secret;
|
||||
}
|
||||
|
||||
public class TestEnvironment : TradeEnvironment
|
||||
|
||||
@@ -130,7 +130,7 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
|
||||
}
|
||||
}
|
||||
|
||||
public class TestRestApi1Client : RestApiClient
|
||||
public class TestRestApi1Client : RestApiClient<TestEnvironment, TestAuthProvider, HMACCredential>
|
||||
{
|
||||
protected override IRestMessageHandler MessageHandler { get; } = new TestRestMessageHandler();
|
||||
|
||||
@@ -159,7 +159,7 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
|
||||
ParameterPositions[method] = position;
|
||||
}
|
||||
|
||||
protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials)
|
||||
protected override TestAuthProvider CreateAuthenticationProvider(HMACCredential credentials)
|
||||
=> new TestAuthProvider(credentials);
|
||||
|
||||
protected override Task<WebCallResult<DateTime>> GetServerTimestampAsync()
|
||||
@@ -168,7 +168,7 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
|
||||
}
|
||||
}
|
||||
|
||||
public class TestRestApi2Client : RestApiClient
|
||||
public class TestRestApi2Client : RestApiClient<TestEnvironment, TestAuthProvider, HMACCredential>
|
||||
{
|
||||
protected override IRestMessageHandler MessageHandler { get; } = new TestRestMessageHandler();
|
||||
|
||||
@@ -186,8 +186,8 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
|
||||
{
|
||||
return await SendAsync<T>("http://www.test.com", new RequestDefinition("/", HttpMethod.Get) { Weight = 0 }, null, ct);
|
||||
}
|
||||
|
||||
protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials)
|
||||
|
||||
protected override TestAuthProvider CreateAuthenticationProvider(HMACCredential credentials)
|
||||
=> new TestAuthProvider(credentials);
|
||||
|
||||
protected override Task<WebCallResult<DateTime>> GetServerTimestampAsync()
|
||||
|
||||
Reference in New Issue
Block a user