public static async Task StartRemote(Action <SpotifyClient> onComplete) { (string verifier, string challenge) = PKCEUtil.GenerateCodes(); m_AuthServer = new EmbedIOAuthServer(m_CallbackUri, 5000); await m_AuthServer.Start(); m_AuthServer.AuthorizationCodeReceived += async(sender, response) => { await m_AuthServer.Stop(); PKCETokenResponse token = await new OAuthClient().RequestToken( new PKCETokenRequest(m_ClientId, response.Code, m_AuthServer.BaseUri, verifier) ); File.WriteAllText(m_TokenPath, JsonConvert.SerializeObject(token)); StartCached(onComplete); }; var request = new LoginRequest(m_AuthServer.BaseUri, m_ClientId, LoginRequest.ResponseType.Code) { CodeChallenge = challenge, CodeChallengeMethod = "S256", Scope = new List <string> { Scopes.PlaylistModifyPublic } }; Uri uri = request.ToUri(); BrowserUtil.Open(uri); }
public static bool HasExpired(this PKCETokenResponse token) { var created = token.CreatedAt; var expirationTime = token.ExpiresIn; return(created.AddSeconds(expirationTime) < DateTime.UtcNow); }
public void StartAuthentification() { // Check if previous auth if (HasPreviousAuthentification()) { // Load local pkce saved token _pkceToken = LoadPKCEToken(); if (_pkceToken != null) { // Set API authenticator SetAuthenticator(_pkceToken); // if not expired, output expire time if (!_pkceToken.IsExpired) { DateTime expireDT = S4UUtility.GetTokenExpiry(_pkceToken.CreatedAt, _pkceToken.ExpiresIn); Debug.Log($"PKCE token loaded | Expires at '{expireDT.ToLocalTime()}'"); } } } else { // No previous auth, first time, get new GetFreshAuth(); } }
public void SerializeConfig(PKCETokenResponse data, string path, RSACryptoServiceProvider rsaKey) { try { // Serialize using (StreamWriter file = new StreamWriter(path, false)) { XmlSerializer controlsDefaultsSerializer = new XmlSerializer(typeof(PKCETokenResponse)); controlsDefaultsSerializer.Serialize(file, data); file.Close(); } } catch (Exception e) { Console.WriteLine(e.Message); } finally { // Encrypt XmlDocument xmlDoc = new XmlDocument(); xmlDoc.PreserveWhitespace = true; xmlDoc.Load(path); Encrypt(xmlDoc, "AccessToken", "AccessToken", rsaKey, "rsaKey"); Encrypt(xmlDoc, "RefreshToken", "RefreshToken", _rsaKey, "rsaKey"); xmlDoc.Save(path); } }
public static async Task SaveAsync(this PKCETokenResponse token, string path) { var serializedToken = JsonSerializer.Serialize(token); await File.WriteAllTextAsync(path, serializedToken); }
private void SetAuthenticator(PKCETokenResponse token) { // Set API authentification once recieved _pkceAuthenticator = new PKCEAuthenticator(_clientID, token); _pkceAuthenticator.TokenRefreshed += this.OnTokenRefreshed; OnAuthenticatorComplete?.Invoke(_pkceAuthenticator); }
private async Task SaveToken(PKCETokenResponse token) { EnsureDirectoryExist(_config.CredentialsPath); var json = JsonConvert.SerializeObject(token); await File.WriteAllTextAsync(_config.CredentialsPath, json); _logger.LogInformation("Token saved to '{filename}'", _config.CredentialsPath); }
public bool HasPreviousAuthentification() { if (PKCEConfig != null) { _pkceToken = LoadPKCEToken(); return(_pkceToken != null); } return(false); }
public void DeauthorizeUser() { // Dispose server if (_server != null) { _server.Dispose(); } _pkceToken = null; }
public async Task SaveTokens(PKCETokenResponse tokenReponse) { _tokens = tokenReponse; Configuration configuration = GetConfiguration(); configuration.Tokens = tokenReponse; string jsonData = JsonSerializer.Serialize <Configuration>(configuration); await File.WriteAllLinesAsync(_filePath, new[] { jsonData }); }
public AppConfig(IOutputHandler outputHandler) { string location = AppDomain.CurrentDomain.BaseDirectory; _directoryPath = $"{location}/.config/"; _filePath = $"{location}/.config/appConfig.json"; _outputHandler = outputHandler; Configuration configData = Initialise(); _clientId = configData.ClientId; _tokens = configData.Tokens; }
/// <summary> /// Refreshes Spotify authentication to continue having access to Spotify music controls /// </summary> /// <returns>Task for refreshing token</returns> private async Task RefreshAuthentication() { if (token == null) { await Task.Run(Init); } else if (token != null && token.IsExpired) { PKCETokenRefreshRequest refreshRequest = new PKCETokenRefreshRequest("<INSERT_CLIENT_ID>", token.RefreshToken); PKCETokenResponse refreshResponse = await new OAuthClient().RequestToken(refreshRequest); client = new SpotifyClient(refreshResponse.AccessToken); } }
/// <summary> /// Completes the Spotify authorization process /// </summary> public async Task Init() { var(v, c) = PKCEUtil.GenerateCodes(); await server.Start(); challenge = (v, c).c; verifier = (v, c).v; server.AuthorizationCodeReceived += async(sender, response) => { await server.Stop(); token = await new OAuthClient().RequestToken( new PKCETokenRequest("<INSERT_CLIENT_ID>", response.Code, server.BaseUri, verifier)); client = new SpotifyClient(token); IsAuthenticated = true; bool hasPremium = await HasPremium(); MessagingCenter.Send(new SpotifyLoginMessage("LoginSuccess", hasPremium), "LoginSuccess"); }; var loginRequest = new LoginRequest( new Uri("http://localhost:5000/callback"), "<INSERT_CLIENT_ID>", LoginRequest.ResponseType.Code) { CodeChallengeMethod = "S256", CodeChallenge = challenge, Scope = new[] { Scopes.UserModifyPlaybackState, Scopes.AppRemoteControl, Scopes.UserReadCurrentlyPlaying, Scopes.UserReadPlaybackState, Scopes.UserLibraryRead, Scopes.UserReadRecentlyPlayed, Scopes.UserReadPrivate, }, }; var uri = loginRequest.ToUri(); try { await Browser.OpenAsync(uri, BrowserLaunchMode.SystemPreferred); } catch (Exception) { // TODO: log error to app center. } }
public void Token_expiration_should_be_correct() { // Arrange var sut = new PKCETokenResponse(); sut.CreatedAt = DateTime.UtcNow.AddDays(-14); sut.ExpiresIn = 1; // Act var result = sut.HasExpired(); // Assert result.Should().BeTrue(); }
public async Task <ISpotifyClient> CreateSpotifyClientAsync() { PKCETokenResponse tokenResponse = _config.Tokens; if (String.IsNullOrEmpty(tokenResponse.AccessToken) || String.IsNullOrEmpty(tokenResponse.RefreshToken)) { tokenResponse = await UseNewTokens(); } else if (tokenResponse.HasExpired()) { tokenResponse = await RefreshTokens(); } var config = SpotifyClientConfig.CreateDefault().WithAuthenticator(new PKCEAuthenticator(_config.ClientId, tokenResponse)); return(new SpotifyClient(config)); }
private async Task StartStreamMode() { try { Log.Instance.PrintMessage("Trying to connect Spotify account", MessageType.Info, "Spotify.StartStreamMode()"); Kernel.InternetAvaliable(false); Stopwatch crono = Stopwatch.StartNew(); if (!File.Exists(AuthPath)) { var(verifier, challenge) = PKCEUtil.GenerateCodes(); var server = new EmbedIOAuthServer(new Uri("http://localhost:4002/callback"), 4002); await server.Start(); server.AuthorizationCodeReceived += async(sender, response) => { await server.Stop(); PKCETokenResponse token = await new OAuthClient().RequestToken(new PKCETokenRequest(PublicKey, response.Code, server.BaseUri, verifier)); await File.WriteAllTextAsync(AuthPath, JsonConvert.SerializeObject(token)); await StartLoginSpotify(crono); server.Dispose(); }; var login = new LoginRequest(server.BaseUri, PublicKey, LoginRequest.ResponseType.Code) { CodeChallenge = challenge, CodeChallengeMethod = "S256", Scope = new List <string> { Scopes.UserReadEmail, Scopes.UserReadPrivate, Scopes.Streaming, Scopes.PlaylistReadPrivate, Scopes.UserReadPlaybackState, Scopes.UserLibraryRead } }; BrowserUtil.Open(login.ToUri()); } else { await StartLoginSpotify(crono); } } catch (APIException e) { Kernel.InternetAvaliable(false); Log.Instance.PrintMessage(e.Message, MessageType.Error); System.Windows.Forms.MessageBox.Show(Kernel.LocalTexts.GetString("error_internet")); } }
private async Task OnAuthCodeRecieved(object sender, AuthorizationCodeResponse response, string verifier) { // Check response and & is valid if (response != null && !string.IsNullOrEmpty(response.Code)) { await _server.Stop(); _pkceToken = await new OAuthClient().RequestToken( new PKCETokenRequest(_clientID, response.Code, _server.BaseUri, verifier) ); // Save PKCE token first SavePKCEToken(_pkceToken); Debug.Log("PKCE: Recieved Auth Code"); SetAuthenticator(_pkceToken); } }
/// <summary> /// Saves the PKCE token using the current PKECTokenSaveType in config /// </summary> /// <param name="token">Current token to save</param> private void SavePKCEToken(PKCETokenResponse token) { if (token != null) { string json = JsonConvert.SerializeObject(token); if (PKCEConfig.TokenSaveType == PKCETokenSaveType.File) { File.WriteAllText(PKCEConfig.TokenPath, json); } else if (PKCEConfig.TokenSaveType == PKCETokenSaveType.PlayerPrefs) { // Save to player prefs on main thread _dispatcher.Add(() => { PlayerPrefs.SetString(PKCEConfig.PlayerPrefsKey, json); }); } } }
public async Task RequestToken() { if (TokenResponse == null) { return; } try { var newResponse = await new OAuthClient().RequestToken( new PKCETokenRefreshRequest(_clientId, TokenResponse.RefreshToken) ); TokenResponse = newResponse; } catch (Exception) { // Ignored } }
public static bool StartCached(Action <SpotifyClient> onComplete) { if (!File.Exists(m_TokenPath)) { return(false); } string json = File.ReadAllText(m_TokenPath); PKCETokenResponse token = JsonConvert.DeserializeObject <PKCETokenResponse>(json); PKCEAuthenticator authenticator = new PKCEAuthenticator(m_ClientId, token); authenticator.TokenRefreshed += (sender, refreshedToken) => File.WriteAllText(m_TokenPath, JsonConvert.SerializeObject(refreshedToken)); SpotifyClientConfig config = SpotifyClientConfig.CreateDefault().WithAuthenticator(authenticator); SpotifyClient client = new SpotifyClient(config); onComplete(client); return(true); }
/// <inheritdoc/> public async Task <JsonResult> GetSpotifyAuthenticationToken() { var authToken = string.Empty; var(verifier, challenge) = PKCEUtil.GenerateCodes(); await SpotifyAuthServer.Start(); // Temporary auth server lsitens for Spotify callback. SpotifyAuthServer.AuthorizationCodeReceived += async(sender, response) => { await SpotifyAuthServer.Stop(); PKCETokenResponse token = await new OAuthClient().RequestToken( new PKCETokenRequest(SpotifyClientId, response.Code, SpotifyAuthServer.BaseUri, verifier)); authToken = JsonConvert.SerializeObject(token); }; // Make spotify auth call. var request = new LoginRequest(SpotifyAuthServer.BaseUri, SpotifyClientId, LoginRequest.ResponseType.Code) { CodeChallenge = challenge, CodeChallengeMethod = "S256", Scope = new List <string> { UserReadPrivate, UserReadRecentlyPlayed } }; Uri uri = request.ToUri(); try { BrowserUtil.Open(uri); Task.Delay(10000).Wait(); } catch (Exception) { Console.WriteLine("Unable to open URL, manually open: {0}", uri); } return(new JsonResult(authToken)); }
private void OnTokenRefreshed(object sender, PKCETokenResponse token) { DateTime expireDT = S4UUtility.GetTokenExpiry(token.CreatedAt, token.ExpiresIn); Debug.Log($"PKCE token refreshed | Expires at '{expireDT.ToLocalTime()}'"); bool triggerEvent = _pkceToken.IsExpired && !token.IsExpired; _pkceToken = token; if (PKCEConfig != null) { SavePKCEToken(_pkceToken); } if (triggerEvent) { Debug.Log("PKCE: Success in refreshing expired token into new token"); OnAuthenticatorComplete?.Invoke(_pkceAuthenticator); } }
public async void StartAuth() { GenerateCode(); await _server.Start(); _server.AuthorizationCodeReceived += async(sender, response) => { await _server.Stop(); TokenResponse = await new OAuthClient().RequestToken( new PKCETokenRequest(_clientId !, response.Code, _server.BaseUri, _verifier) ); Start(); }; CreateLoginRequest(); var uri = _loginRequest.ToUri(); BrowserUtil.Open(uri); }
private void StartAuthentication() { var(verifier, challenge) = PKCEUtil.GenerateCodes(); Task.WaitAll(_server.Start()); _server.AuthorizationCodeReceived += async(sender, response) => { await _server.Stop(); PKCETokenResponse dataTask = await new OAuthClient().RequestToken( new PKCETokenRequest(clientId, response.Code, _server.BaseUri, verifier) ); File.WriteAllText(CredentialsPath, JsonConvert.SerializeObject(dataTask)); File.SetAttributes(CredentialsPath, FileAttributes.ReadOnly); Start(); }; var request = new LoginRequest(_server.BaseUri, clientId, LoginRequest.ResponseType.Code) { CodeChallenge = challenge, CodeChallengeMethod = "S256", Scope = new List <string> { UgcImageUpload, UserReadRecentlyPlayed, UserReadPlaybackPosition, UserTopRead, UserLibraryRead, UserLibraryModify, PlaylistModifyPrivate, PlaylistReadPrivate, UserFollowRead, PlaylistModifyPublic, UserReadPrivate, UserReadEmail, AppRemoteControl, Streaming, UserReadCurrentlyPlaying, UserModifyPlaybackState, UserReadPlaybackState, PlaylistReadCollaborative, UserFollowModify } }; Uri uri = request.ToUri(); try { BrowserUtil.Open(uri); } catch (Exception) { Console.WriteLine("Unable to open URL, manually open: {0}", uri); } }
private static async Task StartAuthentication() { var(verifier, challenge) = PKCEUtil.GenerateCodes(); await _server.Start(); _server.AuthorizationCodeReceived += async(sender, response) => { await _server.Stop(); PKCETokenResponse token = await new OAuthClient().RequestToken( new PKCETokenRequest(clientId !, response.Code, _server.BaseUri, verifier) ); await File.WriteAllTextAsync(CredentialsPath, JsonConvert.SerializeObject(token)); await Start(); }; var request = new LoginRequest(_server.BaseUri, clientId !, LoginRequest.ResponseType.Code) { CodeChallenge = challenge, CodeChallengeMethod = "S256", Scope = new List <string> { UserReadEmail, UserReadPlaybackPosition, UserReadCurrentlyPlaying, UserModifyPlaybackState, UserReadPlaybackState, UserReadPlaybackState, UserReadPrivate, PlaylistReadPrivate, PlaylistModifyPublic, PlaylistModifyPrivate, Streaming, AppRemoteControl, PlaylistReadCollaborative } }; Uri uri = request.ToUri(); try { BrowserUtil.Open(uri); } catch (Exception) { Console.WriteLine("Unable to open URL, manually open: {0}", uri); } } }
private void OnLoggedIn(PrivateUser privateUser, PKCETokenResponse tokenResponse) { var playerStateStruct = PlayerState; playerStateStruct.IsLoggedIn = true; PlayerState = playerStateStruct; _plugin.Configuration.SpotifySettings.TokenResponse = tokenResponse; if (_spotifyState.IsPremiumUser) { _plugin.Configuration.SpotifySettings.LimitedAccess = false; } if (!_spotifyState.IsPremiumUser) { if (!_plugin.Configuration.SpotifySettings.LimitedAccess ) //Do a check to not spam the user, I don't want to force it down their throats. (f**k marketing) { _plugin.PluginInterface.Framework.Gui.Chat.PrintError( "Uh-oh, it looks like you're not premium on Spotify. Some features in Fantasy Player have been disabled."); } _plugin.Configuration.SpotifySettings.LimitedAccess = true; //Change configs if (_plugin.Configuration.PlayerSettings.CompactPlayer) { _plugin.Configuration.PlayerSettings.CompactPlayer = false; } if (!_plugin.Configuration.PlayerSettings.NoButtons) { _plugin.Configuration.PlayerSettings.NoButtons = true; } } _plugin.Configuration.Save(); }
/// <summary> /// Spotify Manager with Spotify Client /// </summary> /// <param name="client">a Spotify client for Spotify controls</param> public SpotifyManager(ISpotifyClient client) { this.token = null; this.client = client; }
private static void WriteOAuthCreds(PKCETokenResponse data) { Directory.CreateDirectory(dataPath); File.WriteAllText(dataPath + "\\oauth.json", JsonConvert.SerializeObject(data)); }
private async void OnTokenRefreshed(object sender, PKCETokenResponse token) { await token.SaveAsync(_credentialsPath); }