/// <summary>
        /// Gets an authentication token from the strava API.
        /// </summary>
        /// <returns> A Strava Authentication token</returns>
        public async Task <StravaAuthenticationToken> GetStravaAuthToken()
        {
            await StravaAuthServer.Start();

            var exchangeToken     = string.Empty;
            var authTokenAsString = string.Empty;

            // Temporary auth server lsitens for Strava callback.
            StravaAuthServer.AuthorizationCodeReceived += async(sender, response) =>
            {
                await StravaAuthServer.Stop();

                exchangeToken = response.Code;
                var client  = new RestClient("https://www.strava.com/oauth/token?client_id=61391&client_secret=8b0eb19e37bbbeffc8b8ba75efdb1b7f9c2cfc95&grant_type=authorization_code");
                var request = new RestRequest(Method.POST);
                request.AddParameter("code", exchangeToken);
                IRestResponse accessTokenResponse = client.Execute(request);
                stravaAuthToken = JsonConvert.DeserializeObject <StravaAuthenticationToken>(accessTokenResponse.Content);
            };

            // Open page for login request
            var authTokenUri = new Uri("http://www.strava.com/oauth/authorize?client_id=61391&response_type=code&redirect_uri=http://localhost:5001/stravatoken&approval_prompt=force&scope=activity:read_all");

            BrowserUtil.Open(authTokenUri);
            Task.Delay(20000).Wait();
            return(stravaAuthToken);
        }
Example #2
0
        public Task <string?> WaitForLogin(Uri address, int port, TimeSpan timeout, string state)
        {
            var tcs = new TaskCompletionSource <string?>();

            var server = new EmbedIOAuthServer(address, port);

            server.AuthorizationCodeReceived += async(sender, response) =>
            {
                await server.Stop();

                if (response.State != state)
                {
                    tcs.SetResult("Given state parameter was not correct.");
                    return;
                }

                var tokenResponse = await _spotifyService.OAuth.RequestToken(
                    new AuthorizationCodeTokenRequest(
                        _appConfig.SpotifyApp.ClientId !,
                        _appConfig.SpotifyApp.ClientSecret !,
                        response.Code,
                        server.BaseUri
                        )
                    );

                _appConfig.SpotifyToken.AccessToken  = tokenResponse.AccessToken;
                _appConfig.SpotifyToken.RefreshToken = tokenResponse.RefreshToken;
                _appConfig.SpotifyToken.CreatedAt    = tokenResponse.CreatedAt;
                _appConfig.SpotifyToken.ExpiresIn    = tokenResponse.ExpiresIn;
                _appConfig.SpotifyToken.TokenType    = tokenResponse.TokenType;

                // Create a temporary spotify with access token to fetch user
                var spotify = new SpotifyClient(_spotifyService.Config.WithToken(tokenResponse.AccessToken));
                var me      = await spotify.UserProfile.Current();

                _appConfig.Account.Id          = me.Id;
                _appConfig.Account.DisplayName = me.DisplayName;
                _appConfig.Account.Uri         = me.Uri;

                await _appConfig.Save();

                server.Dispose();
                tcs.SetResult(null);
            };

            var ct = new CancellationTokenSource(timeout);

            ct.Token.Register(() =>
            {
                server.Stop();
                server.Dispose();
                tcs.TrySetCanceled();
            }, useSynchronizationContext: false);

            server.Start();

            return(tcs.Task);
        }
Example #3
0
        private async UniTaskVoid StartServer()
        {
            try
            {
                Uri baseUri = SpotifyConfiguration.ServerConfiguration.Uri;
                int port    = SpotifyConfiguration.ServerConfiguration.Port;

                EmbedIOAuthServer server = new EmbedIOAuthServer(baseUri, port);
                await server.Start();

                server.AuthorizationCodeReceived += (sender, response) =>
                {
                    server.Stop();
                    server.Dispose();
                    responseCode = response.Code;
                    return(null);
                };

                OnServerInitialized.Raise();

                await UniTask.WaitUntil(() => !string.IsNullOrEmpty(responseCode));

                Client.FromAuthorizationCode(responseCode).Forget();
                Destroy(gameObject);
            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }
        }
