private async Task <SpotifyUserToken> GetDbToken(string synthbotUserId) { var spotifyUserId = await _db.UserLogins .Where(ul => ul.LoginProvider == "Spotify") .Select(ul => ul.ProviderKey) .FirstOrDefaultAsync(); if (string.IsNullOrEmpty(spotifyUserId)) { return(null); } var userTokensQueryable = _db.UserTokens.Where(ut => ut.UserId == synthbotUserId && ut.LoginProvider == "Spotify"); var spotifyToken = SpotifyToken.FromUserTokens(userTokensQueryable); spotifyToken.Validate(); var userToken = new SpotifyUserToken() { SynthbotUserId = synthbotUserId, SpotifyUserId = spotifyUserId, SpotifyAccessToken = spotifyToken.AccessToken, SpotifyAccessTokenExpiry = spotifyToken.ExpiresAt, SpotifyRefreshToken = spotifyToken.RefreshToken }; return(userToken); }
private async Task UpdateDbAsync(SpotifyUserToken userToken) { await _dbSignal.WaitAsync(); var accessTokenRecord = await _db.UserTokens .FirstOrDefaultAsync(t => t.UserId == userToken.SynthbotUserId && t.Name == "access_token"); if (accessTokenRecord != null) { accessTokenRecord.Value = userToken.SpotifyAccessToken; _db.Update(accessTokenRecord); } else { accessTokenRecord = new IdentityUserToken <string>() { LoginProvider = "Spotify", Name = "access_token", UserId = userToken.SynthbotUserId, Value = userToken.SpotifyAccessToken }; await _db.UserTokens.AddAsync(accessTokenRecord); } var expiresAtRecord = await _db.UserTokens.FirstOrDefaultAsync(t => t.UserId == userToken.SynthbotUserId && t.Name == "expires_at"); if (expiresAtRecord != null) { expiresAtRecord.Value = userToken.SpotifyAccessTokenExpiry.ToString("O"); _db.Update(expiresAtRecord); } else { expiresAtRecord = new IdentityUserToken <string>() { LoginProvider = "Spotify", Name = "expires_at", UserId = userToken.SynthbotUserId, Value = userToken.SpotifyAccessTokenExpiry.ToString("O") }; await _db.AddAsync(expiresAtRecord); } try { await _db.SaveChangesAsync(); } finally { _dbSignal.Release(); } }
public async Task <RefreshAccessTokenResponse> RefreshTokenAsync(SpotifyUserToken userToken) { var uri = new Uri($"https://accounts.spotify.com/api/token"); // Create body parameters var parameters = new List <KeyValuePair <string, string> >(); parameters.Add(new KeyValuePair <string, string>("grant_type", "refresh_token")); parameters.Add(new KeyValuePair <string, string>("refresh_token", userToken.SpotifyRefreshToken)); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri) { Content = new FormUrlEncodedContent(parameters) }; // Create encoded credentials header value var sb = new StringBuilder(); sb.Append(_config["spotify.api.clientid"]); sb.Append($":"); sb.Append(_config["spotify.api.clientsecret"]); var encodedCredentials = Convert.ToBase64String(Encoding.UTF8.GetBytes(sb.ToString())); // Add authorization header request.Headers.Add("Authorization", $"Basic {encodedCredentials}"); // Send the request var result = await _httpClient.SendAsync(request); if (result.IsSuccessStatusCode) { var contentString = await result.Content.ReadAsStringAsync(); var tokenResponse = JsonConvert.DeserializeObject <SpotifyAccessTokenResponse>(contentString); // Set the updated access token on the user token that was passed in userToken.SpotifyAccessToken = tokenResponse.AccessToken; userToken.SpotifyAccessTokenExpiry = DateTime.UtcNow.AddSeconds(tokenResponse.ExpiresInSeconds); // Return token response return(RefreshAccessTokenResponse.CreateSuccess()); } else { return(RefreshAccessTokenResponse .CreateFailure( $"Failed to refresh token. Received error response from Spotify. Status Code: {result.StatusCode}")); } }
public async Task <SpotifyUserToken> RefreshToken(SpotifyUserToken userToken, string synthbotUserId) { _logger.Log(LogLevel.Information, "Refreshing spotify token for user: {synthbotUserId}", synthbotUserId); var refreshResponse = await userToken.Refresh(_refreshService); if (!refreshResponse.Success) { _logger.Log(LogLevel.Error, "Token refresh failed for user: {synthbotUserId}", synthbotUserId); return(null); } _logger.Log(LogLevel.Information, "Token refresh successful for user: {synthbotUserId}", synthbotUserId); // Update the token in the DB for future auth await UpdateDbAsync(userToken); return(userToken); }