using System; using System.Threading.Tasks; using SpotifyAPI.Web.Http; namespace SpotifyAPI.Web { /// /// This Authenticator requests new credentials token on demand and stores them into memory. /// It is unable to query user specifc details. /// public class AuthorizationCodeAuthenticator : IAuthenticator { /// /// Initiate a new instance. The token will be refreshed once it expires. /// The initialToken will be updated with the new values on refresh! /// public AuthorizationCodeAuthenticator(string clientId, string clientSecret, AuthorizationCodeTokenResponse initialToken) { Ensure.ArgumentNotNull(clientId, nameof(clientId)); Ensure.ArgumentNotNull(clientSecret, nameof(clientSecret)); Ensure.ArgumentNotNull(initialToken, nameof(initialToken)); InitialToken = initialToken; ClientId = clientId; ClientSecret = clientSecret; } /// /// This event is called once a new refreshed token was aquired /// public event EventHandler? TokenRefreshed; /// /// The ClientID, defined in a spotify application in your Spotify Developer Dashboard /// public string ClientId { get; } /// /// The ClientID, defined in a spotify application in your Spotify Developer Dashboard /// public string ClientSecret { get; } /// /// The inital token passed to the authenticator. Fields will be updated on refresh. /// /// public AuthorizationCodeTokenResponse InitialToken { get; } public async Task Apply(IRequest request, IAPIConnector apiConnector) { Ensure.ArgumentNotNull(request, nameof(request)); if (InitialToken.IsExpired) { AuthorizationCodeRefreshRequest? tokenRequest = new(ClientId, ClientSecret, InitialToken.RefreshToken); AuthorizationCodeRefreshResponse? refreshedToken = await OAuthClient.RequestToken(tokenRequest, apiConnector).ConfigureAwait(false); InitialToken.AccessToken = refreshedToken.AccessToken; InitialToken.CreatedAt = refreshedToken.CreatedAt; InitialToken.ExpiresIn = refreshedToken.ExpiresIn; InitialToken.Scope = refreshedToken.Scope; InitialToken.TokenType = refreshedToken.TokenType; if (refreshedToken.RefreshToken != null) { InitialToken.RefreshToken = refreshedToken.RefreshToken; } TokenRefreshed?.Invoke(this, InitialToken); } request.Headers["Authorization"] = $"{InitialToken.TokenType} {InitialToken.AccessToken}"; } } }