Example #4
0
        /// <summary>
        /// Encapsulate the login flow with <see cref="EmbedIOAuthServer"/>, useful for console application.
        /// </summary>
        public async Task Login()
        {
            var server = new EmbedIOAuthServer(new Uri(_config.CallbackUrl), _config.CallbackPort);
            await server.Start();

            var auth = new TaskCompletionSource();

            server.AuthorizationCodeReceived += async(_, response) =>
            {
                await CompleteLogin(response.Code);

                auth.SetResult();
            };

            var result = await TryLogin();

            await result.IfSomeAsync(async url =>
            {
                BrowserUtil.Open(new Uri(url));
                await auth.Task;
            });

            await server.Stop();

            server.Dispose();
        }
        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);
        }
Example #6
0
        private async Task LoginToSpotify(TaskCompletionSource <bool> tcs)
        {
            Server = new EmbedIOAuthServer(new Uri("http://localhost:5000/callback"), 5000);
            await Server.Start();

            Server.ImplictGrantReceived += async(object sender, ImplictGrantResponse response) =>
            {
                await Server.Stop();

                if (response.AccessToken != null)
                {
                    Spotify = new SpotifyClient(response.AccessToken);
                    Profile = await Spotify.UserProfile.Current();

                    tcs.SetResult(Spotify != null);
                }
                else
                {
                    Log("Error when attempting to log in");
                    tcs.SetResult(false);
                }
            };

            var request = new LoginRequest(Server.BaseUri, SpotifySecrets.CLIENT_ID, LoginRequest.ResponseType.Token)
            {
                Scope = new List <string>
                {
                    Scopes.UserLibraryRead,
                    Scopes.PlaylistModifyPublic
                }
            };

            BrowserUtil.Open(request.ToUri());
        }
        private async Task OnImplicitGrantReceived(object sender, ImplictGrantResponse response)
        {
            await _server.Stop();

            var spotify = new SpotifyClient(response.AccessToken);

            Client = spotify;
            OnAuthEvent?.Invoke();
        }
Example #8
0
    private async Task OnImplicitGrantReceived(object sender, ImplictGrantResponse response)
    {
        // Stop server
        await _server.Stop();

        _lastAuthToken = response;

        // Trigger complete with auth token
        OnAuthenticatorComplete?.Invoke(_lastAuthToken);
    }
Example #9
0
        private static async Task OnAuthorizationCodeReceived(object sender, AuthorizationCodeResponse response)
        {
            await _server.Stop();

            AuthorizationCodeTokenResponse token = await new OAuthClient().RequestToken(
                new AuthorizationCodeTokenRequest(clientId !, clientSecret !, response.Code, _server.BaseUri)
                );

            await File.WriteAllTextAsync(CredentialsPath, JsonConvert.SerializeObject(token));

            await Start();
        }
Example #10
0
        /// <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.
            }
        }
Example #11
0
        private static async Task OnAuthorizationCodeReceived(object sender, AuthorizationCodeResponse response)
        {
            await _server.Stop();

            AuthorizationCodeTokenResponse token = await new OAuthClient().RequestToken(
                new AuthorizationCodeTokenRequest(clientId, clientSecret, response.Code, _server.BaseUri)
                );

            var config  = SpotifyClientConfig.CreateDefault().WithToken(token.AccessToken, token.TokenType);
            var spotify = new SpotifyClient(config);

            var me = await spotify.UserProfile.Current();

            Console.WriteLine($"Your E-Mail: {me.Email}");
            Environment.Exit(0);
        }
Example #12
0
        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"));
            }
        }
Example #13
0
    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);
        }
    }
Example #14
0
        private async Task OnAuthorizationCodeReceivedAsync(object sender, AuthorizationCodeResponse response)
        {
            await Server.Stop();

            Server.Dispose();

            var config        = SpotifyClientConfig.CreateDefault();
            var tokenResponse = await new OAuthClient(config).RequestToken(new AuthorizationCodeTokenRequest(CLIENT_ID, CLIENT_SECRET, response.Code, new Uri("http://localhost:5000/callback")));

            SClient  = new SpotifyClient(tokenResponse.AccessToken);
            SToken   = tokenResponse.AccessToken;
            SRefresh = tokenResponse.RefreshToken;
            SReady   = true;
            SExpiry  = DateTime.Now.AddSeconds(tokenResponse.ExpiresIn);

            Console.Clear();
            await Util.LoggerAsync(new LogMessage(LogSeverity.Info, "Spotify", "Spotify Connected. You can now start queueing songs."));
        }
