added tokenfactoryprovider

This commit is contained in:
andy 2021-10-12 20:23:25 +01:00
parent 539143ad5e
commit 1694f8e3a9
13 changed files with 113 additions and 28 deletions

2
.gitignore vendored
View File

@ -3,6 +3,8 @@
## ##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
appsettings.Development.json
# User-specific files # User-specific files
*.rsuser *.rsuser
*.suo *.suo

15
.vscode/launch.json vendored
View File

@ -1,19 +1,20 @@
{ {
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"name": ".NET Core Launch (console)", "name": ".NET Core Launch (console)",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "build", "preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path. "program": "${workspaceFolder}/Selector.CLI/bin/Debug/net5.0/Selector.CLI.dll",
"program": "${workspaceFolder}/Selector.Tests/bin/Debug/net5.0/Selector.Tests.dll", "env": {
"DOTNET_ENVIRONMENT": "Development"
},
"args": [], "args": [],
"cwd": "${workspaceFolder}/Selector.Tests", "cwd": "${workspaceFolder}/Selector.CLI",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole", "console": "internalConsole",
"stopAtEntry": false "stopAtEntry": false
}, },

6
.vscode/tasks.json vendored
View File

@ -7,7 +7,7 @@
"type": "process", "type": "process",
"args": [ "args": [
"build", "build",
"${workspaceFolder}/Selector.Tests/Selector.Tests.csproj", "${workspaceFolder}/Selector.CLI/Selector.CLI.csproj",
"/property:GenerateFullPaths=true", "/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary" "/consoleloggerparameters:NoSummary"
], ],
@ -19,7 +19,7 @@
"type": "process", "type": "process",
"args": [ "args": [
"publish", "publish",
"${workspaceFolder}/Selector.Tests/Selector.Tests.csproj", "${workspaceFolder}/Selector.CLI/Selector.CLI.csproj",
"/property:GenerateFullPaths=true", "/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary" "/consoleloggerparameters:NoSummary"
], ],
@ -32,7 +32,7 @@
"args": [ "args": [
"watch", "watch",
"run", "run",
"${workspaceFolder}/Selector.Tests/Selector.Tests.csproj", "${workspaceFolder}/Selector.CLI/Selector.CLI.csproj",
"/property:GenerateFullPaths=true", "/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary" "/consoleloggerparameters:NoSummary"
], ],

View File

@ -1,5 +1,4 @@
 using System.Collections.Generic;
using System.Collections.Generic;
namespace Selector.CLI namespace Selector.CLI
{ {
@ -40,7 +39,9 @@ namespace Selector.CLI
public string RefreshKey { get; set; } public string RefreshKey { get; set; }
public int PollPeriod { get; set; } = 5000; public int PollPeriod { get; set; } = 5000;
public WatcherType Type { get; set; } = WatcherType.Player; public WatcherType Type { get; set; } = WatcherType.Player;
#nullable enable
public string? PlaylistUri { get; set; } public string? PlaylistUri { get; set; }
#nullable disable
} }
enum WatcherType enum WatcherType

View File

