Files
SpotiParty/SpotiParty.Web/Services/AuthorizationHandler.cs
2025-11-30 19:01:38 +01:00

70 lines
2.6 KiB
C#

using Microsoft.AspNetCore.Components;
using Microsoft.EntityFrameworkCore;
using SpotifyAPI.Web;
using SpotiParty.Web.Models;
namespace SpotiParty.Web.Services;
public sealed class AuthorizationHandler(NavigationManager navigator, DatabaseContext context, ClientSideStorage storage) {
private async Task<(string clientId, string clientSecret)> GetClientSecrets() {
var fileLines = await File.ReadAllLinesAsync(Path.Combine(Environment.CurrentDirectory, ".dev-token"));
return (fileLines[0], fileLines[1]);
}
public async Task<SpotifyClient?> ConfigureClient(Guid userId) {
var user = await context.Users.FindAsync(userId);
if (user is null) return null;
var (clientId, clientSecret) = await GetClientSecrets();
var request = new AuthorizationCodeRefreshRequest(clientId, clientSecret, user.RefreshToken);
var response = await new OAuthClient().RequestToken(request);
return new SpotifyClient(response.AccessToken);
}
public async Task<Uri> ConstructLoginUri() {
var (clientId, _) = await GetClientSecrets();
var request = new LoginRequest(
new Uri(navigator.BaseUri + "callback"),
clientId,
LoginRequest.ResponseType.Code) {
Scope = [Scopes.UserReadPlaybackState, Scopes.UserModifyPlaybackState, Scopes.UserReadPrivate, Scopes.UserReadEmail]
};
return request.ToUri();
}
public async Task HandleCallback(string code) {
var (clientId, clientSecret) = await GetClientSecrets();
var response = await new OAuthClient().RequestToken(
new AuthorizationCodeTokenRequest(
clientId,
clientSecret,
code,
new Uri(navigator.BaseUri + "callback")));
var client = new SpotifyClient(response.AccessToken);
var spotiUser = await client.UserProfile.Current();
var user = await context.Users.FirstOrDefaultAsync(u => u.SpotifyUserId == spotiUser.Id);
if (user is null) {
user = new User {
DisplayName = spotiUser.DisplayName,
RefreshToken = response.RefreshToken,
SpotifyUserId = spotiUser.Id,
IsAdmin = await context.Users.CountAsync() == 0
};
await context.Users.AddAsync(user);
await context.SaveChangesAsync();
}
else {
user.RefreshToken = response.RefreshToken;
await context.SaveChangesAsync();
}
storage.SaveUserToken(response.RefreshToken);
}
}