Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        public AuthService(IAppConfig config, IOutputHandler outputHandler, OAuthClient oAuthClient)
        {
            (_verifier, _challenge) = PKCEUtil.GenerateCodes();
            _config        = config;
            _outputHandler = outputHandler;

            var loginRequest = new LoginRequest(new Uri(_redirectUri), _config.ClientId, LoginRequest.ResponseType.Code)
            {
                CodeChallengeMethod = "S256",
                CodeChallenge       = _challenge,
                Scope = new [] {
                    Scopes.AppRemoteControl,
                    Scopes.PlaylistModifyPrivate,
                    Scopes.PlaylistModifyPublic,
                    Scopes.PlaylistReadCollaborative,
                    Scopes.PlaylistReadPrivate,
                    Scopes.Streaming,
                    Scopes.UserFollowModify,
                    Scopes.UserFollowRead,
                    Scopes.UserLibraryModify,
                    Scopes.UserLibraryRead,
                    Scopes.UserModifyPlaybackState,
                    Scopes.UserReadCurrentlyPlaying,
                    Scopes.UserReadPlaybackPosition,
                    Scopes.UserReadPlaybackState,
                    Scopes.UserReadPrivate,
                    Scopes.UserReadRecentlyPlayed,
                    Scopes.UserTopRead,
                }
            };

            _oAuthClient = oAuthClient;

            _loginRequestUri = loginRequest.ToUri();
        }
        /// <inheritdoc/>
        public async Task <JsonResult> GetSpotifyAuthenticationToken()
        {
            var(challenge, verifier) = PKCEUtil.GenerateCodes();
            await Task.Delay(0);

            FakeResponseServer.DTO.Request.PKCETokenRequest tokenRequest = new FakeResponseServer.DTO.Request.PKCETokenRequest
            {
                ClientId     = "Some client id",
                Code         = "200",
                CodeVerifier = verifier,
                RedirectUri  = new Uri("http://localhost:2000/callback/")
            };
            var builder = new UriBuilder(fakeSpotifyAuthUrl);
            var query   = HttpUtility.ParseQueryString(builder.Query);

            query["ClientId"]     = tokenRequest.ClientId;
            query["Code"]         = tokenRequest.Code;
            query["CodeVerifier"] = tokenRequest.CodeVerifier;
            query["RedirectUri"]  = tokenRequest.RedirectUri.ToString();
            builder.Query         = query.ToString();
            var    authTokenResponse = externalAPICaller.Get <SpotifyAuthenticationToken>(new Uri("http://localhost:2222/authorize?ClientId=Some+client+id&Code=200&CodeVerifier=KmS_2IQWRizX1bXF5G508LjlbdO2P9432WFf7gKEfD4&RedirectUri=http%3a%2f%2flocalhost%3a2000%2fcallback%2f"));
            string returnMe          = JsonConvert.SerializeObject(authTokenResponse);

            return(new JsonResult(returnMe));
        }
 public SpotifySongExtractor(IOptions <SpotifyApiOptions> spotifyOptions, ILogger <SpotifySongExtractor> logger)
 {
     SpotifyOptions        = spotifyOptions;
     Logger                = logger;
     RedirectUri           = $"http://localhost:{spotifyOptions.Value.AuthServerPort}/callback";
     FileLocation          = Path.Combine(spotifyOptions.Value.FileDirectoryPath, spotifyOptions.Value.CurrentSongFilename);
     (Verifier, Challenge) = PKCEUtil.GenerateCodes(120);
 }
Exemplo n.º 5
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.
            }
        }
Exemplo n.º 6
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"));
            }
        }
Exemplo n.º 7
0
    /// <summary>
    /// Loads the PKCE validator and challenge strings with PKCEConfig properties
    /// </summary>
    /// <returns></returns>
    private (string, string) LoadConfigPKCECodes()
    {
        if (PKCEConfig != null)
        {
            // Check config for a custom verifier
            if (!string.IsNullOrEmpty(PKCEConfig.Verifier))
            {
                return(PKCEUtil.GenerateCodes(PKCEConfig.Verifier));
            }
            else if (PKCEConfig.Length > 0) // or use custom length
            {
                return(PKCEUtil.GenerateCodes(PKCEConfig.Length));
            }
        }

        // Default values
        return(PKCEUtil.GenerateCodes());
    }
