public void RequestAuthorizationUrl_Scopes_UrlContainsSpaceDelimitedScopes()
        {
            // arrange
            const string state = "abc123";

            string[] scopes = new[]
            {
                "user-modify-playback-state",
                "user-read-playback-state",
                "playlist-read-collaborative",
                "playlist-modify-public",
                "playlist-modify-private",
                "playlist-read-private",
                "user-read-email"
            };

            var config = new MockConfiguration().Object;
            var http   = new HttpClient();
            //var tokenStore = new MockRefreshTokenStore(UserHash, config).Object;
            var service = new UserAccountsService(http, config);

            // act
            string url = service.AuthorizeUrl(state, scopes);

            // assert
            Assert.IsTrue(url.Contains(string.Join("%20", scopes)), "url should contain %20 (space) delimited user scopes");
            Trace.WriteLine("RequestAuthorizationUrl_Scopes_UrlContainsSpaceDelimitedScopes url =");
            Trace.WriteLine(url);
        }
Example #2
0
        //[TestMethod]  // only used for manual debugging
        public void ControllerAuthorize1()
        {
            // controller creates state, saves a hash (userHash, state)
            string state = Guid.NewGuid().ToString("N");

            // controller encodes userHash and state (this is optional)
            // controller calls Helper to get Auth URL (userHash, state)
            string url = _accounts.AuthorizeUrl(state, new[]
            {
                "user-modify-playback-state",
                "user-read-playback-state",
                "user-read-currently-playing",

                "user-library-modify",
                "user-library-read",
                "user-top-read",
                "user-read-playback-position",
                "user-read-recently-played",
                "user-follow-read",
                "user-follow-modify"

                //"playlist-read-collaborative",
                //"playlist-modify-public",
                //"playlist-modify-private",
                //"playlist-read-private",
                //"user-read-email",
                //"user-read-private",
            });

            Trace.WriteLine(url);

            // controller redirects to URL
        }
Example #3
0
        //[TestMethod]  // only used for manual debugging
        public void ControllerAuthorize1()
        {
            // controller creates state, saves a hash (userHash, state)
            string state = Guid.NewGuid().ToString("N");

            // controller encodes userHash and state (this is optional)
            // controller calls Helper to get Auth URL (userHash, state)
            string url = _accounts.AuthorizeUrl(state, null);

            // controller redirects to URL
        }
        public void AuthorizeUrl_StateParam_UrlContainsState()
        {
            // arrange
            const string state  = "abc123";
            var          http   = new MockHttpClient().HttpClient;
            var          config = new MockConfiguration().Object;
            //var tokenStore = new MockRefreshTokenStore(UserHash, config).Object;
            var service = new UserAccountsService(http, config);

            // act
            string url = service.AuthorizeUrl(state, null);

            // assert
            Assert.IsTrue(url.Contains(state), "url result should contain state param");
        }
        public IActionResult AuthorizeSpotify(RoomVM roomVM)
        {
            var accountService = new UserAccountsService(new HttpClient(), _config);

            var    roomId = roomVM.SyncAuthorization ? $"{roomVM.CurrentRoom.Id}-sync" : roomVM.CurrentRoom.Id.ToString();
            string url    = accountService
                            .AuthorizeUrl(
                roomId,
                new[] { "user-read-playback-state streaming user-read-private user-read-email playlist-read-private user-library-read playlist-modify-public playlist-modify-private" });

            if (roomVM.SyncAuthorization)
            {
                return(Ok(url));
            }

            return(Redirect(url));
        }
Example #6
0
        //[TestMethod]
        public async Task Usage2()
        {
            // Get a list of a User's devices
            // This requires User authentication and authorization.
            // A `UserAccountsService` is provided to help with this.

            // HttpClient and UserAccountsService can be reused.
            // Tokens can be cached by your code
            var http     = new HttpClient();
            var accounts = new UserAccountsService(http, TestsHelper.GetLocalConfig());

            // See https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-code-flow
            //  for an explanation of the Authorization code flow

            // Generate a random state value to use in the Auth request
            string state = Guid.NewGuid().ToString("N");
            // Accounts service will derive the Auth URL for you
            string url = accounts.AuthorizeUrl(state, new[] { "user-read-playback-state" });

            /*
             *  Redirect the user to `url` and when they have auth'ed Spotify will redirect to your reply URL
             *  The response will include two query parameters: `state` and `code`.
             *  For a full working example see `SpotifyApi.NetCore.Samples`.
             */
            var query = new Dictionary <string, string>();

            // Check that the request has not been tampered with by checking the `state` value matches
            if (state != query["state"])
            {
                throw new ArgumentException();
            }

            // Use the User accounts service to swap `code` for a Refresh token
            BearerAccessRefreshToken token = await accounts.RequestAccessRefreshToken(query["code"]);

            // Use the Bearer (Access) Token to call the Player API
            var player = new PlayerApi(http, accounts);

            Device[] devices = await player.GetDevices(accessToken : token.AccessToken);

            foreach (Device device in devices)
            {
                Trace.WriteLine($"Device {device.Name} Status = {device.Type} Active = {device.IsActive}");
            }
        }
Example #7
0
        public async Task <TokenResponse> Authorize(ITurnContext turnContext, CancellationToken cancellationToken)
        {
            var    info   = RingoBotHelper.NormalizedConversationInfo(turnContext);
            string userId = RingoBotHelper.ChannelUserId(turnContext);

            TokenResponse token = await GetAccessToken(userId);

            if (token != null)
            {
                return(token);
            }

            // User is not authorized by Spotify
            if (BotHelper.IsGroup(turnContext))
            {
                // Don't start authorisation dance in Group chat
                await turnContext.SendActivityAsync(
                    $"Before you play or join with Ringo you need to authorize Spotify. DM (direct message) the word `\"{RingoBotCommands.AuthCommand[0]}\"` to @{info.BotName} to continue.",
                    cancellationToken : cancellationToken);

                return(null);
            }

            _logger.LogInformation($"Requesting Spotify Authorization for UserId {userId}");

            await _userData.CreateUserIfNotExists(info);

            // create state token
            string state = $"{RingoBotStatePrefix}{Guid.NewGuid().ToString("N")}".ToLower();

            // validate state token
            if (!RingoBotStateRegex.IsMatch(state))
            {
                throw new InvalidOperationException("Generated state token does not match RingoBotStateRegex");
            }

            // save state token
            await _userStateData.SaveStateToken(userId, state);

            await _userData.SaveStateToken(userId, state);

            // get URL
            string url = UserAccountsService.AuthorizeUrl(
                state,
                new[] { "user-read-playback-state", "user-modify-playback-state" },
                _config["SpotifyApiClientId"],
                _config["SpotifyAuthRedirectUri"]);

            var message = MessageFactory.Attachment(
                new Attachment
            {
                ContentType = HeroCard.ContentType,
                Content     = new HeroCard
                {
                    Text    = "Authorize Ringo bot to use your Spotify account",
                    Buttons = new[]
                    {
                        new CardAction
                        {
                            Title = "Authorize",
                            Text  = "Click to Authorize. (Opens in your browser)",
                            Value = url,
                            Type  = ActionTypes.OpenUrl,
                        },
                    },
                },
            },
                text: "To play music, Ringo needs to be authorized to use your Spotify Account.");

            await turnContext.SendActivityAsync(message, cancellationToken);

            return(null);
        }