From a091a186544c790c30ea86d44910c8f02c8b3b6c Mon Sep 17 00:00:00 2001 From: tr00d Date: Mon, 4 Sep 2023 08:59:26 +0200 Subject: [PATCH] Create Configuration from IConfiguration, create Credentials from Configuration --- Vonage.Test.Unit/ConfigurationTest.cs | 151 +++++++++++++++++--- Vonage.Test.Unit/Request/CredentialsTest.cs | 85 ----------- Vonage/Configuration.cs | 42 ++++-- Vonage/Request/Credentials.cs | 20 --- 4 files changed, 161 insertions(+), 137 deletions(-) diff --git a/Vonage.Test.Unit/ConfigurationTest.cs b/Vonage.Test.Unit/ConfigurationTest.cs index 29f582f28..3deea68a4 100644 --- a/Vonage.Test.Unit/ConfigurationTest.cs +++ b/Vonage.Test.Unit/ConfigurationTest.cs @@ -1,27 +1,140 @@ using System; +using System.Collections.Generic; using FluentAssertions; using Microsoft.Extensions.Configuration; +using Vonage.Cryptography; using Xunit; namespace Vonage.Test.Unit { - public class ConfigurationTest - { - [Fact] - public void FromConfiguration_ShouldLoadEmptyCredentials_GivenConfigurationContainsNoElement() - { - var credentials = Configuration.FromConfiguration(new ConfigurationBuilder().Build()); - credentials.ApiKey.Should().BeEmpty(); - credentials.ApiSecret.Should().BeEmpty(); - credentials.ApplicationId.Should().BeEmpty(); - credentials.ApplicationKey.Should().BeEmpty(); - credentials.SecuritySecret.Should().BeEmpty(); - credentials.SigningMethod.Should().BeEmpty(); - credentials.UserAgent.Should().BeEmpty(); - credentials.EuropeApiUrl.Should().Be(new Uri("https://api-eu.vonage.com")); - credentials.NexmoApiUrl.Should().Be(new Uri("https://api.nexmo.com")); - credentials.RestApiUrl.Should().Be(new Uri("https://rest.nexmo.com")); - credentials.VideoApiUrl.Should().Be(new Uri("https://video.api.vonage.com")); - } - } + public class ConfigurationTest + { + [Fact] + public void BuildCredentials_ShouldCreateEmptyCredentials_GivenConfigurationContainsNoElement() + { + var credentials = Configuration.FromConfiguration(new ConfigurationBuilder().Build()).BuildCredentials(); + credentials.ApiKey.Should().BeEmpty(); + credentials.ApiSecret.Should().BeEmpty(); + credentials.ApplicationId.Should().BeEmpty(); + credentials.ApplicationKey.Should().BeEmpty(); + credentials.SecuritySecret.Should().BeEmpty(); + credentials.Method.Should().Be(SmsSignatureGenerator.Method.md5hash); + } + + [Fact] + public void FromConfiguration_ShouldCreateEmptyConfiguration_GivenConfigurationContainsNoElement() + { + var configuration = Configuration.FromConfiguration(new ConfigurationBuilder().Build()); + configuration.ApiKey.Should().BeEmpty(); + configuration.ApiSecret.Should().BeEmpty(); + configuration.ApplicationId.Should().BeEmpty(); + configuration.ApplicationKey.Should().BeEmpty(); + configuration.SecuritySecret.Should().BeEmpty(); + configuration.SigningMethod.Should().BeEmpty(); + configuration.UserAgent.Should().BeEmpty(); + configuration.EuropeApiUrl.Should().Be(new Uri("https://api-eu.vonage.com")); + configuration.NexmoApiUrl.Should().Be(new Uri("https://api.nexmo.com")); + configuration.RestApiUrl.Should().Be(new Uri("https://rest.nexmo.com")); + configuration.VideoApiUrl.Should().Be(new Uri("https://video.api.vonage.com")); + } + + [Fact] + public void FromConfiguration_ShouldSetApiKey_GivenConfigurationContainsApiKey() => + Configuration.FromConfiguration(new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + {"appSettings:Vonage_key", "RandomValue"}, + }) + .Build()).ApiKey.Should().Be("RandomValue"); + + [Fact] + public void FromConfiguration_ShouldSetApiKSecret_GivenConfigurationContainsApiSecret() => + Configuration.FromConfiguration(new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + {"appSettings:Vonage_secret", "RandomValue"}, + }) + .Build()).ApiSecret.Should().Be("RandomValue"); + + [Fact] + public void FromConfiguration_ShouldSetApplicationId_GivenConfigurationContainsApplicationId() => + Configuration.FromConfiguration(new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + {"appSettings:Vonage.Application.Id", "RandomValue"}, + }) + .Build()).ApplicationId.Should().Be("RandomValue"); + + [Fact] + public void FromConfiguration_ShouldSetApplicationKey_GivenConfigurationContainsApplicationKey() => + Configuration.FromConfiguration(new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + {"appSettings:Vonage.Application.Key", "RandomValue"}, + }) + .Build()).ApplicationKey.Should().Be("RandomValue"); + + [Fact] + public void FromConfiguration_ShouldSetEuropeApiUrl_GivenConfigurationContainsEuropeApiUrl() => + Configuration.FromConfiguration(new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + {"appSettings:Vonage.Url.Api.Europe", "https://api.vonage.com"}, + }) + .Build()).EuropeApiUrl.Should().Be(new Uri("https://api.vonage.com")); + + [Fact] + public void FromConfiguration_ShouldSetNexmoApiUrl_GivenConfigurationContainsNexmoApiUrl() => + Configuration.FromConfiguration(new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + {"appSettings:Vonage.Url.Api", "https://api.vonage.com"}, + }) + .Build()).NexmoApiUrl.Should().Be(new Uri("https://api.vonage.com")); + + [Fact] + public void FromConfiguration_ShouldSetRestApiUrl_GivenConfigurationContainsRestApiUrl() => + Configuration.FromConfiguration(new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + {"appSettings:Vonage.Url.Rest", "https://api.vonage.com"}, + }) + .Build()).RestApiUrl.Should().Be(new Uri("https://api.vonage.com")); + + [Fact] + public void FromConfiguration_ShouldSetSecuritySecret_GivenConfigurationContainsSecuritySecret() => + Configuration.FromConfiguration(new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + {"appSettings:Vonage.security_secret", "RandomValue"}, + }) + .Build()).SecuritySecret.Should().Be("RandomValue"); + + [Fact] + public void FromConfiguration_ShouldSetSigningMethod_GivenConfigurationContainsSigningMethod() => + Configuration.FromConfiguration(new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + {"appSettings:Vonage.signing_method", "sha512"}, + }) + .Build()).SigningMethod.Should().Be("sha512"); + + [Fact] + public void FromConfiguration_ShouldSetUserAgent_GivenConfigurationContainsUserAgent() => + Configuration.FromConfiguration(new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + {"appSettings:Vonage.UserAgent", "RandomValue"}, + }) + .Build()).UserAgent.Should().Be("RandomValue"); + + [Fact] + public void FromConfiguration_ShouldSetVideoApiUrl_GivenConfigurationContainsVideoApiUrl() => + Configuration.FromConfiguration(new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + {"appSettings:Vonage.Url.Api.Video", "https://api.vonage.com"}, + }) + .Build()).VideoApiUrl.Should().Be(new Uri("https://api.vonage.com")); + } } \ No newline at end of file diff --git a/Vonage.Test.Unit/Request/CredentialsTest.cs b/Vonage.Test.Unit/Request/CredentialsTest.cs index 75a93513c..9f9167c78 100644 --- a/Vonage.Test.Unit/Request/CredentialsTest.cs +++ b/Vonage.Test.Unit/Request/CredentialsTest.cs @@ -13,91 +13,6 @@ namespace Vonage.Test.Unit.Request { public class CredentialsTest { - [Fact] - public void FromConfiguration_ShouldLoadEmptyCredentials_GivenConfigurationContainsNoElement() - { - var credentials = Credentials.FromConfiguration(new ConfigurationBuilder().Build()); - credentials.ApiKey.Should().BeNull(); - credentials.ApiSecret.Should().BeNull(); - credentials.ApplicationId.Should().BeNull(); - credentials.ApplicationKey.Should().BeNull(); - credentials.Method.Should().Be(SmsSignatureGenerator.Method.md5hash); - credentials.SecuritySecret.Should().BeNull(); - credentials.AppUserAgent.Should().BeNull(); - } - - [Fact] - public void FromConfiguration_ShouldSetApiKey_GivenConfigurationContainsApiKey() => - Credentials.FromConfiguration(new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary - { - {"appSettings:Vonage_key", "testKey"}, - }) - .Build()).ApiKey.Should().Be("testKey"); - - [Fact] - public void FromConfiguration_ShouldSetApiKSecret_GivenConfigurationContainsApiSecret() => - Credentials.FromConfiguration(new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary - { - {"appSettings:Vonage_secret", "testSecret"}, - }) - .Build()).ApiSecret.Should().Be("testSecret"); - - [Fact] - public void FromConfiguration_ShouldSetApplicationId_GivenConfigurationContainsApplicationId() => - Credentials.FromConfiguration(new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary - { - {"appSettings:Vonage.Application.Id", "testApplicationId"}, - }) - .Build()).ApplicationId.Should().Be("testApplicationId"); - - [Fact] - public void FromConfiguration_ShouldSetApplicationKey_GivenConfigurationContainsApplicationKey() => - Credentials.FromConfiguration(new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary - { - {"appSettings:Vonage.Application.Key", "testApplicationKey"}, - }) - .Build()).ApplicationKey.Should().Be("testApplicationKey"); - - [Fact] - public void FromConfiguration_ShouldSetDefaultSigningMethod_GivenConfigurationContainsInvalidSigningMethod() => - Credentials.FromConfiguration(new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary - { - {"appSettings:Vonage.signing_method", "invalid"}, - }) - .Build()).Method.Should().Be(SmsSignatureGenerator.Method.md5hash); - - [Fact] - public void FromConfiguration_ShouldSetSecuritySecret_GivenConfigurationContainsSecuritySecret() => - Credentials.FromConfiguration(new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary - { - {"appSettings:Vonage.security_secret", "testSecuritySecret"}, - }) - .Build()).SecuritySecret.Should().Be("testSecuritySecret"); - - [Fact] - public void FromConfiguration_ShouldSetSigningMethod_GivenConfigurationContainsSigningMethod() => - Credentials.FromConfiguration(new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary - { - {"appSettings:Vonage.signing_method", "sha512"}, - }) - .Build()).Method.Should().Be(SmsSignatureGenerator.Method.sha512); - - [Fact] - public void FromConfiguration_ShouldSetUserAgent_GivenConfigurationContainsUserAgent() => - Credentials.FromConfiguration(new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary - { - {"appSettings:Vonage.UserAgent", "testUserAgent"}, - }) - .Build()).AppUserAgent.Should().Be("testUserAgent"); - [Fact] public void GetAuthenticationHeader_ReturnsBasicScheme_GivenContainsApiKeyAndApiSecret() => BuildBasicCredentials() diff --git a/Vonage/Configuration.cs b/Vonage/Configuration.cs index c7761842a..09ce5e840 100644 --- a/Vonage/Configuration.cs +++ b/Vonage/Configuration.cs @@ -1,12 +1,10 @@ using System; using System.Collections.Generic; using System.Net.Http; -using System.Runtime.Serialization; -using System.Text.Json.Serialization; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; -using Newtonsoft.Json; using Vonage.Common.Monads; +using Vonage.Cryptography; using Vonage.Logger; using Vonage.Request; @@ -35,6 +33,7 @@ static Configuration() private Configuration(IConfiguration configuration) { this.Settings = configuration; + this.LogAuthenticationCapabilities(LogProvider.GetLogger(LoggerCategory)); } /// @@ -126,7 +125,6 @@ private Configuration(IConfiguration configuration) internal Configuration() { - var logger = LogProvider.GetLogger(LoggerCategory); var builder = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary { @@ -137,11 +135,13 @@ internal Configuration() {"appSettings:Vonage.EnsureSuccessStatusCode", "false"}, }) .AddJsonFile("settings.json", true, true) - .AddJsonFile("appsettings.json", true, true) - ; + .AddJsonFile("appsettings.json", true, true); this.Settings = builder.Build(); + this.LogAuthenticationCapabilities(LogProvider.GetLogger(LoggerCategory)); + } - // verify we have a minimum amount of configuration + private void LogAuthenticationCapabilities(ILogger logger) + { var authCapabilities = new List(); if (!string.IsNullOrWhiteSpace(this.ApiKey) && !string.IsNullOrWhiteSpace(this.ApiSecret)) @@ -169,15 +169,31 @@ internal Configuration() logger.LogInformation("Available authentication: {0}", string.Join(",", authCapabilities)); } } - + /// + /// Builds a Configuration from an IConfiguration. /// - /// - /// - public static Configuration FromConfiguration(IConfiguration configuration) + /// The configuration properties. + /// The Configuration. + public static Configuration FromConfiguration(IConfiguration configuration) => new(configuration); + + /// + /// Builds a Credentials from the current Configuration. + /// + /// The Credentials. + public Credentials BuildCredentials() => new() { - throw new NotImplementedException(); - } + ApiKey = this.ApiKey, + ApiSecret = this.ApiSecret, + ApplicationId = this.ApplicationId, + ApplicationKey = this.ApplicationKey, + SecuritySecret = this.SecuritySecret, + AppUserAgent = this.UserAgent, + Method = Enum.TryParse(this.SigningMethod, + out SmsSignatureGenerator.Method result) + ? result + : default, + }; private HttpClient BuildDefaultClient() => this.ClientHandler == null diff --git a/Vonage/Request/Credentials.cs b/Vonage/Request/Credentials.cs index 7fd683519..7ef5a31d4 100644 --- a/Vonage/Request/Credentials.cs +++ b/Vonage/Request/Credentials.cs @@ -148,26 +148,6 @@ public static Credentials FromAppIdAndPrivateKeyPath(string appId, string privat return new Credentials {ApplicationId = appId, ApplicationKey = privateKey}; } - /// - /// Initializes a Credentials from configuration. - /// - /// The configuration. - /// The Credentials. - public static Credentials FromConfiguration(IConfiguration configuration) => - new() - { - ApiKey = configuration["appSettings:Vonage_key"], - ApiSecret = configuration["appSettings:Vonage_secret"], - ApplicationId = configuration["appSettings:Vonage.Application.Id"], - ApplicationKey = configuration["appSettings:Vonage.Application.Key"], - SecuritySecret = configuration["appSettings:Vonage.security_secret"], - AppUserAgent = configuration["appSettings:Vonage.UserAgent"], - Method = Enum.TryParse(configuration["appSettings:Vonage.signing_method"], - out SmsSignatureGenerator.Method result) - ? result - : default, - }; - /// /// Provides the preferred authentication based on authentication type. ///