added tokenfactoryprovider
This commit is contained in:
parent
539143ad5e
commit
1694f8e3a9
2
.gitignore
vendored
2
.gitignore
vendored
@ -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
15
.vscode/launch.json
vendored
@ -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
6
.vscode/tasks.json
vendored
@ -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"
|
||||||
],
|
],
|
||||||
|
@ -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
|
||||||
|
@ -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"))
|
||||||
{
|
{
|
||||||
|
@ -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)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"Selector": {
|
"Selector": {
|
||||||
"ClientId": "",
|
"ClientId": "",
|
||||||
"ClientSecret" "",
|
"ClientSecret": "",
|
||||||
"Equality": "uri",
|
"Equality": "uri",
|
||||||
"Watcher": {
|
"Watcher": {
|
||||||
"Instances": [
|
"Instances": [
|
||||||
|
10
Selector/Spotify/ConfigFactory/ISpotifyConfigFactory.cs
Normal file
10
Selector/Spotify/ConfigFactory/ISpotifyConfigFactory.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using SpotifyAPI.Web;
|
||||||
|
|
||||||
|
namespace Selector
|
||||||
|
{
|
||||||
|
public interface ISpotifyConfigFactory
|
||||||
|
{
|
||||||
|
public Task<SpotifyClientConfig> GetConfig();
|
||||||
|
}
|
||||||
|
}
|
@ -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; }
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user