using H.Pipes;
using InABox.Core;
using InABox.DynamicGrid;
using InABox.Wpf.Editors;
using InABox.WPF;
using PRSServices;
using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using InABox.Clients;
using InABox.Rpc;
using PRSServer;
using Comal.Classes;
using InABox.Wpf;
using Microsoft.Win32;
using PRS.Shared;
namespace PRSLicensing;
public class LicenseEditData : BaseObject
{
[EditorSequence(1)]
public CustomerLink Customer { get; set; }
[EditorSequence(2)]
public DateTime ExpiryDate { get; set; }
[EditorSequence(3)]
public bool IsDynamic { get; set; }
}
///
/// Interaction logic for MainWindow.xaml
///
public partial class Console : Window, INotifyPropertyChanged
{
private LicensingConfiguration Settings { get; set; }
private Timer timer;
public event PropertyChangedEventHandler? PropertyChanged;
private bool _isRunning = false;
public bool IsRunning
{
get => _isRunning;
set
{
_isRunning = value;
OnPropertyChanged();
}
}
private bool _isInstalled = false;
public bool IsInstalled
{
get => _isInstalled;
set
{
_isInstalled = value;
OnPropertyChanged();
}
}
private bool _hasDbServer = false;
public bool HasDbServer
{
get => _hasDbServer;
set
{
_hasDbServer = value;
OnPropertyChanged();
}
}
private PipeClient? _client;
private Timer? RefreshTimer;
public Console()
{
InitializeComponent();
LoadSettings();
Progress.DisplayImage = PRSLicensing.Resources.splash_small.AsBitmapImage();
timer = new Timer(2000);
timer.Elapsed += Timer_Elapsed;
timer.AutoReset = true;
timer.Start();
}
private string GetUpdateLocation() => "https://prsdigital.com.au/updates/prs";
private string GetLatestVersion(string location) => Update.GetRemoteFile($"{location}/PreRelease/version.txt").Content;
private string GetReleaseNotes(string location)=> Update.GetRemoteFile($"{location}/Release Notes.txt").Content;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Title = Title = $"PRS Licensing (Release {CoreUtils.GetVersion()})";
var isUpdateAvailable = Update.CheckForUpdates(
GetUpdateLocation, GetLatestVersion, GetReleaseNotes, null, null, false, "");
RefreshStatus();
Progress.ShowModal("Registering Classes", progress =>
{
var tasks = new Task[]
{
Task.Run(() => CoreUtils.RegisterClasses()),
Task.Run(() => ComalUtils.RegisterClasses()),
Task.Run(() => DynamicGridUtils.RegisterClasses()),
};
Task.WaitAll(tasks.ToArray());
});
}
private void Timer_Elapsed(object? sender, ElapsedEventArgs e)
{
RefreshStatus();
}
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
_client?.DisposeAsync().AsTask().Wait();
_client = null;
RefreshTimer?.Stop();
}
private void RefreshStatus()
{
IsRunning = PRSServiceInstaller.IsRunning(Settings.GetServiceName());
IsInstalled = PRSServiceInstaller.IsInstalled(Settings.GetServiceName());
HasDbServer = !String.IsNullOrWhiteSpace(GetProperties().Server);
if(_client is null)
{
if (IsRunning)
{
CreateClient();
}
}
else if(_client.PipeName != GetPipeName())
{
_client.DisposeAsync().AsTask().Wait();
_client = null;
CreateClient();
}
}
private bool _creatingClient = false;
private void CreateClient()
{
if (_creatingClient) return;
_creatingClient = true;
var client = new PipeClient(GetPipeName(), ".");
client.MessageReceived += (o, args) =>
{
Dispatcher.BeginInvoke(() =>
{
ConsoleControl.LoadLogEntry(args.Message ?? "");
});
};
client.Connected += (o, args) =>
{
Dispatcher.BeginInvoke(() =>
{
ConsoleControl.Enabled = true;
});
};
client.Disconnected += (o, args) =>
{
Dispatcher.BeginInvoke(() =>
{
ConsoleControl.Enabled = false;
});
if (RefreshTimer == null)
{
RefreshTimer = new Timer(1000);
RefreshTimer.Elapsed += RefreshTimer_Elapsed;
}
RefreshTimer.Start();
};
client.ExceptionOccurred += (o, args) =>
{
};
if (!client.IsConnecting)
{
client.ConnectAsync();
}
_client = client;
_creatingClient = false;
}
private void RefreshTimer_Elapsed(object? sender, ElapsedEventArgs e)
{
if (_client is null) return;
if (!_client.IsConnected)
{
if (!_client.IsConnecting)
{
_client.ConnectAsync();
}
}
else
{
RefreshTimer?.Stop();
}
}
private string GetPipeName()
{
return Settings.GetServiceName();
}
private void LoadSettings()
{
Settings = PRSLicensingService.GetConfiguration().Load();
ServiceName.Content = Settings.ServiceName;
}
private void SaveSettings()
{
PRSLicensingService.GetConfiguration().Save(Settings);
}
private void Install()
{
var username = GetProperties().Username;
string? password = null;
if (!string.IsNullOrWhiteSpace(username))
{
var passwordEditor = new PasswordDialog(string.Format("Enter password for {0}", username));
if(passwordEditor.ShowDialog() == true)
{
password = passwordEditor.Password;
}
else
{
password = null;
}
}
else
{
username = null;
}
PRSServiceInstaller.InstallService(
Settings.GetServiceName(),
"PRS Licensing Service",
Settings.ServiceName,
username,
password);
}
private void InstallButton_Click(object sender, RoutedEventArgs e)
{
if (PRSServiceInstaller.IsInstalled(Settings.GetServiceName()))
{
Progress.ShowModal("Uninstalling Service", (progress) =>
{
PRSServiceInstaller.UninstallService(Settings.GetServiceName());
});
}
else
{
Progress.ShowModal("Installing Service", (progress) =>
{
Install();
});
}
RefreshStatus();
}
private void StartButton_Click(object sender, RoutedEventArgs e)
{
if (PRSServiceInstaller.IsRunning(Settings.GetServiceName()))
{
Progress.ShowModal("Stopping Service", (progress) =>
{
PRSServiceInstaller.StopService(Settings.GetServiceName());
});
}
else
{
Progress.ShowModal("Starting Service", (progress) =>
{
PRSServiceInstaller.StartService(Settings.GetServiceName());
});
}
RefreshStatus();
}
private LicensingEngineProperties GetProperties()
{
var properties = Serialization.Deserialize(Settings.Properties) ?? new LicensingEngineProperties();
properties.Name = Settings.ServiceName;
var tokens = CoreUtils.TypeList(x =>x.IsSubclassOf(typeof(LicenseToken)))
.OrderBy(x => x.EntityName().Split('.').Last())
.ToArray();
foreach (var token in tokens)
{
if (!properties.Mappings.Any(x => String.Equals(x.License, token.EntityName())))
properties.Mappings.Add(new LicenseProductMapping() { License = token.EntityName() });
}
return properties;
}
private bool CheckConnection()
{
var properties = GetProperties();
if (!String.IsNullOrWhiteSpace(properties.Server))
{
ClientFactory.SetClientType(
typeof(RpcClient<>),
Platform.LicensingEngine,
CoreUtils.GetVersion(),
new RpcClientPipeTransport(DatabaseServerProperties.GetPipeName(properties.Server, true))
);
if (Client.Ping())
{
ClientFactory.SetBypass();
return true;
}
}
return false;
}
private void EditButton_Click(object sender, RoutedEventArgs e)
{
var grid = new DynamicItemsListGrid();
grid.OnEditorLoaded += (editor, items) =>
{
var control = editor.FindEditor(nameof(LicensingEngineProperties.Mappings)) as ButtonEditorControl;
if (control != null)
{
control.OnClick += (o, args) =>
{
DynamicItemsListGrid mappinggrid =
new DynamicItemsListGrid();
mappinggrid.Items = items.First().Mappings;
DynamicGridUtils.CreateGridWindow("License Mappings", mappinggrid).ShowDialog();
};
}
};
Settings.CommitChanges();
var properties = GetProperties();
CheckConnection();
if(grid.EditItems(new LicensingEngineProperties[] { properties }))
{
Settings.Properties = Serialization.Serialize(properties);
Settings.ServiceName = properties.Name;
if (Settings.IsChanged())
{
if(Settings.HasOriginalValue(x => x.ServiceName) || properties.HasOriginalValue(x => x.Username))
{
var oldService = LicensingConfiguration.GetServiceName(Settings.GetOriginalValue(x => x.ServiceName));
if (PRSServiceInstaller.IsInstalled(oldService))
{
Progress.ShowModal("Modifying Service", (progress) =>
{
PRSServiceInstaller.UninstallService(oldService);
Install();
});
}
}
SaveSettings();
ServiceName.Content = Settings.ServiceName;
RefreshStatus();
}
}
}
protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private void GenerateButton_Click(object sender, RoutedEventArgs e)
{
if (!CheckConnection())
{
MessageWindow.ShowMessage("Unable to connect to Server", "Error");
return;
}
var ofd = new OpenFileDialog()
{
FileName = "license.request",
Filter = "Request Files (*.request)|*.request"
};
if (ofd.ShowDialog() == true && System.IO.File.Exists(ofd.FileName))
{
var text = System.IO.File.ReadAllText(ofd.FileName);
if (LicenseUtils.TryDecryptLicenseRequest(text, out var request, out var _))
{
var data = new LicenseEditData();
data.Customer.ID = request.CustomerID;
data.IsDynamic = request.IsDynamic;
var grid = new DynamicItemsListGrid();
grid.OnValidate += (o, items, errors) =>
{
if (items.Any(x => x.Customer.ID == Guid.Empty))
errors.Add("Customer may not be blank!");
if (items.Any(x => x.ExpiryDate <= DateTime.Today))
errors.Add("Expiry must be in the future!");
};
if (grid.EditItems(new LicenseEditData[] { data }))
{
var license = new LicenseData()
{
CustomerID = data.Customer.ID,
Expiry = data.ExpiryDate,
RenewalAvailable = data.ExpiryDate.AddMonths(-1),
LastRenewal = DateTime.Today,
Addresses = request.Addresses,
IsDynamic = data.IsDynamic
};
SaveFileDialog sfd = new SaveFileDialog()
{
FileName = "license.key"
};
if (sfd.ShowDialog() == true)
File.WriteAllText(sfd.FileName, LicenseUtils.EncryptLicense(license));
}
}
else
MessageWindow.ShowMessage("Invalid Request File","Error");
}
}
}