Exemplo n.º 8
0
        /// <summary>
        /// Start a new authentication flow.
        /// </summary>
        /// <returns>The login url</returns>
        public async Task <string> Start()
        {
            var(verifier, challenge) = PKCEUtil.GenerateCodes();
            _verifier = verifier;

            var request = new LoginRequest(_callbackUrl, _clientId, LoginRequest.ResponseType.Code)
            {
                CodeChallenge       = challenge,
                CodeChallengeMethod = "S256",
                Scope = new[]
                {
                    Scopes.UserReadRecentlyPlayed, Scopes.UserReadCurrentlyPlaying,
                    Scopes.UserModifyPlaybackState,
                    Scopes.PlaylistModifyPrivate, Scopes.PlaylistModifyPublic
                }
            };

            return(request.ToUri().ToString());
        }
Exemplo n.º 9
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));
        }
        public void GetAuthToken_AuthTokenIsValid()
        {
            var(verifier, challenge) = PKCEUtil.GenerateCodes();
            var tokenRequest = new DTO.Request.PKCETokenRequest
            {
                ClientId     = ClientId,
                Code         = "0",
                CodeVerifier = verifier,
                RedirectUri  = new Uri("localhost:5000/callback")
            };
            var retrievedToken = sut.GetPKCEAuthToken(tokenRequest);

            retrievedToken.Result.AccessToken.Should().NotBeNullOrEmpty();
            retrievedToken.Result.RefreshToken.Should().NotBeNullOrEmpty();
            retrievedToken.Result.AccessToken.Should().NotBeSameAs(retrievedToken.Result.RefreshToken);
            retrievedToken.Result.TokenType.Should().Be("Bearer");
            retrievedToken.Result.IsExpired.Should().Be(false);
            retrievedToken.Result.Scope.Should().Contain("UserReadRecentlyPlayed");
            retrievedToken.Result.ExpiresIn.Should().Be(3600);
            retrievedToken.Result.CreatedAt.Should().BeBefore(DateTime.Now);
        }
Exemplo n.º 11
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);
            }
        }
Exemplo n.º 12
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);
            }
        }
    }
        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();
            }
        }
Exemplo n.º 14
0
        private static async Task GetSpotifyCredentials()
        {
            string code = null;

            Console.WriteLine("Begin Spotify code aquisition");

            // Temporarily hosts a web server to get redirect information
            var listener = new HttpListener();

            listener.Prefixes.Add("http://localhost:8888/callback/");
            listener.Start();
            IAsyncResult result = listener.BeginGetContext(new AsyncCallback((callback) =>
            {
                HttpListener listen         = (HttpListener)callback.AsyncState;
                HttpListenerContext context = listen.EndGetContext(callback);
                HttpListenerRequest request = context.Request;
                code = request.QueryString["code"];

                HttpListenerResponse response = context.Response;
                string responseString         = "<HTML><BODY><H1>Authentication successful. You may now close this page.</H1></BODY></HTML>";
                byte[] buffer = Encoding.UTF8.GetBytes(responseString);
                // Get a response stream and write the response to it
                response.ContentLength64 = buffer.Length;
                System.IO.Stream output  = response.OutputStream;
                output.Write(buffer, 0, buffer.Length);
                // Close the output stream
                output.Close();
            }), listener);

            // Generates a secure random verifier of length 100 and its challenge
            var(verifier, challenge) = PKCEUtil.GenerateCodes();

            var loginRequest = new LoginRequest(
                new Uri("http://localhost:8888/callback"),
                clientId,
                LoginRequest.ResponseType.Code
                )
            {
                CodeChallengeMethod = "S256",
                CodeChallenge       = challenge,
                Scope = new[] { Scopes.UserReadCurrentlyPlaying, Scopes.UserReadPlaybackState }
            };
            var uri = loginRequest.ToUri();

            Console.WriteLine("Attempting to start browser...");
            Process.Start(uri.ToString());

            // Wait 5 minutes or until code value is fulfilled
            for (int i = 0; i < 300; i++)
            {
                if (code != null)
                {
                    break;
                }
                Console.WriteLine($"Waiting for user to connect account... ({i}/300 sec)");
                Thread.Sleep(1000);
            }

            if (code == null)
            {
                Console.WriteLine("Failed to fetch code! Press any key to continue...");
                Console.ReadKey();
                Environment.Exit(1);
            }
            Console.WriteLine("Code aquisition successful");
            listener.Stop();

            // Log in to Spotify
            // Note that we use the verifier calculated above!
            var initialResponse = await new OAuthClient().RequestToken(
                new PKCETokenRequest(clientId, code, new Uri("http://localhost:8888/callback"), verifier)
                );

            WriteOAuthCreds(initialResponse);
            Console.WriteLine("Credential file written");
            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }
Exemplo n.º 15
0
 private void GenerateCode()
 {
     (_verifier, _challenge) = PKCEUtil.GenerateCodes();
 }