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); }
public ProfileModule(UserAccountsService userAccounts, ILogger <ProfileModule> logger, PairsService pairs, DiscordSocketClient client) { _userAccounts = userAccounts; _logger = logger; _pairs = pairs; _console = client.GetChannel(ulong.Parse(_pairs.GetString("CONSOLE_CHANNEL_ID"))) as SocketTextChannel; }
public async Task PlayContext_SpotifyUri_SpotifyApiErrorException() { // arrange const string userHash = "E11AC28538A7C0A827A726DD9B30B710FC1FCAFFFE2E86FCA853AB90E7C710D2"; const string spotifyUri = "spotify:user:palsvensson:playlist:2iL5fr6OmN8f4yoQvvuWSf"; var http = new HttpClient(); var config = TestsHelper.GetLocalConfig(); var accounts = new UserAccountsService(http, config, new MockRefreshTokenStore(userHash).Object, null); var api = new PlayerApi(http, accounts); // act //try //{ await api.PlayContext(userHash, spotifyUri); //} //catch (SpotifyApiErrorException ex) //{ //Trace.WriteLine(ex.Message); //} // assert }
public async Task GetUserAccessToken_TokenNotExpired_ReturnsCurrentToken() { // arrange var currentToken = new BearerAccessToken { AccessToken = "abcd1234", ExpiresIn = 3600, Expires = DateTime.UtcNow.AddSeconds(3600) }; var http = new MockHttpClient().HttpClient; var bearerTokenStore = new Mock <IBearerTokenStore>(); bearerTokenStore.Setup(s => s.Get(It.IsAny <string>())).ReturnsAsync(currentToken); var config = new MockConfiguration().Object; var refreshTokenStore = new MockRefreshTokenStore(UserHash, config).Object; var service = new UserAccountsService(http, config, refreshTokenStore, bearerTokenStore.Object); // act var token = await service.GetUserAccessToken(UserHash); // assert Assert.AreEqual(currentToken, token); }
public RssJob(ILogger <ReminderJob> logger, DiscordSocketClient client, UserAccountsService accounts) { _logger = logger; _client = client; _accounts = accounts; _channels = new Dictionary <ulong, SocketTextChannel>(); _lastUpdates = new Dictionary <FeedConfig, DateTime?>(); _webClient = new WebClient(); _configs = JsonConvert.DeserializeObject <List <FeedConfig> >(File.ReadAllText("Config/feeds.json")); foreach (var config in _configs) { foreach (var channelId in config.ChannelIds) { if (_channels.ContainsKey(channelId)) { continue; } _channels.Add(channelId, client.GetChannel(channelId) as SocketTextChannel); } } foreach (var feedConfig in _configs) { _lastUpdates.Add(feedConfig, null); } }
public async Task GetUserAccessToken_TokenExpired_ReturnsNewToken() { // arrange var expiredToken = new BearerAccessToken { AccessToken = "abcd1234", ExpiresIn = 3600, Expires = new DateTime(2018, 7, 28, 9, 18, 0, DateTimeKind.Utc) }; const string json = @"{ ""access_token"": ""NgCXRKc...MzYjw"", ""token_type"": ""bearer"", ""expires_in"": 3600, }"; var mockHttp = new MockHttpClient(); mockHttp.SetupSendAsync(json); var http = mockHttp.HttpClient; var bearerTokenStore = new Mock <IBearerTokenStore>(); bearerTokenStore.Setup(s => s.Get(It.IsAny <string>())).ReturnsAsync(expiredToken); var config = new MockConfiguration().Object; var refreshTokenStore = new MockRefreshTokenStore(UserHash, config).Object; var service = new UserAccountsService(http, config, refreshTokenStore, bearerTokenStore.Object); // act var token = await service.GetUserAccessToken(UserHash); // assert Assert.AreNotEqual(expiredToken, token); }
public AdminModule(ILogger <AdminModule> logger, DiscordSocketClient client, PairsService pairs, UserAccountsService accounts) { _logger = logger; _client = client; _pairs = pairs; _accounts = accounts; }
public AssignPointsModule(UserAccountsService accounts, PairsService pairs, ILogger <AssignPointsModule> logger, DiscordSocketClient client) { _accounts = accounts; _pairs = pairs; _logger = logger; _client = client; _webClient = new WebClient(); // Kubík, Hajgrando, and H3G1 _authorizedUsers = new ulong[] { 408675740633268226, 213659030244163585, 688157416407302161 }; }
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 async Task GetUsersProfile_NoUserId_DeserializedResponse() { // arrange var config = TestsHelper.GetLocalConfig(); var accessToken = config["SpotifyUserBearerAccessToken"]; var http = new HttpClient(); var accounts = new UserAccountsService(http, config); var api = new UsersProfileApi(http, accounts); // act // must use a User Access Token for this call var response = await api.GetCurrentUsersProfile(accessToken : accessToken); Assert.IsNotNull(response); }
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)); }
//[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}"); } }
//TODO: Something is up - the first error is not being thrown to the test runner... //[TestMethod] public async Task TwoCompetingUserAccessTokenRequestsGetConsistentResults() { const string userHash = "E11AC28538A7C0A827A726DD9B30B710FC1FCAFFFE2E86FCA853AB90E7C710D2"; const string spotifyUri = "spotify:user:palsvensson:playlist:2iL5fr6OmN8f4yoQvvuWSf"; var store = new MockRefreshTokenStore(userHash).Object; var http1 = new HttpClient(); var accounts1 = new UserAccountsService(http1, TestsHelper.GetLocalConfig(), store); var player1 = new PlayerApi(http1, accounts1); var http2 = new HttpClient(); var accounts2 = new UserAccountsService(http2, TestsHelper.GetLocalConfig(), store); var player2 = new PlayerApi(http2, accounts2); // act //try //{ //TODO: Call Device method instead await player1.PlayContext(userHash, spotifyUri); //} //catch (SpotifyApiErrorException ex) //{ //Trace.WriteLine(ex.Message); //} //try //{ await player2.PlayContext(userHash, spotifyUri); //} //catch (SpotifyApiErrorException ex) //{ // Trace.WriteLine(ex.Message); //} // assert // no error }
public void Initialize() { //_refreshTokenProvider = new MockRefreshTokenStore(UserHash).Object; _accounts = new UserAccountsService(new HttpClient(), TestsHelper.GetLocalConfig()); }
public LeaderboardModule(UserAccountsService userAccounts, PairsService pairs) { _userAccounts = userAccounts; _pairs = pairs; _leaderboardSize = 15; }
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); }