From e701f21a9ee158fa4536b0ee0de2123c56f613f5 Mon Sep 17 00:00:00 2001 From: tr00d Date: Fri, 15 Mar 2024 11:32:14 +0100 Subject: [PATCH] refactor: [breaking] remove obsolete Credentials constructors, making it read-only. It is advised to create Credentials from Configuration, using 'BuildCredentials()' --- Vonage/Request/Credentials.cs | 309 +++++++++++++++------------------- 1 file changed, 136 insertions(+), 173 deletions(-) diff --git a/Vonage/Request/Credentials.cs b/Vonage/Request/Credentials.cs index 42892dfd6..5054800d4 100644 --- a/Vonage/Request/Credentials.cs +++ b/Vonage/Request/Credentials.cs @@ -6,191 +6,154 @@ using Vonage.Common.Monads; using Vonage.Cryptography; -namespace Vonage.Request +namespace Vonage.Request; + +/// +/// Represents credentials for Vonage APIs. +/// +public class Credentials { + internal Credentials() + { + } + + /// + /// Vonage API Key (from your account dashboard) + /// + public string ApiKey { get; internal init; } + + /// + /// Vonage API Secret (from your account dashboard) + /// + public string ApiSecret { get; internal init; } + + /// + /// Application ID (GUID) + /// + public string ApplicationId { get; internal init; } + + /// + /// Application private key contents + /// This is the actual key file contents and NOT a path to the key file! + /// + public string ApplicationKey { get; internal init; } + + /// + /// (Optional) App useragent value to pass with every request + /// + public string AppUserAgent { get; internal init; } + + /// + /// Method to be used for signing SMS Messages + /// + public SmsSignatureGenerator.Method Method { get; internal init; } + + /// + /// Signature Secret (from API settings section of your account settings) + /// + public string SecuritySecret { get; internal set; } + + /// + /// Builds credentials from ApiKey and ApiSecret. + /// + /// The api key. + /// The api secret. + /// The credentials. + public static Credentials FromApiKeyAndSecret(string apiKey, string apiSecret) => + new Credentials {ApiKey = apiKey, ApiSecret = apiSecret}; + /// - /// Represents credentials for Vonage APIs. + /// Builds Credentials from ApiKey, SignatureSecret and Method. /// - public class Credentials + /// The api key. + /// The signature secret. + /// The signature method. + /// The credentials. + public static Credentials FromApiKeySignatureSecretAndMethod(string apiKey, string signatureSecret, + SmsSignatureGenerator.Method signatureMethod) => + new Credentials {ApiKey = apiKey, SecuritySecret = signatureSecret, Method = signatureMethod}; + + /// + /// Builds Credentials from ApplicationId and PrivateKey. + /// + /// The application id. + /// The private key. + /// The credentials. + public static Credentials FromAppIdAndPrivateKey(string appId, string privateKey) => + new Credentials {ApplicationId = appId, ApplicationKey = privateKey}; + + /// + /// Builds Credentials from ApplicationId and PrivateKey file. + /// + /// Your Vonage Application ID + /// path to your private Key file + /// Thrown if app doesn't have required permission to key file + /// + /// privateKeyPath is a zero length string, contains only white space or + /// contains one or more invalid characters + /// + /// privateKeyPath is null + /// + /// The specified path, filename, or both exceed the system-defined max + /// length + /// + /// + /// The specified path is invalid, (for example, it is on an + /// unmapped drive). + /// + /// The file specified in path was not found. + /// path is in an invalid format. + /// CredentialsObject + public static Credentials FromAppIdAndPrivateKeyPath(string appId, string privateKeyPath) { - /// - /// Vonage API Key (from your account dashboard) - /// - public string ApiKey { get; set; } - - /// - /// Vonage API Secret (from your account dashboard) - /// - public string ApiSecret { get; set; } - - /// - /// Application ID (GUID) - /// - public string ApplicationId { get; set; } - - /// - /// Application private key contents - /// This is the actual key file contents and NOT a path to the key file! - /// - public string ApplicationKey { get; set; } - - /// - /// (Optional) App useragent value to pass with every request - /// - public string AppUserAgent { get; set; } - - /// - /// Method to be used for signing SMS Messages - /// - public SmsSignatureGenerator.Method Method { get; set; } - - /// - /// Signature Secret (from API settings section of your account settings) - /// - public string SecuritySecret { get; set; } - - /// - /// Obsolete constructor for Credentials. - /// - [Obsolete( - "Factory methods should be favoured over constructors. Public constructors will be removed on next major release.")] - public Credentials() - { - } + using var reader = File.OpenText(privateKeyPath); + var privateKey = reader.ReadToEnd(); + return new Credentials {ApplicationId = appId, ApplicationKey = privateKey}; + } - /// - /// Obsolete constructor for Credentials. - /// - /// The api key. - /// The api secret. - [Obsolete( - "Factory methods should be favoured over constructors. Public constructors will be removed on next major release.")] - public Credentials(string vonageApiKey, string vonageApiSecret) - { - ApiKey = vonageApiKey; - ApiSecret = vonageApiSecret; - } + /// + /// Provides the preferred authentication based on authentication type. + /// + /// The authentication header if it matches any criteria. A AuthenticationFailure otherwise. + public Result GetAuthenticationHeader() => + this.GetPreferredAuthenticationType().Bind(this.GetPreferredAuthenticationHeader); - /// - /// Obsolete constructor for Credentials. - /// - /// The api key. - /// The api secret. - /// The application id. - /// The private key. - [Obsolete( - "Factory methods should be favoured over constructors. Public constructors will be removed on next major release.")] - public Credentials(string vonageApiKey, string vonageApiSecret, string vonageApplicationId, - string vonageApplicationPrivateKey) + /// + /// Provides the preferred authentication type. + /// + /// The authentication type if it matches any criteria. A AuthenticationFailure otherwise. + /// + /// Bearer will always be preferred over Basic if possible. + /// + public Result GetPreferredAuthenticationType() + { + if (!string.IsNullOrWhiteSpace(this.ApplicationId) && !string.IsNullOrWhiteSpace(this.ApplicationKey)) { - ApiKey = vonageApiKey; - ApiSecret = vonageApiSecret; - ApplicationId = vonageApplicationId; - ApplicationKey = vonageApplicationPrivateKey; + return AuthType.Bearer; } - /// - /// Builds credentials from ApiKey and ApiSecret. - /// - /// The api key. - /// The api secret. - /// The credentials. - public static Credentials FromApiKeyAndSecret(string apiKey, string apiSecret) => - new() {ApiKey = apiKey, ApiSecret = apiSecret}; - - /// - /// Builds Credentials from ApiKey, SignatureSecret and Method. - /// - /// The api key. - /// The signature secret. - /// The signature method. - /// The credentials. - public static Credentials FromApiKeySignatureSecretAndMethod(string apiKey, string signatureSecret, - SmsSignatureGenerator.Method signatureMethod) => - new() {ApiKey = apiKey, SecuritySecret = signatureSecret, Method = signatureMethod}; - - /// - /// Builds Credentials from ApplicationId and PrivateKey. - /// - /// The application id. - /// The private key. - /// The credentials. - public static Credentials FromAppIdAndPrivateKey(string appId, string privateKey) => - new() {ApplicationId = appId, ApplicationKey = privateKey}; - - /// - /// Builds Credentials from ApplicationId and PrivateKey file. - /// - /// Your Vonage Application ID - /// path to your private Key file - /// Thrown if app doesn't have required permission to key file - /// - /// privateKeyPath is a zero length string, contains only white space or - /// contains one or more invalid characters - /// - /// privateKeyPath is null - /// - /// The specified path, filename, or both exceed the system-defined max - /// length - /// - /// - /// The specified path is invalid, (for example, it is on an - /// unmapped drive). - /// - /// The file specified in path was not found. - /// path is in an invalid format. - /// CredentialsObject - public static Credentials FromAppIdAndPrivateKeyPath(string appId, string privateKeyPath) + if (!string.IsNullOrWhiteSpace(this.ApiKey) && !string.IsNullOrWhiteSpace(this.ApiSecret)) { - using var reader = File.OpenText(privateKeyPath); - var privateKey = reader.ReadToEnd(); - return new Credentials {ApplicationId = appId, ApplicationKey = privateKey}; + return AuthType.Basic; } - /// - /// Provides the preferred authentication based on authentication type. - /// - /// The authentication header if it matches any criteria. A AuthenticationFailure otherwise. - public Result GetAuthenticationHeader() => - this.GetPreferredAuthenticationType().Bind(this.GetPreferredAuthenticationHeader); - - /// - /// Provides the preferred authentication type. - /// - /// The authentication type if it matches any criteria. A AuthenticationFailure otherwise. - /// - /// Bearer will always be preferred over Basic if possible. - /// - public Result GetPreferredAuthenticationType() - { - if (!string.IsNullOrWhiteSpace(this.ApplicationId) && !string.IsNullOrWhiteSpace(this.ApplicationKey)) - { - return AuthType.Bearer; - } - - if (!string.IsNullOrWhiteSpace(this.ApiKey) && !string.IsNullOrWhiteSpace(this.ApiSecret)) - { - return AuthType.Basic; - } + return Result.FromFailure(new AuthenticationFailure()); + } - return Result.FromFailure(new AuthenticationFailure()); - } + /// + /// Returns the user agent from credentials if not null, from configuration otherwise. + /// + /// The user agent. + public string GetUserAgent() => + this.AppUserAgent ?? Configuration.Instance.Settings["vonage:Vonage.UserAgent"]; - /// - /// Returns the user agent from credentials if not null, from configuration otherwise. - /// - /// The user agent. - public string GetUserAgent() => - this.AppUserAgent ?? Configuration.Instance.Settings["vonage:Vonage.UserAgent"]; - - private Result GetPreferredAuthenticationHeader(AuthType authenticationType) => - authenticationType switch - { - AuthType.Basic => Result.FromSuccess(new AuthenticationHeaderValue("Basic", - Convert.ToBase64String(Encoding.UTF8.GetBytes($"{this.ApiKey}:{this.ApiSecret}")))), - AuthType.Bearer => new Jwt().GenerateToken(this) - .Map(token => new AuthenticationHeaderValue("Bearer", token)), - _ => Result.FromFailure(new AuthenticationFailure()), - }; - } + private Result GetPreferredAuthenticationHeader(AuthType authenticationType) => + authenticationType switch + { + AuthType.Basic => Result.FromSuccess(new AuthenticationHeaderValue("Basic", + Convert.ToBase64String(Encoding.UTF8.GetBytes($"{this.ApiKey}:{this.ApiSecret}")))), + AuthType.Bearer => new Jwt().GenerateToken(this) + .Map(token => new AuthenticationHeaderValue("Bearer", token)), + _ => Result.FromFailure(new AuthenticationFailure()), + }; } \ No newline at end of file