public void EnforceInvariants_RefreshTokenAndExpiresSet_DoesNotThrow() { var token = new BearerAccessRefreshToken { Expires = DateTime.UtcNow, RefreshToken = "abc" }; token.EnforceInvariants(); }
protected UserAccessToken(string userId, BearerAccessRefreshToken tokens) { PK = UserId = userId; Id = CanonicalId(userId); Type = "UserAccessToken"; Version = "3"; ResetAccessToken(tokens, DateTimeOffset.UtcNow); }
public void BearerAccessRefreshTokenEnforceInvariants_RefreshTokenSetExpiresNotSet_Throws() { var token = new BearerAccessRefreshToken { RefreshToken = "abc" }; token.EnforceInvariants(); }
private Models.BearerAccessToken MapToBearerAccessToken(BearerAccessRefreshToken token) => new Models.BearerAccessToken { AccessToken = token.AccessToken, Expires = token.Expires, Scope = token.Scope, RefreshToken = token.RefreshToken };
public void EnforceInvariants_RefreshTokenNotSet_Throws() { var token = new BearerAccessRefreshToken { ExpiresIn = 3600 }; token.SetExpires(DateTime.UtcNow); token.EnforceInvariants(); }
public async Task <ContentResult> Authorize( [FromQuery(Name = "state")] string state, [FromQuery(Name = "code")] string code = null, [FromQuery(Name = "error")] string error = null) { //string userId = GetUserId(); // if Spotify returned an error, throw it if (error != null) { throw new SpotifyApiErrorException(error); } // validate state if (string.IsNullOrEmpty(state)) { throw new ArgumentException("Invalid State Argument", nameof(state)); } if (!AuthService.RingoBotStateRegex.IsMatch(state)) { throw new ArgumentException("Invalid State Argument", nameof(state)); } // get the userId from state string channelUserId = await _userStateData.GetUserIdFromStateToken(state); if (channelUserId == null) { return(new ContentResult { ContentType = "text/html", StatusCode = (int)HttpStatusCode.OK, Content = $"<html><body><p>This authorization request has expired or is invalid. Please try again.</p></body></html>" }); } // Use the code to request a token BearerAccessRefreshToken token = await _userAccounts.RequestAccessRefreshToken(code); await _userData.SaveUserAccessToken(channelUserId, MapToBearerAccessToken(token)); // return an HTML result with the state token to authorise the bot return(new ContentResult { ContentType = "text/html", StatusCode = (int)HttpStatusCode.OK, Content = $"<html><body style='font-family:Consolas'><p>Copy this code into the chat window:<br/><input style='width:300px' value='{RingoBotCommands.AuthCommand[0]} {state}'/></p></body></html>" }); }
public UserAuth SetUserAuthRefreshToken(string userId, BearerAccessRefreshToken tokens) { //TODO: No concurrency checking. Blows away any existing record var userAuth = GetUserAuth(userId); if (userAuth == null) { throw new InvalidOperationException($"No valid User Auth record found for user hash \"{userId}\""); } userAuth.Authorized = true; userAuth.RefreshToken = tokens.RefreshToken; userAuth.Scopes = tokens.Scope; InsertOrUpdateUserAuth(userId, userAuth); return(userAuth); }
//[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}"); } }
public async Task SetSpotifyAccessToken(string userId, BearerAccessRefreshToken token) { await RetryHelper.RetryAsync(async() => { var storedToken = await _data.GetOrDefault(UserAccessToken.CanonicalId(userId), userId); var uat = new UserAccessRefreshToken(userId, token); uat.EnforceInvariants(); if (storedToken == null) { await _data.Create(uat); } else { await _data.Replace(uat, storedToken.ETag); } }, waitMs : 10, logger : _logger); }
public UserAccessRefreshToken(string userId, BearerAccessRefreshToken tokens) : base(userId, tokens) { RefreshToken = tokens.RefreshToken; }