mirror of
https://github.com/openziti/desktop-edge-win.git
synced 2026-10-12 15:58:34 +00:00
413 lines
16 KiB
C#
413 lines
16 KiB
C#
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Input;
|
|
using System.Diagnostics;
|
|
using System;
|
|
using System.Reflection;
|
|
using System.Net.Mail;
|
|
using System.IO;
|
|
using System.Net;
|
|
using Newtonsoft.Json.Linq;
|
|
using ZitiDesktopEdge.ServiceClient;
|
|
|
|
using NLog;
|
|
using ZitiDesktopEdge.DataStructures;
|
|
using ZitiDesktopEdge.Native;
|
|
using System.Configuration;
|
|
|
|
namespace ZitiDesktopEdge
|
|
{
|
|
/// <summary>
|
|
/// Interaction logic for MainMenu.xaml
|
|
/// </summary>
|
|
public partial class MainMenu : UserControl {
|
|
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
|
|
|
public delegate void AttachementChanged(bool attached);
|
|
public event AttachementChanged OnAttachmentChange;
|
|
public delegate void LogLevelChanged(string level);
|
|
public event LogLevelChanged OnLogLevelChanged;
|
|
public delegate void Detched(MouseButtonEventArgs e);
|
|
public event Detched OnDetach;
|
|
public string menuState = "Main";
|
|
public string licenseData = "it's open source.";
|
|
public string LogLevel = "";
|
|
private string appVersion = null;
|
|
private bool allowReleaseSelect = false;
|
|
|
|
private bool isBeta {
|
|
get {
|
|
return Application.Current.Properties["ReleaseStream"].ToString() == "beta";
|
|
}
|
|
}
|
|
|
|
public MainMenu() {
|
|
InitializeComponent();
|
|
|
|
try {
|
|
allowReleaseSelect = bool.Parse(ConfigurationManager.AppSettings.Get("ReleaseStreamSelect"));
|
|
} catch {
|
|
//if we can't parse the config - leave it as false...
|
|
allowReleaseSelect = false; //setting it here in case anyone changes the default above
|
|
}
|
|
#if DEBUG
|
|
Debug.WriteLine("OVERRIDING allowReleaseSelect to true!");
|
|
allowReleaseSelect = true;
|
|
#endif
|
|
appVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
|
|
LicensesItems.Text = licenseData;
|
|
// don't check from the UI any more... CheckUpdates();
|
|
}
|
|
|
|
private void HideMenu(object sender, MouseButtonEventArgs e) {
|
|
menuState = "Menu";
|
|
UpdateState();
|
|
MainMenuArea.Visibility = Visibility.Collapsed;
|
|
}
|
|
private void Window_MouseDown(object sender, MouseButtonEventArgs e) {
|
|
if (e.ChangedButton == MouseButton.Left) {
|
|
OnDetach(e);
|
|
}
|
|
}
|
|
|
|
private void CloseApp(object sender, MouseButtonEventArgs e) {
|
|
Application.Current.Shutdown();
|
|
}
|
|
|
|
private void ShowAbout(object sender, MouseButtonEventArgs e) {
|
|
menuState = "About";
|
|
UpdateState();
|
|
}
|
|
|
|
private void ShowAdvanced(object sender, MouseButtonEventArgs e) {
|
|
menuState = "Advanced";
|
|
UpdateState();
|
|
}
|
|
private void ShowLicenses(object sender, MouseButtonEventArgs e) {
|
|
menuState = "Licenses";
|
|
UpdateState();
|
|
}
|
|
private void ShowConfig(object sender, MouseButtonEventArgs e) {
|
|
menuState = "Config";
|
|
UpdateState();
|
|
}
|
|
private void ShowLogs(object sender, MouseButtonEventArgs e) {
|
|
menuState = "Logs";
|
|
UpdateState();
|
|
}
|
|
private void ShowUILogs(object sender, MouseButtonEventArgs e) {
|
|
menuState = "UILogs";
|
|
UpdateState();
|
|
}
|
|
private void ShowReleaseStreamMenuAction(object sender, MouseButtonEventArgs e) {
|
|
logger.Warn("this is ShowReleaseStreamMenuAction at warn");
|
|
logger.Info("this is ShowReleaseStreamMenuAction at info");
|
|
logger.Debug("this is ShowReleaseStreamMenuAction at debug");
|
|
logger.Trace("this is ShowReleaseStreamMenuAction at trace");
|
|
menuState = "SetReleaseStream";
|
|
UpdateState();
|
|
}
|
|
|
|
async private void SetReleaseStreamMenuAction(object sender, MouseButtonEventArgs e) {
|
|
CheckForUpdateStatus.Visibility = Visibility.Collapsed;
|
|
TriggerUpdateButton.Visibility = Visibility.Collapsed;
|
|
SubOptionItem opt = (SubOptionItem)sender;
|
|
var monitorClient = (MonitorClient)Application.Current.Properties["MonitorClient"];
|
|
menuState = "SetReleaseStream";
|
|
|
|
bool releaseClicked = opt.Label.ToLower() == "stable";
|
|
|
|
if (releaseClicked) {
|
|
if (isBeta) {
|
|
//toggle to stable
|
|
var r = await monitorClient.SetReleaseStreamAsync("stable");
|
|
checkResponse(r);
|
|
} else {
|
|
logger.Debug("stable clicked but already on stable stream");
|
|
}
|
|
} else {
|
|
if (!isBeta) {
|
|
//toggle to beta
|
|
var r = await monitorClient.SetReleaseStreamAsync("beta");
|
|
checkResponse(r);
|
|
} else {
|
|
logger.Debug("beta clicked but already on beta stream");
|
|
}
|
|
}
|
|
Application.Current.Properties["ReleaseStream"] = opt.Label.ToLower();
|
|
UpdateState();
|
|
}
|
|
|
|
private void checkResponse(SvcResponse r) {
|
|
logger.Info(r.ToString());
|
|
}
|
|
|
|
private void SetLogLevel(object sender, MouseButtonEventArgs e) {
|
|
menuState = "LogLevel";
|
|
UpdateState();
|
|
}
|
|
|
|
private void UpdateState() {
|
|
MainItems.Visibility = Visibility.Collapsed;
|
|
AboutItems.Visibility = Visibility.Collapsed;
|
|
MainItemsButton.Visibility = Visibility.Collapsed;
|
|
AboutItemsArea.Visibility = Visibility.Collapsed;
|
|
BackArrow.Visibility = Visibility.Collapsed;
|
|
AdvancedItems.Visibility = Visibility.Collapsed;
|
|
LicensesItems.Visibility = Visibility.Collapsed;
|
|
LogsItems.Visibility = Visibility.Collapsed;
|
|
ConfigItems.Visibility = Visibility.Collapsed;
|
|
LogLevelItems.Visibility = Visibility.Collapsed;
|
|
ReleaseStreamItems.Visibility = Visibility.Collapsed;
|
|
|
|
if (menuState == "About") {
|
|
MenuTitle.Content = "About";
|
|
AboutItemsArea.Visibility = Visibility.Visible;
|
|
AboutItems.Visibility = Visibility.Visible;
|
|
BackArrow.Visibility = Visibility.Visible;
|
|
|
|
string version = "";
|
|
try {
|
|
TunnelStatus s = (TunnelStatus)Application.Current.Properties["CurrentTunnelStatus"];
|
|
version = $"{s.ServiceVersion.Version}@{s.ServiceVersion.Revision}";
|
|
} catch (Exception e) {
|
|
logger.Warn(e, "Could not get service version/revision?");
|
|
}
|
|
|
|
// Interface Version
|
|
VersionInfo.Content = $"App: {appVersion} Service: {version}";
|
|
|
|
} else if (menuState == "Advanced") {
|
|
MenuTitle.Content = "Advanced Settings";
|
|
AdvancedItems.Visibility = Visibility.Visible;
|
|
BackArrow.Visibility = Visibility.Visible;
|
|
ShowReleaseStreamMenuItem.Visibility = allowReleaseSelect ? Visibility.Visible : Visibility.Collapsed;
|
|
} else if (menuState == "Licenses") {
|
|
MenuTitle.Content = "Third Party Licenses";
|
|
LicensesItems.Visibility = Visibility.Visible;
|
|
BackArrow.Visibility = Visibility.Visible;
|
|
} else if (menuState == "Logs") {
|
|
MenuTitle.Content = "Advanced Settings";
|
|
AdvancedItems.Visibility = Visibility.Visible;
|
|
//string targetFile = NativeMethods.GetFinalPathName(MainWindow.ExpectedLogPathServices);
|
|
string targetFile = MainWindow.ExpectedLogPathServices;
|
|
|
|
OpenLogFile("service", targetFile);
|
|
OpenLogFile("UI", MainWindow.ExpectedLogPathUI);
|
|
BackArrow.Visibility = Visibility.Visible;
|
|
} else if (menuState == "UILogs") {
|
|
MenuTitle.Content = "Advanced Settings";
|
|
AdvancedItems.Visibility = Visibility.Visible;
|
|
OpenLogFile("UI", MainWindow.ExpectedLogPathUI);
|
|
BackArrow.Visibility = Visibility.Visible;
|
|
} else if (menuState == "LogLevel") {
|
|
ResetLevels();
|
|
|
|
MenuTitle.Content = "Set Log Level";
|
|
LogLevelItems.Visibility = Visibility.Visible;
|
|
BackArrow.Visibility = Visibility.Visible;
|
|
} else if (menuState == "SetReleaseStream") {
|
|
SetReleaseStream();
|
|
|
|
MenuTitle.Content = "Set Release Stream";
|
|
ReleaseStreamItems.Visibility = allowReleaseSelect ? Visibility.Visible : Visibility.Collapsed;
|
|
BackArrow.Visibility = Visibility.Visible;
|
|
//xxxxxxxx
|
|
} else if (menuState == "Config") {
|
|
MenuTitle.Content = "Tunnel Configuration";
|
|
ConfigItems.Visibility = Visibility.Visible;
|
|
BackArrow.Visibility = Visibility.Visible;
|
|
|
|
ConfigIp.Value = Application.Current.Properties["ip"]?.ToString();
|
|
ConfigSubnet.Value = Application.Current.Properties["subnet"]?.ToString();
|
|
ConfigMtu.Value = Application.Current.Properties["mtu"]?.ToString();
|
|
ConfigDns.Value = Application.Current.Properties["dns"]?.ToString();
|
|
} else {
|
|
MenuTitle.Content = "Main Menu";
|
|
MainItems.Visibility = Visibility.Visible;
|
|
MainItemsButton.Visibility = Visibility.Visible;
|
|
ReleaseStreamItems.Visibility = Visibility.Collapsed;
|
|
}
|
|
}
|
|
|
|
private void OpenLogFile(string which, string logFile) {
|
|
var whichRoot = Path.Combine(MainWindow.ExpectedLogPathRoot, which);
|
|
try {
|
|
string target = NativeMethods.GetFinalPathName(logFile);
|
|
if (File.Exists(target)) {
|
|
logger.Info("opening {0} logs at: {1}", which, target);
|
|
var p = Process.Start(new ProcessStartInfo(target) { UseShellExecute = true });
|
|
if (p != null) {
|
|
logger.Info("showing {0} logs. file: {1}", which, target);
|
|
} else {
|
|
Process.Start(whichRoot);
|
|
}
|
|
return;
|
|
} else {
|
|
logger.Warn("could not show {0} logs. file not found: {1}", which, target);
|
|
}
|
|
} catch {
|
|
}
|
|
Process.Start(whichRoot);
|
|
}
|
|
|
|
private void GoBack(object sender, MouseButtonEventArgs e) {
|
|
if (menuState == "Config" || menuState == "LogLevel" || menuState == "UILogs" || menuState == "SetReleaseStream") {
|
|
menuState = "Advanced";
|
|
} else if (menuState == "Licenses") {
|
|
menuState = "About";
|
|
} else {
|
|
menuState = "Menu";
|
|
}
|
|
UpdateState();
|
|
}
|
|
private void ShowPrivacy(object sender, MouseButtonEventArgs e) {
|
|
Process.Start(new ProcessStartInfo("https://netfoundry.io/privacy") { UseShellExecute = true });
|
|
}
|
|
private void ShowTerms(object sender, MouseButtonEventArgs e) {
|
|
Process.Start(new ProcessStartInfo("https://netfoundry.io/terms") { UseShellExecute = true });
|
|
}
|
|
|
|
async private void ShowFeedback(object sender, MouseButtonEventArgs e) {
|
|
DataClient client = (DataClient)Application.Current.Properties["ServiceClient"];
|
|
var mailMessage = new MailMessage("ziti-support@netfoundry.io", "ziti-support@netfoundry.io");
|
|
mailMessage.Subject = "Ziti Support";
|
|
mailMessage.IsBodyHtml = false;
|
|
System.Text.StringBuilder sb = new System.Text.StringBuilder();
|
|
sb.Append("Logs collected at : " + DateTime.Now.ToString());
|
|
sb.Append(". client version : " + appVersion);
|
|
|
|
mailMessage.Body = sb.ToString();
|
|
|
|
string timestamp = DateTime.Now.ToFileTime().ToString();
|
|
var monitorClient = (MonitorClient)Application.Current.Properties["MonitorClient"];
|
|
MonitorServiceStatusEvent resp = await monitorClient.CaptureLogsAsync();
|
|
string pathToLogs = resp.Message;
|
|
logger.Info("Log files found at : {0}", resp.Message);
|
|
mailMessage.Attachments.Add(new Attachment(pathToLogs));
|
|
|
|
string emlFile = Path.Combine(Path.GetTempPath(), timestamp + "-ziti.eml");
|
|
|
|
using (var filestream = File.Open(emlFile, FileMode.Create)) {
|
|
var binaryWriter = new BinaryWriter(filestream);
|
|
binaryWriter.Write(System.Text.Encoding.UTF8.GetBytes("X-Unsent: 1" + Environment.NewLine));
|
|
var assembly = typeof(SmtpClient).Assembly;
|
|
var mailWriterType = assembly.GetType("System.Net.Mail.MailWriter");
|
|
var mailWriterContructor = mailWriterType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(Stream) }, null);
|
|
var mailWriter = mailWriterContructor.Invoke(new object[] { filestream });
|
|
var sendMethod = typeof(MailMessage).GetMethod("Send", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
sendMethod.Invoke(mailMessage, BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { mailWriter, true, true }, null);
|
|
var closeMethod = mailWriter.GetType().GetMethod("Close", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
closeMethod.Invoke(mailWriter, BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { }, null);
|
|
}
|
|
|
|
var p = Process.Start(emlFile);
|
|
p.Exited += (object lambdaSender, EventArgs lambdaEventArgs) => {
|
|
logger.Info("Removing temp file: {0}", emlFile);
|
|
File.Delete(emlFile);
|
|
};
|
|
p.EnableRaisingEvents = true;
|
|
}
|
|
|
|
private void ShowSupport(object sender, MouseButtonEventArgs e) {
|
|
Process.Start(new ProcessStartInfo("https://openziti.discourse.group/") { UseShellExecute = true });
|
|
}
|
|
|
|
private void DetachWindow(object sender, MouseButtonEventArgs e) {
|
|
Application.Current.MainWindow.ShowInTaskbar = true;
|
|
DetachButton.Visibility = Visibility.Collapsed;
|
|
AttachButton.Visibility = Visibility.Visible;
|
|
Arrow.Visibility = Visibility.Collapsed;
|
|
if (OnAttachmentChange != null) {
|
|
OnAttachmentChange(false);
|
|
}
|
|
MainMenuArea.Visibility = Visibility.Collapsed;
|
|
}
|
|
|
|
public void Detach() {
|
|
Application.Current.MainWindow.ShowInTaskbar = true;
|
|
DetachButton.Visibility = Visibility.Collapsed;
|
|
AttachButton.Visibility = Visibility.Visible;
|
|
Arrow.Visibility = Visibility.Collapsed;
|
|
}
|
|
private void RetachWindow(object sender, MouseButtonEventArgs e) {
|
|
Application.Current.MainWindow.ShowInTaskbar = false;
|
|
DetachButton.Visibility = Visibility.Visible;
|
|
AttachButton.Visibility = Visibility.Collapsed;
|
|
Arrow.Visibility = Visibility.Visible;
|
|
if (OnAttachmentChange != null) {
|
|
OnAttachmentChange(true);
|
|
}
|
|
}
|
|
|
|
private void ResetLevels() {
|
|
if (this.LogLevel == "") this.LogLevel = "error";
|
|
LogVerbose.IsSelected = false;
|
|
LogDebug.IsSelected = false;
|
|
LogInfo.IsSelected = false;
|
|
LogError.IsSelected = false;
|
|
LogFatal.IsSelected = false;
|
|
LogWarn.IsSelected = false;
|
|
LogTrace.IsSelected = false;
|
|
if (this.LogLevel == "verbose") LogVerbose.IsSelected = true;
|
|
else if (this.LogLevel == "debug") LogDebug.IsSelected = true;
|
|
else if (this.LogLevel == "info") LogInfo.IsSelected = true;
|
|
else if (this.LogLevel == "error") LogError.IsSelected = true;
|
|
else if (this.LogLevel == "fatal") LogFatal.IsSelected = true;
|
|
else if (this.LogLevel == "warn") LogWarn.IsSelected = true;
|
|
else if (this.LogLevel == "trace") LogTrace.IsSelected = true;
|
|
}
|
|
|
|
private void SetLevel(object sender, MouseButtonEventArgs e) {
|
|
SubOptionItem item = (SubOptionItem)sender;
|
|
this.LogLevel = item.Label.ToLower();
|
|
if (OnLogLevelChanged != null) {
|
|
OnLogLevelChanged(this.LogLevel);
|
|
}
|
|
ResetLevels();
|
|
}
|
|
|
|
private void SetReleaseStream() {
|
|
this.ReleaseStreamItemBeta.IsSelected = isBeta;
|
|
this.ReleaseStreamItemStable.IsSelected = !isBeta;
|
|
}
|
|
|
|
async private void CheckForUpdate_Click(object sender, RoutedEventArgs e) {
|
|
logger.Info("checking for update...");
|
|
try {
|
|
CheckForUpdate.IsEnabled = false;
|
|
CheckForUpdateStatus.Content = "Checking for update...";
|
|
CheckForUpdateStatus.Visibility = Visibility.Visible;
|
|
var monitorClient = (MonitorClient)Application.Current.Properties["MonitorClient"];
|
|
var r = await monitorClient.DoUpdateCheck();
|
|
checkResponse(r);
|
|
CheckForUpdateStatus.Content = r.Message;
|
|
if (r.UpdateAvailable) {
|
|
TriggerUpdateButton.Visibility = Visibility.Visible;
|
|
} else {
|
|
TriggerUpdateButton.Visibility = Visibility.Collapsed;
|
|
}
|
|
} catch (Exception ex) {
|
|
logger.Error(ex, "unexpected error in update check: {0}", ex.Message);
|
|
}
|
|
CheckForUpdate.IsEnabled = true;
|
|
}
|
|
|
|
async private void TriggerUpdate_Click(object sender, RoutedEventArgs e) {
|
|
try {
|
|
CheckForUpdate.IsEnabled = false;
|
|
TriggerUpdateButton.IsEnabled = false;
|
|
CheckForUpdateStatus.Content = "Requesting automatic update...";
|
|
var monitorClient = (MonitorClient)Application.Current.Properties["MonitorClient"];
|
|
var r = await monitorClient.TriggerUpdate();
|
|
CheckForUpdateStatus.Content = "Automatic update requested...";
|
|
checkResponse(r);
|
|
} catch (Exception ex) {
|
|
logger.Error(ex, "unexpected error in update check: {0}", ex.Message);
|
|
}
|
|
TriggerUpdateButton.IsEnabled = true;
|
|
CheckForUpdate.IsEnabled = true;
|
|
}
|
|
}
|
|
}
|