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
appsettings.Development.json
# User-specific files
*.rsuser
*.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",
"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)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/Selector.Tests/bin/Debug/net5.0/Selector.Tests.dll",
"program": "${workspaceFolder}/Selector.CLI/bin/Debug/net5.0/Selector.CLI.dll",
"env": {
"DOTNET_ENVIRONMENT": "Development"
},
"args": [],
"cwd": "${workspaceFolder}/Selector.Tests",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"cwd": "${workspaceFolder}/Selector.CLI",
"console": "internalConsole",
"stopAtEntry": false
},

6
.vscode/tasks.json vendored
View File

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

View File

@ -1,5 +1,4 @@

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

View File

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

View File

@ -15,13 +15,17 @@ namespace Selector.CLI
{
private readonly ILogger<WatcherService> Logger;
private readonly RootOptions Config;
private readonly IRefreshTokenFactoryProvider TokenFactoryProvider;
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;
Config = config.Value;
TokenFactoryProvider = tokenFactoryProvider;
TokenFactoryProvider.Initialise(Config.ClientId, Config.ClientSecret);
}
public Task StartAsync(CancellationToken cancellationToken)

View File

@ -1,7 +1,7 @@
{
"Selector": {
"ClientId": "",
"ClientSecret" "",
"ClientSecret": "",
"Equality": "uri",
"Watcher": {
"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>
/// Get config from a refresh token
/// </summary>
public class RefreshTokenFactory : ISpotifyClientFactory
public class RefreshTokenFactory : ISpotifyConfigFactory
{
private string ClientId { 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();
}
}