@ -29,6 +29,7 @@ namespace Selector.CLI
// SERVICES // SERVICES
//services.AddTransient<IWatcherFactory, PlayerWatcher>(); //services.AddTransient<IWatcherFactory, PlayerWatcher>();
//services.AddTransient<IWatcherCollection, WatcherCollection>(); //services.AddTransient<IWatcherCollection, WatcherCollection>();
services.AddSingleton<IRefreshTokenFactoryProvider, RefreshTokenFactoryProvider>();
switch(context.Configuration.GetValue<EqualityChecker>("selector:equality")) switch(context.Configuration.GetValue<EqualityChecker>("selector:equality"))
{ {

View File

@ -15,13 +15,17 @@ namespace Selector.CLI
{ {
private readonly ILogger<WatcherService> Logger; private readonly ILogger<WatcherService> Logger;
private readonly RootOptions Config; private readonly RootOptions Config;
private readonly IRefreshTokenFactoryProvider TokenFactoryProvider;
private Dictionary<string, IWatcherCollection> Watchers { get; set; } = new(); private Dictionary<string, IWatcherCollection> Watchers { get; set; } = new();
public WatcherService(ILogger<WatcherService> logger, IOptions<RootOptions> config) public WatcherService(IRefreshTokenFactoryProvider tokenFactoryProvider, ILogger<WatcherService> logger, IOptions<RootOptions> config)
{ {
Logger = logger; Logger = logger;
Config = config.Value; Config = config.Value;
TokenFactoryProvider = tokenFactoryProvider;
TokenFactoryProvider.Initialise(Config.ClientId, Config.ClientSecret);
} }
public Task StartAsync(CancellationToken cancellationToken) public Task StartAsync(CancellationToken cancellationToken)

View File

@ -1,7 +1,7 @@
{ {
"Selector": { "Selector": {
"ClientId": "", "ClientId": "",
"ClientSecret" "", "ClientSecret": "",
"Equality": "uri", "Equality": "uri",
"Watcher": { "Watcher": {
"Instances": [ "Instances": [

View File

@ -0,0 +1,10 @@
using System.Threading.Tasks;
using SpotifyAPI.Web;
namespace Selector
{
public interface ISpotifyConfigFactory
{
public Task<SpotifyClientConfig> GetConfig();
}
}

View File

@ -8,7 +8,7 @@ namespace Selector
/// <summary> /// <summary>
/// Get config from a refresh token /// Get config from a refresh token
/// </summary> /// </summary>
public class RefreshTokenFactory : ISpotifyClientFactory public class RefreshTokenFactory : ISpotifyConfigFactory
{ {
private string ClientId { get; set; } private string ClientId { get; set; }
private string ClientSecret { get; set; } private string ClientSecret { get; set; }

View File

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using SpotifyAPI.Web;
namespace Selector
{
public class CachingRefreshTokenFactoryProvider : RefreshTokenFactoryProvider
{
protected Dictionary<string, RefreshTokenFactory> Configs = new();
public RefreshTokenFactory GetUserConfig(string userId) => Configs.ContainsKey(userId) ? Configs[userId] : null;
new public async Task<RefreshTokenFactory> GetFactory(string refreshToken)
{
var configProvider = await base.GetFactory(refreshToken);
var newConfig = await configProvider.GetConfig();
var client = new SpotifyClient(newConfig);
var userDetails = await client.UserProfile.Current();
if(Configs.ContainsKey(userDetails.Id))
{
return Configs[userDetails.Id];
}
else
{
Configs[userDetails.Id] = configProvider;
return configProvider;
}
}
}
}

View File

@ -0,0 +1,11 @@
using System.Threading.Tasks;
namespace Selector
{
public interface IRefreshTokenFactoryProvider
{
public void Initialise(string clientId, string clientSecret);
public bool Initialised { get; }
public Task<RefreshTokenFactory> GetFactory(string refreshToken);
}
}

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using SpotifyAPI.Web;
namespace Selector
{
/// <summary>
/// Get config from a refresh token
/// </summary>
public class RefreshTokenFactoryProvider : IRefreshTokenFactoryProvider
{
protected string ClientId { get; set; }
protected string ClientSecret { get; set; }
public void Initialise(string clientId, string clientSecret){
ClientId = clientId;
ClientSecret = clientSecret;
}
public bool Initialised => string.IsNullOrWhiteSpace(ClientId) || string.IsNullOrWhiteSpace(ClientSecret);
public Task<RefreshTokenFactory> GetFactory(string refreshToken)
{
if(!Initialised) throw new InvalidOperationException("Factory not initialised");
if(string.IsNullOrEmpty(refreshToken)) throw new ArgumentException("Null or empty refresh key provided");
return Task.FromResult(new RefreshTokenFactory(ClientId, ClientSecret, refreshToken));
}
}
}

View File

@ -1,13 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using SpotifyAPI.Web;
namespace Selector
{
public interface ISpotifyClientFactory
{
public Task<SpotifyClientConfig> GetConfig();
}
}