Example #15
0
        /// <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));
        }
Example #16
0
        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);
            }
        }
Example #17
0
        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);
        }
Example #18
0
        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);
            }
        }
    }
Example #19
0
        /// <summary>
        /// Called when the user has been authorised
        /// </summary>
        private async Task OnImplicitGrantReceivedAsync(object sender, ImplictGrantResponse response)
        {
            // stop the server and create a new client using the token, get the current users id
            await Server.Stop();

            Client = new SpotifyClient(response.AccessToken);
            string user = (await Client.UserProfile.Current()).Id;

            // make sure the users id isnt null/empty for some strange reason
            if (!String.IsNullOrEmpty(user) && !String.IsNullOrWhiteSpace(user))
            {
                while (true)
                {
                    // get the current users playlists and make sure the list isnt null
                    Paging <SimplePlaylist> playlists = await Client.Playlists.GetUsers(user);

                    if (playlists != null && playlists.Items != null)
                    {
                        // list the playlists to the user
                        ListPlaylists(user, playlists);

                        try
                        {
                            // ask the user which playlist we want to shuffle
                            Console.Write("\nEnter ID of playlist to shuffle: ");
                            int playlistId = Convert.ToInt32(Console.ReadLine());
                            Console.Clear();

                            // make sure the playlist id is valid
                            if (playlistId >= 0 && playlistId < playlists.Items.Count)
                            {
                                // start the shuffle procedure and get the playlist uri
                                string playlistUri = playlists.Items[playlistId].Uri.Split(':')[2];

                                // create our empty lists ready to occupy
                                List <PlaylistTrack <IPlayableItem> > allTracks = new List <PlaylistTrack <IPlayableItem> >();
                                List <Item> songs         = new List <Item>();
                                List <Item> songsToRemove = new List <Item>();

                                // calculate how many loops of 100 to cycle through the whole playlist, most api calls are limited to 100 tracks
                                int loops     = (int)playlists.Items[playlistId].Tracks.Total / 100;
                                int remainder = (int)playlists.Items[playlistId].Tracks.Total % 100;

                                // get all the tracks from the playlist and populate the lists
                                await GetAllTracksAsync(playlistUri, allTracks, loops);

                                PopulateSongLists(allTracks, songs, songsToRemove);

                                // recalculate the loops and remainder of the playlist, some of the tracks may have been invalid
                                loops     = Tracks / 100;
                                remainder = Tracks % 100;
                                Log(LogType.Info, "Shuffle", $"Tracks: {Tracks}, Loops: {loops}, Remainder: {remainder}, Local tracks: {Locals}");

                                // do the actual shuffle
                                List <string> shuffled = Shuffle(songs);
                                if (shuffled.Count != songsToRemove.Count)
                                {
                                    throw new Exception($"For some reason there are not the same amount of songs in each list... Shuffled: {shuffled.Count}, Original: {songsToRemove.Count}");
                                }

                                // remove the tracks from the playlist and then add the shuffled list back
                                await RemoveSongsFromPlaylistAsync(playlistUri, songsToRemove, loops);

                                await Task.Delay(100);
                                await AddSongsToPlaylistAsync(playlistUri, shuffled, loops);

                                await Task.Delay(100);

                                // shuffle local tracks
                                await ReorderSongsAsync(playlistUri);

                                Log(LogType.Success, "Shuffle", "Playlist shuffle complete.");
                            }
                            else
                            {
                                Log(LogType.Error, "Playlist", "Invalid playlist ID");
                            }
                        }
                        catch (APIException apiEx)
                        {
                            Log(LogType.Error, apiEx.Response.StatusCode.ToString(), apiEx.Message);
                        }
                        catch (Exception ex)
                        {
                            Log(LogType.Error, ex.Source, ex.Message);
                        }
                    }
                    else
                    {
                        Log(LogType.Error, "Playlist", "No playlists found");
                    }

                    // check how long left of token
                    int timeLeft = response.ExpiresIn - (int)(DateTime.UtcNow - response.CreatedAt).TotalSeconds;

                    // if enough time remains, ask if they want to shuffle another playlist...
                    if (timeLeft > 60)
                    {
                        Console.Write($"\n\nTime left on token: {timeLeft} seconds");
                        Console.Write("\nWould you like to shuffle another playlist? Y/N ");
                        var key = Console.ReadKey();
                        if (!key.Key.Equals(ConsoleKey.Y))
                        {
                            Log(LogType.Info, "Program", "Exitting program...");
                            await Task.Delay(500);

                            Environment.Exit(0);
                        }
                        else
                        {
                            await Task.Delay(500);
                        }
                    }
                    else // else, ask if they want to obtain a new token
                    {
                        Console.Write("\n\nToken expired... Would you like to obtain a new token? Y/N ");
                        var key = Console.ReadKey();
                        if (!key.Key.Equals(ConsoleKey.Y))
                        {
                            Log(LogType.Info, "Program", "Exitting program...");
                            await Task.Delay(500);

                            Environment.Exit(0);
                        }
                        else
                        {
                            Log(LogType.Info, "Program", "Obtaining new token...");
                            await Server.Start();

                            ObtainToken();
                            return;
                        }
                    }
                }
            }
            else
            {
                Log(LogType.Error, "Playlist", "Invalid user id");
            }

            // end the program if we make it to here...
            Environment.Exit(0);
        }
        async void SpotifyWebAuth()
        {
            try
            {
                if (File.Exists(_path))
                {
                    var token_response = DeserializeConfig(_path, _rsaKey);

                    var authenticator = new PKCEAuthenticator(_clientID, token_response, _path);

                    var config = SpotifyClientConfig.CreateDefault()
                                 .WithAuthenticator(authenticator);
                    _spotify = new SpotifyClient(config);

                    SerializeConfig(token_response, _path, _rsaKey);


                    // This appears to be the easiest way to check if the Spotify client works, but it's not great:
                    try
                    {
                        await _spotify.Search.Item(new SearchRequest(SearchRequest.Types.Track, "fasdofimasdofiasdnfaosnf"));

                        _auth = 1;
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Spotify agent dead: " + e);
                        throw new System.NullReferenceException();
                    }
                }
                else
                {
                    throw new System.NullReferenceException("Token.xml not found!");
                }
            }
            catch (System.NullReferenceException)
            {
                var(verifier, challenge) = PKCEUtil.GenerateCodes(120);

                var loginRequest = new LoginRequest(
                    new Uri("http://localhost:5000/callback"), _clientID, LoginRequest.ResponseType.Code)
                {
                    CodeChallengeMethod = "S256",
                    CodeChallenge       = challenge,
                    Scope = new[] { Scopes.UserLibraryModify, Scopes.UserFollowModify, Scopes.UserFollowRead, Scopes.UserLibraryRead }
                };
                var uri = loginRequest.ToUri();

                var server = new EmbedIOAuthServer(new Uri("http://localhost:5000/callback"), 5000);

                server.PkceReceived += async(sender, response) =>
                {
                    await server.Stop();

                    var initialResponse = await new OAuthClient().RequestToken(
                        new PKCETokenRequest(_clientID, response.Code, server.BaseUri, verifier)
                        );

                    //WriteOutput(initialResponse);

                    var authenticator = new PKCEAuthenticator(_clientID, initialResponse, _path);

                    var config = SpotifyClientConfig.CreateDefault()
                                 .WithAuthenticator(authenticator);
                    _spotify = new SpotifyClient(config);

                    //WriteOutput(initialResponse);
                    SerializeConfig(initialResponse, _path, _rsaKey);
                };
                await server.Start();

                try
                {
                    BrowserUtil.Open(uri);
                }
                catch (Exception)
                {
                    Console.WriteLine("Unable to open URL, manually open: {0}", uri);
                }

                _auth = 1;
            }
            catch (System.Net.WebException)
            {
                _auth = 0;
            }
            finally
            {
                mbApiInterface.MB_RefreshPanels();
                panel.Invalidate();
            }
        }
