Started adding authentication to extension settings.

dashboard
Pat Hartl 2023-01-05 01:07:17 -06:00
parent c18cb1d94b
commit 40ea196594
9 changed files with 184 additions and 48 deletions

View File

@ -3,6 +3,7 @@ using RestSharp;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -11,17 +12,60 @@ namespace LANCommander.Playnite.Extension
internal class LANCommanderClient internal class LANCommanderClient
{ {
private readonly RestClient Client; private readonly RestClient Client;
private AuthToken Token;
public LANCommanderClient() public LANCommanderClient()
{ {
Client = new RestClient("https://localhost:7087"); Client = new RestClient("https://localhost:7087");
} }
private T PostRequest<T>(string route, object body)
{
var request = new RestRequest(route)
.AddJsonBody(body)
.AddHeader("Authorization", $"Bearer {Token.AccessToken}");
var response = Client.Post<T>(request);
return response.Data;
}
public AuthResponse Authenticate(string username, string password)
{
var response = Client.Post<AuthResponse>(new RestRequest("/api/Auth").AddJsonBody(new AuthRequest()
{
UserName = username,
Password = password
}));
return response.Data;
}
public AuthResponse RefreshToken(AuthToken token)
{
var request = new RestRequest("/api/Auth/Refresh")
.AddJsonBody(token);
var response = Client.Post<AuthResponse>(request);
return response.Data;
}
public bool ValidateToken(AuthToken token)
{
var request = new RestRequest("/api/Auth/Validate")
.AddHeader("Authorization", $"Bearer {token.AccessToken}");
var response = Client.Post(request);
return response.StatusCode == HttpStatusCode.OK;
}
public IEnumerable<Game> GetGames() public IEnumerable<Game> GetGames()
{ {
var response = Client.Get<IEnumerable<Game>>(new RestRequest("/api/Games")); var response = Client.Get<IEnumerable<Game>>(new RestRequest("/api/Games"));
return response.Data; return response.Data;
} }
} }
} }

View File

@ -13,7 +13,8 @@ namespace LANCommander.Playnite.Extension
public override void Open() public override void Open()
{ {
throw new NotImplementedException();
System.Diagnostics.Process.Start("https://localhost:7087");
} }
} }
} }

View File

