using System.Text; using System; using System.Net.Http; using System.Collections.Generic; using System.Threading.Tasks; using SpotifyAPI.Web.Http; namespace SpotifyAPI.Web { public class OAuthClient : APIClient, IOAuthClient { public OAuthClient(IAPIConnector apiConnector) : base(apiConnector) { } public OAuthClient() : this(SpotifyClientConfig.CreateDefault()) { } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062")] public OAuthClient(SpotifyClientConfig config) : base(ValidateConfig(config)) { } public Task RequestToken(ClientCredentialsRequest request) { return RequestToken(request, API); } public Task RequestToken(AuthorizationCodeRefreshRequest request) { return RequestToken(request, API); } public Task RequestToken(AuthorizationCodeTokenRequest request) { return RequestToken(request, API); } public static Task RequestToken( ClientCredentialsRequest request, IAPIConnector apiConnector ) { Ensure.ArgumentNotNull(request, nameof(request)); Ensure.ArgumentNotNull(apiConnector, nameof(apiConnector)); var form = new List> { new KeyValuePair("grant_type", "client_credentials") }; return SendOAuthRequest(apiConnector, form, request.ClientId, request.ClientSecret); } public static Task RequestToken( AuthorizationCodeRefreshRequest request, IAPIConnector apiConnector ) { Ensure.ArgumentNotNull(request, nameof(request)); Ensure.ArgumentNotNull(apiConnector, nameof(apiConnector)); var form = new List> { new KeyValuePair("grant_type", "refresh_token"), new KeyValuePair("refresh_token", request.RefreshToken) }; return SendOAuthRequest(apiConnector, form, request.ClientId, request.ClientSecret); } public static Task RequestToken( AuthorizationCodeTokenRequest request, IAPIConnector apiConnector ) { Ensure.ArgumentNotNull(request, nameof(request)); Ensure.ArgumentNotNull(apiConnector, nameof(apiConnector)); var form = new List> { new KeyValuePair("grant_type", "authorization_code"), new KeyValuePair("code", request.Code), new KeyValuePair("redirect_uri", request.RedirectUri.ToString()) }; return SendOAuthRequest(apiConnector, form, request.ClientId, request.ClientSecret); } private static Task SendOAuthRequest( IAPIConnector apiConnector, List> form, string clientId, string clientSecret) { var headers = BuildAuthHeader(clientId, clientSecret); return apiConnector.Post(SpotifyUrls.OAuthToken, null, new FormUrlEncodedContent(form), headers); } private static Dictionary BuildAuthHeader(string clientId, string clientSecret) { var base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{clientId}:{clientSecret}")); return new Dictionary { { "Authorization", $"Basic {base64}"} }; } private static APIConnector ValidateConfig(SpotifyClientConfig config) { Ensure.ArgumentNotNull(config, nameof(config)); return new APIConnector( config.BaseAddress, config.Authenticator, config.JSONSerializer, config.HTTPClient, config.RetryHandler, config.HTTPLogger ); } } }