Example #21
0
 public void Dispose()
 {
     _stateThread?.Abort();
     _server?.Stop();
 }
Example #22
0
        private static async Task OnImplictGrantReceived(object sender, ImplictGrantResponse response)
        {
            await _server.Stop();

            await Start(response.AccessToken);
        }
Example #23
0
 void IDisposable.Dispose()
 {
     _stateTaskCancellationTokenSource?.Cancel();
     _server?.Stop();
 }
Example #24
0
        /// <summary>
        /// Start the authroization code flow or request for an access token if a refresh token is present and the scopes match.
        /// </summary>
        /// <param name="cancel">A <see cref="CancellationToken"/> to cancel the wait for users to authorize on their browsers</param>
        /// <exception cref="OperationCanceledException">Thrown if the wait is canceled</exception>
        public override async Task Authorize(CancellationToken cancel = default)
        {
            OsuTokenResponse tokenResponse;

            if (RefreshToken.IsNullOrEmpty() || !requiredScopes.IsSubsetOf(AuthorizedScopes))
            {
                var taskCompletionSource = new TaskCompletionSource <AuthorizationCodeResponse>();

                EmbedIOAuthServer _server = new EmbedIOAuthServer(new Uri("http://localhost:5001/callback"), 5001);
                await _server.Start();

                _server.AuthorizationCodeReceived += (_, response) =>
                {
                    taskCompletionSource.SetResult(response);
                    return(Task.CompletedTask);
                };

                var request = new LoginRequest(new Uri("https://osu.ppy.sh/oauth/authorize"), _server.BaseUri, ClientId, LoginRequest.ResponseType.Code)
                {
                    Scope = requiredScopes
                };
                Helper.OpenUri(request.ToUri());

                while (!taskCompletionSource.Task.IsCompleted)
                {
                    cancel.ThrowIfCancellationRequested();
                    await Task.Delay(500);
                }

                await _server.Stop();

                var response = taskCompletionSource.Task.Result;

                IRestClient osuAuthClient = new RestClient("https://osu.ppy.sh/").UseNewtonsoftJson();

                osuAuthClient.AddHandler("application/json", () => new JsonDeserializer());

                var tokenRequest = new RestRequest("oauth/token/", Method.POST);
                tokenRequest.AddParameter("client_id", ClientId);
                tokenRequest.AddParameter("client_secret", ClientSecret);
                tokenRequest.AddParameter("code", response.Code);
                tokenRequest.AddParameter("grant_type", "authorization_code");
                tokenRequest.AddParameter("redirect_uri", "http://localhost:5001/callback");

                var codeResponse = await osuAuthClient.ExecuteAsync <OsuTokenResponse>(tokenRequest);

                tokenResponse = codeResponse.Data;
            }
            else
            {
                IRestClient osuAuthClient = new RestClient("https://osu.ppy.sh/").UseNewtonsoftJson();

                osuAuthClient.AddHandler("application/json", () => new JsonDeserializer());

                var tokenRequest = new RestRequest("oauth/token/", Method.POST);
                tokenRequest.AddParameter("client_id", ClientId);
                tokenRequest.AddParameter("client_secret", ClientSecret);
                tokenRequest.AddParameter("refresh_token", RefreshToken);
                tokenRequest.AddParameter("grant_type", "refresh_token");

                var codeResponse = await osuAuthClient.ExecuteAsync <OsuTokenResponse>(tokenRequest);

                tokenResponse = codeResponse.Data;
            }

            RefreshToken     = tokenResponse.refresh_token;
            AccessToken      = tokenResponse.access_token;
            AuthorizedScopes = new List <string>(requiredScopes);

            osu = new RestClient("https://osu.ppy.sh/").UseNewtonsoftJson();
            osu.AddDefaultHeader("Authorization", "Bearer " + tokenResponse.access_token);

            RaiseConfigUpdated(EventArgs.Empty);
        }
