Mixonomer.NET/Mixonomer/Spotify/SpotifyNetworkProvider.cs

86 lines
3.2 KiB
C#
Raw Normal View History

using Google.Cloud.Firestore;
2024-01-21 11:12:23 +00:00
using Google.Cloud.SecretManager.V1;
using Microsoft.Extensions.Logging;
2024-01-21 11:12:23 +00:00
using Mixonomer.Fire;
using SpotifyAPI.Web;
namespace Mixonomer;
2024-01-21 11:12:23 +00:00
public class SpotifyNetworkProvider
{
private readonly SecretManagerServiceClient _secretClient;
private readonly UserRepo _userRepo;
private readonly ILogger<SpotifyNetworkProvider> _logger;
2024-01-21 11:12:23 +00:00
public SpotifyNetworkProvider(UserRepo userRepo, SecretManagerServiceClient? secretClient, ILogger<SpotifyNetworkProvider> logger)
2024-01-21 11:12:23 +00:00
{
_userRepo = userRepo;
_logger = logger;
2024-01-21 11:12:23 +00:00
_secretClient = secretClient ?? SecretManagerServiceClient.Create();
}
public async Task<SpotifyClientConfig> GetUserConfig(string username)
{
return await GetUserConfig(await _userRepo.GetUser(username));
}
public async Task<SpotifyClientConfig> GetUserConfig(User user)
{
var spotifyClient = await _secretClient.AccessSecretVersionAsync(SecretStrings.SPOT_CLIENT_URI);
var spotifySecret = await _secretClient.AccessSecretVersionAsync(SecretStrings.SPOT_SECRET_URI);
var spotifyClientStr = spotifyClient.Payload.Data.ToStringUtf8() ?? throw new ArgumentException("No Spotify Client ID returned");
var spotifySecretStr = spotifySecret.Payload.Data.ToStringUtf8() ?? throw new ArgumentException("No Spotify Secret returned");
2024-01-21 11:12:23 +00:00
var refreshed = await new OAuthClient()
.RequestToken(new AuthorizationCodeRefreshRequest(spotifyClientStr, spotifySecretStr, user.refresh_token));
await WriteUserTokenUpdate(user, new
{
access_token = refreshed.AccessToken,
refresh_token = refreshed.RefreshToken ?? user.refresh_token,
last_refreshed = refreshed.CreatedAt,
token_expiry = refreshed.ExpiresIn
});
2024-01-21 11:12:23 +00:00
var authenticator = new AuthorizationCodeAuthenticator(spotifyClientStr, spotifySecretStr, new()
{
AccessToken = refreshed.AccessToken,
TokenType = refreshed.TokenType,
ExpiresIn = refreshed.ExpiresIn,
Scope = refreshed.Scope,
RefreshToken = refreshed.RefreshToken ?? user.refresh_token,
CreatedAt = refreshed.CreatedAt
});
authenticator.TokenRefreshed += async (sender, resp) =>
2024-01-21 11:12:23 +00:00
{
await WriteUserTokenUpdate(user, new
{
access_token = resp.AccessToken,
refresh_token = resp.RefreshToken ?? user.refresh_token,
last_refreshed = resp.CreatedAt,
token_expiry = resp.ExpiresIn
});
2024-01-21 11:12:23 +00:00
};
var config = SpotifyClientConfig
.CreateDefault()
.WithAuthenticator(authenticator);
return config;
}
private async Task WriteUserTokenUpdate(User user, object updates)
{
try
{
_logger.LogInformation("Token refreshed for [{}], writing to database", user.username);
await user.Reference.SetAsync(updates, SetOptions.MergeAll);
}
catch (Exception e)
{
_logger.LogError(e, "Failed to write updated Spotify tokens to database for [{}]", user.username);
}
}
2024-01-21 11:12:23 +00:00
}