@ -13,8 +13,8 @@ namespace LANCommander.Playnite.Extension
public class PlayniteLibraryPlugin : LibraryPlugin public class PlayniteLibraryPlugin : LibraryPlugin
{ {
public static readonly ILogger Logger = LogManager.GetLogger(); public static readonly ILogger Logger = LogManager.GetLogger();
private SettingsViewModel Settings { get; set; } private PlayniteSettingsViewModel Settings { get; set; }
private LANCommanderClient LANCommander { get; set; } internal LANCommanderClient LANCommander { get; set; }
public override Guid Id { get; } = Guid.Parse("48e1bac7-e0a0-45d7-ba83-36f5e9e959fc"); public override Guid Id { get; } = Guid.Parse("48e1bac7-e0a0-45d7-ba83-36f5e9e959fc");
public override string Name => "LANCommander"; public override string Name => "LANCommander";
@ -23,7 +23,7 @@ namespace LANCommander.Playnite.Extension
public PlayniteLibraryPlugin(IPlayniteAPI api) : base(api) public PlayniteLibraryPlugin(IPlayniteAPI api) : base(api)
{ {
LANCommander = new LANCommanderClient(); LANCommander = new LANCommanderClient();
Settings = new SettingsViewModel(this); Settings = new PlayniteSettingsViewModel(this);
Properties = new LibraryPluginProperties Properties = new LibraryPluginProperties
{ {
HasSettings = true, HasSettings = true,
@ -32,28 +32,51 @@ namespace LANCommander.Playnite.Extension
public override IEnumerable<GameMetadata> GetGames(LibraryGetGamesArgs args) public override IEnumerable<GameMetadata> GetGames(LibraryGetGamesArgs args)
{ {
// Implement LANCommander client here try
var games = LANCommander.GetGames().Select(g => new GameMetadata()
{ {
Name = g.Title, // Implement LANCommander client here
Description = g.Description, var games = LANCommander.GetGames().Select(g => new GameMetadata()
GameId = g.Id.ToString(), {
ReleaseDate = new ReleaseDate(g.ReleasedOn), Name = g.Title,
SortingName = g.SortTitle, Description = g.Description,
Version = g.Archives != null && g.Archives.Count() > 0 ? g.Archives.OrderByDescending(a => a.CreatedOn).FirstOrDefault().Version : null, GameId = g.Id.ToString(),
}); ReleaseDate = new ReleaseDate(g.ReleasedOn),
SortingName = g.SortTitle,
Version = g.Archives != null && g.Archives.Count() > 0 ? g.Archives.OrderByDescending(a => a.CreatedOn).FirstOrDefault().Version : null,
});
return games; return games;
}
catch
{
return new List<GameMetadata>();
}
} }
public override ISettings GetSettings(bool firstRunSettings) public override ISettings GetSettings(bool firstRunSettings)
{ {
return base.GetSettings(firstRunSettings); return Settings;
} }
public override UserControl GetSettingsView(bool firstRunView) public override UserControl GetSettingsView(bool firstRunView)
{ {
return base.GetSettingsView(firstRunView); return new PlayniteSettingsView(this);
}
public void ShowAuthenticationWindow()
{
var window = PlayniteApi.Dialogs.CreateWindow(new WindowCreationOptions()
{
ShowMinimizeButton = false,
});
window.Title = "Authenticate to LANCommander";
window.Content = new PlayniteSettingsView(this);
window.Owner = PlayniteApi.Dialogs.GetCurrentAppWindow();
window.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;
window.ShowDialog();
} }
} }
} }

View File

@ -8,44 +8,44 @@ using System.Threading.Tasks;
namespace LANCommander.Playnite.Extension namespace LANCommander.Playnite.Extension
{ {
public class PlayniteSettings : ObservableObject public class PlayniteSettingsViewModel : ObservableObject, ISettings
{
private string Option1 = String.Empty;
private bool Option2 = false;
private bool OptionThatWontBeSaved = false;
}
public class SettingsViewModel : ObservableObject, ISettings
{ {
private readonly PlayniteLibraryPlugin Plugin; private readonly PlayniteLibraryPlugin Plugin;
private PlayniteSettings EditingClone { get; set; }
private PlayniteSettings Settings { get; set; }
public SettingsViewModel(PlayniteLibraryPlugin plugin) public string ServerUrl { get; set; } = String.Empty;
public string AccessToken { get; set; } = String.Empty;
public string RefreshToken { get; set; } = String.Empty;
public PlayniteSettingsViewModel()
{
}
public PlayniteSettingsViewModel(PlayniteLibraryPlugin plugin)
{ {
Plugin = plugin; Plugin = plugin;
var savedSettings = Plugin.LoadPluginSettings<PlayniteSettings>(); var savedSettings = Plugin.LoadPluginSettings<PlayniteSettingsViewModel>();
if (savedSettings != null) if (savedSettings != null)
Settings = savedSettings; {
else ServerUrl = savedSettings.ServerUrl;
Settings = new PlayniteSettings(); }
} }
public void BeginEdit() public void BeginEdit()
{ {
EditingClone = Serialization.GetClone(Settings);
} }
public void CancelEdit() public void CancelEdit()
{ {
Settings = EditingClone;
} }
public void EndEdit() public void EndEdit()
{ {
Plugin.SavePluginSettings(Settings); Plugin.SavePluginSettings(this);
} }
public bool VerifySettings(out List<string> errors) public bool VerifySettings(out List<string> errors)

View File

@ -1,14 +1,21 @@
<UserControl x:Class="LANCommander.Playnite.Extension.PlayniteSettingsView" <UserControl x:Class="LANCommander.Playnite.Extension.PlayniteSettingsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" xmlns:sys="clr-namespace:System;assembly=mscorlib"
d:DesignHeight="400" d:DesignWidth="600"> mc:Ignorable="d"
<StackPanel> d:DesignHeight="400" d:DesignWidth="600">
<TextBlock Text="Description for Option1:"/> <d:DesignerProperties.DesignStyle>
<TextBox Text="{Binding Settings.Option1}"/> <Style TargetType="UserControl">
<Setter Property="Background" Value="White" />
</Style>
</d:DesignerProperties.DesignStyle>
<StackPanel Margin="20">
<TextBlock Text="LANCommander Server URL"/>
<TextBox Text="{Binding ServerUrl}"/>
<Button Click="AuthenticateButton_Click" Name="AuthenticateButton">Authenticate</Button>
<TextBlock Text="Description for Option2:"/> <TextBlock Text="Description for Option2:"/>
<CheckBox IsChecked="{Binding Settings.Option2}"/> <CheckBox IsChecked="{Binding Option2}"/>
</StackPanel> </StackPanel>
</UserControl> </UserControl>

View File

@ -1,4 +1,6 @@
using System; using LANCommander.SDK.Models;
using Playnite.SDK;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -17,9 +19,31 @@ namespace LANCommander.Playnite.Extension
{ {
public partial class PlayniteSettingsView : UserControl public partial class PlayniteSettingsView : UserControl
{ {
public PlayniteSettingsView() private PlayniteLibraryPlugin Plugin;
{
public PlayniteSettingsView(PlayniteLibraryPlugin plugin)
{
Plugin = plugin;
InitializeComponent();
var settings = Plugin.GetSettings(false) as PlayniteSettingsViewModel;
if (Plugin.LANCommander.ValidateToken(new AuthToken()
{
AccessToken = settings.AccessToken,
RefreshToken = settings.RefreshToken,
}))
{
var authenticateButton = FindName("AuthenticateButton") as Button;
authenticateButton.Visibility = Visibility.Hidden;
}
}
private void AuthenticateButton_Click(object sender, RoutedEventArgs e)
{
Plugin.ShowAuthenticationWindow();
} }
} }
} }

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace LANCommander.SDK.Models
{
public class AuthRequest
{
public string UserName { get; set; }
public string Password { get; set; }
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace LANCommander.SDK.Models
{
public class AuthResponse
{
public string AccessToken { get; set; }
public string RefreshToken { get; set; }
public DateTime Expiration { get; set; }
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace LANCommander.SDK.Models
{
public class AuthToken
{
public string AccessToken { get; set; }
public string RefreshToken { get; set; }
}
}