Example #25
0
        /// <summary>
        /// Start the authroization code flow or request for an access token if a refresh token is present and the scopes match.
        /// </summary>
        /// <param name="cancel">A <see cref="CancellationToken"/> to cancel the wait for users to authorize on their browsers</param>
        /// <exception cref="OperationCanceledException">Thrown if the wait is canceled</exception>
        public override async Task Authorize(CancellationToken cancel = default)
        {
            AuthorizationCodeTokenResponse tokenResponse;

            if (RefreshToken.IsNullOrEmpty() || !requiredScopes.IsSubsetOf(AuthorizedScopes))
            {
                var taskCompletionSource = new TaskCompletionSource <AuthorizationCodeResponse>();

                EmbedIOAuthServer _server = new EmbedIOAuthServer(new Uri("http://localhost:5000/callback"), 5000);
                await _server.Start();

                _server.AuthorizationCodeReceived += (_, response) =>
                {
                    taskCompletionSource.SetResult(response);
                    return(Task.CompletedTask);
                };

                var request = new SpotifyAPI.Web.LoginRequest(_server.BaseUri, ClientId, SpotifyAPI.Web.LoginRequest.ResponseType.Code)
                {
                    Scope = requiredScopes
                };
                Helper.OpenUri(request.ToUri());

                while (!taskCompletionSource.Task.IsCompleted)
                {
                    cancel.ThrowIfCancellationRequested();
                    await Task.Delay(500);
                }

                await _server.Stop();

                var response = taskCompletionSource.Task.Result;
                tokenResponse = await new OAuthClient().RequestToken(
                    new AuthorizationCodeTokenRequest(
                        ClientId, ClientSecret, response.Code, new Uri("http://localhost:5000/callback")
                        )
                    );
                RefreshToken = tokenResponse.RefreshToken;
            }
            else
            {
                var response = await new OAuthClient().RequestToken(new AuthorizationCodeRefreshRequest(ClientId, ClientSecret, RefreshToken));
                tokenResponse = new AuthorizationCodeTokenResponse()
                {
                    RefreshToken = RefreshToken,
                    AccessToken  = response.AccessToken,
                    CreatedAt    = response.CreatedAt,
                    ExpiresIn    = response.ExpiresIn,
                    Scope        = response.Scope,
                    TokenType    = response.TokenType
                };
            }
            AccessToken      = tokenResponse.AccessToken;
            AuthorizedScopes = tokenResponse.Scope.Split(' ').ToList();
            var config = SpotifyClientConfig
                         .CreateDefault()
                         .WithAuthenticator(new AuthorizationCodeAuthenticator(ClientId, ClientSecret, tokenResponse));

            spotify = new SpotifyClient(tokenResponse.AccessToken);
            RaiseConfigUpdated(EventArgs.Empty);
        }
Example #26
0
        private static async Task OnImplicitGrantReceived(object sender, ImplictGrantResponse response)
        {
            await _server.Stop();

            _spotify = new SpotifyClient(response.AccessToken);
        }
        public async Task ConnectWebClient(bool keepRefreshToken = true)
        {
            _securityStore = SecurityStore.Load(pluginDirectory);

            EmbedIOAuthServer _server = new EmbedIOAuthServer(new Uri("http://localhost:4002/callback"), 4002);

            if (_securityStore.HasRefreshToken && keepRefreshToken)
            {
                var refreshRequest = new AuthorizationCodeRefreshRequest(_securityStore.ClientId,
                                                                         _securityStore.ClientSecret,
                                                                         _securityStore.RefreshToken);
                var refreshResponse = await new OAuthClient().RequestToken(refreshRequest);
                lock (_lock)
                {
                    _spotifyClient = new SpotifyClient(refreshResponse.AccessToken);
                }
            }
            else
            {
                await _server.Start();

                _server.AuthorizationCodeReceived += async(object sender, AuthorizationCodeResponse response) =>
                {
                    await _server.Stop();

                    AuthorizationCodeTokenResponse token = await new OAuthClient().RequestToken(
                        new AuthorizationCodeTokenRequest(_securityStore.ClientId,
                                                          _securityStore.ClientSecret,
                                                          response.Code,
                                                          _server.BaseUri));
                    lock (_lock)
                    {
                        _securityStore.RefreshToken = token.RefreshToken;
                        _securityStore.Save(pluginDirectory);
                        _spotifyClient = new SpotifyClient(token.AccessToken);
                    }
                };

                _server.ErrorReceived += async(object sender, string error, string state) =>
                {
                    Console.WriteLine($"Aborting authorization, error received: {error}");
                    await _server.Stop();
                };

                var request = new LoginRequest(_server.BaseUri, _securityStore.ClientId, LoginRequest.ResponseType.Code)
                {
                    Scope = new List <string> {
                        UserLibraryRead,
                        UserReadEmail,
                        UserReadPrivate,
                        UserReadPlaybackPosition,
                        UserReadCurrentlyPlaying,
                        UserReadPlaybackState,
                        UserModifyPlaybackState,
                        AppRemoteControl,
                        PlaylistReadPrivate
                    }
                };

                Uri uri = request.ToUri();
                try {
                    BrowserUtil.Open(uri);
                } catch (Exception) {
                    Console.WriteLine("Unable to open URL, manually open: {0}", uri);
                };
            };
        }