From 02a4a4e4b632274a67768fc566b5e593ccac4f72 Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Tue, 30 Jul 2024 06:57:08 -0400
Subject: [PATCH 01/50] if the tunneler goes down, it's notifying clients, not
the monitor service
---
ZitiUpdateService/UpdateService.cs | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/ZitiUpdateService/UpdateService.cs b/ZitiUpdateService/UpdateService.cs
index 9a675818d..36b8a6709 100644
--- a/ZitiUpdateService/UpdateService.cs
+++ b/ZitiUpdateService/UpdateService.cs
@@ -1009,16 +1009,6 @@ private void Svc_OnClientDisconnected(object sender, object e) {
if (svc.CleanShutdown) {
//then this is fine and expected - the service is shutting down
Logger.Info("client disconnected due to clean service shutdown");
-
- MonitorServiceStatusEvent status = new MonitorServiceStatusEvent() {
- Code = 0,
- Error = "SERVICE DOWN",
- Message = "SERVICE DOWN",
- Status = ServiceActions.ServiceStatus(),
- AutomaticUpgradeDisabled = CurrentSettings.AutomaticUpdatesDisabled.ToString(),
- AutomaticUpgradeURL = CurrentSettings.AutomaticUpdateURL,
- };
- EventRegistry.SendEventToConsumers(status);
} else {
Logger.Error("SERVICE IS DOWN and did not exit cleanly.");
From 4c4721d81744307f7f200b5c1328c41e6162eddc Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Tue, 30 Jul 2024 07:00:34 -0400
Subject: [PATCH 02/50] if the service crashes unexpectedly, issue a toast
---
DesktopEdge/MainWindow.xaml | 2 +-
DesktopEdge/MainWindow.xaml.cs | 31 +++++++++++++-
setup-mfa-test.ps1 | 75 +++++++++++++++++++++++++++++-----
3 files changed, 94 insertions(+), 14 deletions(-)
diff --git a/DesktopEdge/MainWindow.xaml b/DesktopEdge/MainWindow.xaml
index 1ea9e90a5..2995ddfdc 100644
--- a/DesktopEdge/MainWindow.xaml
+++ b/DesktopEdge/MainWindow.xaml
@@ -182,7 +182,7 @@
-
+
diff --git a/DesktopEdge/MainWindow.xaml.cs b/DesktopEdge/MainWindow.xaml.cs
index 9c806370b..e827a3612 100644
--- a/DesktopEdge/MainWindow.xaml.cs
+++ b/DesktopEdge/MainWindow.xaml.cs
@@ -479,6 +479,10 @@ private void ToastNotificationManagerCompat_OnActivated(ToastNotificationActivat
}
}
}
+
+ ToastArguments args = ToastArguments.Parse(e.Argument);
+ this.Show();
+ this.Activate();
});
}
@@ -828,6 +832,10 @@ private void MonitorClient_OnServiceStatusEvent(object sender, MonitorServiceSta
return;
}
SetAutomaticUpdateEnabled(evt.AutomaticUpgradeDisabled, evt.AutomaticUpgradeURL);
+ if(evt.Code != 0) {
+ logger.Error("CODE: " + evt.Code);
+ ShowToast($"The data channel has stopped unexpectedly. If this keeps happening please report an issue.");
+ }
MainMenu.ShowUpdateAvailable();
logger.Debug("MonitorClient_OnServiceStatusEvent: {0}", evt.Status);
Application.Current.Properties["ReleaseStream"] = evt.ReleaseStream;
@@ -935,9 +943,24 @@ private void ShowToast(string header, string message) {
try {
logger.Info("showing toast: {} {}", header, message);
new ToastContentBuilder()
+ .AddArgument("notbutton", "click")
.AddText(header)
.AddText(message)
- .SetBackgroundActivation()
+ .AddButton(new ToastButton()
+ .SetContent("Open Link")
+ .AddArgument("action", "openLink")
+ .AddArgument("action2", "openLink2")
+ )
+ .AddButton(new ToastButton()
+ .SetContent("Open Link2")
+ .AddArgument("btn2.a", "btn2.a.value")
+ .AddArgument("btn2.b", "btn2.b.value")
+ )
+ .AddButton(new ToastButton()
+ .SetContent("Open Link3")
+ .AddArgument("btn3.a", "btn3.a.value")
+ .AddArgument("btn3.b", "btn3.b.value")
+ )
.Show();
NotificationsShownCount++;
} catch {
@@ -1601,7 +1624,7 @@ async private void Disconnect(object sender, RoutedEventArgs e) {
try {
ShowLoad("Disabling Service", "Please wait for the service to stop.");
var r = await monitorClient.StopServiceAsync();
- if (r.Code != 0) {
+ if (r != null && r.Code != 0) {
logger.Warn("ERROR: Error:{0}, Message:{1}", r.Error, r.Message);
} else {
logger.Info("Service stopped!");
@@ -1809,6 +1832,10 @@ private void DoLoading(bool isComplete) {
if (isComplete) HideLoad();
else ShowLoad("Loading", "Please Wait.");
}
+
+ private void Label_MouseDoubleClick_1(object sender, MouseButtonEventArgs e) {
+ ShowToast("here's a toast all rightddd...");
+ }
}
public class ActionCommand : ICommand {
diff --git a/setup-mfa-test.ps1 b/setup-mfa-test.ps1
index bb2b67713..6104a68bf 100644
--- a/setup-mfa-test.ps1
+++ b/setup-mfa-test.ps1
@@ -13,7 +13,6 @@ if ("$env:CLEAR_IDENTITIES_OK" -ne "yes") {
Remove-Item C:\Windows\System32\config\systemprofile\AppData\Roaming\NetFoundry\mfa*.json
Remove-Item C:\Windows\System32\config\systemprofile\AppData\Roaming\NetFoundry\config*.json
Remove-Item "$env:APPDATA\NetFoundry\*.json"
-#copy C:\Users\clint\AppData\Roaming\NetFoundry\empty.config.json C:\Users\clint\AppData\Roaming\NetFoundry\config.json
echo "starting reset"
@@ -75,16 +74,6 @@ ziti edge verify ca $caName --cert $verificationCert
$authPolicy=(ziti edge create auth-policy yubi-mfa --primary-cert-allowed --secondary-req-totp --primary-cert-expired-allowed)
-$newUser="clint"
-ziti pki create client --pki-root "${zitiPkiRoot}" --ca-name "$caName" --client-file "$newUser" --client-name "$newUser"
-$newUserCert=(Get-ChildItem -Path $zitiPkiRoot -Filter "$newUser.cert" -Recurse).FullName
-$newUserKey=(Get-ChildItem -Path $zitiPkiRoot -Filter "$newUser.key" -Recurse).FullName
-ziti edge create identity $newUser --auth-policy "$authPolicy"
-ziti edge create enrollment ottca $newUser $caName
-
-$ottcajwt = (ziti edge list identities "name contains \""$newUser\""" -j | ConvertFrom-Json).data.enrollment.ottca.jwt
-Set-Content -Path "$newUser.jwt" -Value $ottcajwt -NoNewline -Encoding ASCII
-
$count = 0
$iterations = 10
for ($i = 0; $i -lt $iterations; $i++) {
@@ -162,6 +151,70 @@ ziti edge update service-policy "$name.svc.0.ziti.dial" --posture-check-roles "@
+$caName="3rd-party-ca-"+(Get-Date).ToString("yyyy-MM-dd-HH-mm-ss")
+clear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+$zitiUser="admin"
+$zitiPwd="admin"
+$zitiCtrl="localhost:1280"
+ziti edge login $zitiCtrl -u $zitiUser -p $zitiPwd -y
+
+$caName="my-ca"
+$newUser="$caName-user"
+$zitiPkiRoot="C:\temp\support\discourse\2790\$caName\pki"
+ziti pki create ca --pki-root "${zitiPkiRoot}" --ca-file "$caName"
+
+$rootCa=(Get-ChildItem -Path $zitiPkiRoot -Filter "$caName.cert" -Recurse).FullName
+"root ca path: $rootCa"
+
+ziti edge create ca "$caName" "$rootCa" --auth --ottca
+
+$verificationToken=((ziti edge list cas -j | ConvertFrom-Json).data | Where-Object { $_.name -eq $caName }[0]).verificationToken
+ziti pki create client --pki-root "${zitiPkiRoot}" --ca-name "$caName" --client-file "$verificationToken" --client-name "$verificationToken"
+
+$verificationCert=(Get-ChildItem -Path $zitiPkiRoot -Filter "$verificationToken.cert" -Recurse).FullName
+"verification cert path: $verificationCert"
+ziti edge verify ca $caName --cert $verificationCert
+
+
+$authPolicy=(ziti edge create auth-policy "$caName-auth-policy" --primary-cert-allowed --secondary-req-totp --primary-cert-expired-allowed)
+
+
+ziti pki create client --pki-root "${zitiPkiRoot}" --ca-name "$caName" --client-file "$newUser" --client-name "$newUser"
+
+$newUserCert=(Get-ChildItem -Path $zitiPkiRoot -Filter "$newUser.cert" -Recurse).FullName
+$newUserKey=(Get-ChildItem -Path $zitiPkiRoot -Filter "$newUser.key" -Recurse).FullName
+
+ziti edge create identity $newUser --auth-policy "$authPolicy"
+ziti edge create enrollment ottca $newUser $caName
+
+if ($PSVersionTable.PSVersion.Major -gt 5) { #powershell....
+ $ottcajwt = (ziti edge list identities "name contains ""$newUser""" -j | ConvertFrom-Json).data.enrollment.ottca.jwt
+} else {
+ $ottcajwt = (ziti edge list identities "name contains \""$newUser\""" -j | ConvertFrom-Json).data.enrollment.ottca.jwt
+}
+
+Set-Content -Path "$zitiPkiRoot\$newUser.jwt" -Value $ottcajwt -NoNewline -Encoding ASCII
+
+& 'C:\Program Files (x86)\NetFoundry Inc\Ziti Desktop Edge\ziti-edge-tunnel.exe' `
+ enroll `
+ --jwt "$zitiPkiRoot\$newUser.jwt" `
+ --cert $newUserCert `
+ --key $newUserKey `
+ --identity "C:\Windows\System32\config\systemprofile\AppData\Roaming\NetFoundry\${newUser}.json"
From 8ef647a8950c16ba1a4ec74d984118ca227d10b4 Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Tue, 30 Jul 2024 07:52:44 -0400
Subject: [PATCH 03/50] updates to allow alerts on unexpected app failure
---
DesktopEdge/App.config | 2 +-
DesktopEdge/MainWindow.xaml.cs | 47 +++++++++++-----------
DesktopEdge/Views/Screens/MainMenu.xaml | 2 +-
DesktopEdge/Views/Screens/MainMenu.xaml.cs | 18 +++------
Installer/build.ps1 | 2 +-
version | 2 +-
6 files changed, 33 insertions(+), 40 deletions(-)
diff --git a/DesktopEdge/App.config b/DesktopEdge/App.config
index a353d6d8d..37dfe4b8f 100644
--- a/DesktopEdge/App.config
+++ b/DesktopEdge/App.config
@@ -1,7 +1,7 @@
-
+
diff --git a/DesktopEdge/MainWindow.xaml.cs b/DesktopEdge/MainWindow.xaml.cs
index e827a3612..271709825 100644
--- a/DesktopEdge/MainWindow.xaml.cs
+++ b/DesktopEdge/MainWindow.xaml.cs
@@ -462,6 +462,10 @@ async private void MFASetup_OnError(string message) {
await ShowBlurbAsync(message, "", "error");
}
+ private static ToastButton feedbackToastButton = new ToastButton()
+ .SetContent("Click here to collect logs")
+ .AddArgument("action", "feedback");
+
private void ToastNotificationManagerCompat_OnActivated(ToastNotificationActivatedEventArgsCompat e) {
this.Dispatcher.Invoke(() => {
if (e.Argument != null && e.Argument.Length > 0) {
@@ -481,6 +485,12 @@ private void ToastNotificationManagerCompat_OnActivated(ToastNotificationActivat
}
ToastArguments args = ToastArguments.Parse(e.Argument);
+ string value = null;
+ if(args.TryGetValue("action", out value)) {
+ this.Dispatcher.Invoke(() => {
+ MainMenu.CollectFeedbackLogs(e, null);
+ });
+ }
this.Show();
this.Activate();
});
@@ -834,7 +844,9 @@ private void MonitorClient_OnServiceStatusEvent(object sender, MonitorServiceSta
SetAutomaticUpdateEnabled(evt.AutomaticUpgradeDisabled, evt.AutomaticUpgradeURL);
if(evt.Code != 0) {
logger.Error("CODE: " + evt.Code);
- ShowToast($"The data channel has stopped unexpectedly. If this keeps happening please report an issue.");
+ if (MainMenu.ShowUnexpectedFailure) {
+ ShowToast("The data channel has stopped unexpectedly", $"If this keeps happening please collect logs and report the issue.", feedbackToastButton);
+ }
}
MainMenu.ShowUpdateAvailable();
logger.Debug("MonitorClient_OnServiceStatusEvent: {0}", evt.Status);
@@ -913,7 +925,7 @@ private void MonitorClient_OnInstallationNotificationEvent(object sender, Instal
}
}
} else {
- ShowToast("New version available", $"Version {evt.ZDEVersion} is available for Ziti Desktop Edge");
+ ShowToast("New version available", $"Version {evt.ZDEVersion} is available for Ziti Desktop Edge", null);
}
SetNotifyIcon("");
// display a tag in UI and a button for the update software
@@ -939,37 +951,26 @@ private bool isToastEnabled() {
return result;
}
- private void ShowToast(string header, string message) {
+ private void ShowToast(string header, string message, ToastButton button) {
try {
- logger.Info("showing toast: {} {}", header, message);
- new ToastContentBuilder()
+ logger.Debug("showing toast: {} {}", header, message);
+ var builder = new ToastContentBuilder()
.AddArgument("notbutton", "click")
.AddText(header)
- .AddText(message)
- .AddButton(new ToastButton()
- .SetContent("Open Link")
- .AddArgument("action", "openLink")
- .AddArgument("action2", "openLink2")
- )
- .AddButton(new ToastButton()
- .SetContent("Open Link2")
- .AddArgument("btn2.a", "btn2.a.value")
- .AddArgument("btn2.b", "btn2.b.value")
- )
- .AddButton(new ToastButton()
- .SetContent("Open Link3")
- .AddArgument("btn3.a", "btn3.a.value")
- .AddArgument("btn3.b", "btn3.b.value")
- )
- .Show();
+ .AddText(message);
+ if (button != null) {
+ builder.AddButton(button);
+ }
+ builder.Show();
NotificationsShownCount++;
} catch {
logger.Warn("couldn't show toast: {} {}", header, message);
}
}
+
private void ShowToast(string message) {
- ShowToast("Important Notice", message);
+ ShowToast("Important Notice", message, null);
}
async private Task WaitForServiceToStop(DateTime until) {
diff --git a/DesktopEdge/Views/Screens/MainMenu.xaml b/DesktopEdge/Views/Screens/MainMenu.xaml
index 2e4e7ff89..4d20a3315 100644
--- a/DesktopEdge/Views/Screens/MainMenu.xaml
+++ b/DesktopEdge/Views/Screens/MainMenu.xaml
@@ -44,7 +44,7 @@
-
+
diff --git a/DesktopEdge/Views/Screens/MainMenu.xaml.cs b/DesktopEdge/Views/Screens/MainMenu.xaml.cs
index 75bc8e557..999e39856 100644
--- a/DesktopEdge/Views/Screens/MainMenu.xaml.cs
+++ b/DesktopEdge/Views/Screens/MainMenu.xaml.cs
@@ -53,16 +53,11 @@ public partial class MainMenu : UserControl {
public string licenseData = "it's open source.";
public string LogLevel = "";
private string appVersion = null;
- private bool allowReleaseSelect = false;
public double MainHeight = 500;
private ZDEWViewState state;
- private bool isBeta {
- get {
- return Application.Current.Properties["ReleaseStream"]?.ToString() == "beta";
- }
- }
+ public bool ShowUnexpectedFailure { get; set; }
public void ShowUpdateAvailable() {
if (state.UpdateAvailable) {
@@ -90,15 +85,12 @@ public MainMenu() {
state = (ZDEWViewState)Application.Current.Properties["ZDEWViewState"];
try {
- allowReleaseSelect = bool.Parse(ConfigurationManager.AppSettings.Get("ReleaseStreamSelect"));
+ ShowUnexpectedFailure = bool.Parse(ConfigurationManager.AppSettings.Get("ShowUnexpectedFailure"));
} catch {
//if we can't parse the config - leave it as false...
- allowReleaseSelect = false; //setting it here in case anyone changes the default above
+ ShowUnexpectedFailure = 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();
@@ -323,7 +315,7 @@ 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) {
+ async public void CollectFeedbackLogs(object sender, MouseButtonEventArgs e) {
try {
MainWindow.ShowLoad("Collecting Information", "Please wait while we run some commands\nand collect some diagnostic information");
diff --git a/Installer/build.ps1 b/Installer/build.ps1
index 73d04a359..b8680ce29 100644
--- a/Installer/build.ps1
+++ b/Installer/build.ps1
@@ -18,7 +18,7 @@ $ADV_INST_HOME = "C:\Program Files (x86)\Caphyon\Advanced Installer ${ADV_INST_V
$SIGNTOOL="${ADV_INST_HOME}\third-party\winsdk\x64\signtool.exe"
$ADVINST = "${ADV_INST_HOME}\bin\x86\AdvancedInstaller.com"
$ADVPROJECT = "${scriptPath}\ZitiDesktopEdge.aip"
-$ZITI_EDGE_TUNNEL_VERSION="v2.0.0-alpha10"
+$ZITI_EDGE_TUNNEL_VERSION="v2.0.0-alpha11"
echo "Cleaning previous build folder if it exists"
Remove-Item "${buildPath}" -r -ErrorAction Ignore
diff --git a/version b/version
index 4dae5f4ab..2501d5d1b 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-2.5.0.2
+2.5.0.3
From bdb08fdbb2af4d62dabbb89b629ba69abdc04d62 Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Tue, 30 Jul 2024 07:54:08 -0400
Subject: [PATCH 04/50] remove unexpected event
---
DesktopEdge/MainWindow.xaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/DesktopEdge/MainWindow.xaml b/DesktopEdge/MainWindow.xaml
index 2995ddfdc..1ea9e90a5 100644
--- a/DesktopEdge/MainWindow.xaml
+++ b/DesktopEdge/MainWindow.xaml
@@ -182,7 +182,7 @@
-
+
From 54ae26e1b04776ba1e28a51a2810abc64e246c1e Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Tue, 30 Jul 2024 07:58:30 -0400
Subject: [PATCH 05/50] update release notes
---
release-notes.md | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/release-notes.md b/release-notes.md
index 5d7990080..9543a1d83 100644
--- a/release-notes.md
+++ b/release-notes.md
@@ -1,3 +1,17 @@
+# Release 2.5.0.3
+
+## What's New
+* none
+
+## Other changes:
+* added debug option to show when the data channel closes unexpectedly
+
+## Bugs fixed:
+* n/a
+
+## Dependency Updates
+* ziti-tunnel-sdk-c v2.0.0-alpha11/c sdk 2.0.0-alpha8
+
# Release 2.5.0.2
## What's New
From 88eb98c1b075fe7557ec37735869c5ad33bcc179 Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Tue, 30 Jul 2024 13:54:33 -0400
Subject: [PATCH 06/50] add 2.5.0.3 alpha
---
release-streams/ctrlha-alpha.json | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/release-streams/ctrlha-alpha.json b/release-streams/ctrlha-alpha.json
index b4abcaec4..299504643 100644
--- a/release-streams/ctrlha-alpha.json
+++ b/release-streams/ctrlha-alpha.json
@@ -1,12 +1,12 @@
{
- "name": "2.5.0.2",
- "tag_name": "2.5.0.2",
- "published_at": "2024-07-25T11:10:53Z",
+ "name": "2.5.0.3",
+ "tag_name": "2.5.0.3",
+ "published_at": "2024-07-30T14:53:31Z",
"installation_critical": false,
"assets": [
{
- "name": "Ziti.Desktop.Edge.Client-2.5.0.2.exe",
- "browser_download_url": "https://github.com/openziti/desktop-edge-win/releases/download/2.5.0.0-alpha/Ziti.Desktop.Edge.Client-2.5.0.2.exe"
+ "name": "Ziti.Desktop.Edge.Client-2.5.0.3.exe",
+ "browser_download_url": "https://github.com/openziti/desktop-edge-win/releases/download/2.5.0.3-alpha/Ziti.Desktop.Edge.Client-2.5.0.3.exe"
}
]
}
From 90e0e3b37595c169c7babd410f903b55f97a66f8 Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Tue, 13 Aug 2024 08:04:53 -0400
Subject: [PATCH 07/50] remove unneeded active boolean from tunnel status
---
DesktopEdge/MainWindow.xaml.cs | 7 ++-----
.../DataStructures/DataStructures.cs | 3 ---
build-test-release.ps1 | 17 ++++++++++-------
3 files changed, 12 insertions(+), 15 deletions(-)
diff --git a/DesktopEdge/MainWindow.xaml.cs b/DesktopEdge/MainWindow.xaml.cs
index 271709825..0c4431247 100644
--- a/DesktopEdge/MainWindow.xaml.cs
+++ b/DesktopEdge/MainWindow.xaml.cs
@@ -1287,11 +1287,6 @@ private void LoadStatusFromService(TunnelStatus status) {
_isServiceInError = false;
UpdateServiceView();
NoServiceView.Visibility = Visibility.Collapsed;
- if (status.Active) {
- SetNotifyIcon("green");
- } else {
- SetNotifyIcon("white");
- }
if (!Application.Current.Properties.Contains("ip")) {
Application.Current.Properties.Add("ip", status?.IpInfo?.Ip);
} else {
@@ -1468,6 +1463,7 @@ private void TunnelConnected(bool isConnected) {
DisconnectButton.Visibility = Visibility.Visible;
MainMenu.Connected();
HideLoad();
+ SetNotifyIcon("green");
} else {
ConnectButton.Visibility = Visibility.Visible;
DisconnectButton.Visibility = Visibility.Collapsed;
@@ -1477,6 +1473,7 @@ private void TunnelConnected(bool isConnected) {
MainMenu.Disconnected();
DownloadSpeed.Content = "0.0";
UploadSpeed.Content = "0.0";
+ SetNotifyIcon("white");
}
});
}
diff --git a/ZitiDesktopEdge.Client/DataStructures/DataStructures.cs b/ZitiDesktopEdge.Client/DataStructures/DataStructures.cs
index 30e7254d4..02ec3a58c 100644
--- a/ZitiDesktopEdge.Client/DataStructures/DataStructures.cs
+++ b/ZitiDesktopEdge.Client/DataStructures/DataStructures.cs
@@ -380,8 +380,6 @@ public class ZitiTunnelStatus : SvcResponse
public class TunnelStatus
{
- public bool Active { get; set; }
-
public long Duration { get; set; }
public List Identities { get; set; }
@@ -397,7 +395,6 @@ public class TunnelStatus
public void Dump(System.IO.TextWriter writer)
{
try {
- writer.WriteLine($"Tunnel Active: {Active}");
writer.WriteLine($" LogLevel : {LogLevel}");
writer.WriteLine($" EvaluatedLogLevel: {EvaluateLogLevel()}");
foreach (Identity id in Identities) {
diff --git a/build-test-release.ps1 b/build-test-release.ps1
index 69e32f3fa..48ff24219 100644
--- a/build-test-release.ps1
+++ b/build-test-release.ps1
@@ -12,13 +12,19 @@ param(
[string]$stream = "beta",
[datetime]$published_at = (Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ"),
[bool]$jsonOnly = $false,
- [bool]$revertGitAfter = $false
+ [bool]$revertGitAfter = $true
)
echo ""
$env:ZITI_DESKTOP_EDGE_DOWNLOAD_URL="$url"
$env:ZITI_DESKTOP_EDGE_VERSION="$version"
$scriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Path -Parent
+$outputPath = "${version}.json"
+& .\Installer\output-build-json.ps1 -version $version -url $url -stream $stream -published_at $published_at -outputPath $outputPath
+Copy-Item -Force "$outputPath" "$scriptDirectory\release-streams\local\${version}"
+Copy-Item -Force "${version}.json" "$scriptDirectory\release-streams\${stream}.json"
+echo "json file written to: $scriptDirectory\release-streams\${stream}.json"
+
if(! $jsonOnly) {
$scriptToExecute = Join-Path -Path $scriptDirectory -ChildPath "Installer\build.ps1"
& $scriptToExecute
@@ -31,14 +37,11 @@ if(! $jsonOnly) {
mkdir $scriptDirectory\release-streams\local\${version} -ErrorAction Ignore > $null
Move-Item -Force "./Installer/Output/Ziti Desktop Edge Client-${version}.exe" "$scriptDirectory\release-streams\local\${version}\Ziti.Desktop.Edge.Client-${version}.exe"
Move-Item -Force "./Installer/Output/Ziti Desktop Edge Client-${version}.exe.sha256" "$scriptDirectory\release-streams\local\${version}\Ziti.Desktop.Edge.Client-${version}.exe.sha256"
+ Write-Host ""
+ Write-Host "done."
+ Write-Host "installer exists at $scriptDirectory\release-streams\local\${version}\Ziti.Desktop.Edge.Client-${version}.exe"
}
-$outputPath = "${version}.json"
-& .\Installer\output-build-json.ps1 -version $version -url $url -stream $stream -published_at $published_at -outputPath $outputPath
-Copy-Item -Force "$outputPath" "$scriptDirectory\release-streams\local\${version}"
-Copy-Item -Force "${version}.json" "$scriptDirectory\release-streams\${stream}.json"
-echo "json file written to: $scriptDirectory\release-streams\${stream}.json"
-
if($revertGitAfter) {
git checkout DesktopEdge/Properties/AssemblyInfo.cs ZitiUpdateService/Properties/AssemblyInfo.cs Installer/ZitiDesktopEdge.aip
}
\ No newline at end of file
From 1c9406eb050dd063a888a7f90dc47ab291d250cb Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Tue, 13 Aug 2024 10:47:09 -0400
Subject: [PATCH 08/50] add more error handling when the monitor service is off
---
DesktopEdge/MainWindow.xaml.cs | 47 ++-
DesktopEdge/Views/Screens/MainMenu.xaml.cs | 54 ++--
.../ServiceClient/AbstractClient.cs | 15 +-
.../ServiceClient/MonitorClient.cs | 297 +++++++-----------
4 files changed, 202 insertions(+), 211 deletions(-)
diff --git a/DesktopEdge/MainWindow.xaml.cs b/DesktopEdge/MainWindow.xaml.cs
index 0c4431247..67f8a1fd6 100644
--- a/DesktopEdge/MainWindow.xaml.cs
+++ b/DesktopEdge/MainWindow.xaml.cs
@@ -40,12 +40,7 @@ limitations under the License.
using NLog.Targets;
using Microsoft.Win32;
-using System.Windows.Interop;
-using Windows.UI.Notifications;
-using Windows.Data.Xml.Dom;
using Ziti.Desktop.Edge.Models;
-using System.Reflection;
-using System.Windows.Threading;
namespace ZitiDesktopEdge {
@@ -1016,15 +1011,19 @@ async private void StartZitiService(object sender, RoutedEventArgs e) {
logger.Debug("ERROR: {0} : {1}", r.Message, r.Error);
} else {
logger.Info("Service started!");
- //no longer used: startZitiButtonVisible = false;
CloseErrorButton.Click -= StartZitiService;
CloseError(null, null);
}
+ } catch (MonitorServiceException me) {
+ logger.Warn("the monitor service appears offline. {0}", me);
+ CloseErrorButton.IsEnabled = true;
+ HideLoad();
+ ShowError("Error Starting Service", "The monitor service is offline");
} catch (Exception ex) {
- logger.Info(ex, "UNEXPECTED ERROR!");
- //no longer used: startZitiButtonVisible = false;
- //CloseErrorButton.Click += StartZitiService;
+ logger.Error(ex, "UNEXPECTED ERROR!");
CloseErrorButton.IsEnabled = true;
+ HideLoad();
+ ShowError("Unexpected Error", "Code 2:" + ex.Message);
}
CloseErrorButton.IsEnabled = true;
// HideLoad();
@@ -1040,10 +1039,26 @@ private void MonitorClient_OnClientConnected(object sender, object e) {
MainMenu.SetAppUpgradeAvailableText("");
}
- async private void LogLevelChanged(string level) {
- await serviceClient.SetLogLevelAsync(level);
- await monitorClient.SetLogLevelAsync(level);
- Ziti.Desktop.Edge.Utils.UIUtils.SetLogLevel(level);
+ async private Task LogLevelChanged(string level) {
+ int logsSet = 0;
+ try {
+ await serviceClient.SetLogLevelAsync(level);
+ logsSet++;
+ await monitorClient.SetLogLevelAsync(level);
+ logsSet++;
+ Ziti.Desktop.Edge.Utils.UIUtils.SetLogLevel(level);
+ return true;
+ } catch (Exception ex) {
+ logger.Error(ex, "Unexpected error. logsSet: {0}", logsSet);
+ if (logsSet > 1) {
+ await ShowBlurbAsync("Unexpected error setting logs?", "");
+ } else if (logsSet > 0) {
+ await ShowBlurbAsync("Failed to set monitor client log level", "");
+ } else {
+ await ShowBlurbAsync("Failed to set log levels", "");
+ }
+ }
+ return false;
}
private void IdentityMenu_OnError(string message) {
@@ -1622,11 +1637,14 @@ async private void Disconnect(object sender, RoutedEventArgs e) {
try {
ShowLoad("Disabling Service", "Please wait for the service to stop.");
var r = await monitorClient.StopServiceAsync();
- if (r != null && r.Code != 0) {
+ if (r.Code != 0) {
logger.Warn("ERROR: Error:{0}, Message:{1}", r.Error, r.Message);
} else {
logger.Info("Service stopped!");
}
+ } catch (MonitorServiceException me) {
+ logger.Warn("the monitor service appears offline. {0}", me);
+ ShowError("Error Disabling Service", "The monitor service is offline");
} catch (Exception ex) {
logger.Error(ex, "unexpected error: {0}", ex.Message);
ShowError("Error Disabling Service", "An error occurred while trying to disable the data service. Is the monitor service running?");
@@ -1716,7 +1734,6 @@ async private void CollectLogFileClick(object sender, RoutedEventArgs e) {
async private Task CollectLogFiles() {
MonitorServiceStatusEvent resp = await monitorClient.CaptureLogsAsync();
if (resp != null) {
-
logger.Info("response: {0}", resp.Message);
} else {
ShowError("Error Collecting Feedback", "An error occurred while trying to gather feedback. Is the monitor service running?");
diff --git a/DesktopEdge/Views/Screens/MainMenu.xaml.cs b/DesktopEdge/Views/Screens/MainMenu.xaml.cs
index 999e39856..8d6395e58 100644
--- a/DesktopEdge/Views/Screens/MainMenu.xaml.cs
+++ b/DesktopEdge/Views/Screens/MainMenu.xaml.cs
@@ -43,7 +43,7 @@ public partial class MainMenu : UserControl {
public delegate void AttachementChanged(bool attached);
public event AttachementChanged OnAttachmentChange;
- public delegate void LogLevelChanged(string level);
+ public delegate Task LogLevelChanged(string level);
public event LogLevelChanged OnLogLevelChanged;
public delegate void Detched(MouseButtonEventArgs e);
public event Detched OnDetach;
@@ -160,10 +160,15 @@ async private void SetAutomaticUpgradesMenuAction(object sender, MouseButtonEven
disableAutomaticUpgrades = true;
}
var monitorClient = (MonitorClient)Application.Current.Properties["MonitorClient"];
-
- SvcResponse r = await monitorClient.SetAutomaticUpgradeDisabledAsync(disableAutomaticUpgrades);
- if (r.Code != 0) {
- logger.Error(r?.Error);
+ try {
+ SvcResponse r = await monitorClient.SetAutomaticUpgradeDisabledAsync(disableAutomaticUpgrades);
+ if (r.Code != 0) {
+ logger.Error(r?.Error);
+ }
+ } catch (MonitorServiceException) {
+ MainWindow.ShowError("Could Not Set Automatic Update", "The monitor service is offline");
+ } catch (Exception ex) {
+ logger.Error("unexpected error when setting automatic upgrade enabled", ex);
}
SetAutomaticUpgradesState();
}
@@ -346,8 +351,11 @@ async public void CollectFeedbackLogs(object sender, MouseButtonEventArgs e) {
ProcessStartInfo pfi = new ProcessStartInfo("Explorer.exe", args);
Process.Start(pfi);
+ } catch (MonitorServiceException) {
+ MainWindow.ShowError("Could Not Collect Feedback", "The monitor service is offline");
} catch (Exception ex) {
logger.Warn(ex, "An unexpected error has occurred when submitting feedback? {0}", ex.Message);
+ MainWindow.ShowError("Could Not Collect Feedback", "The monitor service is offline");
}
MainWindow.HideLoad();
}
@@ -399,11 +407,12 @@ private void ResetLevels() {
else if (this.LogLevel == "trace") LogTrace.IsSelected = true;
}
- private void SetLevel(object sender, MouseButtonEventArgs e) {
+ async private void SetLevel(object sender, MouseButtonEventArgs e) {
SubOptionItem item = (SubOptionItem)sender;
- this.LogLevel = item.Label.ToLower();
if (OnLogLevelChanged != null) {
- OnLogLevelChanged(this.LogLevel);
+ if(await OnLogLevelChanged(this.LogLevel)) {
+ this.LogLevel = item.Label.ToLower();
+ }
}
ResetLevels();
}
@@ -436,8 +445,11 @@ async private void CheckForUpdate_OnClick(object sender, MouseButtonEventArgs e)
TriggerUpdateButton.Visibility = Visibility.Collapsed;
ForceUpdate.Visibility = Visibility.Collapsed;
}
+ } catch (MonitorServiceException me) {
+ CheckForUpdateStatus.Content = "Monitor service is offline";
} catch (Exception ex) {
logger.Error(ex, "unexpected error in update check: {0}", ex.Message);
+ CheckForUpdateStatus.Content = "Error checking for updates. See logs.";
}
CheckForUpdate.IsEnabled = true;
}
@@ -737,17 +749,23 @@ private void ResetUrlButton_Click(object sender, RoutedEventArgs e) {
}
private async void SetUpdateUrlButton_Click(object sender, MouseButtonEventArgs e) {
- var monitorClient = (MonitorClient)Application.Current.Properties["MonitorClient"];
+ try {
+ var monitorClient = (MonitorClient)Application.Current.Properties["MonitorClient"];
- SvcResponse r = await monitorClient.SetAutomaticUpgradeURLAsync(UpdateUrl.Text);
- if (r == null) {
- logger.Error("Failed to set automatic upgrade url! SvcResponse was null?!?!?");
- MainWindow.ShowError("Could not set url!", "Is the monitor service running?");
- } else if (r.Code != 0) {
- logger.Error(r?.Error);
- MainWindow.ShowError("Could not set url", r?.Error);
- } else {
- this.OnShowBlurb?.Invoke("Config Saved.");
+ SvcResponse r = await monitorClient.SetAutomaticUpgradeURLAsync(UpdateUrl.Text);
+ if (r == null) {
+ logger.Error("Failed to set automatic upgrade url! SvcResponse was null?!?!?");
+ MainWindow.ShowError("Could not set url!", "Is the monitor service running?");
+ } else if (r.Code != 0) {
+ logger.Error(r?.Error);
+ MainWindow.ShowError("Could not set url", r?.Error);
+ } else {
+ this.OnShowBlurb?.Invoke("Config Saved.");
+ }
+ } catch (MonitorServiceException) {
+ MainWindow.ShowError("Could Not Set URL", "The monitor service is offline");
+ } catch (Exception ex) {
+ logger.Error("unexpected error when setting automatic upgrade enabled", ex);
}
}
diff --git a/ZitiDesktopEdge.Client/ServiceClient/AbstractClient.cs b/ZitiDesktopEdge.Client/ServiceClient/AbstractClient.cs
index 37a1d25a3..f89994869 100644
--- a/ZitiDesktopEdge.Client/ServiceClient/AbstractClient.cs
+++ b/ZitiDesktopEdge.Client/ServiceClient/AbstractClient.cs
@@ -130,7 +130,7 @@ async protected Task sendAsync(object objToSend) {
await ipcWriter.WriteAsync('\n');
await ipcWriter.FlushAsync();
} else {
- throw new Exception("the monitor service appears to be offline?");
+ throw new MonitorServiceException("the monitor service appears to be offline?");
}
} else {
Logger.Debug("NOT sending empty object??? " + objToSend?.ToString());
@@ -145,7 +145,9 @@ async protected Task sendAsync(object objToSend) {
} else {
retried = true; //fall back through to the while and try again
}
- } catch (Exception ex) {
+ } catch (MonitorServiceException) {
+ throw;
+ } catch (Exception ex) {
//if this fails it's usually because the writer is null/invalid. throwing IOException
//will trigger the pipe to rebuild
throw new IOException("Unexpected error when sending data to service. " + ex.Message);
@@ -287,4 +289,13 @@ protected override JsonProperty CreateProperty(MemberInfo member, MemberSerializ
return property;
}
}
+
+ public class MonitorServiceException : Exception {
+ public MonitorServiceException() { }
+ public MonitorServiceException(string message) : base(message) {
+
+ }
+ public MonitorServiceException(string message, Exception source) : base(message, source) {
+ }
+ }
}
diff --git a/ZitiDesktopEdge.Client/ServiceClient/MonitorClient.cs b/ZitiDesktopEdge.Client/ServiceClient/MonitorClient.cs
index ca8df4239..59b64d4d1 100644
--- a/ZitiDesktopEdge.Client/ServiceClient/MonitorClient.cs
+++ b/ZitiDesktopEdge.Client/ServiceClient/MonitorClient.cs
@@ -42,184 +42,129 @@ limitations under the License.
///
///
namespace ZitiDesktopEdge.ServiceClient {
- public class MonitorClient : AbstractClient {
- private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
- protected override Logger Logger { get { return _logger; } }
-
- public const int EXPECTED_API_VERSION = 1;
-
- public event EventHandler OnServiceStatusEvent;
- public event EventHandler OnNotificationEvent;
-
- protected virtual void ServiceStatusEvent(MonitorServiceStatusEvent e) {
- OnServiceStatusEvent?.Invoke(this, e);
- }
-
- protected virtual void InstallationNotificationEvent(InstallationNotificationEvent e) {
- OnNotificationEvent?.Invoke(this, e);
- }
-
- public MonitorClient(string id) : base(id) {
-
- }
-
- async protected override Task ConnectPipesAsync() {
- await semaphoreSlim.WaitAsync();
- try {
- pipeClient = new NamedPipeClientStream(localPipeServer, IPCServer.PipeName, PipeDirection.InOut);
- eventClient = new NamedPipeClientStream(localPipeServer, IPCServer.EventPipeName, PipeDirection.In);
- await eventClient.ConnectAsync(ServiceConnectTimeout);
- await pipeClient.ConnectAsync(ServiceConnectTimeout);
- ClientConnected(null);
- } catch (Exception ex) {
- semaphoreSlim.Release();
- throw new ServiceException("Could not connect to the service.", 1, ex.Message);
- }
- semaphoreSlim.Release();
- }
-
- protected override void ProcessLine(string line) {
- var evt = serializer.Deserialize(new JsonTextReader(new StringReader(line)));
-
- switch (evt.Type) {
- case "Notification":
- var instEvt = serializer.Deserialize(new JsonTextReader(new StringReader(line)));
- InstallationNotificationEvent(instEvt);
- break;
- default:
- ServiceStatusEvent(evt);
- break;
- }
- }
-
- async internal Task SendServiceFunctionAsync(object toSend) {
- try {
- await sendAsync(toSend);
- var resp = await readMessageAsync(ipcReader);
- Logger.Info("RESPONSE: {0}", resp);
- return resp;
- } catch (Exception ex) {
- Logger.Error(ex, "Unexpected error");
- }
- return null;
- }
-
- async public Task StopServiceAsync() {
- ActionEvent action = new ActionEvent() { Op = "Stop", Action = "Normal" };
- try {
- await sendAsync(action);
- return await readAsync(ipcReader);
- } catch (Exception ex) {
- Logger.Error(ex, "Unexpected error");
- }
- return null;
- }
- async public Task StartServiceAsync() {
- ActionEvent action = new ActionEvent() { Op = "Start", Action = "Normal" };
- try {
- await sendAsync(action);
- return await readAsync(ipcReader);
- } catch (Exception ex) {
- Logger.Error(ex, "Unexpected error");
- }
- return null;
- }
- async public Task ForceTerminateAsync() {
- ActionEvent action = new ActionEvent() { Op = "Stop", Action = "Force" };
- try {
- await sendAsync(action);
- return await readAsync(ipcReader);
- } catch (Exception ex) {
- Logger.Error(ex, "Unexpected error");
- }
- return null;
- }
- async public Task StatusAsync() {
- ActionEvent action = new ActionEvent() { Op = "Status", Action = "" };
- try {
- await sendAsync(action);
- return await readAsync(ipcReader);
- } catch (Exception ex) {
- Logger.Error(ex, "Unexpected error");
- }
- return null;
- }
- async public Task CaptureLogsAsync() {
- ActionEvent action = new ActionEvent() { Op = "CaptureLogs", Action = "Normal" };
- try {
- await sendAsync(action);
- return await readAsync(ipcReader);
- } catch (Exception ex) {
- Logger.Error(ex, "Unexpected error");
- }
- return null;
- }
-
- async public Task SetReleaseStreamAsync(string stream) {
- ActionEvent action = new ActionEvent() { Op = "SetReleaseStream", Action = stream };
- try {
- await sendAsync(action);
- return await readAsync(ipcReader);
- } catch (Exception ex) {
- Logger.Error(ex, "Unexpected error");
- }
- return null;
- }
- async public Task SetLogLevelAsync(string level) {
- if ("verbose".Equals(level?.ToLower())) {
- //only the data client understands verbose - so use trace...
- level = "TRACE";
- }
- ActionEvent action = new ActionEvent() { Op = "SetLogLevel", Action = level };
- try {
- await sendAsync(action);
- return await readAsync(ipcReader);
- } catch (Exception ex) {
- Logger.Error(ex, "Unexpected error");
- }
- return null;
- }
- async public Task DoUpdateCheck() {
- ActionEvent action = new ActionEvent() { Op = "DoUpdateCheck", Action = "" };
- try {
- await sendAsync(action);
- return await readAsync(ipcReader);
- } catch (Exception ex) {
- Logger.Error(ex, "Unexpected error");
- }
- return null;
- }
+ public class MonitorClient : AbstractClient {
+ private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
+ protected override Logger Logger { get { return _logger; } }
+
+ public const int EXPECTED_API_VERSION = 1;
+
+ public event EventHandler OnServiceStatusEvent;
+ public event EventHandler OnNotificationEvent;
+
+ protected virtual void ServiceStatusEvent(MonitorServiceStatusEvent e) {
+ OnServiceStatusEvent?.Invoke(this, e);
+ }
+
+ protected virtual void InstallationNotificationEvent(InstallationNotificationEvent e) {
+ OnNotificationEvent?.Invoke(this, e);
+ }
+
+ public MonitorClient(string id) : base(id) {
+
+ }
+
+ async protected override Task ConnectPipesAsync() {
+ await semaphoreSlim.WaitAsync();
+ try {
+ pipeClient = new NamedPipeClientStream(localPipeServer, IPCServer.PipeName, PipeDirection.InOut);
+ eventClient = new NamedPipeClientStream(localPipeServer, IPCServer.EventPipeName, PipeDirection.In);
+ await eventClient.ConnectAsync(ServiceConnectTimeout);
+ await pipeClient.ConnectAsync(ServiceConnectTimeout);
+ ClientConnected(null);
+ } catch (Exception ex) {
+ semaphoreSlim.Release();
+ throw new ServiceException("Could not connect to the service.", 1, ex.Message);
+ }
+ semaphoreSlim.Release();
+ }
+
+ protected override void ProcessLine(string line) {
+ var evt = serializer.Deserialize(new JsonTextReader(new StringReader(line)));
+
+ switch (evt.Type) {
+ case "Notification":
+ var instEvt = serializer.Deserialize(new JsonTextReader(new StringReader(line)));
+ InstallationNotificationEvent(instEvt);
+ break;
+ default:
+ ServiceStatusEvent(evt);
+ break;
+ }
+ }
+
+ async public Task StopServiceAsync() {
+ ActionEvent action = new ActionEvent() { Op = "Stop", Action = "Normal" };
+ await sendAsync(action);
+ return await readAsync(ipcReader);
+ }
+
+ async public Task StartServiceAsync() {
+ ActionEvent action = new ActionEvent() { Op = "Start", Action = "Normal" };
+ await sendAsync(action);
+ return await readAsync(ipcReader);
+ }
+
+ async public Task ForceTerminateAsync() {
+ ActionEvent action = new ActionEvent() { Op = "Stop", Action = "Force" };
+ try {
+ await sendAsync(action);
+ return await readAsync(ipcReader);
+ } catch (Exception ex) {
+ Logger.Error(ex, "Unexpected error");
+ }
+ return null;
+ }
+
+ async public Task StatusAsync() {
+ ActionEvent action = new ActionEvent() { Op = "Status", Action = "" };
+ try {
+ await sendAsync(action);
+ return await readAsync(ipcReader);
+ } catch (Exception ex) {
+ Logger.Error(ex, "Unexpected error");
+ }
+ return null;
+ }
+
+ async public Task CaptureLogsAsync() {
+ ActionEvent action = new ActionEvent() { Op = "CaptureLogs", Action = "Normal" };
+ await sendAsync(action);
+ return await readAsync(ipcReader);
+ }
+
+ async public Task SetLogLevelAsync(string level) {
+ if ("verbose".Equals(level?.ToLower())) {
+ //only the data client understands verbose - so use trace...
+ level = "TRACE";
+ }
+ ActionEvent action = new ActionEvent() { Op = "SetLogLevel", Action = level };
+ await sendAsync(action);
+ return await readAsync(ipcReader);
+ }
+
+ async public Task DoUpdateCheck() {
+ ActionEvent action = new ActionEvent() { Op = "DoUpdateCheck", Action = "" };
+ await sendAsync(action);
+ return await readAsync(ipcReader);
+ }
async public Task TriggerUpdate() {
UpgradeSentinel.StartUpgradeSentinel();
ActionEvent action = new ActionEvent() { Op = "TriggerUpdate", Action = "" };
- try {
- await sendAsync(action);
- return await readAsync(ipcReader);
- } catch (Exception ex) {
- Logger.Error(ex, "Unexpected error");
- }
- return null;
- }
- async public Task SetAutomaticUpgradeDisabledAsync(bool disabled) {
- ActionEvent action = new ActionEvent() { Op = "SetAutomaticUpgradeDisabled", Action = (disabled ? "true" : "false") };
- try {
- await sendAsync(action);
- return await readAsync(ipcReader);
- } catch (Exception ex) {
- Logger.Error(ex, "Unexpected error");
- }
- return null;
- }
- async public Task SetAutomaticUpgradeURLAsync(string url) {
- ActionEvent action = new ActionEvent() { Op = "SetAutomaticUpgradeURL", Action = (url) };
- try {
- await sendAsync(action);
- return await readAsync(ipcReader);
- } catch (Exception ex) {
- Logger.Error(ex, "Unexpected error");
- }
- return null;
- }
- }
+ await sendAsync(action);
+ return await readAsync(ipcReader);
+ }
+
+ async public Task SetAutomaticUpgradeDisabledAsync(bool disabled) {
+ ActionEvent action = new ActionEvent() { Op = "SetAutomaticUpgradeDisabled", Action = (disabled ? "true" : "false") };
+ await sendAsync(action);
+ return await readAsync(ipcReader);
+ }
+
+ async public Task SetAutomaticUpgradeURLAsync(string url) {
+ ActionEvent action = new ActionEvent() { Op = "SetAutomaticUpgradeURL", Action = (url) };
+ await sendAsync(action);
+ return await readAsync(ipcReader);
+ }
+ }
}
\ No newline at end of file
From 5dfd231a12d34faec8295b6c54cd3ac059b6e46e Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Mon, 9 Sep 2024 09:35:04 -0400
Subject: [PATCH 09/50] better icon indication
---
DesktopEdge/MainWindow.xaml.cs | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/DesktopEdge/MainWindow.xaml.cs b/DesktopEdge/MainWindow.xaml.cs
index 271709825..8e21c507a 100644
--- a/DesktopEdge/MainWindow.xaml.cs
+++ b/DesktopEdge/MainWindow.xaml.cs
@@ -977,7 +977,7 @@ async private Task WaitForServiceToStop(DateTime until) {
//continually poll for the service to stop. If it is stuck - ask the user if they want to try to force
//close the service
while (DateTime.Now < until) {
- await Task.Delay(2000);
+ await Task.Delay(250);
MonitorServiceStatusEvent resp = await monitorClient.StatusAsync();
if (resp.IsStopped()) {
// good - that's what we are waiting for...
@@ -1076,6 +1076,7 @@ private void ServiceClient_OnClientDisconnected(object sender, object e) {
logger.Debug(e.ToString());
}
//SetCantDisplay("Start the Ziti Tunnel Service to continue");
+ SetNotifyIcon("red");
ShowServiceNotStarted();
});
}
@@ -1287,11 +1288,7 @@ private void LoadStatusFromService(TunnelStatus status) {
_isServiceInError = false;
UpdateServiceView();
NoServiceView.Visibility = Visibility.Collapsed;
- if (status.Active) {
- SetNotifyIcon("green");
- } else {
- SetNotifyIcon("white");
- }
+ SetNotifyIcon("green");
if (!Application.Current.Properties.Contains("ip")) {
Application.Current.Properties.Add("ip", status?.IpInfo?.Ip);
} else {
@@ -1376,6 +1373,7 @@ private void SetNotifyIcon(string iconPrefix) {
}
}
icon += ".ico";
+ logger.Warn("INON: {}", icon);
var iconUri = new Uri(icon);
Stream iconStream = Application.GetResourceStream(iconUri).Stream;
notifyIcon.Icon = new Icon(iconStream);
@@ -1629,6 +1627,7 @@ async private void Disconnect(object sender, RoutedEventArgs e) {
logger.Warn("ERROR: Error:{0}, Message:{1}", r.Error, r.Message);
} else {
logger.Info("Service stopped!");
+ SetNotifyIcon("white");
}
} catch (Exception ex) {
logger.Error(ex, "unexpected error: {0}", ex.Message);
From 7f9b7767d73b7926849ce0f0ddc7fb782061818f Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Mon, 9 Sep 2024 09:36:10 -0400
Subject: [PATCH 10/50] forgot to save the file with the removal
---
DesktopEdge/MainWindow.xaml.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/DesktopEdge/MainWindow.xaml.cs b/DesktopEdge/MainWindow.xaml.cs
index 8e21c507a..3e3233b6c 100644
--- a/DesktopEdge/MainWindow.xaml.cs
+++ b/DesktopEdge/MainWindow.xaml.cs
@@ -1373,7 +1373,6 @@ private void SetNotifyIcon(string iconPrefix) {
}
}
icon += ".ico";
- logger.Warn("INON: {}", icon);
var iconUri = new Uri(icon);
Stream iconStream = Application.GetResourceStream(iconUri).Stream;
notifyIcon.Icon = new Icon(iconStream);
From 87e6a92e92692a7c62447e0c2465c02d3b543364 Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Mon, 9 Sep 2024 09:42:07 -0400
Subject: [PATCH 11/50] use alpha17
---
Installer/build.ps1 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Installer/build.ps1 b/Installer/build.ps1
index b8680ce29..0a92da4cb 100644
--- a/Installer/build.ps1
+++ b/Installer/build.ps1
@@ -18,7 +18,7 @@ $ADV_INST_HOME = "C:\Program Files (x86)\Caphyon\Advanced Installer ${ADV_INST_V
$SIGNTOOL="${ADV_INST_HOME}\third-party\winsdk\x64\signtool.exe"
$ADVINST = "${ADV_INST_HOME}\bin\x86\AdvancedInstaller.com"
$ADVPROJECT = "${scriptPath}\ZitiDesktopEdge.aip"
-$ZITI_EDGE_TUNNEL_VERSION="v2.0.0-alpha11"
+$ZITI_EDGE_TUNNEL_VERSION="v2.0.0-alpha17"
echo "Cleaning previous build folder if it exists"
Remove-Item "${buildPath}" -r -ErrorAction Ignore
From be85d75e0c9d979296f6b30bd3069b97d13fc5ad Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Mon, 9 Sep 2024 09:43:29 -0400
Subject: [PATCH 12/50] update version
---
version | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/version b/version
index 2501d5d1b..b5f320161 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-2.5.0.3
+2.5.0.4
From c9767d3cb317e05cea35d674d4829658aa907113 Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Mon, 9 Sep 2024 09:51:10 -0400
Subject: [PATCH 13/50] udpate release stream
---
release-streams/ctrlha-alpha.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/release-streams/ctrlha-alpha.json b/release-streams/ctrlha-alpha.json
index 299504643..58ee9dcac 100644
--- a/release-streams/ctrlha-alpha.json
+++ b/release-streams/ctrlha-alpha.json
@@ -1,11 +1,11 @@
{
- "name": "2.5.0.3",
- "tag_name": "2.5.0.3",
+ "name": "2.5.0.4",
+ "tag_name": "2.5.0.4",
"published_at": "2024-07-30T14:53:31Z",
"installation_critical": false,
"assets": [
{
- "name": "Ziti.Desktop.Edge.Client-2.5.0.3.exe",
+ "name": "Ziti.Desktop.Edge.Client-2.5.0.4.exe",
"browser_download_url": "https://github.com/openziti/desktop-edge-win/releases/download/2.5.0.3-alpha/Ziti.Desktop.Edge.Client-2.5.0.3.exe"
}
]
From 4e4263f0fe7964bc2989109fc65824f9d504af04 Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Mon, 9 Sep 2024 10:30:58 -0400
Subject: [PATCH 14/50] update ctrlha dl link
---
DesktopEdge/MainWindow.xaml.cs | 1 -
release-streams/ctrlha-alpha.json | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/DesktopEdge/MainWindow.xaml.cs b/DesktopEdge/MainWindow.xaml.cs
index 59426d8b2..d83ebcd8f 100644
--- a/DesktopEdge/MainWindow.xaml.cs
+++ b/DesktopEdge/MainWindow.xaml.cs
@@ -1490,7 +1490,6 @@ private void TunnelConnected(bool isConnected) {
MainMenu.Disconnected();
DownloadSpeed.Content = "0.0";
UploadSpeed.Content = "0.0";
- SetNotifyIcon("white");
}
});
}
diff --git a/release-streams/ctrlha-alpha.json b/release-streams/ctrlha-alpha.json
index 58ee9dcac..201a0cbdd 100644
--- a/release-streams/ctrlha-alpha.json
+++ b/release-streams/ctrlha-alpha.json
@@ -6,7 +6,7 @@
"assets": [
{
"name": "Ziti.Desktop.Edge.Client-2.5.0.4.exe",
- "browser_download_url": "https://github.com/openziti/desktop-edge-win/releases/download/2.5.0.3-alpha/Ziti.Desktop.Edge.Client-2.5.0.3.exe"
+ "browser_download_url": "https://github.com/openziti/desktop-edge-win/releases/download/2.5.0.4-alpha/Ziti.Desktop.Edge.Client-2.5.0.4.exe"
}
]
}
From 86d6dcc854758dddffb849613535257a9e4dbba2 Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Tue, 17 Sep 2024 17:40:46 -0400
Subject: [PATCH 15/50] first commit at implementing the zet healthcheck
---
.editorconfig | 2 +-
.github/workflows/installer.build.yml | 8 +-
DesktopEdge/Views/Screens/MainMenu.xaml.cs | 2 +-
.../ServiceClient/AbstractClient.cs | 41 +++---
.../ServiceClient/DataClient.cs | 2 +-
.../ServiceClient/MonitorClient.cs | 2 +-
ZitiUpdateService/UpdateService.cs | 124 +++++++-----------
version | 2 +-
8 files changed, 76 insertions(+), 107 deletions(-)
diff --git a/.editorconfig b/.editorconfig
index a2713da48..611d3f329 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -75,7 +75,7 @@ tab_width = 4
indent_size = 4
end_of_line = crlf
dotnet_style_collection_initializer = true:suggestion
-indent_style = tab
+indent_style = space
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
diff --git a/.github/workflows/installer.build.yml b/.github/workflows/installer.build.yml
index 70c294b5b..6b115ea56 100644
--- a/.github/workflows/installer.build.yml
+++ b/.github/workflows/installer.build.yml
@@ -94,18 +94,18 @@ jobs:
ziti_ci_gpg_key_id: ${{ secrets.ZITI_CI_GPG_KEY_ID }}
run: powershell -File .\Installer\build.ps1
- name: Upload installer onto job
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: ZitiDesktopEdgeClient-${{ env.VERSION }}
path: "Installer/Output/Ziti Desktop Edge Client-*"
- name: Upload update json to job
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
with:
- name: ZitiDesktopEdgeClient-${{ env.VERSION }}
+ name: ZitiDesktopEdgeClient-${{ env.VERSION }}.json
path: ${{ env.VERSION }}.json
- name: Job Failure - Upload the signing log job
if: failure()
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
with:
name: SigningLogs
path: '**/*AWSSigner.log*'
diff --git a/DesktopEdge/Views/Screens/MainMenu.xaml.cs b/DesktopEdge/Views/Screens/MainMenu.xaml.cs
index 8d6395e58..1aef73bd4 100644
--- a/DesktopEdge/Views/Screens/MainMenu.xaml.cs
+++ b/DesktopEdge/Views/Screens/MainMenu.xaml.cs
@@ -445,7 +445,7 @@ async private void CheckForUpdate_OnClick(object sender, MouseButtonEventArgs e)
TriggerUpdateButton.Visibility = Visibility.Collapsed;
ForceUpdate.Visibility = Visibility.Collapsed;
}
- } catch (MonitorServiceException me) {
+ } catch (MonitorServiceException) {
CheckForUpdateStatus.Content = "Monitor service is offline";
} catch (Exception ex) {
logger.Error(ex, "unexpected error in update check: {0}", ex.Message);
diff --git a/ZitiDesktopEdge.Client/ServiceClient/AbstractClient.cs b/ZitiDesktopEdge.Client/ServiceClient/AbstractClient.cs
index f89994869..9716a674b 100644
--- a/ZitiDesktopEdge.Client/ServiceClient/AbstractClient.cs
+++ b/ZitiDesktopEdge.Client/ServiceClient/AbstractClient.cs
@@ -66,21 +66,22 @@ protected virtual void ClientConnected(object e) {
ipcReader = new StreamReader(pipeClient);
Task.Run(async () => { //hack for now until it's async...
try {
- StreamReader eventReader = new StreamReader(eventClient);
- while (true) {
- if (eventReader.EndOfStream) {
- break;
- }
- string respAsString = null;
- try {
- respAsString = await readMessageAsync(eventReader);
+ using (StreamReader eventReader = new StreamReader(eventClient)) {
+ while (true) {
+ if (eventReader.EndOfStream) {
+ break;
+ }
+ string respAsString = null;
try {
- ProcessLine(respAsString);
+ respAsString = await readMessageAsync(eventReader);
+ try {
+ ProcessLine(respAsString);
+ } catch (Exception ex) {
+ Logger.Warn(ex, "ERROR caught in ProcessLine: {0}", respAsString);
+ }
} catch (Exception ex) {
- Logger.Warn(ex, "ERROR caught in ProcessLine: {0}", respAsString);
+ Logger.Warn(ex, "ERROR caught in readMessageAsync: {0}", respAsString);
}
- } catch (Exception ex) {
- Logger.Warn(ex, "ERROR caught in readMessageAsync: {0}", respAsString);
}
}
} catch (Exception ex) {
@@ -130,7 +131,7 @@ async protected Task sendAsync(object objToSend) {
await ipcWriter.WriteAsync('\n');
await ipcWriter.FlushAsync();
} else {
- throw new MonitorServiceException("the monitor service appears to be offline?");
+ throw new IPCException("ipcWriter is null. the target appears to be offline?");
}
} else {
Logger.Debug("NOT sending empty object??? " + objToSend?.ToString());
@@ -292,10 +293,14 @@ protected override JsonProperty CreateProperty(MemberInfo member, MemberSerializ
public class MonitorServiceException : Exception {
public MonitorServiceException() { }
- public MonitorServiceException(string message) : base(message) {
-
- }
- public MonitorServiceException(string message, Exception source) : base(message, source) {
- }
+ public MonitorServiceException(string message) : base(message) { }
+ public MonitorServiceException(string message, Exception source) : base(message, source) { }
+ }
+
+ public class IPCException : Exception {
+ public IPCException() { }
+ public IPCException(string message) : base(message) { }
+ public IPCException(string message, Exception source) : base(message, source) { }
+
}
}
diff --git a/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs b/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs
index cd1a70f46..8cdda9124 100644
--- a/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs
+++ b/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs
@@ -140,7 +140,7 @@ async protected override Task ConnectPipesAsync() {
ClientConnected(null);
} catch (Exception ex) {
semaphoreSlim.Release();
- throw new ServiceException("Could not connect to the service.", 1, ex.Message);
+ throw new ServiceException("Could not connect to the data service.", 1, ex.Message);
}
semaphoreSlim.Release();
}
diff --git a/ZitiDesktopEdge.Client/ServiceClient/MonitorClient.cs b/ZitiDesktopEdge.Client/ServiceClient/MonitorClient.cs
index 59b64d4d1..cba5edb54 100644
--- a/ZitiDesktopEdge.Client/ServiceClient/MonitorClient.cs
+++ b/ZitiDesktopEdge.Client/ServiceClient/MonitorClient.cs
@@ -73,7 +73,7 @@ async protected override Task ConnectPipesAsync() {
ClientConnected(null);
} catch (Exception ex) {
semaphoreSlim.Release();
- throw new ServiceException("Could not connect to the service.", 1, ex.Message);
+ throw new ServiceException("Could not connect to the monitor service.", 1, ex.Message);
}
semaphoreSlim.Release();
}
diff --git a/ZitiUpdateService/UpdateService.cs b/ZitiUpdateService/UpdateService.cs
index 36b8a6709..7434e610c 100644
--- a/ZitiUpdateService/UpdateService.cs
+++ b/ZitiUpdateService/UpdateService.cs
@@ -40,6 +40,7 @@ limitations under the License.
using ZitiUpdateService.Utils;
using ZitiUpdateService.Checkers;
using System.Security.Policy;
+using Newtonsoft.Json.Linq;
#if !SKIPUPDATE
using ZitiUpdateService.Checkers.PeFile;
@@ -47,7 +48,8 @@ limitations under the License.
namespace ZitiUpdateService {
public partial class UpdateService : ServiceBase {
- private string betaStreamMarkerFile = "use-beta-stream.txt";
+ private const string betaStreamMarkerFile = "use-beta-stream.txt";
+ private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private static Settings CurrentSettings = new Settings(true);
public bool IsBeta {
@@ -57,10 +59,9 @@ public bool IsBeta {
private set { }
}
- private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private System.Timers.Timer _updateTimer = new System.Timers.Timer();
- private static SemaphoreSlim semaphore = new SemaphoreSlim(1, 1);
+ private SemaphoreSlim semaphore = new SemaphoreSlim(1, 1);
private string exeLocation = null;
@@ -69,15 +70,17 @@ private set { }
private string asmDir = null;
private string updateFolder = null;
private string filePrefix = "Ziti.Desktop.Edge.Client-";
- Version assemblyVersion = null;
+ private Version assemblyVersion = null;
- ServiceController controller;
- IPCServer svr = new IPCServer();
- Task ipcServer = null;
- Task eventServer = null;
+ private ServiceController controller;
+ private IPCServer svr = new IPCServer();
+ private Task ipcServer = null;
+ private Task eventServer = null;
- private System.Timers.Timer dnsProbeTimer = new System.Timers.Timer();
- private IPAddress dnsIpAddress = null;
+ private const int zetHealthcheckInterval = 5;
+ private SemaphoreSlim zetSemaphore = new SemaphoreSlim(1, 1);
+ private System.Timers.Timer zetHealthcheck = new System.Timers.Timer();
+ private int zetFailedCheckCounter = 0;
private UpdateCheck lastUpdateCheck;
private InstallationNotificationEvent lastInstallationNotification;
@@ -513,8 +516,8 @@ protected override void OnStart(string[] args) {
AccessUtils.GrantAccessToFile(Path.Combine(exeLocation, "ZitiDesktopEdge.exe.config")); //allow anyone to change the config file
AccessUtils.GrantAccessToFile(Path.Combine(exeLocation, "ZitiDesktopEdge-log.config")); //allow anyone to change the log file config
- //dnsProbeTimer.Elapsed += DnsProbe_Elapsed; disable the dns probe for now
- dnsProbeTimer.Interval = dnsProbeIntervalInSeconds * 1000;
+ zetHealthcheck.Interval = zetHealthcheckInterval * 1000;
+ zetHealthcheck.Elapsed += zitiEdgeTunnelAlivenessCheck;
Logger.Info("starting ipc server");
ipcServer = svr.startIpcServerAsync(onIpcClientAsync);
@@ -532,63 +535,28 @@ protected override void OnStart(string[] args) {
base.OnStart(args);
}
- IPAddress lh = IPAddress.Parse("127.0.0.1"); //expected result
- int dnsProbeFailCount = 0;
- int dnsProbeIntervalInSeconds = 60;
- bool dnsProbeStarted = false;
-
- private void DnsProbe_Elapsed(object sender, ElapsedEventArgs e) {
- if (dnsProbeStarted) return; //skip out if it's already going...
- dnsProbeStarted = true;
- Logger.Trace("dns probe started");
+ private void zitiEdgeTunnelAlivenessCheck(object sender, ElapsedEventArgs e) {
try {
- if (dnsIpAddress != null) {
- DnsQuestion q = new DnsQuestion("dew-dns-probe.openziti.org", QueryType.A);
- var dnsEp = new IPEndPoint(dnsIpAddress, 53);
- var dnsProbe = new LookupClient(dnsEp);
- IDnsQueryResponse resp = dnsProbe.Query(q);
- if (resp != null && resp.Answers?.Count > 0) {
- foreach (DnsResourceRecord dnsrec in resp.Answers) {
- if (dnsrec.GetType() == typeof(ARecord)) {
- ARecord arec = (ARecord)dnsrec;
- if (arec.Address.Equals(lh)) {
- dnsProbeFailCount = 0;
- Logger.Debug("dns probe success");
- } else {
- logDnsProbeFailure(null);
- }
- } else {
- Logger.Debug("dns probe returned an answer but response was not an ARecord? [" + dnsrec.GetType().Name + "]");
- }
- }
- } else {
- Logger.Debug("dns probe failed. no answer found for dew-dns-probe.openziti.org");
- logDnsProbeFailure(null);
- }
- }
- } catch (Exception dnse) {
- //don't really care but it probably means a timeout happened. but might as well log a trace error anyway...
- //it's expected that this is due to the service shutting down...
- logDnsProbeFailure(dnse);
- }
- dnsProbeStarted = false;
- }
-
- private void logDnsProbeFailure(Exception e) {
- dnsProbeFailCount++;
- bool logit = false;
- if (dnsProbeFailCount <= 4) {
- logit = true;
- } else {
- //else log it every 5 minutes...
- logit = dnsProbeFailCount % (5 * 60 / dnsProbeIntervalInSeconds) == 0;
- }
- if (logit) {
- if (e != null) {
- Logger.Warn(e, "dns probe failed due to error. This has happened {0} times", dnsProbeFailCount);
+ if(zetSemaphore.Wait(TimeSpan.FromSeconds(zetHealthcheckInterval))) {
+ Logger.Trace("ziti-edge-tunnel aliveness check starts");
+ dataClient.GetStatusAsync().Wait();
+ zetSemaphore.Release();
+ Interlocked.Exchange(ref zetFailedCheckCounter, 0);
+ Logger.Info("ziti-edge-tunnel aliveness check ends {}", zetFailedCheckCounter);
} else {
- Logger.Warn("dns probe failed. This has happened {0} times", dnsProbeFailCount);
+ Interlocked.Add(ref zetFailedCheckCounter, 1);
+ Logger.Warn("ziti-edge-tunnel aliveness check appears blocked and has been for {} times", zetFailedCheckCounter);
+ if (zetFailedCheckCounter > 2) {
+ //after 10 seconds, just terminate ziti-edge-tunnel
+ Logger.Warn("forcefully stopping ziti-edge-tunnel as it has been blocked for too long");
+ stopProcessForcefully("ziti-edge-tunnel", "data service [ziti]");
+
+ Logger.Info("immediately restarting ziti-edge-tunnel");
+ ServiceActions.StartService(); //attempt to start the service
+ }
}
+ } catch(Exception ex) {
+ Logger.Error("ziti-edge-tunnel aliveness check ends exceptionally: {}", ex.Message);
}
}
@@ -827,11 +795,11 @@ private void installZDE(UpdateCheck check) {
Logger.Debug("downloaded file hash was correct. update can continue.");
#if !SKIPUPDATE
try {
- Logger.Info("verifying file [{}]", fileDestination);
- new SignedFileValidator(fileDestination).Verify();
- Logger.Info("SignedFileValidator complete");
+ Logger.Info("verifying file [{}]", fileDestination);
+ new SignedFileValidator(fileDestination).Verify();
+ Logger.Info("SignedFileValidator complete");
- StopZiti();
+ StopZiti();
StopUI().Wait();
Logger.Info("Running update package: " + fileDestination);
@@ -986,29 +954,25 @@ private void Svc_OnTunnelStatusEvent(object sender, TunnelStatusEvent e) {
string op = e?.Op;
Logger.Info($"Operation {op}. running dns: {dns} at version {version}");
- try {
- dnsIpAddress = IPAddress.Parse(dns);
- } catch {
- //ignore it
- }
SetLogLevel(e.Status.LogLevel);
}
private void Svc_OnClientConnected(object sender, object e) {
Logger.Info("successfully connected to service");
- if (!dnsProbeTimer.Enabled) {
- dnsProbeTimer.Enabled = true;
- dnsProbeTimer.Start();
- Logger.Info("DNS Probe enabled");
+ if (!zetHealthcheck.Enabled) {
+ zetHealthcheck.Enabled = true;
+ zetHealthcheck.Start();
+ Logger.Info("ziti-edge-tunnel health check enabled");
}
}
private void Svc_OnClientDisconnected(object sender, object e) {
- //dnsProbeTimer.Stop();
DataClient svc = (DataClient)sender;
if (svc.CleanShutdown) {
//then this is fine and expected - the service is shutting down
Logger.Info("client disconnected due to clean service shutdown");
+ zetHealthcheck.Stop();
+ zetHealthcheck.Enabled = false;
} else {
Logger.Error("SERVICE IS DOWN and did not exit cleanly.");
diff --git a/version b/version
index b5f320161..389b437ac 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-2.5.0.4
+2.5.0.5
\ No newline at end of file
From c05f9b858cc3ff4a3a49afcc1c8ad5e1c2f27a83 Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Tue, 17 Sep 2024 18:29:33 -0400
Subject: [PATCH 16/50] add more error handling after killing the zet process
ended up with some unexpected errors
---
Installer/build.ps1 | 2 +-
ZitiDesktopEdge.Client/Server/IPCServer.cs | 32 +++++++-----
.../ServiceClient/DataClient.cs | 2 +-
ZitiUpdateService/UpdateService.cs | 50 ++++++++++---------
4 files changed, 49 insertions(+), 37 deletions(-)
diff --git a/Installer/build.ps1 b/Installer/build.ps1
index 0a92da4cb..017de3fff 100644
--- a/Installer/build.ps1
+++ b/Installer/build.ps1
@@ -18,7 +18,7 @@ $ADV_INST_HOME = "C:\Program Files (x86)\Caphyon\Advanced Installer ${ADV_INST_V
$SIGNTOOL="${ADV_INST_HOME}\third-party\winsdk\x64\signtool.exe"
$ADVINST = "${ADV_INST_HOME}\bin\x86\AdvancedInstaller.com"
$ADVPROJECT = "${scriptPath}\ZitiDesktopEdge.aip"
-$ZITI_EDGE_TUNNEL_VERSION="v2.0.0-alpha17"
+$ZITI_EDGE_TUNNEL_VERSION="v2.0.0-alpha19"
echo "Cleaning previous build folder if it exists"
Remove-Item "${buildPath}" -r -ErrorAction Ignore
diff --git a/ZitiDesktopEdge.Client/Server/IPCServer.cs b/ZitiDesktopEdge.Client/Server/IPCServer.cs
index ee934314e..4ef483ad3 100644
--- a/ZitiDesktopEdge.Client/Server/IPCServer.cs
+++ b/ZitiDesktopEdge.Client/Server/IPCServer.cs
@@ -167,18 +167,23 @@ async public Task handleIpcClientAsync(NamedPipeServerStream ss, OnClientAsync o
}
async public Task handleEventClientAsync(NamedPipeServerStream ss, OnClientAsync onClient) {
- using (ss) {
- StreamWriter writer = new StreamWriter(ss);
+ try {
+ using (ss) {
+ StreamWriter writer = new StreamWriter(ss);
- EventHandler eh = async (object sender, EventArgs e) => {
- await writer.WriteLineAsync(sender.ToString());
- await writer.FlushAsync();
- };
+ EventHandler eh = async (object sender, EventArgs e) => {
+ try {
+ await writer.WriteLineAsync(sender.ToString());
+ await writer.FlushAsync();
+ } catch (Exception ex) {
+ Logger.Error("problem with event handler in handleEventClientAsync: {}", ex.Message);
+ }
+ };
- await onClient(writer);
+ await onClient(writer);
- EventRegistry.MyEvent += eh;
- try {
+ EventRegistry.MyEvent += eh;
+ //try {
StreamReader reader = new StreamReader(ss);
string line = await reader.ReadLineAsync();
@@ -188,10 +193,13 @@ async public Task handleEventClientAsync(NamedPipeServerStream ss, OnClientAsync
}
Logger.Debug("handleEventClientAsync is complete");
- } catch (Exception e) {
- Logger.Error(e, "Unexpected error when reading from or writing to a client pipe.");
+ //} catch (Exception e) {
+ // Logger.Error(e, "Unexpected error when reading from or writing to a client pipe.");
+ //}
+ EventRegistry.MyEvent -= eh;
}
- EventRegistry.MyEvent -= eh;
+ } catch (Exception e) {
+ Logger.Error(e, "Unexpected error when reading from or writing to a client pipe.");
}
}
diff --git a/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs b/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs
index 8cdda9124..3f1b3bb27 100644
--- a/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs
+++ b/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs
@@ -154,7 +154,7 @@ async public Task GetStatusAsync() {
//almost certainly a problem with the pipe - recreate the pipe...
//setupPipe();
//throw ioe;
- Logger.Error(ioe, "Unexpected error");
+ Logger.Error(ioe, "Unexpected error in GetStatusAsync");
}
return null;
}
diff --git a/ZitiUpdateService/UpdateService.cs b/ZitiUpdateService/UpdateService.cs
index 7434e610c..0039e4e8e 100644
--- a/ZitiUpdateService/UpdateService.cs
+++ b/ZitiUpdateService/UpdateService.cs
@@ -542,7 +542,7 @@ private void zitiEdgeTunnelAlivenessCheck(object sender, ElapsedEventArgs e) {
dataClient.GetStatusAsync().Wait();
zetSemaphore.Release();
Interlocked.Exchange(ref zetFailedCheckCounter, 0);
- Logger.Info("ziti-edge-tunnel aliveness check ends {}", zetFailedCheckCounter);
+ Logger.Info("ziti-edge-tunnel aliveness check ends successfully");
} else {
Interlocked.Add(ref zetFailedCheckCounter, 1);
Logger.Warn("ziti-edge-tunnel aliveness check appears blocked and has been for {} times", zetFailedCheckCounter);
@@ -561,27 +561,31 @@ private void zitiEdgeTunnelAlivenessCheck(object sender, ElapsedEventArgs e) {
}
async private Task onEventsClientAsync(StreamWriter writer) {
- Logger.Info("a new events client was connected");
- //reset to release stream
- //initial status when connecting the event stream
- MonitorServiceStatusEvent status = new MonitorServiceStatusEvent() {
- Code = 0,
- Error = "",
- Message = "Success",
- Type = "Status",
- Status = ServiceActions.ServiceStatus(),
- ReleaseStream = IsBeta ? "beta" : "stable",
- AutomaticUpgradeDisabled = CurrentSettings.AutomaticUpdatesDisabled.ToString(),
- AutomaticUpgradeURL = CurrentSettings.AutomaticUpdateURL,
- };
- await writer.WriteLineAsync(JsonConvert.SerializeObject(status));
- await writer.FlushAsync();
-
- //if a new client attaches - send the last update check status
- if (lastUpdateCheck != null) {
- await writer.WriteLineAsync(JsonConvert.SerializeObject(lastInstallationNotification));
- await writer.FlushAsync();
- }
+ try {
+ Logger.Info("a new events client was connected");
+ //reset to release stream
+ //initial status when connecting the event stream
+ MonitorServiceStatusEvent status = new MonitorServiceStatusEvent() {
+ Code = 0,
+ Error = "",
+ Message = "Success",
+ Type = "Status",
+ Status = ServiceActions.ServiceStatus(),
+ ReleaseStream = IsBeta ? "beta" : "stable",
+ AutomaticUpgradeDisabled = CurrentSettings.AutomaticUpdatesDisabled.ToString(),
+ AutomaticUpgradeURL = CurrentSettings.AutomaticUpdateURL,
+ };
+ await writer.WriteLineAsync(JsonConvert.SerializeObject(status));
+ await writer.FlushAsync();
+
+ //if a new client attaches - send the last update check status
+ if (lastUpdateCheck != null) {
+ await writer.WriteLineAsync(JsonConvert.SerializeObject(lastInstallationNotification));
+ await writer.FlushAsync();
+ }
+ } catch (Exception ex) {
+ Logger.Error("UNEXPECTED ERROR: {}", ex);
+ }
}
#pragma warning disable 1998 //This async method lacks 'await'
@@ -902,7 +906,7 @@ private void stopProcessForcefully(string processName, string description) {
}
worker.Kill();
worker.WaitForExit(5000);
- Logger.Info("Stopping the {description} process exited cleanly", description);
+ Logger.Info("Stopping the {description} process killed", description);
worker.Dispose();
} catch (Exception e) {
Logger.Error(e, "Unexpected error when closing the {description}!", description);
From 0cecf159cc31c16fa4dac188a4576df88aeb02ef Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Tue, 17 Sep 2024 18:31:11 -0400
Subject: [PATCH 17/50] remove comments that didn't get saved
---
ZitiDesktopEdge.Client/Server/IPCServer.cs | 4 ----
1 file changed, 4 deletions(-)
diff --git a/ZitiDesktopEdge.Client/Server/IPCServer.cs b/ZitiDesktopEdge.Client/Server/IPCServer.cs
index 4ef483ad3..bb275daa3 100644
--- a/ZitiDesktopEdge.Client/Server/IPCServer.cs
+++ b/ZitiDesktopEdge.Client/Server/IPCServer.cs
@@ -183,7 +183,6 @@ async public Task handleEventClientAsync(NamedPipeServerStream ss, OnClientAsync
await onClient(writer);
EventRegistry.MyEvent += eh;
- //try {
StreamReader reader = new StreamReader(ss);
string line = await reader.ReadLineAsync();
@@ -193,9 +192,6 @@ async public Task handleEventClientAsync(NamedPipeServerStream ss, OnClientAsync
}
Logger.Debug("handleEventClientAsync is complete");
- //} catch (Exception e) {
- // Logger.Error(e, "Unexpected error when reading from or writing to a client pipe.");
- //}
EventRegistry.MyEvent -= eh;
}
} catch (Exception e) {
From 1bc659c58661126ff9b08fc17efceace9badfc61 Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Tue, 17 Sep 2024 18:35:48 -0400
Subject: [PATCH 18/50] changes after PR review
---
ZitiUpdateService/UpdateService.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/ZitiUpdateService/UpdateService.cs b/ZitiUpdateService/UpdateService.cs
index 0039e4e8e..31dd6e5aa 100644
--- a/ZitiUpdateService/UpdateService.cs
+++ b/ZitiUpdateService/UpdateService.cs
@@ -542,12 +542,12 @@ private void zitiEdgeTunnelAlivenessCheck(object sender, ElapsedEventArgs e) {
dataClient.GetStatusAsync().Wait();
zetSemaphore.Release();
Interlocked.Exchange(ref zetFailedCheckCounter, 0);
- Logger.Info("ziti-edge-tunnel aliveness check ends successfully");
+ Logger.Trace("ziti-edge-tunnel aliveness check ends successfully");
} else {
Interlocked.Add(ref zetFailedCheckCounter, 1);
Logger.Warn("ziti-edge-tunnel aliveness check appears blocked and has been for {} times", zetFailedCheckCounter);
if (zetFailedCheckCounter > 2) {
- //after 10 seconds, just terminate ziti-edge-tunnel
+ //after 3 failures, just terminate ziti-edge-tunnel
Logger.Warn("forcefully stopping ziti-edge-tunnel as it has been blocked for too long");
stopProcessForcefully("ziti-edge-tunnel", "data service [ziti]");
From 0c7305cffbaa1630418b8060ea330c0c7ad9c839 Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Tue, 17 Sep 2024 18:47:17 -0400
Subject: [PATCH 19/50] add release-notes and remove a catch
---
.../ServiceClient/DataClient.cs | 14 +++-------
release-notes.md | 27 +++++++++++++++++++
2 files changed, 30 insertions(+), 11 deletions(-)
diff --git a/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs b/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs
index 3f1b3bb27..6c2e298c9 100644
--- a/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs
+++ b/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs
@@ -146,17 +146,9 @@ async protected override Task ConnectPipesAsync() {
}
async public Task GetStatusAsync() {
- try {
- await sendAsync(new ServiceFunction() { Command = "Status" });
- var rtn = await readAsync(ipcReader);
- return rtn;
- } catch (Exception ioe) {
- //almost certainly a problem with the pipe - recreate the pipe...
- //setupPipe();
- //throw ioe;
- Logger.Error(ioe, "Unexpected error in GetStatusAsync");
- }
- return null;
+ await sendAsync(new ServiceFunction() { Command = "Status" });
+ var rtn = await readAsync(ipcReader);
+ return rtn;
}
async public Task AddIdentityAsync(string jwtFileName, bool activate, string jwtContent) {
diff --git a/release-notes.md b/release-notes.md
index 9543a1d83..1d8171b99 100644
--- a/release-notes.md
+++ b/release-notes.md
@@ -1,3 +1,30 @@
+# Release 2.5.0.5
+
+## What's New
+* Added stalled ziti-edge-tunnel detection. If the process doesn't respond for 15 seconds the monitor service will
+ administratively terminate the process. Example log output shown below:
+
+ [2024-09-17T22:27:20.980Z] INFO ZitiUpdateService.UpdateService ziti-edge-tunnel aliveness check ends successfully
+ [2024-09-17T22:27:35.974Z] WARN ZitiUpdateService.UpdateService ziti-edge-tunnel aliveness check appears blocked and has been for 1 times
+ [2024-09-17T22:27:40.975Z] WARN ZitiUpdateService.UpdateService ziti-edge-tunnel aliveness check appears blocked and has been for 2 times
+ [2024-09-17T22:27:45.975Z] WARN ZitiUpdateService.UpdateService ziti-edge-tunnel aliveness check appears blocked and has been for 3 times
+ [2024-09-17T22:27:45.975Z] WARN ZitiUpdateService.UpdateService forcefully stopping ziti-edge-tunnel as it has been blocked for too long
+ [2024-09-17T22:27:45.975Z] INFO ZitiUpdateService.UpdateService Closing the "data service [ziti]" process
+ [2024-09-17T22:27:45.975Z] INFO ZitiUpdateService.UpdateService Killing: System.Diagnostics.Process (ziti-edge-tunnel)
+
+## Other changes:
+* n/a
+
+## Bugs fixed:
+* n/a
+
+## Dependency Updates
+
+ziti-edge-tunnel.exe version -v:
+* ziti-tunneler: v2.0.0-alpha19
+* *ziti-sdk: 2.0.0-alpha21
+* *tlsuv: v0.31.4[OpenSSL 3.3.1 4 Jun 2024]
+
# Release 2.5.0.3
## What's New
From fd7427c1856156c8a71fbfcd4cfbc282e55df2d3 Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Tue, 17 Sep 2024 19:57:28 -0400
Subject: [PATCH 20/50] github workflow updates, update to 2.5.0.6
---
.github/workflows/dependabot.yml | 12 ++++++++++++
.github/workflows/installer.build.yml | 8 ++++----
release-streams/ctrlha-alpha.json | 20 ++++++++++----------
version | 2 +-
4 files changed, 27 insertions(+), 15 deletions(-)
create mode 100644 .github/workflows/dependabot.yml
diff --git a/.github/workflows/dependabot.yml b/.github/workflows/dependabot.yml
new file mode 100644
index 000000000..465aa07cc
--- /dev/null
+++ b/.github/workflows/dependabot.yml
@@ -0,0 +1,12 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
+name: dependabot
+
+version: 2
+updates:
+ - package-ecosystem: "" # See documentation for possible values
+ directory: "/" # Location of package manifests
+ schedule:
+ interval: "weekly"
diff --git a/.github/workflows/installer.build.yml b/.github/workflows/installer.build.yml
index 6b115ea56..baf65d404 100644
--- a/.github/workflows/installer.build.yml
+++ b/.github/workflows/installer.build.yml
@@ -43,12 +43,12 @@ jobs:
- name: Set up environment variable
run: echo "ZITI_EDGE_TUNNEL_BUILD=${{ github.event.inputs.zet }}" >> $GITHUB_ENV
- name: Git Checkout
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
with:
persist-credentials: false
- - uses: microsoft/setup-msbuild@v1
+ - uses: microsoft/setup-msbuild@v
- name: Set up Go
- uses: actions/setup-go@v3
+ uses: actions/setup-go@v5
- if: github.event_name == 'push'
run: echo "GIT_BRANCH=$($env:GITHUB_REF.replace('refs/heads/', ''))" >> $env:GITHUB_ENV
- if: github.event_name == 'pull_request'
@@ -71,7 +71,7 @@ jobs:
run: choco install advanced-installer --version="$(cat .\adv-inst-version)" --yes
- name: Setting up VERSION env var
run: echo "VERSION=$(cat .\version)" >> $env:GITHUB_ENV
- - uses: nuget/setup-nuget@v1
+ - uses: nuget/setup-nuget@v2
with:
nuget-api-key: ${{ secrets.NuGetAPIKey }}
nuget-version: '5.8.1'
diff --git a/release-streams/ctrlha-alpha.json b/release-streams/ctrlha-alpha.json
index 201a0cbdd..4e0775f2d 100644
--- a/release-streams/ctrlha-alpha.json
+++ b/release-streams/ctrlha-alpha.json
@@ -1,12 +1,12 @@
{
- "name": "2.5.0.4",
- "tag_name": "2.5.0.4",
- "published_at": "2024-07-30T14:53:31Z",
- "installation_critical": false,
- "assets": [
- {
- "name": "Ziti.Desktop.Edge.Client-2.5.0.4.exe",
- "browser_download_url": "https://github.com/openziti/desktop-edge-win/releases/download/2.5.0.4-alpha/Ziti.Desktop.Edge.Client-2.5.0.4.exe"
- }
- ]
+ "name": "2.5.0.5",
+ "tag_name": "2.5.0.5",
+ "published_at": "2024-09-17T22:53:03Z",
+ "installation_critical": false,
+ "assets": [
+ {
+ "name": "Ziti.Desktop.Edge.Client-2.5.0.5.exe",
+ "browser_download_url": "https://github.com/openziti/desktop-edge-win/releases/download/2.5.0.5/Ziti.Desktop.Edge.Client-2.5.0.5.exe"
+ }
+ ]
}
diff --git a/version b/version
index 389b437ac..6b9721605 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-2.5.0.5
\ No newline at end of file
+2.5.0.6
\ No newline at end of file
From 279483e798cd48431adb6276eaf3be42caf9018e Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Tue, 17 Sep 2024 19:58:25 -0400
Subject: [PATCH 21/50] missed the 2
---
.github/workflows/installer.build.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/installer.build.yml b/.github/workflows/installer.build.yml
index baf65d404..898f229f6 100644
--- a/.github/workflows/installer.build.yml
+++ b/.github/workflows/installer.build.yml
@@ -46,7 +46,7 @@ jobs:
uses: actions/checkout@v4
with:
persist-credentials: false
- - uses: microsoft/setup-msbuild@v
+ - uses: microsoft/setup-msbuild@v2
- name: Set up Go
uses: actions/setup-go@v5
- if: github.event_name == 'push'
From 94fadabdfbf48d437a7491d4b49de5befddcf9b7 Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Tue, 17 Sep 2024 20:48:35 -0400
Subject: [PATCH 22/50] build updates
---
Installer/build.ps1 | 2 +-
Installer/output-build-json.ps1 | 4 ++--
build-test-release.ps1 | 15 ++++++++-------
release-notes.md | 2 +-
4 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/Installer/build.ps1 b/Installer/build.ps1
index 017de3fff..a589a70f6 100644
--- a/Installer/build.ps1
+++ b/Installer/build.ps1
@@ -128,5 +128,5 @@ echo "========================== build.ps1 completed =========================="
$defaultRootUrl = "https://github.com/openziti/desktop-edge-win/releases/download/"
$defaultStream = "beta"
$defaultPublishedAt = Get-Date
-$updateJson = "${installerVersion}.json"
+$updateJson = "${scriptPath}\Output\Ziti Desktop Edge Client-${installerVersion}.exe.json"
& .\Installer\output-build-json.ps1 -version $installerVersion -url $defaultRootUrl -stream $defaultStream -published_at $defaultPublishedAt -outputPath $updateJson
diff --git a/Installer/output-build-json.ps1 b/Installer/output-build-json.ps1
index bca078a90..77c8ef39b 100644
--- a/Installer/output-build-json.ps1
+++ b/Installer/output-build-json.ps1
@@ -5,8 +5,8 @@
param(
[Parameter(Mandatory = $true)]
[string]$version,
- [string]$url = "http://localhost:8000/local",
- [string]$stream = "beta",
+ [string]$url = "http://localhost:8000/release-streams/local",
+ [string]$stream = "local",
[string]$outputPath = "${version}.json",
[datetime]$published_at
)
diff --git a/build-test-release.ps1 b/build-test-release.ps1
index 48ff24219..ebbd569bc 100644
--- a/build-test-release.ps1
+++ b/build-test-release.ps1
@@ -8,8 +8,8 @@
param(
[Parameter(Mandatory = $true)]
[string]$version,
- [string]$url = "http://localhost:8000/local",
- [string]$stream = "beta",
+ [string]$url = "http://localhost:8000/release-streams/local",
+ [string]$stream = "local",
[datetime]$published_at = (Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ"),
[bool]$jsonOnly = $false,
[bool]$revertGitAfter = $true
@@ -21,7 +21,7 @@ $scriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Path -Parent
$outputPath = "${version}.json"
& .\Installer\output-build-json.ps1 -version $version -url $url -stream $stream -published_at $published_at -outputPath $outputPath
-Copy-Item -Force "$outputPath" "$scriptDirectory\release-streams\local\${version}"
+
Copy-Item -Force "${version}.json" "$scriptDirectory\release-streams\${stream}.json"
echo "json file written to: $scriptDirectory\release-streams\${stream}.json"
@@ -33,10 +33,11 @@ if(! $jsonOnly) {
Write-Host "build.ps1 failed!"
exit $exitCode
}
- Write-Host "only updating the json at $scriptDirectory\release-streams\${stream}.json"
- mkdir $scriptDirectory\release-streams\local\${version} -ErrorAction Ignore > $null
- Move-Item -Force "./Installer/Output/Ziti Desktop Edge Client-${version}.exe" "$scriptDirectory\release-streams\local\${version}\Ziti.Desktop.Edge.Client-${version}.exe"
- Move-Item -Force "./Installer/Output/Ziti Desktop Edge Client-${version}.exe.sha256" "$scriptDirectory\release-streams\local\${version}\Ziti.Desktop.Edge.Client-${version}.exe.sha256"
+
+ mkdir "$scriptDirectory\release-streams\local\${version}" -ErrorAction Ignore > $null
+ #echo "$scriptDirectory/Installer/Output/Ziti Desktop Edge Client-${version}.exe" "$scriptDirectory\release-streams\local\${version}\Ziti.Desktop.Edge.Client-${version}.exe"
+ Move-Item -Force "$scriptDirectory/Installer/Output/Ziti Desktop Edge Client-${version}.exe" "$scriptDirectory\release-streams\local\${version}\Ziti.Desktop.Edge.Client-${version}.exe"
+ Move-Item -Force "$scriptDirectory/Installer/Output/Ziti Desktop Edge Client-${version}.exe.sha256" "$scriptDirectory\release-streams\local\${version}\Ziti.Desktop.Edge.Client-${version}.exe.sha256"
Write-Host ""
Write-Host "done."
Write-Host "installer exists at $scriptDirectory\release-streams\local\${version}\Ziti.Desktop.Edge.Client-${version}.exe"
diff --git a/release-notes.md b/release-notes.md
index 1d8171b99..bc4a012ce 100644
--- a/release-notes.md
+++ b/release-notes.md
@@ -1,4 +1,4 @@
-# Release 2.5.0.5
+# Release 2.5.0.6
## What's New
* Added stalled ziti-edge-tunnel detection. If the process doesn't respond for 15 seconds the monitor service will
From e85ca9dd531c83492ab2ee36ec3e2ee2db377a23 Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Tue, 17 Sep 2024 21:01:24 -0400
Subject: [PATCH 23/50] use correct url
---
release-streams/ctrlha-alpha.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/release-streams/ctrlha-alpha.json b/release-streams/ctrlha-alpha.json
index 4e0775f2d..f442dd9da 100644
--- a/release-streams/ctrlha-alpha.json
+++ b/release-streams/ctrlha-alpha.json
@@ -6,7 +6,7 @@
"assets": [
{
"name": "Ziti.Desktop.Edge.Client-2.5.0.5.exe",
- "browser_download_url": "https://github.com/openziti/desktop-edge-win/releases/download/2.5.0.5/Ziti.Desktop.Edge.Client-2.5.0.5.exe"
+ "browser_download_url": "https://github.com/openziti/desktop-edge-win/releases/download/2.5.0.5-alpha/Ziti.Desktop.Edge.Client-2.5.0.6.exe"
}
]
}
From eed7c01aa62314a92d0867559dc525aa944b461d Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Tue, 17 Sep 2024 21:07:49 -0400
Subject: [PATCH 24/50] update ctrlha to 2.5.0.6
---
release-streams/ctrlha-alpha.json | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/release-streams/ctrlha-alpha.json b/release-streams/ctrlha-alpha.json
index f442dd9da..ead99af98 100644
--- a/release-streams/ctrlha-alpha.json
+++ b/release-streams/ctrlha-alpha.json
@@ -1,12 +1,12 @@
{
- "name": "2.5.0.5",
- "tag_name": "2.5.0.5",
- "published_at": "2024-09-17T22:53:03Z",
+ "name": "2.5.0.6",
+ "tag_name": "2.5.0.6",
+ "published_at": "2024-09-18T00:51:57Z",
"installation_critical": false,
"assets": [
{
- "name": "Ziti.Desktop.Edge.Client-2.5.0.5.exe",
- "browser_download_url": "https://github.com/openziti/desktop-edge-win/releases/download/2.5.0.5-alpha/Ziti.Desktop.Edge.Client-2.5.0.6.exe"
+ "name": "Ziti.Desktop.Edge.Client-2.5.0.6.exe",
+ "browser_download_url": "https://github.com/openziti/desktop-edge-win/releases/download/2.5.0.6-alpha/Ziti.Desktop.Edge.Client-2.5.0.6.exe"
}
]
}
From 1b20be0f26486ce84e978ebdad1fedf4659490a1 Mon Sep 17 00:00:00 2001
From: dovholuknf <46322585+dovholuknf@users.noreply.github.com>
Date: Wed, 18 Sep 2024 14:17:53 -0400
Subject: [PATCH 25/50] updates after additional testing
---
Installer/build.ps1 | 32 ++++++----
.../ServiceClient/AbstractClient.cs | 8 +--
.../ServiceClient/DataClient.cs | 2 +-
ZitiDesktopEdge.sln | 3 +
ZitiUpdateService/UpdateService.cs | 59 +++++++++++--------
.../ZitiUpdateService-log.config | 4 +-
build-test-release.ps1 | 16 +++--
7 files changed, 77 insertions(+), 47 deletions(-)
diff --git a/Installer/build.ps1 b/Installer/build.ps1
index a589a70f6..a03f0f9d5 100644
--- a/Installer/build.ps1
+++ b/Installer/build.ps1
@@ -1,5 +1,13 @@
-$ErrorActionPreference = "Stop"
+param(
+ [string]$version,
+ [string]$url = "https://github.com/openziti/desktop-edge-win/releases/download/",
+ [string]$stream = "beta",
+ [datetime]$published_at = (Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ"),
+ [bool]$jsonOnly = $false,
+ [bool]$revertGitAfter = $true
+)
+$ErrorActionPreference = "Stop"
function verifyFile($path) {
if (Test-Path -Path "$path") {
"OK: $path exists!"
@@ -18,7 +26,7 @@ $ADV_INST_HOME = "C:\Program Files (x86)\Caphyon\Advanced Installer ${ADV_INST_V
$SIGNTOOL="${ADV_INST_HOME}\third-party\winsdk\x64\signtool.exe"
$ADVINST = "${ADV_INST_HOME}\bin\x86\AdvancedInstaller.com"
$ADVPROJECT = "${scriptPath}\ZitiDesktopEdge.aip"
-$ZITI_EDGE_TUNNEL_VERSION="v2.0.0-alpha19"
+$ZITI_EDGE_TUNNEL_VERSION="v2.0.0-alpha20"
echo "Cleaning previous build folder if it exists"
Remove-Item "${buildPath}" -r -ErrorAction Ignore
@@ -77,7 +85,11 @@ msbuild ZitiDesktopEdge.sln /property:Configuration=Release
Pop-Location
-$installerVersion=(Get-Content -Path ${checkoutRoot}\version)
+if ($version -eq "") {
+ $version=(Get-Content -Path ${checkoutRoot}\version)
+} else {
+ echo "VERSION set to $version"
+}
if($null -ne $env:ZITI_DESKTOP_EDGE_VERSION) {
echo "ZITI_DESKTOP_EDGE_VERSION is set. Using that: ${env:ZITI_DESKTOP_EDGE_VERSION} instead of version found in file ${installerVersion}"
$installerVersion=$env:ZITI_DESKTOP_EDGE_VERSION
@@ -85,8 +97,8 @@ if($null -ne $env:ZITI_DESKTOP_EDGE_VERSION) {
}
$action = '/SetVersion'
-echo "issuing $ADVINST /edit $ADVPROJECT $action $installerVersion (service version: $serviceVersion) - see https://www.advancedinstaller.com/user-guide/set-version.html"
-& $ADVINST /edit $ADVPROJECT $action $installerVersion
+echo "issuing $ADVINST /edit $ADVPROJECT $action $version (service version: $serviceVersion) - see https://www.advancedinstaller.com/user-guide/set-version.html"
+& $ADVINST /edit $ADVPROJECT $action $version
$action = '/build'
echo "Assembling installer using AdvancedInstaller at: $ADVINST $action $ADVPROJECT"
@@ -125,8 +137,8 @@ if($null -eq $env:OPENZITI_P12_PASS_2024) {
(Get-FileHash "${exeAbsPath}").Hash > "${scriptPath}\Output\Ziti Desktop Edge Client-${installerVersion}.exe.sha256"
echo "========================== build.ps1 completed =========================="
-$defaultRootUrl = "https://github.com/openziti/desktop-edge-win/releases/download/"
-$defaultStream = "beta"
-$defaultPublishedAt = Get-Date
-$updateJson = "${scriptPath}\Output\Ziti Desktop Edge Client-${installerVersion}.exe.json"
-& .\Installer\output-build-json.ps1 -version $installerVersion -url $defaultRootUrl -stream $defaultStream -published_at $defaultPublishedAt -outputPath $updateJson
+$outputPath = "${scriptPath}\Output\Ziti Desktop Edge Client-${installerVersion}.exe.json"
+& .\Installer\output-build-json.ps1 -version $version -url $url -stream $stream -published_at $published_at -outputPath $outputPath
+
+echo "REMOVING .back files: ${scriptPath}\*back*"
+Remove-Item "${scriptPath}\*back*" -Recurse -ErrorAction SilentlyContinue
diff --git a/ZitiDesktopEdge.Client/ServiceClient/AbstractClient.cs b/ZitiDesktopEdge.Client/ServiceClient/AbstractClient.cs
index 9716a674b..01725a4f7 100644
--- a/ZitiDesktopEdge.Client/ServiceClient/AbstractClient.cs
+++ b/ZitiDesktopEdge.Client/ServiceClient/AbstractClient.cs
@@ -59,8 +59,8 @@ public abstract class AbstractClient {
protected virtual void ClientConnected(object e) {
Connected = true;
Reconnecting = false;
- CleanShutdown = false;
- Logger.Debug("Client connected successfully. Setting CleanShutdown set to false.");
+ ExpectedShutdown = false;
+ Logger.Debug("Client connected successfully. Setting UnexpectedShutdown set to false.");
ipcWriter = new StreamWriter(pipeClient);
ipcReader = new StreamReader(pipeClient);
@@ -102,7 +102,7 @@ protected virtual void ClientDisconnected(object e) {
}
protected virtual void ShutdownEvent(StatusEvent e) {
- CleanShutdown = true;
+ ExpectedShutdown = true;
OnShutdownEvent?.Invoke(this, e);
}
@@ -158,7 +158,7 @@ async protected Task sendAsync(object objToSend) {
public bool Reconnecting { get; set; }
public bool Connected { get; set; }
- public bool CleanShutdown { get; set; }
+ public bool ExpectedShutdown { get; set; }
public AbstractClient(string id) {
this.Id = id;
diff --git a/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs b/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs
index 6c2e298c9..793f5a114 100644
--- a/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs
+++ b/ZitiDesktopEdge.Client/ServiceClient/DataClient.cs
@@ -55,7 +55,7 @@ public class DataClient : AbstractClient {
protected override void ShutdownEvent(StatusEvent e) {
Logger.Debug("Clean shutdown detected from ziti");
- CleanShutdown = true;
+ ExpectedShutdown = true;
base.ShutdownEvent(e);
}
diff --git a/ZitiDesktopEdge.sln b/ZitiDesktopEdge.sln
index 02ca30986..f6986126b 100644
--- a/ZitiDesktopEdge.sln
+++ b/ZitiDesktopEdge.sln
@@ -11,6 +11,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
Installer\build.ps1 = Installer\build.ps1
.github\workflows\installer.build.yml = .github\workflows\installer.build.yml
.github\workflows\mattermost-ziti-webhook.yml = .github\workflows\mattermost-ziti-webhook.yml
+ Installer\output-build-json.ps1 = Installer\output-build-json.ps1
README.md = README.md
Installer\reg.bat = Installer\reg.bat
release-notes.md = release-notes.md
@@ -32,6 +33,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "release-streams", "release-streams", "{36C30126-C9DC-4233-835E-9E036BCD1A29}"
ProjectSection(SolutionItems) = preProject
release-streams\beta.json = release-streams\beta.json
+ release-streams\ctrlha-alpha.json = release-streams\ctrlha-alpha.json
release-streams\dev.json = release-streams\dev.json
release-streams\latest.json = release-streams\latest.json
release-streams\stable.json = release-streams\stable.json
@@ -44,6 +46,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{472A
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{DB005713-0237-4719-9F7B-A239879B290D}"
ProjectSection(SolutionItems) = preProject
+ .github\workflows\dependabot.yml = .github\workflows\dependabot.yml
.github\workflows\installer.build.yml = .github\workflows\installer.build.yml
.github\workflows\mattermost-ziti-webhook.yml = .github\workflows\mattermost-ziti-webhook.yml
.github\workflows\release-drafter.yml = .github\workflows\release-drafter.yml
diff --git a/ZitiUpdateService/UpdateService.cs b/ZitiUpdateService/UpdateService.cs
index 31dd6e5aa..ac739554b 100644
--- a/ZitiUpdateService/UpdateService.cs
+++ b/ZitiUpdateService/UpdateService.cs
@@ -41,6 +41,7 @@ limitations under the License.
using ZitiUpdateService.Checkers;
using System.Security.Policy;
using Newtonsoft.Json.Linq;
+using System.Runtime.Remoting.Messaging;
#if !SKIPUPDATE
using ZitiUpdateService.Checkers.PeFile;
@@ -548,6 +549,7 @@ private void zitiEdgeTunnelAlivenessCheck(object sender, ElapsedEventArgs e) {
Logger.Warn("ziti-edge-tunnel aliveness check appears blocked and has been for {} times", zetFailedCheckCounter);
if (zetFailedCheckCounter > 2) {
//after 3 failures, just terminate ziti-edge-tunnel
+ Interlocked.Exchange(ref zetFailedCheckCounter, 0); //reset the counter back to 0
Logger.Warn("forcefully stopping ziti-edge-tunnel as it has been blocked for too long");
stopProcessForcefully("ziti-edge-tunnel", "data service [ziti]");
@@ -561,31 +563,31 @@ private void zitiEdgeTunnelAlivenessCheck(object sender, ElapsedEventArgs e) {
}
async private Task onEventsClientAsync(StreamWriter writer) {
- try {
- Logger.Info("a new events client was connected");
- //reset to release stream
- //initial status when connecting the event stream
- MonitorServiceStatusEvent status = new MonitorServiceStatusEvent() {
- Code = 0,
- Error = "",
- Message = "Success",
- Type = "Status",
- Status = ServiceActions.ServiceStatus(),
- ReleaseStream = IsBeta ? "beta" : "stable",
- AutomaticUpgradeDisabled = CurrentSettings.AutomaticUpdatesDisabled.ToString(),
- AutomaticUpgradeURL = CurrentSettings.AutomaticUpdateURL,
- };
- await writer.WriteLineAsync(JsonConvert.SerializeObject(status));
- await writer.FlushAsync();
-
- //if a new client attaches - send the last update check status
- if (lastUpdateCheck != null) {
- await writer.WriteLineAsync(JsonConvert.SerializeObject(lastInstallationNotification));
- await writer.FlushAsync();
- }
- } catch (Exception ex) {
- Logger.Error("UNEXPECTED ERROR: {}", ex);
- }
+ try {
+ Logger.Info("a new events client was connected");
+ //reset to release stream
+ //initial status when connecting the event stream
+ MonitorServiceStatusEvent status = new MonitorServiceStatusEvent() {
+ Code = 0,
+ Error = "",
+ Message = "Success",
+ Type = "Status",
+ Status = ServiceActions.ServiceStatus(),
+ ReleaseStream = IsBeta ? "beta" : "stable",
+ AutomaticUpgradeDisabled = CurrentSettings.AutomaticUpdatesDisabled.ToString(),
+ AutomaticUpgradeURL = CurrentSettings.AutomaticUpdateURL,
+ };
+ await writer.WriteLineAsync(JsonConvert.SerializeObject(status));
+ await writer.FlushAsync();
+
+ //if a new client attaches - send the last update check status
+ if (lastUpdateCheck != null) {
+ await writer.WriteLineAsync(JsonConvert.SerializeObject(lastInstallationNotification));
+ await writer.FlushAsync();
+ }
+ } catch (Exception ex) {
+ Logger.Error("UNEXPECTED ERROR: {}", ex);
+ }
}
#pragma warning disable 1998 //This async method lacks 'await'
@@ -898,6 +900,11 @@ private void stopProcessForcefully(string processName, string description) {
Logger.Info("No {description} process found to close.", description);
return;
}
+ // though strange, because we're about to kill the process, this is still
+ // considered 'expected' since the monitor service is shutting it down (forcefully).
+ // not clean is to indicate the process ended unexpectedly
+ dataClient.ExpectedShutdown = true;
+
foreach (Process worker in workers) {
try {
Logger.Info("Killing: {0}", worker);
@@ -972,7 +979,7 @@ private void Svc_OnClientConnected(object sender, object e) {
private void Svc_OnClientDisconnected(object sender, object e) {
DataClient svc = (DataClient)sender;
- if (svc.CleanShutdown) {
+ if (svc.ExpectedShutdown) {
//then this is fine and expected - the service is shutting down
Logger.Info("client disconnected due to clean service shutdown");
zetHealthcheck.Stop();
diff --git a/ZitiUpdateService/ZitiUpdateService-log.config b/ZitiUpdateService/ZitiUpdateService-log.config
index 6184e0bee..27be79ed0 100644
--- a/ZitiUpdateService/ZitiUpdateService-log.config
+++ b/ZitiUpdateService/ZitiUpdateService-log.config
@@ -5,7 +5,9 @@
-
Date: Wed, 18 Sep 2024 14:19:56 -0400
Subject: [PATCH 26/50] nothing more than a format commit on all files
---
AWSSigner.NET/Program.cs | 426 +-
DesktopEdge/App.xaml.cs | 179 +-
DesktopEdge/MainWindow.xaml.cs | 4028 +++++++++--------
DesktopEdge/Models/FilterData.cs | 77 +-
DesktopEdge/Models/MFA.cs | 58 +-
DesktopEdge/Models/MessageCount.cs | 65 +-
DesktopEdge/Models/UIModel.cs | 39 +-
DesktopEdge/Models/ViewState.cs | 67 +-
DesktopEdge/Models/ZitiIdentity.cs | 332 +-
DesktopEdge/Models/ZitiService.cs | 633 +--
DesktopEdge/Native/NativeMethods.cs | 97 +-
DesktopEdge/Native/WinAPI.cs | 139 +-
DesktopEdge/Properties/AssemblyInfo.cs | 110 +-
DesktopEdge/Utils/UIUtils.cs | 93 +-
.../Views/Controls/StyledButton.xaml.cs | 188 +-
DesktopEdge/Views/Controls/Toggler.xaml.cs | 167 +-
.../Views/ItemRenderers/Filter.xaml.cs | 236 +-
.../Views/ItemRenderers/IdentityItem.xaml.cs | 740 +--
.../Views/ItemRenderers/MenuEditItem.xaml.cs | 133 +-
.../ItemRenderers/MenuEditSearch.xaml.cs | 155 +-
.../ItemRenderers/MenuEditToggle.xaml.cs | 171 +-
.../ItemRenderers/MenuIdentityItem.xaml.cs | 156 +-
.../Views/ItemRenderers/MenuItem.xaml.cs | 123 +-
.../Views/ItemRenderers/SubMenuItem.xaml.cs | 82 +-
.../Views/ItemRenderers/SubOptionItem.xaml.cs | 109 +-
DesktopEdge/Views/Screens/Debugging.xaml.cs | 83 +-
.../Views/Screens/IdentityDetails.xaml.cs | 1181 ++---
DesktopEdge/Views/Screens/MFAScreen.xaml.cs | 698 +--
DesktopEdge/Views/Screens/MainMenu.xaml.cs | 1691 +++----
.../DataStructures/DataStructures.cs | 261 +-
.../Properties/AssemblyInfo.cs | 34 +-
.../Server/EventRegistry.cs | 43 +-
ZitiDesktopEdge.Client/Server/IPCServer.cs | 176 +-
.../Server/ServiceActions.cs | 98 +-
.../ServiceClient/AbstractClient.cs | 255 +-
.../ServiceClient/DataClient.cs | 292 +-
.../ServiceClient/MonitorClient.cs | 312 +-
ZitiDesktopEdge.Client/Utility/GithubAPI.cs | 109 +-
.../Utility/UpgradeSentinel.cs | 103 +-
ZitiUpdateService/Program.cs | 165 +-
ZitiUpdateService/ProjectInstaller.cs | 56 +-
ZitiUpdateService/Properties/AssemblyInfo.cs | 34 +-
ZitiUpdateService/UpdateService.cs | 2213 +++++----
ZitiUpdateService/Utils.cs | 63 +-
ZitiUpdateService/checkers/FilesystemCheck.cs | 101 +-
ZitiUpdateService/checkers/GithubCheck.cs | 379 +-
.../checkers/PeFile/SignedFileStructs.cs | 115 +-
.../checkers/PeFile/SignedFileValidator.cs | 339 +-
.../checkers/PeFile/StructHelper.cs | 43 +-
.../checkers/PeFile/Win32Crypto.cs | 99 +-
ZitiUpdateService/checkers/UpdateCheckers.cs | 55 +-
ZitiUpdateService/utils/Settings.cs | 271 +-
ZitiUpgradeSentinel/Program.cs | 354 +-
.../Properties/AssemblyInfo.cs | 34 +-
54 files changed, 10215 insertions(+), 8045 deletions(-)
diff --git a/AWSSigner.NET/Program.cs b/AWSSigner.NET/Program.cs
index 89c63ea4d..24517f9d5 100644
--- a/AWSSigner.NET/Program.cs
+++ b/AWSSigner.NET/Program.cs
@@ -26,203 +26,231 @@ limitations under the License.
using NLog.Targets;
-namespace AWSSigner {
- class Program {
- private static readonly NLog.Logger Logger = LogManager.GetCurrentClassLogger();
- private static bool showDebugOutput = "TRUE" == ("" + Environment.GetEnvironmentVariable("AWSSIGNER_DEBUG")).ToUpper();
- static void Main(string[] args) {
- var asm = Assembly.GetExecutingAssembly();
- var curdir = Path.GetDirectoryName(System.AppContext.BaseDirectory);
- var config = new LoggingConfiguration();
- // Targets where to log to: File and Console
- var logfile = new FileTarget("logfile") {
- FileName = $"AWSSigner.log",
- ArchiveEvery = FileArchivePeriod.Day,
- ArchiveNumbering = ArchiveNumberingMode.Rolling,
- MaxArchiveFiles = 7,
- AutoFlush = true,
- Layout = "[${date:universalTime=true:format=yyyy-MM-ddTHH:mm:ss.fff}Z] ${level:uppercase=true:padding=5}\t${logger}\t${message}\t${exception:format=tostring}",
- };
- var logconsole = new ConsoleTarget("logconsole");
-
- // Rules for mapping loggers to targets
- config.AddRule(LogLevel.Info, LogLevel.Fatal, logconsole);
- config.AddRule(LogLevel.Info, LogLevel.Fatal, logfile);
-
- // Apply config
- LogManager.Configuration = config;
-
- Logger.Info("========================= signing started =========================");
- Logger.Info("logger initialized");
- Logger.Info(" - name : {0}", asm.GetName());
- Logger.Info(" - path : {0}", curdir);
- Logger.Info(" - args : {0}", String.Join(",", args));
- Logger.Info("========================================================================");
-
- if (args[0].Contains(AppDomain.CurrentDomain.FriendlyName)) {
- Logger.Debug("args[0] contains the AppDomain.CurrentDomain.FriendlyName, must be using dotnet run?");
- args = args.Skip(1).ToArray();
- }
-
- bool argsValid = true;
- if (args.Length < 1) {
- Logger.Info("Usage: signfile \n");
- Logger.Info("ERROR: provide target file to sign and cert to use as arguments");
- argsValid = false;
- }
-
- bool envVarsExist = VerifyEnvVar("AWS_KEY_ID");
- envVarsExist = VerifyEnvVar("AWS_ACCESS_KEY_ID");
- envVarsExist = VerifyEnvVar("AWS_REGION");
- envVarsExist = VerifyEnvVar("AWS_SECRET_ACCESS_KEY");
- envVarsExist = VerifyEnvVar("SIGNING_CERT");
-
- if (!argsValid || !envVarsExist) {
- return;
- }
-
- bool filesExist = true;
- string fileToSign = String.Join(",", args); //have to join all the args when spaces are used???
- Logger.Info($"File to sign: '{fileToSign}'");
- if (!File.Exists(fileToSign)) {
- Logger.Info($"File to sign doesn't exist: {fileToSign}");
- filesExist = false;
- }
- string certToUse = Environment.GetEnvironmentVariable("SIGNING_CERT");
- if (!File.Exists(certToUse)) {
- Logger.Info($"Cert to use doesn't exist : {certToUse}");
- filesExist = false;
- }
-
- if (!filesExist) { return; }
-
- string exeAbsPath = Path.GetFullPath(fileToSign);
- string loc = Path.GetDirectoryName(exeAbsPath);
-
- string signToolPath = GetFullPath("signtool.exe");
- string awsKeyId = Environment.GetEnvironmentVariable("AWS_KEY_ID");
-
- if (!File.Exists(signToolPath)) {
- string signToolPathEnv = Environment.GetEnvironmentVariable("SIGNTOOL_PATH");
- if (!File.Exists(signToolPathEnv)) {
- Logger.Info($"ERROR: Signtool not found on path and SIGNTOOL_PATH environment variable not set or file doesn't exist: {signToolPathEnv}!");
- return;
- } else {
- Logger.Info($"Using signtool found via environment variable at: {signToolPathEnv}");
- signToolPath= signToolPathEnv;
- }
- }
-
- Logger.Info($"Using signtool : {signToolPath}");
- Logger.Info($"Using cert : {certToUse}");
- Logger.Info($"Signing file : {fileToSign}");
-
- Logger.Debug("----- signFile: producing digest to send to AWS KMS -----");
- RunProcess(signToolPath, $"sign /dg {loc} /fd sha256 /f \"{certToUse}\" \"{exeAbsPath}\"");
- Logger.Info(" - digest file produced, sending to KMS for signing");
-
- byte[] tosign = Convert.FromBase64String(File.ReadAllText($"{exeAbsPath}.dig"));
- Logger.Debug("----- signFile: sending digest to AWS KMS for signing. -----");
- string signature = SignWithAwsKms(awsKeyId, tosign);
- File.WriteAllText($"{exeAbsPath}.dig.signed", signature);
- Logger.Info(" - digest signed, attaching signature");
-
- Logger.Debug($"----- signature len: {signature.Length} ----");
- Logger.Debug("----- done signing digest -----");
- Logger.Debug("----- signFile: adding signature -----");
- RunProcess(signToolPath, $"sign /di \"{loc}\" \"{exeAbsPath}\"");
- Logger.Info(" - signature attached, timestamping");
-
- Logger.Debug("----- signFile: adding timestamp -----");
- RunProcess(signToolPath, $"timestamp /tr http://timestamp.digicert.com /td sha256 \"{exeAbsPath}\"");
- Logger.Info(" - timestamped, verifying");
-
- RunProcess(signToolPath, $"verify /pa \"{exeAbsPath}\"");
- Logger.Info(" - verified, removing any files leftover from signing");
- DeleteFile($"{exeAbsPath}.dig");
- DeleteFile($"{exeAbsPath}.dig.signed");
- DeleteFile($"{exeAbsPath}.p7u");
-
- Logger.Info($"process complete. signed: {fileToSign}\n");
- }
-
- static void RunProcess(string fileName, string arguments) {
- Logger.Debug($"RunProcess Args: {fileName} {arguments}");
- var process = new Process {
- StartInfo = new ProcessStartInfo {
- FileName = fileName,
- Arguments = arguments,
- RedirectStandardOutput = true,
- RedirectStandardError = true,
- UseShellExecute = false,
- CreateNoWindow = true
- }
- };
-
- process.Start();
- process.WaitForExit();
-
- string output = process.StandardOutput.ReadToEnd();
- string error = process.StandardError.ReadToEnd();
-
- if (!string.IsNullOrEmpty(output)) {
- Logger.Debug(output);
- }
-
- if (!string.IsNullOrEmpty(error)) {
- Logger.Error(error);
- }
-
- if (process.ExitCode != 0) {
- throw new Exception($"Process exited with code {process.ExitCode}: {error}");
- }
- }
-
- static string SignWithAwsKms(string keyId, byte[] digest) {
- var kmsClient = new AmazonKeyManagementServiceClient();
- var request = new SignRequest {
- KeyId = keyId,
- Message = new MemoryStream(digest),
- MessageType = MessageType.DIGEST,
- SigningAlgorithm = SigningAlgorithmSpec.RSASSA_PKCS1_V1_5_SHA_256
- };
-
- var response = kmsClient.SignAsync(request).Result;
-
- return Convert.ToBase64String(response.Signature.ToArray());
- }
-
- static void DeleteFile(string path) {
- if (File.Exists(path)) {
- File.Delete(path);
- }
- }
-
- public static bool ExistsOnPath(string fileName) {
- return GetFullPath(fileName) != null;
- }
-
- public static string GetFullPath(string fileName) {
- if (File.Exists(fileName))
- return Path.GetFullPath(fileName);
-
- string values = Environment.GetEnvironmentVariable("PATH");
- if (values == null) { return null; }
- foreach (var path in values.Split(Path.PathSeparator)) {
- var fullPath = Path.Combine(path, fileName);
- if (File.Exists(fullPath))
- return Path.GetFullPath(fullPath);
- }
- return null;
- }
-
- public static bool VerifyEnvVar(string envVar) {
- var val = Environment.GetEnvironmentVariable(envVar);
- if (string.IsNullOrEmpty(val)) {
- Logger.Info($"ERROR: Environment variable must be set: {envVar}");
- return false;
- }
- return true;
- }
- }
+namespace AWSSigner
+{
+ class Program
+ {
+ private static readonly NLog.Logger Logger = LogManager.GetCurrentClassLogger();
+ private static bool showDebugOutput = "TRUE" == ("" + Environment.GetEnvironmentVariable("AWSSIGNER_DEBUG")).ToUpper();
+ static void Main(string[] args)
+ {
+ var asm = Assembly.GetExecutingAssembly();
+ var curdir = Path.GetDirectoryName(System.AppContext.BaseDirectory);
+ var config = new LoggingConfiguration();
+ // Targets where to log to: File and Console
+ var logfile = new FileTarget("logfile")
+ {
+ FileName = $"AWSSigner.log",
+ ArchiveEvery = FileArchivePeriod.Day,
+ ArchiveNumbering = ArchiveNumberingMode.Rolling,
+ MaxArchiveFiles = 7,
+ AutoFlush = true,
+ Layout = "[${date:universalTime=true:format=yyyy-MM-ddTHH:mm:ss.fff}Z] ${level:uppercase=true:padding=5}\t${logger}\t${message}\t${exception:format=tostring}",
+ };
+ var logconsole = new ConsoleTarget("logconsole");
+
+ // Rules for mapping loggers to targets
+ config.AddRule(LogLevel.Info, LogLevel.Fatal, logconsole);
+ config.AddRule(LogLevel.Info, LogLevel.Fatal, logfile);
+
+ // Apply config
+ LogManager.Configuration = config;
+
+ Logger.Info("========================= signing started =========================");
+ Logger.Info("logger initialized");
+ Logger.Info(" - name : {0}", asm.GetName());
+ Logger.Info(" - path : {0}", curdir);
+ Logger.Info(" - args : {0}", String.Join(",", args));
+ Logger.Info("========================================================================");
+
+ if (args[0].Contains(AppDomain.CurrentDomain.FriendlyName))
+ {
+ Logger.Debug("args[0] contains the AppDomain.CurrentDomain.FriendlyName, must be using dotnet run?");
+ args = args.Skip(1).ToArray();
+ }
+
+ bool argsValid = true;
+ if (args.Length < 1)
+ {
+ Logger.Info("Usage: signfile \n");
+ Logger.Info("ERROR: provide target file to sign and cert to use as arguments");
+ argsValid = false;
+ }
+
+ bool envVarsExist = VerifyEnvVar("AWS_KEY_ID");
+ envVarsExist = VerifyEnvVar("AWS_ACCESS_KEY_ID");
+ envVarsExist = VerifyEnvVar("AWS_REGION");
+ envVarsExist = VerifyEnvVar("AWS_SECRET_ACCESS_KEY");
+ envVarsExist = VerifyEnvVar("SIGNING_CERT");
+
+ if (!argsValid || !envVarsExist)
+ {
+ return;
+ }
+
+ bool filesExist = true;
+ string fileToSign = String.Join(",", args); //have to join all the args when spaces are used???
+ Logger.Info($"File to sign: '{fileToSign}'");
+ if (!File.Exists(fileToSign))
+ {
+ Logger.Info($"File to sign doesn't exist: {fileToSign}");
+ filesExist = false;
+ }
+ string certToUse = Environment.GetEnvironmentVariable("SIGNING_CERT");
+ if (!File.Exists(certToUse))
+ {
+ Logger.Info($"Cert to use doesn't exist : {certToUse}");
+ filesExist = false;
+ }
+
+ if (!filesExist) { return; }
+
+ string exeAbsPath = Path.GetFullPath(fileToSign);
+ string loc = Path.GetDirectoryName(exeAbsPath);
+
+ string signToolPath = GetFullPath("signtool.exe");
+ string awsKeyId = Environment.GetEnvironmentVariable("AWS_KEY_ID");
+
+ if (!File.Exists(signToolPath))
+ {
+ string signToolPathEnv = Environment.GetEnvironmentVariable("SIGNTOOL_PATH");
+ if (!File.Exists(signToolPathEnv))
+ {
+ Logger.Info($"ERROR: Signtool not found on path and SIGNTOOL_PATH environment variable not set or file doesn't exist: {signToolPathEnv}!");
+ return;
+ }
+ else
+ {
+ Logger.Info($"Using signtool found via environment variable at: {signToolPathEnv}");
+ signToolPath = signToolPathEnv;
+ }
+ }
+
+ Logger.Info($"Using signtool : {signToolPath}");
+ Logger.Info($"Using cert : {certToUse}");
+ Logger.Info($"Signing file : {fileToSign}");
+
+ Logger.Debug("----- signFile: producing digest to send to AWS KMS -----");
+ RunProcess(signToolPath, $"sign /dg {loc} /fd sha256 /f \"{certToUse}\" \"{exeAbsPath}\"");
+ Logger.Info(" - digest file produced, sending to KMS for signing");
+
+ byte[] tosign = Convert.FromBase64String(File.ReadAllText($"{exeAbsPath}.dig"));
+ Logger.Debug("----- signFile: sending digest to AWS KMS for signing. -----");
+ string signature = SignWithAwsKms(awsKeyId, tosign);
+ File.WriteAllText($"{exeAbsPath}.dig.signed", signature);
+ Logger.Info(" - digest signed, attaching signature");
+
+ Logger.Debug($"----- signature len: {signature.Length} ----");
+ Logger.Debug("----- done signing digest -----");
+ Logger.Debug("----- signFile: adding signature -----");
+ RunProcess(signToolPath, $"sign /di \"{loc}\" \"{exeAbsPath}\"");
+ Logger.Info(" - signature attached, timestamping");
+
+ Logger.Debug("----- signFile: adding timestamp -----");
+ RunProcess(signToolPath, $"timestamp /tr http://timestamp.digicert.com /td sha256 \"{exeAbsPath}\"");
+ Logger.Info(" - timestamped, verifying");
+
+ RunProcess(signToolPath, $"verify /pa \"{exeAbsPath}\"");
+ Logger.Info(" - verified, removing any files leftover from signing");
+ DeleteFile($"{exeAbsPath}.dig");
+ DeleteFile($"{exeAbsPath}.dig.signed");
+ DeleteFile($"{exeAbsPath}.p7u");
+
+ Logger.Info($"process complete. signed: {fileToSign}\n");
+ }
+
+ static void RunProcess(string fileName, string arguments)
+ {
+ Logger.Debug($"RunProcess Args: {fileName} {arguments}");
+ var process = new Process
+ {
+ StartInfo = new ProcessStartInfo
+ {
+ FileName = fileName,
+ Arguments = arguments,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ UseShellExecute = false,
+ CreateNoWindow = true
+ }
+ };
+
+ process.Start();
+ process.WaitForExit();
+
+ string output = process.StandardOutput.ReadToEnd();
+ string error = process.StandardError.ReadToEnd();
+
+ if (!string.IsNullOrEmpty(output))
+ {
+ Logger.Debug(output);
+ }
+
+ if (!string.IsNullOrEmpty(error))
+ {
+ Logger.Error(error);
+ }
+
+ if (process.ExitCode != 0)
+ {
+ throw new Exception($"Process exited with code {process.ExitCode}: {error}");
+ }
+ }
+
+ static string SignWithAwsKms(string keyId, byte[] digest)
+ {
+ var kmsClient = new AmazonKeyManagementServiceClient();
+ var request = new SignRequest
+ {
+ KeyId = keyId,
+ Message = new MemoryStream(digest),
+ MessageType = MessageType.DIGEST,
+ SigningAlgorithm = SigningAlgorithmSpec.RSASSA_PKCS1_V1_5_SHA_256
+ };
+
+ var response = kmsClient.SignAsync(request).Result;
+
+ return Convert.ToBase64String(response.Signature.ToArray());
+ }
+
+ static void DeleteFile(string path)
+ {
+ if (File.Exists(path))
+ {
+ File.Delete(path);
+ }
+ }
+
+ public static bool ExistsOnPath(string fileName)
+ {
+ return GetFullPath(fileName) != null;
+ }
+
+ public static string GetFullPath(string fileName)
+ {
+ if (File.Exists(fileName))
+ return Path.GetFullPath(fileName);
+
+ string values = Environment.GetEnvironmentVariable("PATH");
+ if (values == null) { return null; }
+ foreach (var path in values.Split(Path.PathSeparator))
+ {
+ var fullPath = Path.Combine(path, fileName);
+ if (File.Exists(fullPath))
+ return Path.GetFullPath(fullPath);
+ }
+ return null;
+ }
+
+ public static bool VerifyEnvVar(string envVar)
+ {
+ var val = Environment.GetEnvironmentVariable(envVar);
+ if (string.IsNullOrEmpty(val))
+ {
+ Logger.Info($"ERROR: Environment variable must be set: {envVar}");
+ return false;
+ }
+ return true;
+ }
+ }
}
\ No newline at end of file
diff --git a/DesktopEdge/App.xaml.cs b/DesktopEdge/App.xaml.cs
index 8bc2f2814..aeaa26baf 100644
--- a/DesktopEdge/App.xaml.cs
+++ b/DesktopEdge/App.xaml.cs
@@ -1,20 +1,20 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-using System;
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+using System;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
@@ -31,79 +31,98 @@ limitations under the License.
using System.Reflection;
using ZitiDesktopEdge.Utility;
-namespace ZitiDesktopEdge {
- ///
- /// Interaction logic for App.xaml
- ///
- public partial class App : Application {
+namespace ZitiDesktopEdge
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App : Application
+ {
private const string NamedPipeName = "ZitiDesktopEdgePipe";
- private static readonly Logger logger = LogManager.GetCurrentClassLogger();
- private static Mutex _mutex = null;
+ private static readonly Logger logger = LogManager.GetCurrentClassLogger();
+ private static Mutex _mutex = null;
- protected override void OnSessionEnding(SessionEndingCancelEventArgs e) {
- base.OnSessionEnding(e);
- }
+ protected override void OnSessionEnding(SessionEndingCancelEventArgs e)
+ {
+ base.OnSessionEnding(e);
+ }
- protected override void OnStartup(StartupEventArgs e) {
- UpgradeSentinel.RemoveUpgradeSentinelExe();
- try {
- Current.Properties["ZDEWViewState"] = new ZDEWViewState();
+ protected override void OnStartup(StartupEventArgs e)
+ {
+ UpgradeSentinel.RemoveUpgradeSentinelExe();
+ try
+ {
+ Current.Properties["ZDEWViewState"] = new ZDEWViewState();
- const string appName = "Ziti Desktop Edge";
+ const string appName = "Ziti Desktop Edge";
- bool createdNew;
+ bool createdNew;
- _mutex = new Mutex(true, appName, out createdNew);
+ _mutex = new Mutex(true, appName, out createdNew);
- if (!createdNew) {
- using (var client = new NamedPipeClientStream(NamedPipeName)) {
- logger.Info("Another instance exists. Attempting to notify it to open");
- try {
- client.Connect(1000);
- } catch {
- return;
- }
+ if (!createdNew)
+ {
+ using (var client = new NamedPipeClientStream(NamedPipeName))
+ {
+ logger.Info("Another instance exists. Attempting to notify it to open");
+ try
+ {
+ client.Connect(1000);
+ }
+ catch
+ {
+ return;
+ }
- if (!client.IsConnected)
- return;
+ if (!client.IsConnected)
+ return;
- using (StreamWriter writer = new StreamWriter(client)) {
- writer.Write("showscreen");
- writer.Flush();
- }
- }
- Application.Current.Shutdown();
- } else {
+ using (StreamWriter writer = new StreamWriter(client))
+ {
+ writer.Write("showscreen");
+ writer.Flush();
+ }
+ }
+ Application.Current.Shutdown();
+ }
+ else
+ {
#pragma warning disable 4014 //This async method lacks 'await'
- StartServer();
+ StartServer();
#pragma warning restore 4014 //This async method lacks 'await'
- }
- } catch (Exception ex) {
- logger.Error($"OnStartup FAILED unexpectedly. Exiting", ex);
- Application.Current.Shutdown();
- }
- }
-
- async public Task StartServer() {
- logger.Debug("Starting IPC server to listen for other instances of the app");
- while (true) {
- string text;
- using (var server = new NamedPipeServerStream(NamedPipeName)) {
- await server.WaitForConnectionAsync();
- logger.Debug("Another instance opened and connected.");
- using (StreamReader reader = new StreamReader(server)) {
- text = await reader.ReadToEndAsync();
- }
- }
-
- logger.Debug("received: {0}. Calling OnReceivedString", text);
- OnReceivedString(text);
- }
- }
-
- public event Action ReceiveString;
- protected virtual void OnReceivedString(string text) => ReceiveString?.Invoke(text);
-
- }
+ }
+ }
+ catch (Exception ex)
+ {
+ logger.Error($"OnStartup FAILED unexpectedly. Exiting", ex);
+ Application.Current.Shutdown();
+ }
+ }
+
+ async public Task StartServer()
+ {
+ logger.Debug("Starting IPC server to listen for other instances of the app");
+ while (true)
+ {
+ string text;
+ using (var server = new NamedPipeServerStream(NamedPipeName))
+ {
+ await server.WaitForConnectionAsync();
+ logger.Debug("Another instance opened and connected.");
+ using (StreamReader reader = new StreamReader(server))
+ {
+ text = await reader.ReadToEndAsync();
+ }
+ }
+
+ logger.Debug("received: {0}. Calling OnReceivedString", text);
+ OnReceivedString(text);
+ }
+ }
+
+ public event Action ReceiveString;
+ protected virtual void OnReceivedString(string text) => ReceiveString?.Invoke(text);
+
+ }
}
\ No newline at end of file
diff --git a/DesktopEdge/MainWindow.xaml.cs b/DesktopEdge/MainWindow.xaml.cs
index d83ebcd8f..fb5ebbf36 100644
--- a/DesktopEdge/MainWindow.xaml.cs
+++ b/DesktopEdge/MainWindow.xaml.cs
@@ -14,7 +14,7 @@ You may obtain a copy of the License at
limitations under the License.
*/
-using System;
+using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;
@@ -42,730 +42,880 @@ limitations under the License.
using Ziti.Desktop.Edge.Models;
-namespace ZitiDesktopEdge {
-
- public partial class MainWindow : Window {
- private static readonly Logger logger = LogManager.GetCurrentClassLogger();
-
- public string RECOVER = "RECOVER";
- public System.Windows.Forms.NotifyIcon notifyIcon;
- public string Position = "Bottom";
- private DateTime _startDate;
- private System.Windows.Forms.Timer _tunnelUptimeTimer;
- private DataClient serviceClient = null;
- MonitorClient monitorClient = null;
- private bool _isAttached = true;
- private bool _isServiceInError = false;
- private int _right = 75;
- private int _left = 75;
- private int _top = 30;
- private int defaultHeight = 540;
- public int NotificationsShownCount = 0;
- private double _maxHeight = 800d;
- public string CurrentIcon = "white";
- private string[] suffixes = { "Bps", "kBps", "mBps", "gBps", "tBps", "pBps" };
- private string _blurbUrl = "";
-
- private DateTime NextNotificationTime;
- private static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 1);
-
- static System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();
-
- public static string ThisAssemblyName;
- public static string ExecutionDirectory;
- public static string ExpectedLogPathRoot;
- public static string ExpectedLogPathUI;
- public static string ExpectedLogPathServices;
-
- private static ZDEWViewState state;
- static MainWindow() {
- asm = System.Reflection.Assembly.GetExecutingAssembly();
- ThisAssemblyName = asm.GetName().Name;
- state = (ZDEWViewState)Application.Current.Properties["ZDEWViewState"];
+namespace ZitiDesktopEdge
+{
+
+ public partial class MainWindow : Window
+ {
+ private static readonly Logger logger = LogManager.GetCurrentClassLogger();
+
+ public string RECOVER = "RECOVER";
+ public System.Windows.Forms.NotifyIcon notifyIcon;
+ public string Position = "Bottom";
+ private DateTime _startDate;
+ private System.Windows.Forms.Timer _tunnelUptimeTimer;
+ private DataClient serviceClient = null;
+ MonitorClient monitorClient = null;
+ private bool _isAttached = true;
+ private bool _isServiceInError = false;
+ private int _right = 75;
+ private int _left = 75;
+ private int _top = 30;
+ private int defaultHeight = 540;
+ public int NotificationsShownCount = 0;
+ private double _maxHeight = 800d;
+ public string CurrentIcon = "white";
+ private string[] suffixes = { "Bps", "kBps", "mBps", "gBps", "tBps", "pBps" };
+ private string _blurbUrl = "";
+
+ private DateTime NextNotificationTime;
+ private static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 1);
+
+ static System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();
+
+ public static string ThisAssemblyName;
+ public static string ExecutionDirectory;
+ public static string ExpectedLogPathRoot;
+ public static string ExpectedLogPathUI;
+ public static string ExpectedLogPathServices;
+
+ private static ZDEWViewState state;
+ static MainWindow()
+ {
+ asm = System.Reflection.Assembly.GetExecutingAssembly();
+ ThisAssemblyName = asm.GetName().Name;
+ state = (ZDEWViewState)Application.Current.Properties["ZDEWViewState"];
#if DEBUG
- ExecutionDirectory = @"C:\Program Files (x86)\NetFoundry, Inc\Ziti Desktop Edge";
+ ExecutionDirectory = @"C:\Program Files (x86)\NetFoundry, Inc\Ziti Desktop Edge";
#else
ExecutionDirectory = Path.GetDirectoryName(asm.Location);
#endif
- ExpectedLogPathRoot = Path.Combine(ExecutionDirectory, "logs");
- ExpectedLogPathUI = Path.Combine(ExpectedLogPathRoot, "UI", $"{ThisAssemblyName}.log");
- ExpectedLogPathServices = Path.Combine(ExpectedLogPathRoot, "service", $"ziti-tunneler.log");
- }
-
- async private void IdentityMenu_OnMessage(string message) {
- await ShowBlurbAsync(message, "");
- }
-
- private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e) {
- LoadIdentities(true);
- }
-
- private List identities {
- get {
- return (List)Application.Current.Properties["Identities"];
- }
- }
-
- ///
- /// The MFA Toggle was toggled
- ///
- /// True if the toggle was on
- private async void MFAToggled(bool isOn) {
- if (isOn) {
- ShowLoad("Generating MFA", "MFA Setup Commencing, please wait");
-
- await serviceClient.EnableMFA(this.IdentityMenu.Identity.Identifier);
- } else {
- this.ShowMFA(IdentityMenu.Identity, 3);
- }
-
- HideLoad();
- }
-
- ///
- /// When a Service Client is ready to setup the MFA Authorization
- ///
- /// The service client
- /// The MFA Event
- private void ServiceClient_OnMfaEvent(object sender, MfaEvent mfa) {
- HideLoad();
- this.Dispatcher.Invoke(async () => {
- if (mfa.Action == "enrollment_challenge") {
- string url = HttpUtility.UrlDecode(mfa.ProvisioningUrl);
- string secret = HttpUtility.ParseQueryString(url)["secret"];
- this.IdentityMenu.Identity.RecoveryCodes = mfa?.RecoveryCodes?.ToArray();
- SetupMFA(this.IdentityMenu.Identity, url, secret);
- } else if (mfa.Action == "auth_challenge") {
- for (int i = 0; i < identities.Count; i++) {
- if (identities[i].Identifier == mfa.Identifier) {
- identities[i].WasNotified = false;
- identities[i].WasFullNotified = false;
- identities[i].IsMFANeeded = true;
- identities[i].IsTimingOut = false;
- break;
- }
- }
- } else if (mfa.Action == "enrollment_verification") {
- if (mfa.Successful) {
- var found = identities.Find(id => id.Identifier == mfa.Identifier);
- for (int i = 0; i < identities.Count; i++) {
- if (identities[i].Identifier == mfa.Identifier) {
- identities[i].WasNotified = false;
- identities[i].WasFullNotified = false;
- identities[i].IsMFANeeded = false;
- identities[i].IsMFAEnabled = true;
- identities[i].IsTimingOut = false;
- identities[i].LastUpdatedTime = DateTime.Now;
- for (int j = 0; j < identities[i].Services.Count; j++) {
- identities[i].Services[j].TimeUpdated = DateTime.Now;
- identities[i].Services[j].TimeoutRemaining = identities[i].Services[j].Timeout;
- }
- found = identities[i];
- found.IsMFAEnabled = true;
- break;
- }
- }
- if (this.IdentityMenu.Identity != null && this.IdentityMenu.Identity.Identifier == mfa.Identifier) this.IdentityMenu.Identity = found;
- ShowMFARecoveryCodes(found);
- } else {
- await ShowBlurbAsync("Provided code could not be verified", "");
- }
- } else if (mfa.Action == "enrollment_remove") {
- if (mfa.Successful) {
- var found = identities.Find(id => id.Identifier == mfa.Identifier);
- for (int i = 0; i < identities.Count; i++) {
- if (identities[i].Identifier == mfa.Identifier) {
- identities[i].WasNotified = false;
- identities[i].WasFullNotified = false;
- identities[i].IsMFAEnabled = false;
- identities[i].IsMFANeeded = false;
- identities[i].LastUpdatedTime = DateTime.Now;
- identities[i].IsTimingOut = false;
- for (int j = 0; j < identities[i].Services.Count; j++) {
- identities[i].Services[j].TimeUpdated = DateTime.Now;
- identities[i].Services[j].TimeoutRemaining = 0;
- }
- found = identities[i];
- break;
- }
- }
- if (this.IdentityMenu.Identity != null && this.IdentityMenu.Identity.Identifier == mfa.Identifier) this.IdentityMenu.Identity = found;
- await ShowBlurbAsync("MFA Disabled, Service Access Can Be Limited", "");
- } else {
- await ShowBlurbAsync("MFA Removal Failed", "");
- }
- } else if (mfa.Action == "mfa_auth_status") {
- var found = identities.Find(id => id.Identifier == mfa.Identifier);
- for (int i = 0; i < identities.Count; i++) {
- if (identities[i].Identifier == mfa.Identifier) {
- identities[i].WasNotified = false;
- identities[i].WasFullNotified = false;
- identities[i].IsTimingOut = false;
- identities[i].IsMFANeeded = !mfa.Successful;
- identities[i].LastUpdatedTime = DateTime.Now;
- for (int j = 0; j < identities[i].Services.Count; j++) {
- identities[i].Services[j].TimeUpdated = DateTime.Now;
- identities[i].Services[j].TimeoutRemaining = identities[i].Services[j].Timeout;
- }
- found = identities[i];
- break;
- }
- }
- if (this.IdentityMenu.Identity != null && this.IdentityMenu.Identity.Identifier == mfa.Identifier) this.IdentityMenu.Identity = found;
- // ShowBlurb("mfa authenticated: " + mfa.Successful, "");
- } else {
- await ShowBlurbAsync("Unexpected error when processing MFA", "");
- logger.Error("unexpected action: " + mfa.Action);
- }
-
- LoadIdentities(true);
- });
- }
-
- ///
- /// Show the MFA Setup Modal
- ///
- /// The Ziti Identity to Setup
- public void SetupMFA(ZitiIdentity identity, string url, string secret) {
- MFASetup.Opacity = 0;
- MFASetup.Visibility = Visibility.Visible;
- MFASetup.Margin = new Thickness(0, 0, 0, 0);
- MFASetup.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(1, TimeSpan.FromSeconds(.3)));
- MFASetup.BeginAnimation(Grid.MarginProperty, new ThicknessAnimation(new Thickness(30, 30, 30, 30), TimeSpan.FromSeconds(.3)));
- MFASetup.ShowSetup(identity, url, secret);
- ShowModal();
- }
-
- ///
- /// Show the MFA Authentication Screen when it is time to authenticate
- ///
- /// The Ziti Identity to Authenticate
- public void MFAAuthenticate(ZitiIdentity identity) {
- this.ShowMFA(identity, 1);
- }
-
- ///
- /// Show MFA for the identity and set the type of screen to show
- ///
- /// The Identity that is currently active
- /// The type of screen to show - 1 Setup, 2 Authenticate, 3 Remove MFA, 4 Regenerate Codes
- private void ShowMFA(ZitiIdentity identity, int type) {
- MFASetup.Opacity = 0;
- MFASetup.Visibility = Visibility.Visible;
- MFASetup.Margin = new Thickness(0, 0, 0, 0);
-
- DoubleAnimation animatin = new DoubleAnimation(1, TimeSpan.FromSeconds(.3));
- animatin.Completed += Animatin_Completed;
- MFASetup.BeginAnimation(Grid.OpacityProperty, animatin);
- MFASetup.BeginAnimation(Grid.MarginProperty, new ThicknessAnimation(new Thickness(30, 30, 30, 30), TimeSpan.FromSeconds(.3)));
-
- MFASetup.ShowMFA(identity, type);
-
- ShowModal();
- }
-
- private void Animatin_Completed(object sender, EventArgs e) {
- MFASetup.AuthCode.Focusable = true;
- MFASetup.AuthCode.Focus();
- }
-
- ///
- /// Show the MFA Recovery Codes
- ///
- /// The Ziti Identity to Authenticate
- async public void ShowMFARecoveryCodes(ZitiIdentity identity) {
- if (identity.IsMFAEnabled) {
- if (identity.IsMFAEnabled && identity.RecoveryCodes != null) {
- MFASetup.Opacity = 0;
- MFASetup.Visibility = Visibility.Visible;
- MFASetup.Margin = new Thickness(0, 0, 0, 0);
- MFASetup.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(1, TimeSpan.FromSeconds(.3)));
- MFASetup.BeginAnimation(Grid.MarginProperty, new ThicknessAnimation(new Thickness(30, 30, 30, 30), TimeSpan.FromSeconds(.3)));
-
- MFASetup.ShowRecovery(identity.RecoveryCodes, identity);
-
- ShowModal();
- } else {
- this.ShowMFA(IdentityMenu.Identity, 2);
- }
- } else {
- await ShowBlurbAsync("MFA is not setup on this Identity", "");
- }
- }
-
- ///
- /// Show the modal, aniimating opacity
- ///
- private void ShowModal() {
- ModalBg.Visibility = Visibility.Visible;
- ModalBg.Opacity = 0;
- DoubleAnimation animation = new DoubleAnimation(.8, TimeSpan.FromSeconds(.3));
- ModalBg.BeginAnimation(Grid.OpacityProperty, animation);
- }
-
- ///
- /// Close the various MFA windows
- ///
- /// The close button
- /// The event arguments
- private void CloseComplete(object sender, EventArgs e) {
- MFASetup.Visibility = Visibility.Collapsed;
- }
-
- ///
- /// Hide the modal animating the opacity
- ///
- private void HideModal() {
- DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3));
- animation.Completed += ModalHideComplete;
- ModalBg.BeginAnimation(Grid.OpacityProperty, animation);
- }
-
- ///
- /// When the animation completes, set the visibility to avoid UI object conflicts
- ///
- /// The animation
- /// The event
- private void ModalHideComplete(object sender, EventArgs e) {
- ModalBg.Visibility = Visibility.Collapsed;
- }
-
- ///
- /// Close the MFA Screen with animation
- ///
- private void DoClose(bool isComplete) {
- DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3));
- ThicknessAnimation animateThick = new ThicknessAnimation(new Thickness(0, 0, 0, 0), TimeSpan.FromSeconds(.3));
- animation.Completed += CloseComplete;
- MFASetup.BeginAnimation(Grid.OpacityProperty, animation);
- MFASetup.BeginAnimation(Grid.MarginProperty, animateThick);
- HideModal();
- if (isComplete) {
- if (MFASetup.Type == 1) {
- for (int i = 0; i < identities.Count; i++) {
- if (identities[i].Identifier == MFASetup.Identity.Identifier) {
- identities[i] = MFASetup.Identity;
- identities[i].LastUpdatedTime = DateTime.Now;
- }
- }
- }
- }
- if (IdentityMenu.IsVisible) {
- if (isComplete) {
- if (MFASetup.Type == 2) {
- ShowRecovery(IdentityMenu.Identity);
- } else if (MFASetup.Type == 3) {
- } else if (MFASetup.Type == 4) {
- ShowRecovery(IdentityMenu.Identity);
- }
- }
- IdentityMenu.UpdateView();
- }
- LoadIdentities(true);
- }
-
- private void AddIdentity(ZitiIdentity id) {
- semaphoreSlim.Wait();
- if (!identities.Any(i => id.Identifier == i.Identifier)) {
- identities.Add(id);
- }
- semaphoreSlim.Release();
- }
-
- private System.Windows.Forms.ContextMenu contextMenu;
- private System.Windows.Forms.MenuItem contextMenuItem;
- private System.ComponentModel.IContainer components;
- public MainWindow() {
- InitializeComponent();
- NextNotificationTime = DateTime.Now;
- SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
- string nlogFile = Path.Combine(ExecutionDirectory, ThisAssemblyName + "-log.config");
-
-
- ToastNotificationManagerCompat.OnActivated += ToastNotificationManagerCompat_OnActivated;
-
- bool byFile = false;
- if (File.Exists(nlogFile)) {
- LogManager.Configuration = new XmlLoggingConfiguration(nlogFile);
- byFile = true;
- } else {
- var config = new LoggingConfiguration();
- // Targets where to log to: File and Console
- var logfile = new FileTarget("logfile") {
- FileName = ExpectedLogPathUI,
- ArchiveEvery = FileArchivePeriod.Day,
- ArchiveNumbering = ArchiveNumberingMode.Rolling,
- MaxArchiveFiles = 7,
- AutoFlush = true,
- Layout = "[${date:format=yyyy-MM-ddTHH:mm:ss.fff}Z] ${level:uppercase=true:padding=5}\t${logger}\t${message}\t${exception:format=tostring}",
- };
- var logconsole = new ConsoleTarget("logconsole");
-
- // Rules for mapping loggers to targets
- config.AddRule(LogLevel.Debug, LogLevel.Fatal, logconsole);
- config.AddRule(LogLevel.Debug, LogLevel.Fatal, logfile);
-
- // Apply config
- LogManager.Configuration = config;
- }
- logger.Info("============================== UI started ==============================");
- logger.Info("logger initialized");
- logger.Info(" - version : {0}", asm.GetName().Version.ToString());
- logger.Info(" - using file: {0}", byFile);
- logger.Info(" - file: {0}", nlogFile);
- logger.Info("========================================================================");
-
- App.Current.MainWindow.WindowState = WindowState.Normal;
- App.Current.MainWindow.Deactivated += MainWindow_Deactivated;
- App.Current.MainWindow.Activated += MainWindow_Activated;
- App.Current.Exit += Current_Exit;
- App.Current.SessionEnding += Current_SessionEnding;
-
-
- this.components = new System.ComponentModel.Container();
- this.contextMenu = new System.Windows.Forms.ContextMenu();
- this.contextMenuItem = new System.Windows.Forms.MenuItem();
- this.contextMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.contextMenuItem });
-
- this.contextMenuItem.Index = 0;
- this.contextMenuItem.Text = "&Close UI";
- this.contextMenuItem.Click += new System.EventHandler(this.contextMenuItem_Click);
-
-
- notifyIcon = new System.Windows.Forms.NotifyIcon();
- notifyIcon.Visible = true;
- notifyIcon.Click += TargetNotifyIcon_Click;
- notifyIcon.Visible = true;
- notifyIcon.BalloonTipClosed += NotifyIcon_BalloonTipClosed;
- notifyIcon.MouseClick += NotifyIcon_MouseClick;
- notifyIcon.ContextMenu = this.contextMenu;
-
- IdentityMenu.OnDetach += OnDetach;
- MainMenu.OnDetach += OnDetach;
-
- this.MainMenu.MainWindow = this;
- this.IdentityMenu.MainWindow = this;
- SetNotifyIcon("white");
-
- this.PreviewKeyDown += KeyPressed;
- MFASetup.OnLoad += MFASetup_OnLoad;
- MFASetup.OnError += MFASetup_OnError;
- IdentityMenu.OnMessage += IdentityMenu_OnMessage;
- }
-
- async private void MFASetup_OnError(string message) {
- await ShowBlurbAsync(message, "", "error");
- }
-
- private static ToastButton feedbackToastButton = new ToastButton()
- .SetContent("Click here to collect logs")
- .AddArgument("action", "feedback");
-
- private void ToastNotificationManagerCompat_OnActivated(ToastNotificationActivatedEventArgsCompat e) {
- this.Dispatcher.Invoke(() => {
- if (e.Argument != null && e.Argument.Length > 0) {
- string[] items = e.Argument.Split(';');
- if (items.Length > 0) {
- string[] values = items[0].Split('=');
- if (values.Length == 2) {
- string identifier = values[1];
- for (int i = 0; i < identities.Count; i++) {
- if (identities[i].Identifier == identifier) {
- ShowMFA(identities[i], 1);
- break;
- }
- }
- }
- }
- }
-
- ToastArguments args = ToastArguments.Parse(e.Argument);
- string value = null;
- if(args.TryGetValue("action", out value)) {
- this.Dispatcher.Invoke(() => {
- MainMenu.CollectFeedbackLogs(e, null);
- });
- }
- this.Show();
- this.Activate();
- });
- }
-
- private void KeyPressed(object sender, KeyEventArgs e) {
- if (e.Key == Key.Escape) {
- if (IdentityMenu.Visibility == Visibility.Visible) IdentityMenu.Visibility = Visibility.Collapsed;
- else if (MainMenu.Visibility == Visibility.Visible) MainMenu.Visibility = Visibility.Collapsed;
- }
- }
-
- private void MFASetup_OnLoad(bool isComplete, string title, string message) {
- if (isComplete) HideLoad();
- else ShowLoad(title, message);
- }
-
- private void Current_SessionEnding(object sender, SessionEndingCancelEventArgs e) {
- if (notifyIcon != null) {
- notifyIcon.Visible = false;
- notifyIcon.Icon.Dispose();
- notifyIcon.Dispose();
- notifyIcon = null;
- }
- Application.Current.Shutdown();
- }
-
- private void Current_Exit(object sender, ExitEventArgs e) {
- if (notifyIcon != null) {
- notifyIcon.Visible = false;
- if (notifyIcon.Icon != null) {
- notifyIcon.Icon.Dispose();
- }
- notifyIcon.Dispose();
- notifyIcon = null;
- }
- }
-
- private void contextMenuItem_Click(object Sender, EventArgs e) {
- Application.Current.Shutdown();
- }
-
- private void NotifyIcon_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e) {
- if (e.Button == System.Windows.Forms.MouseButtons.Left) {
- System.Windows.Forms.MouseEventArgs mea = (System.Windows.Forms.MouseEventArgs)e;
- this.Show();
- this.Activate();
- //Do the awesome left clickness
- } else if (e.Button == System.Windows.Forms.MouseButtons.Right) {
- //Do the wickedy right clickness
- } else {
- //Some other button from the enum :)
- }
- }
-
- private void NotifyIcon_BalloonTipClosed(object sender, EventArgs e) {
- var thisIcon = (System.Windows.Forms.NotifyIcon)sender;
- thisIcon.Visible = false;
- thisIcon.Dispose();
- }
-
- private void Window_MouseDown(object sender, MouseButtonEventArgs e) {
- OnDetach(e);
- }
-
- private void OnDetach(MouseButtonEventArgs e) {
- if (e.ChangedButton == MouseButton.Left) {
- _isAttached = false;
- IdentityMenu.Arrow.Visibility = Visibility.Collapsed;
- Arrow.Visibility = Visibility.Collapsed;
- MainMenu.Detach();
- this.DragMove();
- }
- }
-
- private void MainWindow_Activated(object sender, EventArgs e) {
- Placement();
- this.Show();
- this.Visibility = Visibility.Visible;
- this.Opacity = 1;
- }
-
- private void MainWindow_Deactivated(object sender, EventArgs e) {
- if (this._isAttached) {
- this.Visibility = Visibility.Hidden;
- }
- }
-
- private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
- if (notifyIcon != null) {
- notifyIcon.Visible = false;
- notifyIcon.Icon.Dispose();
- notifyIcon.Dispose();
- notifyIcon = null;
- }
- Application.Current.Shutdown();
- }
-
- private void SetCantDisplay(string title, string detailMessage, Visibility closeButtonVisibility) {
- this.Dispatcher.Invoke(() => {
- NoServiceView.Visibility = Visibility.Visible;
- CloseErrorButton.IsEnabled = true;
- CloseErrorButton.Visibility = closeButtonVisibility;
- ErrorMsg.Content = title;
- ErrorMsgDetail.Content = detailMessage;
- SetNotifyIcon("red");
- _isServiceInError = true;
- UpdateServiceView();
- });
- }
-
- private void TargetNotifyIcon_Click(object sender, EventArgs e) {
- this.Show();
- this.Activate();
- Application.Current.MainWindow.Activate();
- }
-
- private void UpdateServiceView() {
- if (_isServiceInError) {
- AddIdAreaButton.Opacity = 0.1;
- AddIdAreaButton.IsEnabled = false;
- AddIdButton.Opacity = 0.1;
- AddIdButton.IsEnabled = false;
- ConnectButton.Opacity = 0.1;
- StatArea.Opacity = 0.1;
- } else {
- AddIdAreaButton.Opacity = 1.0;
- AddIdAreaButton.IsEnabled = true;
- AddIdButton.Opacity = 1.0;
- AddIdButton.IsEnabled = true;
- StatArea.Opacity = 1.0;
- ConnectButton.Opacity = 1.0;
- }
- TunnelConnected(!_isServiceInError);
- }
-
- private void App_ReceiveString(string obj) {
- Console.WriteLine(obj);
- this.Show();
- this.Activate();
- }
-
- async private void MainWindow_Loaded(object sender, RoutedEventArgs e) {
-
- Window window = Window.GetWindow(App.Current.MainWindow);
- ZitiDesktopEdge.App app = (ZitiDesktopEdge.App)App.Current;
- app.ReceiveString += App_ReceiveString;
-
- // add a new service client
- serviceClient = new DataClient("ui");
- serviceClient.OnClientConnected += ServiceClient_OnClientConnected;
- serviceClient.OnClientDisconnected += ServiceClient_OnClientDisconnected;
- serviceClient.OnIdentityEvent += ServiceClient_OnIdentityEvent;
- serviceClient.OnMetricsEvent += ServiceClient_OnMetricsEvent;
- serviceClient.OnServiceEvent += ServiceClient_OnServiceEvent;
- serviceClient.OnTunnelStatusEvent += ServiceClient_OnTunnelStatusEvent;
- serviceClient.OnMfaEvent += ServiceClient_OnMfaEvent;
- serviceClient.OnLogLevelEvent += ServiceClient_OnLogLevelEvent;
- serviceClient.OnBulkServiceEvent += ServiceClient_OnBulkServiceEvent;
- serviceClient.OnNotificationEvent += ServiceClient_OnNotificationEvent;
- serviceClient.OnControllerEvent += ServiceClient_OnControllerEvent;
- Application.Current.Properties.Add("ServiceClient", serviceClient);
-
- monitorClient = new MonitorClient("ui");
- monitorClient.OnClientConnected += MonitorClient_OnClientConnected;
- monitorClient.OnNotificationEvent += MonitorClient_OnInstallationNotificationEvent;
- monitorClient.OnServiceStatusEvent += MonitorClient_OnServiceStatusEvent;
- monitorClient.OnShutdownEvent += MonitorClient_OnShutdownEvent;
- monitorClient.OnCommunicationError += MonitorClient_OnCommunicationError;
- monitorClient.OnReconnectFailure += MonitorClient_OnReconnectFailure;
- Application.Current.Properties.Add("MonitorClient", monitorClient);
-
- Application.Current.Properties.Add("Identities", new List());
- MainMenu.OnAttachmentChange += AttachmentChanged;
- MainMenu.OnLogLevelChanged += LogLevelChanged;
- MainMenu.OnShowBlurb += MainMenu_OnShowBlurb;
- IdentityMenu.OnError += IdentityMenu_OnError;
-
- try {
- await serviceClient.ConnectAsync();
- await serviceClient.WaitForConnectionAsync();
- } catch /*ignored for now (Exception ex) */{
- ShowServiceNotStarted();
- serviceClient.Reconnect();
- }
-
- try {
- await monitorClient.ConnectAsync();
- await monitorClient.WaitForConnectionAsync();
- } catch /*ignored for now (Exception ex) */{
- monitorClient.Reconnect();
- }
-
- IdentityMenu.OnForgot += IdentityForgotten;
- Placement();
- }
-
- private void MonitorClient_OnCommunicationError(object sender, Exception e) {
- string msg = "Communication Error with monitor?";
- ShowError(msg, e.Message);
- }
-
- private void MainMenu_OnShowBlurb(string message) {
- _ = ShowBlurbAsync(message, "", "info");
- }
-
- private void ServiceClient_OnBulkServiceEvent(object sender, BulkServiceEvent e) {
- var found = identities.Find(id => id.Identifier == e.Identifier);
- if (found == null) {
- logger.Warn($"{e.Action} service event for {e.Identifier} but the provided identity identifier was not found!");
- return;
- } else {
- if (e.RemovedServices != null) {
- foreach (var removed in e.RemovedServices) {
- removeService(found, removed);
- }
- }
- if (e.AddedServices != null) {
- foreach (var added in e.AddedServices) {
- addService(found, added);
- }
- }
- LoadIdentities(true);
- this.Dispatcher.Invoke(() => {
- IdentityDetails deets = ((MainWindow)Application.Current.MainWindow).IdentityMenu;
- if (deets.IsVisible) {
- deets.UpdateView();
- }
- });
- }
- }
-
- private void ServiceClient_OnNotificationEvent(object sender, NotificationEvent e) {
- var displayMFARequired = false;
- var displayMFATimout = false;
- foreach (var notification in e.Notification) {
- var found = identities.Find(id => id.Identifier == notification.Identifier);
- if (found == null) {
- logger.Warn($"{e.Op} event for {notification.Identifier} but the provided identity identifier was not found!");
- continue;
- } else {
- found.TimeoutMessage = notification.Message;
- found.MaxTimeout = notification.MfaMaximumTimeout;
- found.MinTimeout = notification.MfaMinimumTimeout;
-
- if (notification.MfaMinimumTimeout == 0) {
- // display mfa token icon
- displayMFARequired = true;
- } else {
- displayMFATimout = true;
- }
-
- for (int i = 0; i < identities.Count; i++) {
- if (identities[i].Identifier == found.Identifier) {
- identities[i] = found;
- break;
- }
- }
- }
- }
-
- // we may need to display mfa icon, based on the timer in UI, remove found.MFAInfo.ShowMFA setting in this function.
- // the below function can show mfa icon even after user authenticates successfully, in race conditions
- if (displayMFARequired || displayMFATimout) {
- this.Dispatcher.Invoke(() => {
- IdentityDetails deets = ((MainWindow)Application.Current.MainWindow).IdentityMenu;
- if (deets.IsVisible) {
- deets.UpdateView();
- }
- });
- }
- LoadIdentities(true);
- }
-
- private void ServiceClient_OnControllerEvent(object sender, ControllerEvent e) {
- logger.Debug($"==== ControllerEvent : action:{e.Action} identifier:{e.Identifier}");
- // commenting this block, because when it receives the disconnected events, identities are disabled and
- // it is not allowing me to click/perform any operation on the identity
- // the color of the title is also too dark, and it is not clearly visible, when the identity is disconnected
- /* if (e.Action == "connected") {
+ ExpectedLogPathRoot = Path.Combine(ExecutionDirectory, "logs");
+ ExpectedLogPathUI = Path.Combine(ExpectedLogPathRoot, "UI", $"{ThisAssemblyName}.log");
+ ExpectedLogPathServices = Path.Combine(ExpectedLogPathRoot, "service", $"ziti-tunneler.log");
+ }
+
+ async private void IdentityMenu_OnMessage(string message)
+ {
+ await ShowBlurbAsync(message, "");
+ }
+
+ private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
+ {
+ LoadIdentities(true);
+ }
+
+ private List identities
+ {
+ get
+ {
+ return (List)Application.Current.Properties["Identities"];
+ }
+ }
+
+ ///
+ /// The MFA Toggle was toggled
+ ///
+ /// True if the toggle was on
+ private async void MFAToggled(bool isOn)
+ {
+ if (isOn)
+ {
+ ShowLoad("Generating MFA", "MFA Setup Commencing, please wait");
+
+ await serviceClient.EnableMFA(this.IdentityMenu.Identity.Identifier);
+ }
+ else
+ {
+ this.ShowMFA(IdentityMenu.Identity, 3);
+ }
+
+ HideLoad();
+ }
+
+ ///
+ /// When a Service Client is ready to setup the MFA Authorization
+ ///
+ /// The service client
+ /// The MFA Event
+ private void ServiceClient_OnMfaEvent(object sender, MfaEvent mfa)
+ {
+ HideLoad();
+ this.Dispatcher.Invoke(async () =>
+ {
+ if (mfa.Action == "enrollment_challenge")
+ {
+ string url = HttpUtility.UrlDecode(mfa.ProvisioningUrl);
+ string secret = HttpUtility.ParseQueryString(url)["secret"];
+ this.IdentityMenu.Identity.RecoveryCodes = mfa?.RecoveryCodes?.ToArray();
+ SetupMFA(this.IdentityMenu.Identity, url, secret);
+ }
+ else if (mfa.Action == "auth_challenge")
+ {
+ for (int i = 0; i < identities.Count; i++)
+ {
+ if (identities[i].Identifier == mfa.Identifier)
+ {
+ identities[i].WasNotified = false;
+ identities[i].WasFullNotified = false;
+ identities[i].IsMFANeeded = true;
+ identities[i].IsTimingOut = false;
+ break;
+ }
+ }
+ }
+ else if (mfa.Action == "enrollment_verification")
+ {
+ if (mfa.Successful)
+ {
+ var found = identities.Find(id => id.Identifier == mfa.Identifier);
+ for (int i = 0; i < identities.Count; i++)
+ {
+ if (identities[i].Identifier == mfa.Identifier)
+ {
+ identities[i].WasNotified = false;
+ identities[i].WasFullNotified = false;
+ identities[i].IsMFANeeded = false;
+ identities[i].IsMFAEnabled = true;
+ identities[i].IsTimingOut = false;
+ identities[i].LastUpdatedTime = DateTime.Now;
+ for (int j = 0; j < identities[i].Services.Count; j++)
+ {
+ identities[i].Services[j].TimeUpdated = DateTime.Now;
+ identities[i].Services[j].TimeoutRemaining = identities[i].Services[j].Timeout;
+ }
+ found = identities[i];
+ found.IsMFAEnabled = true;
+ break;
+ }
+ }
+ if (this.IdentityMenu.Identity != null && this.IdentityMenu.Identity.Identifier == mfa.Identifier) this.IdentityMenu.Identity = found;
+ ShowMFARecoveryCodes(found);
+ }
+ else
+ {
+ await ShowBlurbAsync("Provided code could not be verified", "");
+ }
+ }
+ else if (mfa.Action == "enrollment_remove")
+ {
+ if (mfa.Successful)
+ {
+ var found = identities.Find(id => id.Identifier == mfa.Identifier);
+ for (int i = 0; i < identities.Count; i++)
+ {
+ if (identities[i].Identifier == mfa.Identifier)
+ {
+ identities[i].WasNotified = false;
+ identities[i].WasFullNotified = false;
+ identities[i].IsMFAEnabled = false;
+ identities[i].IsMFANeeded = false;
+ identities[i].LastUpdatedTime = DateTime.Now;
+ identities[i].IsTimingOut = false;
+ for (int j = 0; j < identities[i].Services.Count; j++)
+ {
+ identities[i].Services[j].TimeUpdated = DateTime.Now;
+ identities[i].Services[j].TimeoutRemaining = 0;
+ }
+ found = identities[i];
+ break;
+ }
+ }
+ if (this.IdentityMenu.Identity != null && this.IdentityMenu.Identity.Identifier == mfa.Identifier) this.IdentityMenu.Identity = found;
+ await ShowBlurbAsync("MFA Disabled, Service Access Can Be Limited", "");
+ }
+ else
+ {
+ await ShowBlurbAsync("MFA Removal Failed", "");
+ }
+ }
+ else if (mfa.Action == "mfa_auth_status")
+ {
+ var found = identities.Find(id => id.Identifier == mfa.Identifier);
+ for (int i = 0; i < identities.Count; i++)
+ {
+ if (identities[i].Identifier == mfa.Identifier)
+ {
+ identities[i].WasNotified = false;
+ identities[i].WasFullNotified = false;
+ identities[i].IsTimingOut = false;
+ identities[i].IsMFANeeded = !mfa.Successful;
+ identities[i].LastUpdatedTime = DateTime.Now;
+ for (int j = 0; j < identities[i].Services.Count; j++)
+ {
+ identities[i].Services[j].TimeUpdated = DateTime.Now;
+ identities[i].Services[j].TimeoutRemaining = identities[i].Services[j].Timeout;
+ }
+ found = identities[i];
+ break;
+ }
+ }
+ if (this.IdentityMenu.Identity != null && this.IdentityMenu.Identity.Identifier == mfa.Identifier) this.IdentityMenu.Identity = found;
+ // ShowBlurb("mfa authenticated: " + mfa.Successful, "");
+ }
+ else
+ {
+ await ShowBlurbAsync("Unexpected error when processing MFA", "");
+ logger.Error("unexpected action: " + mfa.Action);
+ }
+
+ LoadIdentities(true);
+ });
+ }
+
+ ///
+ /// Show the MFA Setup Modal
+ ///
+ /// The Ziti Identity to Setup
+ public void SetupMFA(ZitiIdentity identity, string url, string secret)
+ {
+ MFASetup.Opacity = 0;
+ MFASetup.Visibility = Visibility.Visible;
+ MFASetup.Margin = new Thickness(0, 0, 0, 0);
+ MFASetup.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(1, TimeSpan.FromSeconds(.3)));
+ MFASetup.BeginAnimation(Grid.MarginProperty, new ThicknessAnimation(new Thickness(30, 30, 30, 30), TimeSpan.FromSeconds(.3)));
+ MFASetup.ShowSetup(identity, url, secret);
+ ShowModal();
+ }
+
+ ///
+ /// Show the MFA Authentication Screen when it is time to authenticate
+ ///
+ /// The Ziti Identity to Authenticate
+ public void MFAAuthenticate(ZitiIdentity identity)
+ {
+ this.ShowMFA(identity, 1);
+ }
+
+ ///
+ /// Show MFA for the identity and set the type of screen to show
+ ///
+ /// The Identity that is currently active
+ /// The type of screen to show - 1 Setup, 2 Authenticate, 3 Remove MFA, 4 Regenerate Codes
+ private void ShowMFA(ZitiIdentity identity, int type)
+ {
+ MFASetup.Opacity = 0;
+ MFASetup.Visibility = Visibility.Visible;
+ MFASetup.Margin = new Thickness(0, 0, 0, 0);
+
+ DoubleAnimation animatin = new DoubleAnimation(1, TimeSpan.FromSeconds(.3));
+ animatin.Completed += Animatin_Completed;
+ MFASetup.BeginAnimation(Grid.OpacityProperty, animatin);
+ MFASetup.BeginAnimation(Grid.MarginProperty, new ThicknessAnimation(new Thickness(30, 30, 30, 30), TimeSpan.FromSeconds(.3)));
+
+ MFASetup.ShowMFA(identity, type);
+
+ ShowModal();
+ }
+
+ private void Animatin_Completed(object sender, EventArgs e)
+ {
+ MFASetup.AuthCode.Focusable = true;
+ MFASetup.AuthCode.Focus();
+ }
+
+ ///
+ /// Show the MFA Recovery Codes
+ ///
+ /// The Ziti Identity to Authenticate
+ async public void ShowMFARecoveryCodes(ZitiIdentity identity)
+ {
+ if (identity.IsMFAEnabled)
+ {
+ if (identity.IsMFAEnabled && identity.RecoveryCodes != null)
+ {
+ MFASetup.Opacity = 0;
+ MFASetup.Visibility = Visibility.Visible;
+ MFASetup.Margin = new Thickness(0, 0, 0, 0);
+ MFASetup.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(1, TimeSpan.FromSeconds(.3)));
+ MFASetup.BeginAnimation(Grid.MarginProperty, new ThicknessAnimation(new Thickness(30, 30, 30, 30), TimeSpan.FromSeconds(.3)));
+
+ MFASetup.ShowRecovery(identity.RecoveryCodes, identity);
+
+ ShowModal();
+ }
+ else
+ {
+ this.ShowMFA(IdentityMenu.Identity, 2);
+ }
+ }
+ else
+ {
+ await ShowBlurbAsync("MFA is not setup on this Identity", "");
+ }
+ }
+
+ ///
+ /// Show the modal, aniimating opacity
+ ///
+ private void ShowModal()
+ {
+ ModalBg.Visibility = Visibility.Visible;
+ ModalBg.Opacity = 0;
+ DoubleAnimation animation = new DoubleAnimation(.8, TimeSpan.FromSeconds(.3));
+ ModalBg.BeginAnimation(Grid.OpacityProperty, animation);
+ }
+
+ ///
+ /// Close the various MFA windows
+ ///
+ /// The close button
+ /// The event arguments
+ private void CloseComplete(object sender, EventArgs e)
+ {
+ MFASetup.Visibility = Visibility.Collapsed;
+ }
+
+ ///
+ /// Hide the modal animating the opacity
+ ///
+ private void HideModal()
+ {
+ DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3));
+ animation.Completed += ModalHideComplete;
+ ModalBg.BeginAnimation(Grid.OpacityProperty, animation);
+ }
+
+ ///
+ /// When the animation completes, set the visibility to avoid UI object conflicts
+ ///
+ /// The animation
+ /// The event
+ private void ModalHideComplete(object sender, EventArgs e)
+ {
+ ModalBg.Visibility = Visibility.Collapsed;
+ }
+
+ ///
+ /// Close the MFA Screen with animation
+ ///
+ private void DoClose(bool isComplete)
+ {
+ DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3));
+ ThicknessAnimation animateThick = new ThicknessAnimation(new Thickness(0, 0, 0, 0), TimeSpan.FromSeconds(.3));
+ animation.Completed += CloseComplete;
+ MFASetup.BeginAnimation(Grid.OpacityProperty, animation);
+ MFASetup.BeginAnimation(Grid.MarginProperty, animateThick);
+ HideModal();
+ if (isComplete)
+ {
+ if (MFASetup.Type == 1)
+ {
+ for (int i = 0; i < identities.Count; i++)
+ {
+ if (identities[i].Identifier == MFASetup.Identity.Identifier)
+ {
+ identities[i] = MFASetup.Identity;
+ identities[i].LastUpdatedTime = DateTime.Now;
+ }
+ }
+ }
+ }
+ if (IdentityMenu.IsVisible)
+ {
+ if (isComplete)
+ {
+ if (MFASetup.Type == 2)
+ {
+ ShowRecovery(IdentityMenu.Identity);
+ }
+ else if (MFASetup.Type == 3)
+ {
+ }
+ else if (MFASetup.Type == 4)
+ {
+ ShowRecovery(IdentityMenu.Identity);
+ }
+ }
+ IdentityMenu.UpdateView();
+ }
+ LoadIdentities(true);
+ }
+
+ private void AddIdentity(ZitiIdentity id)
+ {
+ semaphoreSlim.Wait();
+ if (!identities.Any(i => id.Identifier == i.Identifier))
+ {
+ identities.Add(id);
+ }
+ semaphoreSlim.Release();
+ }
+
+ private System.Windows.Forms.ContextMenu contextMenu;
+ private System.Windows.Forms.MenuItem contextMenuItem;
+ private System.ComponentModel.IContainer components;
+ public MainWindow()
+ {
+ InitializeComponent();
+ NextNotificationTime = DateTime.Now;
+ SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
+ string nlogFile = Path.Combine(ExecutionDirectory, ThisAssemblyName + "-log.config");
+
+
+ ToastNotificationManagerCompat.OnActivated += ToastNotificationManagerCompat_OnActivated;
+
+ bool byFile = false;
+ if (File.Exists(nlogFile))
+ {
+ LogManager.Configuration = new XmlLoggingConfiguration(nlogFile);
+ byFile = true;
+ }
+ else
+ {
+ var config = new LoggingConfiguration();
+ // Targets where to log to: File and Console
+ var logfile = new FileTarget("logfile")
+ {
+ FileName = ExpectedLogPathUI,
+ ArchiveEvery = FileArchivePeriod.Day,
+ ArchiveNumbering = ArchiveNumberingMode.Rolling,
+ MaxArchiveFiles = 7,
+ AutoFlush = true,
+ Layout = "[${date:format=yyyy-MM-ddTHH:mm:ss.fff}Z] ${level:uppercase=true:padding=5}\t${logger}\t${message}\t${exception:format=tostring}",
+ };
+ var logconsole = new ConsoleTarget("logconsole");
+
+ // Rules for mapping loggers to targets
+ config.AddRule(LogLevel.Debug, LogLevel.Fatal, logconsole);
+ config.AddRule(LogLevel.Debug, LogLevel.Fatal, logfile);
+
+ // Apply config
+ LogManager.Configuration = config;
+ }
+ logger.Info("============================== UI started ==============================");
+ logger.Info("logger initialized");
+ logger.Info(" - version : {0}", asm.GetName().Version.ToString());
+ logger.Info(" - using file: {0}", byFile);
+ logger.Info(" - file: {0}", nlogFile);
+ logger.Info("========================================================================");
+
+ App.Current.MainWindow.WindowState = WindowState.Normal;
+ App.Current.MainWindow.Deactivated += MainWindow_Deactivated;
+ App.Current.MainWindow.Activated += MainWindow_Activated;
+ App.Current.Exit += Current_Exit;
+ App.Current.SessionEnding += Current_SessionEnding;
+
+
+ this.components = new System.ComponentModel.Container();
+ this.contextMenu = new System.Windows.Forms.ContextMenu();
+ this.contextMenuItem = new System.Windows.Forms.MenuItem();
+ this.contextMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.contextMenuItem });
+
+ this.contextMenuItem.Index = 0;
+ this.contextMenuItem.Text = "&Close UI";
+ this.contextMenuItem.Click += new System.EventHandler(this.contextMenuItem_Click);
+
+
+ notifyIcon = new System.Windows.Forms.NotifyIcon();
+ notifyIcon.Visible = true;
+ notifyIcon.Click += TargetNotifyIcon_Click;
+ notifyIcon.Visible = true;
+ notifyIcon.BalloonTipClosed += NotifyIcon_BalloonTipClosed;
+ notifyIcon.MouseClick += NotifyIcon_MouseClick;
+ notifyIcon.ContextMenu = this.contextMenu;
+
+ IdentityMenu.OnDetach += OnDetach;
+ MainMenu.OnDetach += OnDetach;
+
+ this.MainMenu.MainWindow = this;
+ this.IdentityMenu.MainWindow = this;
+ SetNotifyIcon("white");
+
+ this.PreviewKeyDown += KeyPressed;
+ MFASetup.OnLoad += MFASetup_OnLoad;
+ MFASetup.OnError += MFASetup_OnError;
+ IdentityMenu.OnMessage += IdentityMenu_OnMessage;
+ }
+
+ async private void MFASetup_OnError(string message)
+ {
+ await ShowBlurbAsync(message, "", "error");
+ }
+
+ private static ToastButton feedbackToastButton = new ToastButton()
+ .SetContent("Click here to collect logs")
+ .AddArgument("action", "feedback");
+
+ private void ToastNotificationManagerCompat_OnActivated(ToastNotificationActivatedEventArgsCompat e)
+ {
+ this.Dispatcher.Invoke(() =>
+ {
+ if (e.Argument != null && e.Argument.Length > 0)
+ {
+ string[] items = e.Argument.Split(';');
+ if (items.Length > 0)
+ {
+ string[] values = items[0].Split('=');
+ if (values.Length == 2)
+ {
+ string identifier = values[1];
+ for (int i = 0; i < identities.Count; i++)
+ {
+ if (identities[i].Identifier == identifier)
+ {
+ ShowMFA(identities[i], 1);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ ToastArguments args = ToastArguments.Parse(e.Argument);
+ string value = null;
+ if (args.TryGetValue("action", out value))
+ {
+ this.Dispatcher.Invoke(() =>
+ {
+ MainMenu.CollectFeedbackLogs(e, null);
+ });
+ }
+ this.Show();
+ this.Activate();
+ });
+ }
+
+ private void KeyPressed(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Escape)
+ {
+ if (IdentityMenu.Visibility == Visibility.Visible) IdentityMenu.Visibility = Visibility.Collapsed;
+ else if (MainMenu.Visibility == Visibility.Visible) MainMenu.Visibility = Visibility.Collapsed;
+ }
+ }
+
+ private void MFASetup_OnLoad(bool isComplete, string title, string message)
+ {
+ if (isComplete) HideLoad();
+ else ShowLoad(title, message);
+ }
+
+ private void Current_SessionEnding(object sender, SessionEndingCancelEventArgs e)
+ {
+ if (notifyIcon != null)
+ {
+ notifyIcon.Visible = false;
+ notifyIcon.Icon.Dispose();
+ notifyIcon.Dispose();
+ notifyIcon = null;
+ }
+ Application.Current.Shutdown();
+ }
+
+ private void Current_Exit(object sender, ExitEventArgs e)
+ {
+ if (notifyIcon != null)
+ {
+ notifyIcon.Visible = false;
+ if (notifyIcon.Icon != null)
+ {
+ notifyIcon.Icon.Dispose();
+ }
+ notifyIcon.Dispose();
+ notifyIcon = null;
+ }
+ }
+
+ private void contextMenuItem_Click(object Sender, EventArgs e)
+ {
+ Application.Current.Shutdown();
+ }
+
+ private void NotifyIcon_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
+ {
+ if (e.Button == System.Windows.Forms.MouseButtons.Left)
+ {
+ System.Windows.Forms.MouseEventArgs mea = (System.Windows.Forms.MouseEventArgs)e;
+ this.Show();
+ this.Activate();
+ //Do the awesome left clickness
+ }
+ else if (e.Button == System.Windows.Forms.MouseButtons.Right)
+ {
+ //Do the wickedy right clickness
+ }
+ else
+ {
+ //Some other button from the enum :)
+ }
+ }
+
+ private void NotifyIcon_BalloonTipClosed(object sender, EventArgs e)
+ {
+ var thisIcon = (System.Windows.Forms.NotifyIcon)sender;
+ thisIcon.Visible = false;
+ thisIcon.Dispose();
+ }
+
+ private void Window_MouseDown(object sender, MouseButtonEventArgs e)
+ {
+ OnDetach(e);
+ }
+
+ private void OnDetach(MouseButtonEventArgs e)
+ {
+ if (e.ChangedButton == MouseButton.Left)
+ {
+ _isAttached = false;
+ IdentityMenu.Arrow.Visibility = Visibility.Collapsed;
+ Arrow.Visibility = Visibility.Collapsed;
+ MainMenu.Detach();
+ this.DragMove();
+ }
+ }
+
+ private void MainWindow_Activated(object sender, EventArgs e)
+ {
+ Placement();
+ this.Show();
+ this.Visibility = Visibility.Visible;
+ this.Opacity = 1;
+ }
+
+ private void MainWindow_Deactivated(object sender, EventArgs e)
+ {
+ if (this._isAttached)
+ {
+ this.Visibility = Visibility.Hidden;
+ }
+ }
+
+ private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
+ {
+ if (notifyIcon != null)
+ {
+ notifyIcon.Visible = false;
+ notifyIcon.Icon.Dispose();
+ notifyIcon.Dispose();
+ notifyIcon = null;
+ }
+ Application.Current.Shutdown();
+ }
+
+ private void SetCantDisplay(string title, string detailMessage, Visibility closeButtonVisibility)
+ {
+ this.Dispatcher.Invoke(() =>
+ {
+ NoServiceView.Visibility = Visibility.Visible;
+ CloseErrorButton.IsEnabled = true;
+ CloseErrorButton.Visibility = closeButtonVisibility;
+ ErrorMsg.Content = title;
+ ErrorMsgDetail.Content = detailMessage;
+ SetNotifyIcon("red");
+ _isServiceInError = true;
+ UpdateServiceView();
+ });
+ }
+
+ private void TargetNotifyIcon_Click(object sender, EventArgs e)
+ {
+ this.Show();
+ this.Activate();
+ Application.Current.MainWindow.Activate();
+ }
+
+ private void UpdateServiceView()
+ {
+ if (_isServiceInError)
+ {
+ AddIdAreaButton.Opacity = 0.1;
+ AddIdAreaButton.IsEnabled = false;
+ AddIdButton.Opacity = 0.1;
+ AddIdButton.IsEnabled = false;
+ ConnectButton.Opacity = 0.1;
+ StatArea.Opacity = 0.1;
+ }
+ else
+ {
+ AddIdAreaButton.Opacity = 1.0;
+ AddIdAreaButton.IsEnabled = true;
+ AddIdButton.Opacity = 1.0;
+ AddIdButton.IsEnabled = true;
+ StatArea.Opacity = 1.0;
+ ConnectButton.Opacity = 1.0;
+ }
+ TunnelConnected(!_isServiceInError);
+ }
+
+ private void App_ReceiveString(string obj)
+ {
+ Console.WriteLine(obj);
+ this.Show();
+ this.Activate();
+ }
+
+ async private void MainWindow_Loaded(object sender, RoutedEventArgs e)
+ {
+
+ Window window = Window.GetWindow(App.Current.MainWindow);
+ ZitiDesktopEdge.App app = (ZitiDesktopEdge.App)App.Current;
+ app.ReceiveString += App_ReceiveString;
+
+ // add a new service client
+ serviceClient = new DataClient("ui");
+ serviceClient.OnClientConnected += ServiceClient_OnClientConnected;
+ serviceClient.OnClientDisconnected += ServiceClient_OnClientDisconnected;
+ serviceClient.OnIdentityEvent += ServiceClient_OnIdentityEvent;
+ serviceClient.OnMetricsEvent += ServiceClient_OnMetricsEvent;
+ serviceClient.OnServiceEvent += ServiceClient_OnServiceEvent;
+ serviceClient.OnTunnelStatusEvent += ServiceClient_OnTunnelStatusEvent;
+ serviceClient.OnMfaEvent += ServiceClient_OnMfaEvent;
+ serviceClient.OnLogLevelEvent += ServiceClient_OnLogLevelEvent;
+ serviceClient.OnBulkServiceEvent += ServiceClient_OnBulkServiceEvent;
+ serviceClient.OnNotificationEvent += ServiceClient_OnNotificationEvent;
+ serviceClient.OnControllerEvent += ServiceClient_OnControllerEvent;
+ Application.Current.Properties.Add("ServiceClient", serviceClient);
+
+ monitorClient = new MonitorClient("ui");
+ monitorClient.OnClientConnected += MonitorClient_OnClientConnected;
+ monitorClient.OnNotificationEvent += MonitorClient_OnInstallationNotificationEvent;
+ monitorClient.OnServiceStatusEvent += MonitorClient_OnServiceStatusEvent;
+ monitorClient.OnShutdownEvent += MonitorClient_OnShutdownEvent;
+ monitorClient.OnCommunicationError += MonitorClient_OnCommunicationError;
+ monitorClient.OnReconnectFailure += MonitorClient_OnReconnectFailure;
+ Application.Current.Properties.Add("MonitorClient", monitorClient);
+
+ Application.Current.Properties.Add("Identities", new List());
+ MainMenu.OnAttachmentChange += AttachmentChanged;
+ MainMenu.OnLogLevelChanged += LogLevelChanged;
+ MainMenu.OnShowBlurb += MainMenu_OnShowBlurb;
+ IdentityMenu.OnError += IdentityMenu_OnError;
+
+ try
+ {
+ await serviceClient.ConnectAsync();
+ await serviceClient.WaitForConnectionAsync();
+ }
+ catch /*ignored for now (Exception ex) */
+ {
+ ShowServiceNotStarted();
+ serviceClient.Reconnect();
+ }
+
+ try
+ {
+ await monitorClient.ConnectAsync();
+ await monitorClient.WaitForConnectionAsync();
+ }
+ catch /*ignored for now (Exception ex) */
+ {
+ monitorClient.Reconnect();
+ }
+
+ IdentityMenu.OnForgot += IdentityForgotten;
+ Placement();
+ }
+
+ private void MonitorClient_OnCommunicationError(object sender, Exception e)
+ {
+ string msg = "Communication Error with monitor?";
+ ShowError(msg, e.Message);
+ }
+
+ private void MainMenu_OnShowBlurb(string message)
+ {
+ _ = ShowBlurbAsync(message, "", "info");
+ }
+
+ private void ServiceClient_OnBulkServiceEvent(object sender, BulkServiceEvent e)
+ {
+ var found = identities.Find(id => id.Identifier == e.Identifier);
+ if (found == null)
+ {
+ logger.Warn($"{e.Action} service event for {e.Identifier} but the provided identity identifier was not found!");
+ return;
+ }
+ else
+ {
+ if (e.RemovedServices != null)
+ {
+ foreach (var removed in e.RemovedServices)
+ {
+ removeService(found, removed);
+ }
+ }
+ if (e.AddedServices != null)
+ {
+ foreach (var added in e.AddedServices)
+ {
+ addService(found, added);
+ }
+ }
+ LoadIdentities(true);
+ this.Dispatcher.Invoke(() =>
+ {
+ IdentityDetails deets = ((MainWindow)Application.Current.MainWindow).IdentityMenu;
+ if (deets.IsVisible)
+ {
+ deets.UpdateView();
+ }
+ });
+ }
+ }
+
+ private void ServiceClient_OnNotificationEvent(object sender, NotificationEvent e)
+ {
+ var displayMFARequired = false;
+ var displayMFATimout = false;
+ foreach (var notification in e.Notification)
+ {
+ var found = identities.Find(id => id.Identifier == notification.Identifier);
+ if (found == null)
+ {
+ logger.Warn($"{e.Op} event for {notification.Identifier} but the provided identity identifier was not found!");
+ continue;
+ }
+ else
+ {
+ found.TimeoutMessage = notification.Message;
+ found.MaxTimeout = notification.MfaMaximumTimeout;
+ found.MinTimeout = notification.MfaMinimumTimeout;
+
+ if (notification.MfaMinimumTimeout == 0)
+ {
+ // display mfa token icon
+ displayMFARequired = true;
+ }
+ else
+ {
+ displayMFATimout = true;
+ }
+
+ for (int i = 0; i < identities.Count; i++)
+ {
+ if (identities[i].Identifier == found.Identifier)
+ {
+ identities[i] = found;
+ break;
+ }
+ }
+ }
+ }
+
+ // we may need to display mfa icon, based on the timer in UI, remove found.MFAInfo.ShowMFA setting in this function.
+ // the below function can show mfa icon even after user authenticates successfully, in race conditions
+ if (displayMFARequired || displayMFATimout)
+ {
+ this.Dispatcher.Invoke(() =>
+ {
+ IdentityDetails deets = ((MainWindow)Application.Current.MainWindow).IdentityMenu;
+ if (deets.IsVisible)
+ {
+ deets.UpdateView();
+ }
+ });
+ }
+ LoadIdentities(true);
+ }
+
+ private void ServiceClient_OnControllerEvent(object sender, ControllerEvent e)
+ {
+ logger.Debug($"==== ControllerEvent : action:{e.Action} identifier:{e.Identifier}");
+ // commenting this block, because when it receives the disconnected events, identities are disabled and
+ // it is not allowing me to click/perform any operation on the identity
+ // the color of the title is also too dark, and it is not clearly visible, when the identity is disconnected
+ /* if (e.Action == "connected") {
var found = identities.Find(i => i.Identifier == e.Identifier);
found.IsConnected = true;
for (int i = 0; i < identities.Count; i++) {
@@ -786,1091 +936,1375 @@ private void ServiceClient_OnControllerEvent(object sender, ControllerEvent e) {
}
LoadIdentities(true);
} */
- }
-
-
- string nextVersionStr = null;
- private void MonitorClient_OnReconnectFailure(object sender, object e) {
- logger.Trace("OnReconnectFailure triggered");
- if (nextVersionStr == null) {
- // check for the current version
- nextVersionStr = "checking for update";
- Version nextVersion = GithubAPI.GetVersion(GithubAPI.GetJson(GithubAPI.ProdUrl));
- nextVersionStr = nextVersion.ToString();
- Version currentVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; //fetch from ziti?
-
- int compare = currentVersion.CompareTo(nextVersion);
- if (compare < 0) {
- MainMenu.SetAppUpgradeAvailableText("Upgrade available: " + nextVersionStr);
- logger.Info("upgrade is available. Published version: {} is newer than the current version: {}", nextVersion, currentVersion);
- //UpgradeAvailable();
- } else if (compare > 0) {
- logger.Info("the version installed: {0} is newer than the released version: {1}", currentVersion, nextVersion);
- MainMenu.SetAppIsNewer("This version is newer than the latest: " + nextVersionStr);
- } else {
- logger.Info("Current version installed: {0} is the same as the latest released version {1}", currentVersion, nextVersion);
- MainMenu.SetAppUpgradeAvailableText("");
- }
- }
- }
-
- private void MonitorClient_OnShutdownEvent(object sender, StatusEvent e) {
- logger.Info("The monitor has indicated the application should shut down.");
- this.Dispatcher.Invoke(() => {
- Application.Current.Shutdown();
- });
- }
-
- private void MonitorClient_OnServiceStatusEvent(object sender, MonitorServiceStatusEvent evt) {
- this.Dispatcher.Invoke(() => {
- try {
- if (evt.Message?.ToLower() == "upgrading") {
- logger.Info("The monitor has indicated an upgrade is in progress. Shutting down the UI");
- UpgradeSentinel.StartUpgradeSentinel();
-
- App.Current.Exit -= Current_Exit;
- logger.Info("Removed Current_Exit handler");
- notifyIcon.Visible = false;
- notifyIcon.Icon.Dispose();
- notifyIcon.Dispose();
- Application.Current.Shutdown();
- return;
- }
- SetAutomaticUpdateEnabled(evt.AutomaticUpgradeDisabled, evt.AutomaticUpgradeURL);
- if(evt.Code != 0) {
- logger.Error("CODE: " + evt.Code);
- if (MainMenu.ShowUnexpectedFailure) {
- ShowToast("The data channel has stopped unexpectedly", $"If this keeps happening please collect logs and report the issue.", feedbackToastButton);
- }
- }
- MainMenu.ShowUpdateAvailable();
- logger.Debug("MonitorClient_OnServiceStatusEvent: {0}", evt.Status);
- Application.Current.Properties["ReleaseStream"] = evt.ReleaseStream;
-
- ServiceControllerStatus status = (ServiceControllerStatus)Enum.Parse(typeof(ServiceControllerStatus), evt.Status);
-
- switch (status) {
- case ServiceControllerStatus.Running:
- logger.Info("Service is started");
- break;
- case ServiceControllerStatus.Stopped:
- logger.Info("Service is stopped");
- ShowServiceNotStarted();
- break;
- case ServiceControllerStatus.StopPending:
- logger.Info("Service is stopping...");
-
- this.Dispatcher.Invoke(async () => {
- SetCantDisplay("The Service is Stopping", "Please wait while the service stops", Visibility.Visible);
- await WaitForServiceToStop(DateTime.Now + TimeSpan.FromSeconds(30));
- });
- break;
- case ServiceControllerStatus.StartPending:
- logger.Info("Service is starting...");
- break;
- case ServiceControllerStatus.PausePending:
- logger.Warn("UNEXPECTED STATUS: PausePending");
- break;
- case ServiceControllerStatus.Paused:
- logger.Warn("UNEXPECTED STATUS: Paused");
- break;
- default:
- logger.Warn("UNEXPECTED STATUS: {0}", evt.Status);
- break;
- }
- } catch (Exception ex) {
- logger.Warn(ex, "unexpected exception in MonitorClient_OnServiceStatusEvent? {0}", ex.Message);
- }
- });
- }
-
- public void SetAutomaticUpdateEnabled(string enabled, string url) {
- this.Dispatcher.Invoke(() => {
- state.AutomaticUpdatesDisabled = bool.Parse(enabled);
- state.AutomaticUpdateURL = url;
- });
- }
-
- private void MonitorClient_OnInstallationNotificationEvent(object sender, InstallationNotificationEvent evt) {
- this.Dispatcher.Invoke(() => {
- logger.Debug("MonitorClient_OnInstallationNotificationEvent: {0}", evt.Message);
- switch (evt.Message?.ToLower()) {
- case "installationupdate":
- logger.Debug("Installation Update is available - {0}", evt.ZDEVersion);
- var remaining = evt.InstallTime - DateTime.Now;
-
- state.PendingUpdate.Version = evt.ZDEVersion;
- state.PendingUpdate.InstallTime = evt.InstallTime;
- state.UpdateAvailable = true;
- SetAutomaticUpdateEnabled(evt.AutomaticUpgradeDisabled, evt.AutomaticUpgradeURL);
- MainMenu.ShowUpdateAvailable();
- AlertCanvas.Visibility = Visibility.Visible;
-
- if (isToastEnabled()) {
- if (!state.AutomaticUpdatesDisabled) {
- if (remaining.TotalSeconds < 60) {
- //this is an immediate update - show a different message
- ShowToast("Ziti Desktop Edge will initiate auto installation in the next minute!");
- } else {
- if (DateTime.Now > NextNotificationTime) {
- ShowToast($"Update {evt.ZDEVersion} is available for Ziti Desktop Edge and will be automatically installed by " + evt.InstallTime);
- NextNotificationTime = DateTime.Now + evt.NotificationDuration;
- } else {
- logger.Debug("Skipping notification. Time until next notification {} seconds which is at {}", (int)((NextNotificationTime - DateTime.Now).TotalSeconds), NextNotificationTime);
- }
- }
- } else {
- ShowToast("New version available", $"Version {evt.ZDEVersion} is available for Ziti Desktop Edge", null);
- }
- SetNotifyIcon("");
- // display a tag in UI and a button for the update software
- }
- break;
- case "configuration changed":
- break;
- default:
- logger.Debug("unexpected event type?");
- break;
- }
- });
- }
-
- private bool isToastEnabled() {
- bool result;
- //only show notifications once if automatic updates are disabled
- if (NotificationsShownCount == 0) {
- result = true; //regardless - if never notified, always return true
- } else {
- result = !state.AutomaticUpdatesDisabled;
- }
- return result;
- }
-
- private void ShowToast(string header, string message, ToastButton button) {
- try {
- logger.Debug("showing toast: {} {}", header, message);
- var builder = new ToastContentBuilder()
- .AddArgument("notbutton", "click")
- .AddText(header)
- .AddText(message);
- if (button != null) {
- builder.AddButton(button);
- }
- builder.Show();
- NotificationsShownCount++;
- } catch {
- logger.Warn("couldn't show toast: {} {}", header, message);
- }
- }
-
-
- private void ShowToast(string message) {
- ShowToast("Important Notice", message, null);
- }
-
- async private Task WaitForServiceToStop(DateTime until) {
- //continually poll for the service to stop. If it is stuck - ask the user if they want to try to force
- //close the service
- while (DateTime.Now < until) {
- await Task.Delay(250);
- MonitorServiceStatusEvent resp = await monitorClient.StatusAsync();
- if (resp.IsStopped()) {
- // good - that's what we are waiting for...
- return;
- } else {
- // bad - not stopped yet...
- logger.Debug("Waiting for service to stop... Still not stopped yet. Status: {0}", resp.Status);
- }
- }
- // real bad - means it's stuck probably. Ask the user if they want to try to force it...
- logger.Warn("Waiting for service to stop... Service did not reach stopped state in the expected amount of time.");
- SetCantDisplay("The Service Appears Stuck", "Would you like to try to force close the service?", Visibility.Visible);
- CloseErrorButton.Content = "Force Quit";
- CloseErrorButton.Click -= CloseError;
- CloseErrorButton.Click += ForceQuitButtonClick;
- }
-
- async private void ForceQuitButtonClick(object sender, RoutedEventArgs e) {
- MonitorServiceStatusEvent status = await monitorClient.ForceTerminateAsync();
- if (status.IsStopped()) {
- //good
- CloseErrorButton.Click += CloseError; //reset the close button...
- CloseErrorButton.Click -= ForceQuitButtonClick;
- } else {
- //bad...
- SetCantDisplay("The Service Is Still Running", "Current status is: " + status.Status, Visibility.Visible);
- }
- }
-
- async private void StartZitiService(object sender, RoutedEventArgs e) {
- try {
- ShowLoad("Starting", "Starting the data service");
- logger.Info("StartZitiService");
- var r = await monitorClient.StartServiceAsync();
- if (r.Code != 0) {
- logger.Debug("ERROR: {0} : {1}", r.Message, r.Error);
- } else {
- logger.Info("Service started!");
- CloseErrorButton.Click -= StartZitiService;
- CloseError(null, null);
- }
- } catch (MonitorServiceException me) {
- logger.Warn("the monitor service appears offline. {0}", me);
- CloseErrorButton.IsEnabled = true;
- HideLoad();
- ShowError("Error Starting Service", "The monitor service is offline");
- } catch (Exception ex) {
- logger.Error(ex, "UNEXPECTED ERROR!");
- CloseErrorButton.IsEnabled = true;
- HideLoad();
- ShowError("Unexpected Error", "Code 2:" + ex.Message);
- }
- CloseErrorButton.IsEnabled = true;
- // HideLoad();
- }
-
- private void ShowServiceNotStarted() {
- TunnelConnected(false);
- LoadIdentities(true);
- }
-
- private void MonitorClient_OnClientConnected(object sender, object e) {
- logger.Debug("MonitorClient_OnClientConnected");
- MainMenu.SetAppUpgradeAvailableText("");
- }
-
- async private Task LogLevelChanged(string level) {
- int logsSet = 0;
- try {
- await serviceClient.SetLogLevelAsync(level);
- logsSet++;
- await monitorClient.SetLogLevelAsync(level);
- logsSet++;
- Ziti.Desktop.Edge.Utils.UIUtils.SetLogLevel(level);
- return true;
- } catch (Exception ex) {
- logger.Error(ex, "Unexpected error. logsSet: {0}", logsSet);
- if (logsSet > 1) {
- await ShowBlurbAsync("Unexpected error setting logs?", "");
- } else if (logsSet > 0) {
- await ShowBlurbAsync("Failed to set monitor client log level", "");
- } else {
- await ShowBlurbAsync("Failed to set log levels", "");
- }
- }
- return false;
- }
-
- private void IdentityMenu_OnError(string message) {
- ShowError("Identity Error", message);
- }
-
- private void ServiceClient_OnClientConnected(object sender, object e) {
- this.Dispatcher.Invoke(() => {
- MainMenu.Connected();
- NoServiceView.Visibility = Visibility.Collapsed;
- _isServiceInError = false;
- UpdateServiceView();
- SetNotifyIcon("white");
- LoadIdentities(true);
- });
- }
-
- private void ServiceClient_OnClientDisconnected(object sender, object e) {
- this.Dispatcher.Invoke(() => {
- IdentityMenu.Visibility = Visibility.Collapsed;
- MFASetup.Visibility = Visibility.Collapsed;
- HideModal();
- MainMenu.Disconnected();
- for (int i = 0; i < IdList.Children.Count; i++) {
- IdentityItem item = (IdentityItem)IdList.Children[i];
- item.StopTimers();
- }
- IdList.Children.Clear();
- if (e != null) {
- logger.Debug(e.ToString());
- }
- //SetCantDisplay("Start the Ziti Tunnel Service to continue");
- SetNotifyIcon("red");
- ShowServiceNotStarted();
- });
- }
-
- ///
- /// If an identity gets added late, execute this.
- ///
- /// Do not update services for identity events
- ///
- /// The sending service
- /// The identity event
- private void ServiceClient_OnIdentityEvent(object sender, IdentityEvent e) {
- if (e == null) return;
-
- ZitiIdentity zid = ZitiIdentity.FromClient(e.Id);
- logger.Debug($"==== IdentityEvent : action:{e.Action} identifer:{e.Id.Identifier} name:{e.Id.Name} ");
-
- this.Dispatcher.Invoke(async () => {
- if (e.Action == "added") {
- var found = identities.Find(i => i.Identifier == e.Id.Identifier);
- if (found == null) {
- AddIdentity(zid);
- LoadIdentities(true);
- } else {
- // means we likely are getting an update for some reason. compare the identities and use the latest info
- if (zid.Name != null && zid.Name.Length > 0) found.Name = zid.Name;
- if (zid.ControllerUrl != null && zid.ControllerUrl.Length > 0) found.ControllerUrl = zid.ControllerUrl;
- if (zid.ContollerVersion != null && zid.ContollerVersion.Length > 0) found.ContollerVersion = zid.ContollerVersion;
- found.IsEnabled = zid.IsEnabled;
- found.IsMFAEnabled = e.Id.MfaEnabled;
- found.IsConnected = true;
- for (int i = 0; i < identities.Count; i++) {
- if (identities[i].Identifier == found.Identifier) {
- identities[i] = found;
- break;
- }
- }
- LoadIdentities(true);
- }
- } else if (e.Action == "updated") {
- //this indicates that all updates have been sent to the UI... wait for 2 seconds then trigger any ui updates needed
- await Task.Delay(2000);
- LoadIdentities(true);
- } else if (e.Action == "connected") {
- var found = identities.Find(i => i.Identifier == e.Id.Identifier);
- found.IsConnected = true;
- for (int i = 0; i < identities.Count; i++) {
- if (identities[i].Identifier == found.Identifier) {
- identities[i] = found;
- break;
- }
- }
- LoadIdentities(true);
- } else if (e.Action == "disconnected") {
- var found = identities.Find(i => i.Identifier == e.Id.Identifier);
- found.IsConnected = false;
- for (int i = 0; i < identities.Count; i++) {
- if (identities[i].Identifier == found.Identifier) {
- identities[i] = found;
- break;
- }
- }
- LoadIdentities(true);
- } else {
- IdentityForgotten(ZitiIdentity.FromClient(e.Id));
- }
- });
- logger.Debug($"IDENTITY EVENT. Action: {e.Action} identifier: {zid.Identifier}");
- }
-
- private void ServiceClient_OnMetricsEvent(object sender, List ids) {
- if (ids != null) {
- long totalUp = 0;
- long totalDown = 0;
- foreach (var id in ids) {
- //logger.Debug($"==== MetricsEvent : id {id.Name} down: {id.Metrics.Down} up:{id.Metrics.Up}");
- if (id?.Metrics != null) {
- totalDown += id.Metrics.Down;
- totalUp += id.Metrics.Up;
- }
- }
- this.Dispatcher.Invoke(() => {
- SetSpeed(totalUp, UploadSpeed, UploadSpeedLabel);
- SetSpeed(totalDown, DownloadSpeed, DownloadSpeedLabel);
- });
- }
- }
-
- public void SetSpeed(decimal bytes, Label speed, Label speedLabel) {
- int counter = 0;
- while (Math.Round(bytes / 1024) >= 1) {
- bytes = bytes / 1024;
- counter++;
- }
- speed.Content = bytes.ToString("0.0");
- speedLabel.Content = suffixes[counter];
- }
-
- private void ServiceClient_OnServiceEvent(object sender, ServiceEvent e) {
- if (e == null) return;
-
- logger.Debug($"==== ServiceEvent : action:{e.Action} identifier:{e.Identifier} name:{e.Service.Name} ");
- var found = identities.Find(id => id.Identifier == e.Identifier);
- if (found == null) {
- logger.Debug($"{e.Action} service event for {e.Service.Name} but the provided identity identifier {e.Identifier} is not found!");
- return;
- }
-
- if (e.Action == "added") {
- addService(found, e.Service);
- } else {
- removeService(found, e.Service);
- }
- LoadIdentities(true);
- this.Dispatcher.Invoke(() => {
- IdentityDetails deets = ((MainWindow)Application.Current.MainWindow).IdentityMenu;
- if (deets.IsVisible) {
- deets.UpdateView();
- }
- });
- }
-
- private void addService(ZitiIdentity found, Service added) {
- ZitiService zs = new ZitiService(added);
- var svc = found.Services.Find(s => s.Name == zs.Name);
- if (svc == null) {
- logger.Debug("Service Added: " + zs.Name);
- found.Services.Add(zs);
- if (zs.HasFailingPostureCheck()) {
- found.HasServiceFailingPostureCheck = true;
- if (zs.PostureChecks.Any(p => !p.IsPassing && p.QueryType == "MFA")) {
- found.IsMFANeeded = true;
- }
- }
- } else {
- logger.Debug("the service named " + zs.Name + " is already accounted for on this identity.");
- }
- }
-
- private void removeService(ZitiIdentity found, Service removed) {
- logger.Debug("removing the service named: {0}", removed.Name);
- found.Services.RemoveAll(s => s.Name == removed.Name);
- }
-
- private void ServiceClient_OnTunnelStatusEvent(object sender, TunnelStatusEvent e) {
- if (e == null) return; //just skip it for now...
- logger.Debug($"==== TunnelStatusEvent: ");
- Application.Current.Properties.Remove("CurrentTunnelStatus");
- Application.Current.Properties.Add("CurrentTunnelStatus", e.Status);
- e.Status.Dump(Console.Out);
- this.Dispatcher.Invoke(() => {
- /*if (e.ApiVersion != DataClient.EXPECTED_API_VERSION) {
+ }
+
+
+ string nextVersionStr = null;
+ private void MonitorClient_OnReconnectFailure(object sender, object e)
+ {
+ logger.Trace("OnReconnectFailure triggered");
+ if (nextVersionStr == null)
+ {
+ // check for the current version
+ nextVersionStr = "checking for update";
+ Version nextVersion = GithubAPI.GetVersion(GithubAPI.GetJson(GithubAPI.ProdUrl));
+ nextVersionStr = nextVersion.ToString();
+ Version currentVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; //fetch from ziti?
+
+ int compare = currentVersion.CompareTo(nextVersion);
+ if (compare < 0)
+ {
+ MainMenu.SetAppUpgradeAvailableText("Upgrade available: " + nextVersionStr);
+ logger.Info("upgrade is available. Published version: {} is newer than the current version: {}", nextVersion, currentVersion);
+ //UpgradeAvailable();
+ }
+ else if (compare > 0)
+ {
+ logger.Info("the version installed: {0} is newer than the released version: {1}", currentVersion, nextVersion);
+ MainMenu.SetAppIsNewer("This version is newer than the latest: " + nextVersionStr);
+ }
+ else
+ {
+ logger.Info("Current version installed: {0} is the same as the latest released version {1}", currentVersion, nextVersion);
+ MainMenu.SetAppUpgradeAvailableText("");
+ }
+ }
+ }
+
+ private void MonitorClient_OnShutdownEvent(object sender, StatusEvent e)
+ {
+ logger.Info("The monitor has indicated the application should shut down.");
+ this.Dispatcher.Invoke(() =>
+ {
+ Application.Current.Shutdown();
+ });
+ }
+
+ private void MonitorClient_OnServiceStatusEvent(object sender, MonitorServiceStatusEvent evt)
+ {
+ this.Dispatcher.Invoke(() =>
+ {
+ try
+ {
+ if (evt.Message?.ToLower() == "upgrading")
+ {
+ logger.Info("The monitor has indicated an upgrade is in progress. Shutting down the UI");
+ UpgradeSentinel.StartUpgradeSentinel();
+
+ App.Current.Exit -= Current_Exit;
+ logger.Info("Removed Current_Exit handler");
+ notifyIcon.Visible = false;
+ notifyIcon.Icon.Dispose();
+ notifyIcon.Dispose();
+ Application.Current.Shutdown();
+ return;
+ }
+ SetAutomaticUpdateEnabled(evt.AutomaticUpgradeDisabled, evt.AutomaticUpgradeURL);
+ if (evt.Code != 0)
+ {
+ logger.Error("CODE: " + evt.Code);
+ if (MainMenu.ShowUnexpectedFailure)
+ {
+ ShowToast("The data channel has stopped unexpectedly", $"If this keeps happening please collect logs and report the issue.", feedbackToastButton);
+ }
+ }
+ MainMenu.ShowUpdateAvailable();
+ logger.Debug("MonitorClient_OnServiceStatusEvent: {0}", evt.Status);
+ Application.Current.Properties["ReleaseStream"] = evt.ReleaseStream;
+
+ ServiceControllerStatus status = (ServiceControllerStatus)Enum.Parse(typeof(ServiceControllerStatus), evt.Status);
+
+ switch (status)
+ {
+ case ServiceControllerStatus.Running:
+ logger.Info("Service is started");
+ break;
+ case ServiceControllerStatus.Stopped:
+ logger.Info("Service is stopped");
+ ShowServiceNotStarted();
+ break;
+ case ServiceControllerStatus.StopPending:
+ logger.Info("Service is stopping...");
+
+ this.Dispatcher.Invoke(async () =>
+ {
+ SetCantDisplay("The Service is Stopping", "Please wait while the service stops", Visibility.Visible);
+ await WaitForServiceToStop(DateTime.Now + TimeSpan.FromSeconds(30));
+ });
+ break;
+ case ServiceControllerStatus.StartPending:
+ logger.Info("Service is starting...");
+ break;
+ case ServiceControllerStatus.PausePending:
+ logger.Warn("UNEXPECTED STATUS: PausePending");
+ break;
+ case ServiceControllerStatus.Paused:
+ logger.Warn("UNEXPECTED STATUS: Paused");
+ break;
+ default:
+ logger.Warn("UNEXPECTED STATUS: {0}", evt.Status);
+ break;
+ }
+ }
+ catch (Exception ex)
+ {
+ logger.Warn(ex, "unexpected exception in MonitorClient_OnServiceStatusEvent? {0}", ex.Message);
+ }
+ });
+ }
+
+ public void SetAutomaticUpdateEnabled(string enabled, string url)
+ {
+ this.Dispatcher.Invoke(() =>
+ {
+ state.AutomaticUpdatesDisabled = bool.Parse(enabled);
+ state.AutomaticUpdateURL = url;
+ });
+ }
+
+ private void MonitorClient_OnInstallationNotificationEvent(object sender, InstallationNotificationEvent evt)
+ {
+ this.Dispatcher.Invoke(() =>
+ {
+ logger.Debug("MonitorClient_OnInstallationNotificationEvent: {0}", evt.Message);
+ switch (evt.Message?.ToLower())
+ {
+ case "installationupdate":
+ logger.Debug("Installation Update is available - {0}", evt.ZDEVersion);
+ var remaining = evt.InstallTime - DateTime.Now;
+
+ state.PendingUpdate.Version = evt.ZDEVersion;
+ state.PendingUpdate.InstallTime = evt.InstallTime;
+ state.UpdateAvailable = true;
+ SetAutomaticUpdateEnabled(evt.AutomaticUpgradeDisabled, evt.AutomaticUpgradeURL);
+ MainMenu.ShowUpdateAvailable();
+ AlertCanvas.Visibility = Visibility.Visible;
+
+ if (isToastEnabled())
+ {
+ if (!state.AutomaticUpdatesDisabled)
+ {
+ if (remaining.TotalSeconds < 60)
+ {
+ //this is an immediate update - show a different message
+ ShowToast("Ziti Desktop Edge will initiate auto installation in the next minute!");
+ }
+ else
+ {
+ if (DateTime.Now > NextNotificationTime)
+ {
+ ShowToast($"Update {evt.ZDEVersion} is available for Ziti Desktop Edge and will be automatically installed by " + evt.InstallTime);
+ NextNotificationTime = DateTime.Now + evt.NotificationDuration;
+ }
+ else
+ {
+ logger.Debug("Skipping notification. Time until next notification {} seconds which is at {}", (int)((NextNotificationTime - DateTime.Now).TotalSeconds), NextNotificationTime);
+ }
+ }
+ }
+ else
+ {
+ ShowToast("New version available", $"Version {evt.ZDEVersion} is available for Ziti Desktop Edge", null);
+ }
+ SetNotifyIcon("");
+ // display a tag in UI and a button for the update software
+ }
+ break;
+ case "configuration changed":
+ break;
+ default:
+ logger.Debug("unexpected event type?");
+ break;
+ }
+ });
+ }
+
+ private bool isToastEnabled()
+ {
+ bool result;
+ //only show notifications once if automatic updates are disabled
+ if (NotificationsShownCount == 0)
+ {
+ result = true; //regardless - if never notified, always return true
+ }
+ else
+ {
+ result = !state.AutomaticUpdatesDisabled;
+ }
+ return result;
+ }
+
+ private void ShowToast(string header, string message, ToastButton button)
+ {
+ try
+ {
+ logger.Debug("showing toast: {} {}", header, message);
+ var builder = new ToastContentBuilder()
+ .AddArgument("notbutton", "click")
+ .AddText(header)
+ .AddText(message);
+ if (button != null)
+ {
+ builder.AddButton(button);
+ }
+ builder.Show();
+ NotificationsShownCount++;
+ }
+ catch
+ {
+ logger.Warn("couldn't show toast: {} {}", header, message);
+ }
+ }
+
+
+ private void ShowToast(string message)
+ {
+ ShowToast("Important Notice", message, null);
+ }
+
+ async private Task WaitForServiceToStop(DateTime until)
+ {
+ //continually poll for the service to stop. If it is stuck - ask the user if they want to try to force
+ //close the service
+ while (DateTime.Now < until)
+ {
+ await Task.Delay(250);
+ MonitorServiceStatusEvent resp = await monitorClient.StatusAsync();
+ if (resp.IsStopped())
+ {
+ // good - that's what we are waiting for...
+ return;
+ }
+ else
+ {
+ // bad - not stopped yet...
+ logger.Debug("Waiting for service to stop... Still not stopped yet. Status: {0}", resp.Status);
+ }
+ }
+ // real bad - means it's stuck probably. Ask the user if they want to try to force it...
+ logger.Warn("Waiting for service to stop... Service did not reach stopped state in the expected amount of time.");
+ SetCantDisplay("The Service Appears Stuck", "Would you like to try to force close the service?", Visibility.Visible);
+ CloseErrorButton.Content = "Force Quit";
+ CloseErrorButton.Click -= CloseError;
+ CloseErrorButton.Click += ForceQuitButtonClick;
+ }
+
+ async private void ForceQuitButtonClick(object sender, RoutedEventArgs e)
+ {
+ MonitorServiceStatusEvent status = await monitorClient.ForceTerminateAsync();
+ if (status.IsStopped())
+ {
+ //good
+ CloseErrorButton.Click += CloseError; //reset the close button...
+ CloseErrorButton.Click -= ForceQuitButtonClick;
+ }
+ else
+ {
+ //bad...
+ SetCantDisplay("The Service Is Still Running", "Current status is: " + status.Status, Visibility.Visible);
+ }
+ }
+
+ async private void StartZitiService(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ ShowLoad("Starting", "Starting the data service");
+ logger.Info("StartZitiService");
+ var r = await monitorClient.StartServiceAsync();
+ if (r.Code != 0)
+ {
+ logger.Debug("ERROR: {0} : {1}", r.Message, r.Error);
+ }
+ else
+ {
+ logger.Info("Service started!");
+ CloseErrorButton.Click -= StartZitiService;
+ CloseError(null, null);
+ }
+ }
+ catch (MonitorServiceException me)
+ {
+ logger.Warn("the monitor service appears offline. {0}", me);
+ CloseErrorButton.IsEnabled = true;
+ HideLoad();
+ ShowError("Error Starting Service", "The monitor service is offline");
+ }
+ catch (Exception ex)
+ {
+ logger.Error(ex, "UNEXPECTED ERROR!");
+ CloseErrorButton.IsEnabled = true;
+ HideLoad();
+ ShowError("Unexpected Error", "Code 2:" + ex.Message);
+ }
+ CloseErrorButton.IsEnabled = true;
+ // HideLoad();
+ }
+
+ private void ShowServiceNotStarted()
+ {
+ TunnelConnected(false);
+ LoadIdentities(true);
+ }
+
+ private void MonitorClient_OnClientConnected(object sender, object e)
+ {
+ logger.Debug("MonitorClient_OnClientConnected");
+ MainMenu.SetAppUpgradeAvailableText("");
+ }
+
+ async private Task LogLevelChanged(string level)
+ {
+ int logsSet = 0;
+ try
+ {
+ await serviceClient.SetLogLevelAsync(level);
+ logsSet++;
+ await monitorClient.SetLogLevelAsync(level);
+ logsSet++;
+ Ziti.Desktop.Edge.Utils.UIUtils.SetLogLevel(level);
+ return true;
+ }
+ catch (Exception ex)
+ {
+ logger.Error(ex, "Unexpected error. logsSet: {0}", logsSet);
+ if (logsSet > 1)
+ {
+ await ShowBlurbAsync("Unexpected error setting logs?", "");
+ }
+ else if (logsSet > 0)
+ {
+ await ShowBlurbAsync("Failed to set monitor client log level", "");
+ }
+ else
+ {
+ await ShowBlurbAsync("Failed to set log levels", "");
+ }
+ }
+ return false;
+ }
+
+ private void IdentityMenu_OnError(string message)
+ {
+ ShowError("Identity Error", message);
+ }
+
+ private void ServiceClient_OnClientConnected(object sender, object e)
+ {
+ this.Dispatcher.Invoke(() =>
+ {
+ MainMenu.Connected();
+ NoServiceView.Visibility = Visibility.Collapsed;
+ _isServiceInError = false;
+ UpdateServiceView();
+ SetNotifyIcon("white");
+ LoadIdentities(true);
+ });
+ }
+
+ private void ServiceClient_OnClientDisconnected(object sender, object e)
+ {
+ this.Dispatcher.Invoke(() =>
+ {
+ IdentityMenu.Visibility = Visibility.Collapsed;
+ MFASetup.Visibility = Visibility.Collapsed;
+ HideModal();
+ MainMenu.Disconnected();
+ for (int i = 0; i < IdList.Children.Count; i++)
+ {
+ IdentityItem item = (IdentityItem)IdList.Children[i];
+ item.StopTimers();
+ }
+ IdList.Children.Clear();
+ if (e != null)
+ {
+ logger.Debug(e.ToString());
+ }
+ //SetCantDisplay("Start the Ziti Tunnel Service to continue");
+ SetNotifyIcon("red");
+ ShowServiceNotStarted();
+ });
+ }
+
+ ///
+ /// If an identity gets added late, execute this.
+ ///
+ /// Do not update services for identity events
+ ///
+ /// The sending service
+ /// The identity event
+ private void ServiceClient_OnIdentityEvent(object sender, IdentityEvent e)
+ {
+ if (e == null) return;
+
+ ZitiIdentity zid = ZitiIdentity.FromClient(e.Id);
+ logger.Debug($"==== IdentityEvent : action:{e.Action} identifer:{e.Id.Identifier} name:{e.Id.Name} ");
+
+ this.Dispatcher.Invoke(async () =>
+ {
+ if (e.Action == "added")
+ {
+ var found = identities.Find(i => i.Identifier == e.Id.Identifier);
+ if (found == null)
+ {
+ AddIdentity(zid);
+ LoadIdentities(true);
+ }
+ else
+ {
+ // means we likely are getting an update for some reason. compare the identities and use the latest info
+ if (zid.Name != null && zid.Name.Length > 0) found.Name = zid.Name;
+ if (zid.ControllerUrl != null && zid.ControllerUrl.Length > 0) found.ControllerUrl = zid.ControllerUrl;
+ if (zid.ContollerVersion != null && zid.ContollerVersion.Length > 0) found.ContollerVersion = zid.ContollerVersion;
+ found.IsEnabled = zid.IsEnabled;
+ found.IsMFAEnabled = e.Id.MfaEnabled;
+ found.IsConnected = true;
+ for (int i = 0; i < identities.Count; i++)
+ {
+ if (identities[i].Identifier == found.Identifier)
+ {
+ identities[i] = found;
+ break;
+ }
+ }
+ LoadIdentities(true);
+ }
+ }
+ else if (e.Action == "updated")
+ {
+ //this indicates that all updates have been sent to the UI... wait for 2 seconds then trigger any ui updates needed
+ await Task.Delay(2000);
+ LoadIdentities(true);
+ }
+ else if (e.Action == "connected")
+ {
+ var found = identities.Find(i => i.Identifier == e.Id.Identifier);
+ found.IsConnected = true;
+ for (int i = 0; i < identities.Count; i++)
+ {
+ if (identities[i].Identifier == found.Identifier)
+ {
+ identities[i] = found;
+ break;
+ }
+ }
+ LoadIdentities(true);
+ }
+ else if (e.Action == "disconnected")
+ {
+ var found = identities.Find(i => i.Identifier == e.Id.Identifier);
+ found.IsConnected = false;
+ for (int i = 0; i < identities.Count; i++)
+ {
+ if (identities[i].Identifier == found.Identifier)
+ {
+ identities[i] = found;
+ break;
+ }
+ }
+ LoadIdentities(true);
+ }
+ else
+ {
+ IdentityForgotten(ZitiIdentity.FromClient(e.Id));
+ }
+ });
+ logger.Debug($"IDENTITY EVENT. Action: {e.Action} identifier: {zid.Identifier}");
+ }
+
+ private void ServiceClient_OnMetricsEvent(object sender, List ids)
+ {
+ if (ids != null)
+ {
+ long totalUp = 0;
+ long totalDown = 0;
+ foreach (var id in ids)
+ {
+ //logger.Debug($"==== MetricsEvent : id {id.Name} down: {id.Metrics.Down} up:{id.Metrics.Up}");
+ if (id?.Metrics != null)
+ {
+ totalDown += id.Metrics.Down;
+ totalUp += id.Metrics.Up;
+ }
+ }
+ this.Dispatcher.Invoke(() =>
+ {
+ SetSpeed(totalUp, UploadSpeed, UploadSpeedLabel);
+ SetSpeed(totalDown, DownloadSpeed, DownloadSpeedLabel);
+ });
+ }
+ }
+
+ public void SetSpeed(decimal bytes, Label speed, Label speedLabel)
+ {
+ int counter = 0;
+ while (Math.Round(bytes / 1024) >= 1)
+ {
+ bytes = bytes / 1024;
+ counter++;
+ }
+ speed.Content = bytes.ToString("0.0");
+ speedLabel.Content = suffixes[counter];
+ }
+
+ private void ServiceClient_OnServiceEvent(object sender, ServiceEvent e)
+ {
+ if (e == null) return;
+
+ logger.Debug($"==== ServiceEvent : action:{e.Action} identifier:{e.Identifier} name:{e.Service.Name} ");
+ var found = identities.Find(id => id.Identifier == e.Identifier);
+ if (found == null)
+ {
+ logger.Debug($"{e.Action} service event for {e.Service.Name} but the provided identity identifier {e.Identifier} is not found!");
+ return;
+ }
+
+ if (e.Action == "added")
+ {
+ addService(found, e.Service);
+ }
+ else
+ {
+ removeService(found, e.Service);
+ }
+ LoadIdentities(true);
+ this.Dispatcher.Invoke(() =>
+ {
+ IdentityDetails deets = ((MainWindow)Application.Current.MainWindow).IdentityMenu;
+ if (deets.IsVisible)
+ {
+ deets.UpdateView();
+ }
+ });
+ }
+
+ private void addService(ZitiIdentity found, Service added)
+ {
+ ZitiService zs = new ZitiService(added);
+ var svc = found.Services.Find(s => s.Name == zs.Name);
+ if (svc == null)
+ {
+ logger.Debug("Service Added: " + zs.Name);
+ found.Services.Add(zs);
+ if (zs.HasFailingPostureCheck())
+ {
+ found.HasServiceFailingPostureCheck = true;
+ if (zs.PostureChecks.Any(p => !p.IsPassing && p.QueryType == "MFA"))
+ {
+ found.IsMFANeeded = true;
+ }
+ }
+ }
+ else
+ {
+ logger.Debug("the service named " + zs.Name + " is already accounted for on this identity.");
+ }
+ }
+
+ private void removeService(ZitiIdentity found, Service removed)
+ {
+ logger.Debug("removing the service named: {0}", removed.Name);
+ found.Services.RemoveAll(s => s.Name == removed.Name);
+ }
+
+ private void ServiceClient_OnTunnelStatusEvent(object sender, TunnelStatusEvent e)
+ {
+ if (e == null) return; //just skip it for now...
+ logger.Debug($"==== TunnelStatusEvent: ");
+ Application.Current.Properties.Remove("CurrentTunnelStatus");
+ Application.Current.Properties.Add("CurrentTunnelStatus", e.Status);
+ e.Status.Dump(Console.Out);
+ this.Dispatcher.Invoke(() =>
+ {
+ /*if (e.ApiVersion != DataClient.EXPECTED_API_VERSION) {
SetCantDisplay("Version mismatch!", "The version of the Service is not compatible", Visibility.Visible);
return;
}*/
- this.MainMenu.LogLevel = e.Status.LogLevel;
- Ziti.Desktop.Edge.Utils.UIUtils.SetLogLevel(e.Status.LogLevel);
-
- InitializeTimer((int)e.Status.Duration);
- LoadStatusFromService(e.Status);
- LoadIdentities(true);
- IdentityDetails deets = ((MainWindow)Application.Current.MainWindow).IdentityMenu;
- if (deets.IsVisible) {
- deets.UpdateView();
- }
- });
- }
-
- private void ServiceClient_OnLogLevelEvent(object sender, LogLevelEvent e) {
- if (e.LogLevel != null) {
- SetLogLevel_monitor(e.LogLevel);
- this.Dispatcher.Invoke(() => {
- this.MainMenu.LogLevel = e.LogLevel;
- Ziti.Desktop.Edge.Utils.UIUtils.SetLogLevel(e.LogLevel);
- });
- }
- }
-
- async private void SetLogLevel_monitor(string loglevel) {
- await monitorClient.SetLogLevelAsync(loglevel);
- }
-
- private void IdentityForgotten(ZitiIdentity forgotten) {
- ZitiIdentity idToRemove = null;
- foreach (var id in identities) {
- if (id.Identifier == forgotten.Identifier) {
- idToRemove = id;
- break;
- }
- }
- identities.Remove(idToRemove);
- LoadIdentities(false);
- }
-
- private void AttachmentChanged(bool attached) {
- _isAttached = attached;
- if (!_isAttached) {
- SetLocation();
- }
- Placement();
- MainMenu.Visibility = Visibility.Collapsed;
- }
-
- private void LoadStatusFromService(TunnelStatus status) {
- //clear any identities
- this.identities.Clear();
-
- if (status != null) {
- _isServiceInError = false;
- UpdateServiceView();
- NoServiceView.Visibility = Visibility.Collapsed;
- SetNotifyIcon("green");
- if (!Application.Current.Properties.Contains("ip")) {
- Application.Current.Properties.Add("ip", status?.IpInfo?.Ip);
- } else {
- Application.Current.Properties["ip"] = status?.IpInfo?.Ip;
- }
- if (!Application.Current.Properties.Contains("subnet")) {
- Application.Current.Properties.Add("subnet", status?.IpInfo?.Subnet);
- } else {
- Application.Current.Properties["subnet"] = status?.IpInfo?.Subnet;
- }
- if (!Application.Current.Properties.Contains("mtu")) {
- Application.Current.Properties.Add("mtu", status?.IpInfo?.MTU);
- } else {
- Application.Current.Properties["mtu"] = status?.IpInfo?.MTU;
- }
- if (!Application.Current.Properties.Contains("dns")) {
- Application.Current.Properties.Add("dns", status?.IpInfo?.DNS);
- } else {
- Application.Current.Properties["dns"] = status?.IpInfo?.DNS;
- }
- if (!Application.Current.Properties.Contains("dnsenabled")) {
- Application.Current.Properties.Add("dnsenabled", status?.AddDns);
- } else {
- Application.Current.Properties["dnsenabled"] = status?.AddDns;
- }
-
- string key = "ApiPageSize";
- if (!Application.Current.Properties.Contains(key)) {
- Application.Current.Properties.Add(key, status?.ApiPageSize);
- } else {
- Application.Current.Properties[key] = status?.ApiPageSize;
- }
-
- foreach (var id in status.Identities) {
- updateViewWithIdentity(id);
- }
- LoadIdentities(true);
- } else {
- ShowServiceNotStarted();
- }
- }
-
- private void updateViewWithIdentity(Identity id) {
- var zid = ZitiIdentity.FromClient(id);
- foreach (var i in identities) {
- if (i.Identifier == zid.Identifier) {
- identities.Remove(i);
- break;
- }
- }
- identities.Add(zid);
- }
-
- private bool IsTimingOut() {
- if (identities != null) {
- for (int i = 0; i < identities.Count; i++) {
- if (identities[i].IsTimingOut) return true;
- }
- }
- return false;
- }
-
- private bool IsTimedOut() {
- if (identities != null) {
- return identities.Any(i => i.IsTimedOut);
- }
- return false;
- }
-
- private void SetNotifyIcon(string iconPrefix) {
- if (iconPrefix != "") CurrentIcon = iconPrefix;
- string icon = "pack://application:,,/Assets/Images/ziti-" + CurrentIcon;
- if (state.UpdateAvailable) {
- icon += "-update";
- } else {
- if (IsTimedOut()) {
- icon += "-mfa";
- } else {
- if (IsTimingOut()) {
- icon += "-timer";
- }
- }
- }
- icon += ".ico";
- var iconUri = new Uri(icon);
- Stream iconStream = Application.GetResourceStream(iconUri).Stream;
- notifyIcon.Icon = new Icon(iconStream);
-
- Application.Current.MainWindow.Icon = System.Windows.Media.Imaging.BitmapFrame.Create(iconUri);
- }
-
- private void LoadIdentities(Boolean repaint) {
- this.Dispatcher.Invoke(() => {
- for (int i = 0; i < IdList.Children.Count; i++) {
- IdentityItem item = (IdentityItem)IdList.Children[i];
- item.StopTimers();
- }
- IdList.Children.Clear();
- IdList.Height = 0;
- var desktopWorkingArea = SystemParameters.WorkArea;
- if (_maxHeight > (desktopWorkingArea.Height - 10)) _maxHeight = desktopWorkingArea.Height - 10;
- if (_maxHeight < 100) _maxHeight = 100;
- IdList.MaxHeight = _maxHeight - 520;
- ZitiIdentity[] ids = identities.OrderBy(i => (i.Name != null) ? i.Name.ToLower() : i.Name).ToArray();
- MainMenu.SetupIdList(ids);
- if (ids.Length > 0 && serviceClient.Connected) {
- double height = defaultHeight + (ids.Length * 60);
- if (height > _maxHeight) height = _maxHeight;
- this.Height = height;
- IdentityMenu.SetHeight(this.Height - 160);
- MainMenu.IdentitiesButton.Visibility = Visibility.Visible;
- foreach (var id in ids) {
- IdentityItem idItem = new IdentityItem();
-
- idItem.ToggleStatus.IsEnabled = id.IsEnabled;
- if (id.IsEnabled) idItem.ToggleStatus.Content = "ENABLED";
- else idItem.ToggleStatus.Content = "DISABLED";
-
- idItem.Authenticate += IdItem_Authenticate;
- idItem.OnStatusChanged += Id_OnStatusChanged;
- idItem.Identity = id;
- idItem.IdentityChanged += IdItem_IdentityChanged;
-
- if (repaint) idItem.RefreshUI();
-
- IdList.Children.Add(idItem);
-
- if (IdentityMenu.Visibility == Visibility.Visible) {
- if (id.Identifier == IdentityMenu.Identity.Identifier) IdentityMenu.Identity = id;
- }
- }
- DoubleAnimation animation = new DoubleAnimation((double)(ids.Length * 64), TimeSpan.FromSeconds(.2));
- IdList.BeginAnimation(FrameworkElement.HeightProperty, animation);
- IdListScroller.Visibility = Visibility.Visible;
- } else {
- this.Height = defaultHeight;
- MainMenu.IdentitiesButton.Visibility = Visibility.Collapsed;
- IdListScroller.Visibility = Visibility.Visible;
-
- }
- AddIdButton.Visibility = Visibility.Visible;
- AddIdAreaButton.Visibility = Visibility.Visible;
-
- Placement();
- SetNotifyIcon("");
- });
- }
-
- private void IdItem_IdentityChanged(ZitiIdentity identity) {
- for (int i = 0; i < identities.Count; i++) {
- if (identities[i].Identifier == identity.Identifier) {
- identities[i] = identity;
- break;
- }
- }
- SetNotifyIcon("");
- }
-
- private void IdItem_Authenticate(ZitiIdentity identity) {
- ShowAuthenticate(identity);
- }
-
- private void Id_OnStatusChanged(bool attached) {
- for (int i = 0; i < IdList.Children.Count; i++) {
- IdentityItem item = IdList.Children[i] as IdentityItem;
- if (item.ToggleSwitch.Enabled) break;
- }
- }
-
- private void TunnelConnected(bool isConnected) {
- this.Dispatcher.Invoke(() => {
- if (isConnected) {
- ConnectButton.Visibility = Visibility.Collapsed;
- DisconnectButton.Visibility = Visibility.Visible;
- MainMenu.Connected();
- HideLoad();
- SetNotifyIcon("green");
- } else {
- ConnectButton.Visibility = Visibility.Visible;
- DisconnectButton.Visibility = Visibility.Collapsed;
- IdentityMenu.Visibility = Visibility.Collapsed;
- MainMenu.Visibility = Visibility.Collapsed;
- HideBlurb();
- MainMenu.Disconnected();
- DownloadSpeed.Content = "0.0";
- UploadSpeed.Content = "0.0";
- }
- });
- }
-
- private void SetLocation() {
- var desktopWorkingArea = SystemParameters.WorkArea;
-
- var height = MainView.ActualHeight;
- IdentityMenu.MainHeight = MainView.ActualHeight;
- MainMenu.MainHeight = MainView.ActualHeight;
-
- Rectangle trayRectangle = WinAPI.GetTrayRectangle();
- if (trayRectangle.Top < 20) {
- this.Position = "Top";
- this.Top = desktopWorkingArea.Top + _top;
- this.Left = desktopWorkingArea.Right - this.Width - _right;
- Arrow.SetValue(Canvas.TopProperty, (double)0);
- Arrow.SetValue(Canvas.LeftProperty, (double)185);
- MainMenu.Arrow.SetValue(Canvas.TopProperty, (double)0);
- MainMenu.Arrow.SetValue(Canvas.LeftProperty, (double)185);
- IdentityMenu.Arrow.SetValue(Canvas.TopProperty, (double)0);
- IdentityMenu.Arrow.SetValue(Canvas.LeftProperty, (double)185);
- } else if (trayRectangle.Left < 20) {
- this.Position = "Left";
- this.Left = _left;
- this.Top = desktopWorkingArea.Bottom - this.ActualHeight - 75;
- Arrow.SetValue(Canvas.TopProperty, height - 200);
- Arrow.SetValue(Canvas.LeftProperty, (double)0);
- MainMenu.Arrow.SetValue(Canvas.TopProperty, height - 200);
- MainMenu.Arrow.SetValue(Canvas.LeftProperty, (double)0);
- IdentityMenu.Arrow.SetValue(Canvas.TopProperty, height - 200);
- IdentityMenu.Arrow.SetValue(Canvas.LeftProperty, (double)0);
- } else if (desktopWorkingArea.Right == (double)trayRectangle.Left) {
- this.Position = "Right";
- this.Left = desktopWorkingArea.Right - this.Width - 20;
- this.Top = desktopWorkingArea.Bottom - height - 75;
- Arrow.SetValue(Canvas.TopProperty, height - 100);
- Arrow.SetValue(Canvas.LeftProperty, this.Width - 30);
- MainMenu.Arrow.SetValue(Canvas.TopProperty, height - 100);
- MainMenu.Arrow.SetValue(Canvas.LeftProperty, this.Width - 30);
- IdentityMenu.Arrow.SetValue(Canvas.TopProperty, height - 100);
- IdentityMenu.Arrow.SetValue(Canvas.LeftProperty, this.Width - 30);
- } else {
- this.Position = "Bottom";
- this.Left = desktopWorkingArea.Right - this.Width - 75;
- this.Top = desktopWorkingArea.Bottom - height;
- Arrow.SetValue(Canvas.TopProperty, height - 35);
- Arrow.SetValue(Canvas.LeftProperty, (double)185);
- MainMenu.Arrow.SetValue(Canvas.TopProperty, height - 35);
- MainMenu.Arrow.SetValue(Canvas.LeftProperty, (double)185);
- IdentityMenu.Arrow.SetValue(Canvas.TopProperty, height - 35);
- IdentityMenu.Arrow.SetValue(Canvas.LeftProperty, (double)185);
- }
- }
- public void Placement() {
- if (_isAttached) {
- Arrow.Visibility = Visibility.Visible;
- IdentityMenu.Arrow.Visibility = Visibility.Visible;
- SetLocation();
- } else {
- IdentityMenu.Arrow.Visibility = Visibility.Collapsed;
- Arrow.Visibility = Visibility.Collapsed;
- }
- }
-
- private void OpenIdentity(ZitiIdentity identity) {
- IdentityMenu.Identity = identity;
- }
-
- private void ShowMenu(object sender, MouseButtonEventArgs e) {
- MainMenu.Visibility = Visibility.Visible;
- }
-
- async private void AddIdentity(object sender, MouseButtonEventArgs e) {
- UIModel.HideOnLostFocus = false;
- Microsoft.Win32.OpenFileDialog jwtDialog = new Microsoft.Win32.OpenFileDialog();
- UIModel.HideOnLostFocus = true;
- jwtDialog.DefaultExt = ".jwt";
- jwtDialog.Filter = "Ziti Identities (*.jwt)|*.jwt";
-
- if (jwtDialog.ShowDialog() == true) {
- ShowLoad("Adding Identity", "Please wait while the identity is added");
- string fileContent = File.ReadAllText(jwtDialog.FileName);
-
- try {
- Identity createdId = await serviceClient.AddIdentityAsync(System.IO.Path.GetFileName(jwtDialog.FileName), false, fileContent);
-
- if (createdId != null) {
- var zid = ZitiIdentity.FromClient(createdId);
- AddIdentity(zid);
- LoadIdentities(true);
- await serviceClient.IdentityOnOffAsync(createdId.Identifier, true);
- }/* else {
+ this.MainMenu.LogLevel = e.Status.LogLevel;
+ Ziti.Desktop.Edge.Utils.UIUtils.SetLogLevel(e.Status.LogLevel);
+
+ InitializeTimer((int)e.Status.Duration);
+ LoadStatusFromService(e.Status);
+ LoadIdentities(true);
+ IdentityDetails deets = ((MainWindow)Application.Current.MainWindow).IdentityMenu;
+ if (deets.IsVisible)
+ {
+ deets.UpdateView();
+ }
+ });
+ }
+
+ private void ServiceClient_OnLogLevelEvent(object sender, LogLevelEvent e)
+ {
+ if (e.LogLevel != null)
+ {
+ SetLogLevel_monitor(e.LogLevel);
+ this.Dispatcher.Invoke(() =>
+ {
+ this.MainMenu.LogLevel = e.LogLevel;
+ Ziti.Desktop.Edge.Utils.UIUtils.SetLogLevel(e.LogLevel);
+ });
+ }
+ }
+
+ async private void SetLogLevel_monitor(string loglevel)
+ {
+ await monitorClient.SetLogLevelAsync(loglevel);
+ }
+
+ private void IdentityForgotten(ZitiIdentity forgotten)
+ {
+ ZitiIdentity idToRemove = null;
+ foreach (var id in identities)
+ {
+ if (id.Identifier == forgotten.Identifier)
+ {
+ idToRemove = id;
+ break;
+ }
+ }
+ identities.Remove(idToRemove);
+ LoadIdentities(false);
+ }
+
+ private void AttachmentChanged(bool attached)
+ {
+ _isAttached = attached;
+ if (!_isAttached)
+ {
+ SetLocation();
+ }
+ Placement();
+ MainMenu.Visibility = Visibility.Collapsed;
+ }
+
+ private void LoadStatusFromService(TunnelStatus status)
+ {
+ //clear any identities
+ this.identities.Clear();
+
+ if (status != null)
+ {
+ _isServiceInError = false;
+ UpdateServiceView();
+ NoServiceView.Visibility = Visibility.Collapsed;
+ SetNotifyIcon("green");
+ if (!Application.Current.Properties.Contains("ip"))
+ {
+ Application.Current.Properties.Add("ip", status?.IpInfo?.Ip);
+ }
+ else
+ {
+ Application.Current.Properties["ip"] = status?.IpInfo?.Ip;
+ }
+ if (!Application.Current.Properties.Contains("subnet"))
+ {
+ Application.Current.Properties.Add("subnet", status?.IpInfo?.Subnet);
+ }
+ else
+ {
+ Application.Current.Properties["subnet"] = status?.IpInfo?.Subnet;
+ }
+ if (!Application.Current.Properties.Contains("mtu"))
+ {
+ Application.Current.Properties.Add("mtu", status?.IpInfo?.MTU);
+ }
+ else
+ {
+ Application.Current.Properties["mtu"] = status?.IpInfo?.MTU;
+ }
+ if (!Application.Current.Properties.Contains("dns"))
+ {
+ Application.Current.Properties.Add("dns", status?.IpInfo?.DNS);
+ }
+ else
+ {
+ Application.Current.Properties["dns"] = status?.IpInfo?.DNS;
+ }
+ if (!Application.Current.Properties.Contains("dnsenabled"))
+ {
+ Application.Current.Properties.Add("dnsenabled", status?.AddDns);
+ }
+ else
+ {
+ Application.Current.Properties["dnsenabled"] = status?.AddDns;
+ }
+
+ string key = "ApiPageSize";
+ if (!Application.Current.Properties.Contains(key))
+ {
+ Application.Current.Properties.Add(key, status?.ApiPageSize);
+ }
+ else
+ {
+ Application.Current.Properties[key] = status?.ApiPageSize;
+ }
+
+ foreach (var id in status.Identities)
+ {
+ updateViewWithIdentity(id);
+ }
+ LoadIdentities(true);
+ }
+ else
+ {
+ ShowServiceNotStarted();
+ }
+ }
+
+ private void updateViewWithIdentity(Identity id)
+ {
+ var zid = ZitiIdentity.FromClient(id);
+ foreach (var i in identities)
+ {
+ if (i.Identifier == zid.Identifier)
+ {
+ identities.Remove(i);
+ break;
+ }
+ }
+ identities.Add(zid);
+ }
+
+ private bool IsTimingOut()
+ {
+ if (identities != null)
+ {
+ for (int i = 0; i < identities.Count; i++)
+ {
+ if (identities[i].IsTimingOut) return true;
+ }
+ }
+ return false;
+ }
+
+ private bool IsTimedOut()
+ {
+ if (identities != null)
+ {
+ return identities.Any(i => i.IsTimedOut);
+ }
+ return false;
+ }
+
+ private void SetNotifyIcon(string iconPrefix)
+ {
+ if (iconPrefix != "") CurrentIcon = iconPrefix;
+ string icon = "pack://application:,,/Assets/Images/ziti-" + CurrentIcon;
+ if (state.UpdateAvailable)
+ {
+ icon += "-update";
+ }
+ else
+ {
+ if (IsTimedOut())
+ {
+ icon += "-mfa";
+ }
+ else
+ {
+ if (IsTimingOut())
+ {
+ icon += "-timer";
+ }
+ }
+ }
+ icon += ".ico";
+ var iconUri = new Uri(icon);
+ Stream iconStream = Application.GetResourceStream(iconUri).Stream;
+ notifyIcon.Icon = new Icon(iconStream);
+
+ Application.Current.MainWindow.Icon = System.Windows.Media.Imaging.BitmapFrame.Create(iconUri);
+ }
+
+ private void LoadIdentities(Boolean repaint)
+ {
+ this.Dispatcher.Invoke(() =>
+ {
+ for (int i = 0; i < IdList.Children.Count; i++)
+ {
+ IdentityItem item = (IdentityItem)IdList.Children[i];
+ item.StopTimers();
+ }
+ IdList.Children.Clear();
+ IdList.Height = 0;
+ var desktopWorkingArea = SystemParameters.WorkArea;
+ if (_maxHeight > (desktopWorkingArea.Height - 10)) _maxHeight = desktopWorkingArea.Height - 10;
+ if (_maxHeight < 100) _maxHeight = 100;
+ IdList.MaxHeight = _maxHeight - 520;
+ ZitiIdentity[] ids = identities.OrderBy(i => (i.Name != null) ? i.Name.ToLower() : i.Name).ToArray();
+ MainMenu.SetupIdList(ids);
+ if (ids.Length > 0 && serviceClient.Connected)
+ {
+ double height = defaultHeight + (ids.Length * 60);
+ if (height > _maxHeight) height = _maxHeight;
+ this.Height = height;
+ IdentityMenu.SetHeight(this.Height - 160);
+ MainMenu.IdentitiesButton.Visibility = Visibility.Visible;
+ foreach (var id in ids)
+ {
+ IdentityItem idItem = new IdentityItem();
+
+ idItem.ToggleStatus.IsEnabled = id.IsEnabled;
+ if (id.IsEnabled) idItem.ToggleStatus.Content = "ENABLED";
+ else idItem.ToggleStatus.Content = "DISABLED";
+
+ idItem.Authenticate += IdItem_Authenticate;
+ idItem.OnStatusChanged += Id_OnStatusChanged;
+ idItem.Identity = id;
+ idItem.IdentityChanged += IdItem_IdentityChanged;
+
+ if (repaint) idItem.RefreshUI();
+
+ IdList.Children.Add(idItem);
+
+ if (IdentityMenu.Visibility == Visibility.Visible)
+ {
+ if (id.Identifier == IdentityMenu.Identity.Identifier) IdentityMenu.Identity = id;
+ }
+ }
+ DoubleAnimation animation = new DoubleAnimation((double)(ids.Length * 64), TimeSpan.FromSeconds(.2));
+ IdList.BeginAnimation(FrameworkElement.HeightProperty, animation);
+ IdListScroller.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ this.Height = defaultHeight;
+ MainMenu.IdentitiesButton.Visibility = Visibility.Collapsed;
+ IdListScroller.Visibility = Visibility.Visible;
+
+ }
+ AddIdButton.Visibility = Visibility.Visible;
+ AddIdAreaButton.Visibility = Visibility.Visible;
+
+ Placement();
+ SetNotifyIcon("");
+ });
+ }
+
+ private void IdItem_IdentityChanged(ZitiIdentity identity)
+ {
+ for (int i = 0; i < identities.Count; i++)
+ {
+ if (identities[i].Identifier == identity.Identifier)
+ {
+ identities[i] = identity;
+ break;
+ }
+ }
+ SetNotifyIcon("");
+ }
+
+ private void IdItem_Authenticate(ZitiIdentity identity)
+ {
+ ShowAuthenticate(identity);
+ }
+
+ private void Id_OnStatusChanged(bool attached)
+ {
+ for (int i = 0; i < IdList.Children.Count; i++)
+ {
+ IdentityItem item = IdList.Children[i] as IdentityItem;
+ if (item.ToggleSwitch.Enabled) break;
+ }
+ }
+
+ private void TunnelConnected(bool isConnected)
+ {
+ this.Dispatcher.Invoke(() =>
+ {
+ if (isConnected)
+ {
+ ConnectButton.Visibility = Visibility.Collapsed;
+ DisconnectButton.Visibility = Visibility.Visible;
+ MainMenu.Connected();
+ HideLoad();
+ SetNotifyIcon("green");
+ }
+ else
+ {
+ ConnectButton.Visibility = Visibility.Visible;
+ DisconnectButton.Visibility = Visibility.Collapsed;
+ IdentityMenu.Visibility = Visibility.Collapsed;
+ MainMenu.Visibility = Visibility.Collapsed;
+ HideBlurb();
+ MainMenu.Disconnected();
+ DownloadSpeed.Content = "0.0";
+ UploadSpeed.Content = "0.0";
+ }
+ });
+ }
+
+ private void SetLocation()
+ {
+ var desktopWorkingArea = SystemParameters.WorkArea;
+
+ var height = MainView.ActualHeight;
+ IdentityMenu.MainHeight = MainView.ActualHeight;
+ MainMenu.MainHeight = MainView.ActualHeight;
+
+ Rectangle trayRectangle = WinAPI.GetTrayRectangle();
+ if (trayRectangle.Top < 20)
+ {
+ this.Position = "Top";
+ this.Top = desktopWorkingArea.Top + _top;
+ this.Left = desktopWorkingArea.Right - this.Width - _right;
+ Arrow.SetValue(Canvas.TopProperty, (double)0);
+ Arrow.SetValue(Canvas.LeftProperty, (double)185);
+ MainMenu.Arrow.SetValue(Canvas.TopProperty, (double)0);
+ MainMenu.Arrow.SetValue(Canvas.LeftProperty, (double)185);
+ IdentityMenu.Arrow.SetValue(Canvas.TopProperty, (double)0);
+ IdentityMenu.Arrow.SetValue(Canvas.LeftProperty, (double)185);
+ }
+ else if (trayRectangle.Left < 20)
+ {
+ this.Position = "Left";
+ this.Left = _left;
+ this.Top = desktopWorkingArea.Bottom - this.ActualHeight - 75;
+ Arrow.SetValue(Canvas.TopProperty, height - 200);
+ Arrow.SetValue(Canvas.LeftProperty, (double)0);
+ MainMenu.Arrow.SetValue(Canvas.TopProperty, height - 200);
+ MainMenu.Arrow.SetValue(Canvas.LeftProperty, (double)0);
+ IdentityMenu.Arrow.SetValue(Canvas.TopProperty, height - 200);
+ IdentityMenu.Arrow.SetValue(Canvas.LeftProperty, (double)0);
+ }
+ else if (desktopWorkingArea.Right == (double)trayRectangle.Left)
+ {
+ this.Position = "Right";
+ this.Left = desktopWorkingArea.Right - this.Width - 20;
+ this.Top = desktopWorkingArea.Bottom - height - 75;
+ Arrow.SetValue(Canvas.TopProperty, height - 100);
+ Arrow.SetValue(Canvas.LeftProperty, this.Width - 30);
+ MainMenu.Arrow.SetValue(Canvas.TopProperty, height - 100);
+ MainMenu.Arrow.SetValue(Canvas.LeftProperty, this.Width - 30);
+ IdentityMenu.Arrow.SetValue(Canvas.TopProperty, height - 100);
+ IdentityMenu.Arrow.SetValue(Canvas.LeftProperty, this.Width - 30);
+ }
+ else
+ {
+ this.Position = "Bottom";
+ this.Left = desktopWorkingArea.Right - this.Width - 75;
+ this.Top = desktopWorkingArea.Bottom - height;
+ Arrow.SetValue(Canvas.TopProperty, height - 35);
+ Arrow.SetValue(Canvas.LeftProperty, (double)185);
+ MainMenu.Arrow.SetValue(Canvas.TopProperty, height - 35);
+ MainMenu.Arrow.SetValue(Canvas.LeftProperty, (double)185);
+ IdentityMenu.Arrow.SetValue(Canvas.TopProperty, height - 35);
+ IdentityMenu.Arrow.SetValue(Canvas.LeftProperty, (double)185);
+ }
+ }
+ public void Placement()
+ {
+ if (_isAttached)
+ {
+ Arrow.Visibility = Visibility.Visible;
+ IdentityMenu.Arrow.Visibility = Visibility.Visible;
+ SetLocation();
+ }
+ else
+ {
+ IdentityMenu.Arrow.Visibility = Visibility.Collapsed;
+ Arrow.Visibility = Visibility.Collapsed;
+ }
+ }
+
+ private void OpenIdentity(ZitiIdentity identity)
+ {
+ IdentityMenu.Identity = identity;
+ }
+
+ private void ShowMenu(object sender, MouseButtonEventArgs e)
+ {
+ MainMenu.Visibility = Visibility.Visible;
+ }
+
+ async private void AddIdentity(object sender, MouseButtonEventArgs e)
+ {
+ UIModel.HideOnLostFocus = false;
+ Microsoft.Win32.OpenFileDialog jwtDialog = new Microsoft.Win32.OpenFileDialog();
+ UIModel.HideOnLostFocus = true;
+ jwtDialog.DefaultExt = ".jwt";
+ jwtDialog.Filter = "Ziti Identities (*.jwt)|*.jwt";
+
+ if (jwtDialog.ShowDialog() == true)
+ {
+ ShowLoad("Adding Identity", "Please wait while the identity is added");
+ string fileContent = File.ReadAllText(jwtDialog.FileName);
+
+ try
+ {
+ Identity createdId = await serviceClient.AddIdentityAsync(System.IO.Path.GetFileName(jwtDialog.FileName), false, fileContent);
+
+ if (createdId != null)
+ {
+ var zid = ZitiIdentity.FromClient(createdId);
+ AddIdentity(zid);
+ LoadIdentities(true);
+ await serviceClient.IdentityOnOffAsync(createdId.Identifier, true);
+ }/* else {
ShowError("Identity Error", "Identity Id was null, please try again");
}*/
- } catch (ServiceException se) {
- ShowError(se.Message, se.AdditionalInfo);
- } catch (Exception ex) {
- ShowError("Unexpected Error", "Code 2:" + ex.Message);
- }
- HideLoad();
- }
- }
-
- private void OnTimedEvent(object sender, EventArgs e) {
- TimeSpan span = (DateTime.Now - _startDate);
- int hours = span.Hours;
- int minutes = span.Minutes;
- int seconds = span.Seconds;
- var hoursString = (hours > 9) ? hours.ToString() : "0" + hours;
- var minutesString = (minutes > 9) ? minutes.ToString() : "0" + minutes;
- var secondsString = (seconds > 9) ? seconds.ToString() : "0" + seconds;
- ConnectedTime.Content = hoursString + ":" + minutesString + ":" + secondsString;
- }
-
- private void InitializeTimer(int millisAgoStarted) {
- _startDate = DateTime.Now.Subtract(new TimeSpan(0, 0, 0, 0, millisAgoStarted));
- _tunnelUptimeTimer = new System.Windows.Forms.Timer();
- _tunnelUptimeTimer.Interval = 100;
- _tunnelUptimeTimer.Tick += OnTimedEvent;
- _tunnelUptimeTimer.Enabled = true;
- _tunnelUptimeTimer.Start();
- }
-
- async private Task DoConnectAsync() {
- try {
- SetNotifyIcon("green");
- TunnelConnected(true);
-
- for (int i = 0; i < identities.Count; i++) {
- await serviceClient.IdentityOnOffAsync(identities[i].Identifier, true);
- }
- for (int i = 0; i < IdList.Children.Count; i++) {
- IdentityItem item = IdList.Children[i] as IdentityItem;
- item._identity.IsEnabled = true;
- item.RefreshUI();
- }
- } catch (ServiceException se) {
- ShowError("Error Occurred", se.Message + " " + se.AdditionalInfo);
- } catch (Exception ex) {
- ShowError("Unexpected Error", "Code 3:" + ex.Message);
- }
- }
-
- async private void Disconnect(object sender, RoutedEventArgs e) {
- try {
- ShowLoad("Disabling Service", "Please wait for the service to stop.");
- var r = await monitorClient.StopServiceAsync();
- if (r.Code != 0) {
- logger.Warn("ERROR: Error:{0}, Message:{1}", r.Error, r.Message);
- } else {
- logger.Info("Service stopped!");
- SetNotifyIcon("white");
- }
- } catch (MonitorServiceException me) {
- logger.Warn("the monitor service appears offline. {0}", me);
- ShowError("Error Disabling Service", "The monitor service is offline");
- } catch (Exception ex) {
- logger.Error(ex, "unexpected error: {0}", ex.Message);
- ShowError("Error Disabling Service", "An error occurred while trying to disable the data service. Is the monitor service running?");
- }
- HideLoad();
- }
-
- internal void ShowLoad(string title, string msg) {
- this.Dispatcher.Invoke(() => {
- LoadingDetails.Text = msg;
- LoadingTitle.Content = title;
- LoadProgress.IsIndeterminate = true;
- LoadingScreen.Visibility = Visibility.Visible;
- UpdateLayout();
- });
- }
-
- internal void HideLoad() {
- this.Dispatcher.Invoke(() => {
- LoadingScreen.Visibility = Visibility.Collapsed;
- LoadProgress.IsIndeterminate = false;
- });
- }
-
- private void FormFadeOut_Completed(object sender, EventArgs e) {
- closeCompleted = true;
- }
- private bool closeCompleted = false;
- private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
- if (!closeCompleted) {
- FormFadeOut.Begin();
- e.Cancel = true;
- }
- }
-
- public void ShowError(string title, string message) {
- this.Dispatcher.Invoke(() => {
- ErrorTitle.Content = title;
- ErrorDetails.Text = message;
- ErrorView.Visibility = Visibility.Visible;
- });
- }
-
- private void CloseError(object sender, RoutedEventArgs e) {
- this.Dispatcher.Invoke(() => {
- ErrorView.Visibility = Visibility.Collapsed;
- NoServiceView.Visibility = Visibility.Collapsed;
- CloseErrorButton.IsEnabled = true;
- });
- }
-
- private void CloseApp(object sender, RoutedEventArgs e) {
- Application.Current.Shutdown();
- }
-
- private void MainUI_Deactivated(object sender, EventArgs e) {
- if (this._isAttached) {
+ }
+ catch (ServiceException se)
+ {
+ ShowError(se.Message, se.AdditionalInfo);
+ }
+ catch (Exception ex)
+ {
+ ShowError("Unexpected Error", "Code 2:" + ex.Message);
+ }
+ HideLoad();
+ }
+ }
+
+ private void OnTimedEvent(object sender, EventArgs e)
+ {
+ TimeSpan span = (DateTime.Now - _startDate);
+ int hours = span.Hours;
+ int minutes = span.Minutes;
+ int seconds = span.Seconds;
+ var hoursString = (hours > 9) ? hours.ToString() : "0" + hours;
+ var minutesString = (minutes > 9) ? minutes.ToString() : "0" + minutes;
+ var secondsString = (seconds > 9) ? seconds.ToString() : "0" + seconds;
+ ConnectedTime.Content = hoursString + ":" + minutesString + ":" + secondsString;
+ }
+
+ private void InitializeTimer(int millisAgoStarted)
+ {
+ _startDate = DateTime.Now.Subtract(new TimeSpan(0, 0, 0, 0, millisAgoStarted));
+ _tunnelUptimeTimer = new System.Windows.Forms.Timer();
+ _tunnelUptimeTimer.Interval = 100;
+ _tunnelUptimeTimer.Tick += OnTimedEvent;
+ _tunnelUptimeTimer.Enabled = true;
+ _tunnelUptimeTimer.Start();
+ }
+
+ async private Task DoConnectAsync()
+ {
+ try
+ {
+ SetNotifyIcon("green");
+ TunnelConnected(true);
+
+ for (int i = 0; i < identities.Count; i++)
+ {
+ await serviceClient.IdentityOnOffAsync(identities[i].Identifier, true);
+ }
+ for (int i = 0; i < IdList.Children.Count; i++)
+ {
+ IdentityItem item = IdList.Children[i] as IdentityItem;
+ item._identity.IsEnabled = true;
+ item.RefreshUI();
+ }
+ }
+ catch (ServiceException se)
+ {
+ ShowError("Error Occurred", se.Message + " " + se.AdditionalInfo);
+ }
+ catch (Exception ex)
+ {
+ ShowError("Unexpected Error", "Code 3:" + ex.Message);
+ }
+ }
+
+ async private void Disconnect(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ ShowLoad("Disabling Service", "Please wait for the service to stop.");
+ var r = await monitorClient.StopServiceAsync();
+ if (r.Code != 0)
+ {
+ logger.Warn("ERROR: Error:{0}, Message:{1}", r.Error, r.Message);
+ }
+ else
+ {
+ logger.Info("Service stopped!");
+ SetNotifyIcon("white");
+ }
+ }
+ catch (MonitorServiceException me)
+ {
+ logger.Warn("the monitor service appears offline. {0}", me);
+ ShowError("Error Disabling Service", "The monitor service is offline");
+ }
+ catch (Exception ex)
+ {
+ logger.Error(ex, "unexpected error: {0}", ex.Message);
+ ShowError("Error Disabling Service", "An error occurred while trying to disable the data service. Is the monitor service running?");
+ }
+ HideLoad();
+ }
+
+ internal void ShowLoad(string title, string msg)
+ {
+ this.Dispatcher.Invoke(() =>
+ {
+ LoadingDetails.Text = msg;
+ LoadingTitle.Content = title;
+ LoadProgress.IsIndeterminate = true;
+ LoadingScreen.Visibility = Visibility.Visible;
+ UpdateLayout();
+ });
+ }
+
+ internal void HideLoad()
+ {
+ this.Dispatcher.Invoke(() =>
+ {
+ LoadingScreen.Visibility = Visibility.Collapsed;
+ LoadProgress.IsIndeterminate = false;
+ });
+ }
+
+ private void FormFadeOut_Completed(object sender, EventArgs e)
+ {
+ closeCompleted = true;
+ }
+ private bool closeCompleted = false;
+ private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
+ {
+ if (!closeCompleted)
+ {
+ FormFadeOut.Begin();
+ e.Cancel = true;
+ }
+ }
+
+ public void ShowError(string title, string message)
+ {
+ this.Dispatcher.Invoke(() =>
+ {
+ ErrorTitle.Content = title;
+ ErrorDetails.Text = message;
+ ErrorView.Visibility = Visibility.Visible;
+ });
+ }
+
+ private void CloseError(object sender, RoutedEventArgs e)
+ {
+ this.Dispatcher.Invoke(() =>
+ {
+ ErrorView.Visibility = Visibility.Collapsed;
+ NoServiceView.Visibility = Visibility.Collapsed;
+ CloseErrorButton.IsEnabled = true;
+ });
+ }
+
+ private void CloseApp(object sender, RoutedEventArgs e)
+ {
+ Application.Current.Shutdown();
+ }
+
+ private void MainUI_Deactivated(object sender, EventArgs e)
+ {
+ if (this._isAttached)
+ {
#if DEBUG
- logger.Debug("debug is enabled - windows pinned");
+ logger.Debug("debug is enabled - windows pinned");
#else
this.Visibility = Visibility.Collapsed;
#endif
- }
- }
-
- private void Label_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
- Placement();
- }
-
- int cur = 0;
- LogLevelEnum[] levels = new LogLevelEnum[] { LogLevelEnum.FATAL, LogLevelEnum.ERROR, LogLevelEnum.WARN, LogLevelEnum.INFO, LogLevelEnum.DEBUG, LogLevelEnum.TRACE, LogLevelEnum.VERBOSE };
- public LogLevelEnum NextLevel() {
- cur++;
- if (cur > 6) {
- cur = 0;
- }
- return levels[cur];
- }
-
- private void IdList_LayoutUpdated(object sender, EventArgs e) {
- Placement();
- }
-
- async private void CollectLogFileClick(object sender, RoutedEventArgs e) {
- await CollectLogFiles();
- }
- async private Task CollectLogFiles() {
- MonitorServiceStatusEvent resp = await monitorClient.CaptureLogsAsync();
- if (resp != null) {
- logger.Info("response: {0}", resp.Message);
- } else {
- ShowError("Error Collecting Feedback", "An error occurred while trying to gather feedback. Is the monitor service running?");
- }
- }
-
- ///
- /// Show the blurb as a growler notification
- ///
- /// The message to show
- /// The url or action name to execute
- public async Task ShowBlurbAsync(string message, string url, string level = "error") {
- RedBlurb.Visibility = Visibility.Collapsed;
- InfoBlurb.Visibility = Visibility.Collapsed;
- if (level == "error") {
- RedBlurb.Visibility = Visibility.Visible;
- } else {
- InfoBlurb.Visibility = Visibility.Visible;
- }
- Blurb.Content = message;
- _blurbUrl = url;
- BlurbArea.Visibility = Visibility.Visible;
- BlurbArea.Opacity = 0;
- BlurbArea.Margin = new Thickness(0, 0, 0, 0);
- DoubleAnimation animation = new DoubleAnimation(1, TimeSpan.FromSeconds(.3));
- ThicknessAnimation animateThick = new ThicknessAnimation(new Thickness(15, 0, 15, 15), TimeSpan.FromSeconds(.3));
- BlurbArea.BeginAnimation(Grid.OpacityProperty, animation);
- BlurbArea.BeginAnimation(Grid.MarginProperty, animateThick);
- await Task.Delay(5000);
- HideBlurb();
- }
-
- ///
- /// Execute the hide operation wihout an action from the growler
- ///
- /// The object that was clicked
- /// The click event
- private void DoHideBlurb(object sender, MouseButtonEventArgs e) {
- HideBlurb();
- }
-
- ///
- /// Hide the blurb area
- ///
- private void HideBlurb() {
- DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3));
- ThicknessAnimation animateThick = new ThicknessAnimation(new Thickness(0, 0, 0, 0), TimeSpan.FromSeconds(.3));
- animation.Completed += HideComplete;
- BlurbArea.BeginAnimation(Grid.OpacityProperty, animation);
- BlurbArea.BeginAnimation(Grid.MarginProperty, animateThick);
- }
-
- ///
- /// Hide the blurb area after the animation fades out
- ///
- /// The animation object
- /// The completion event
- private void HideComplete(object sender, EventArgs e) {
- BlurbArea.Visibility = Visibility.Collapsed;
- }
-
- ///
- /// Execute a predefined action or url when the pop up is clicked
- ///
- /// The object that was clicked
- /// The click event
- private void BlurbAction(object sender, MouseButtonEventArgs e) {
- if (_blurbUrl.Length > 0) {
- // So this simply execute a url but you could do like if (_blurbUrl=="DoSomethingNifty") CallNifyFunction();
- if (_blurbUrl == this.RECOVER) {
- this.ShowMFA(IdentityMenu.Identity, 4);
- } else {
- Process.Start(new ProcessStartInfo(_blurbUrl) { UseShellExecute = true });
- }
- HideBlurb();
- } else {
- HideBlurb();
- }
- }
-
- private void ShowAuthenticate(ZitiIdentity identity) {
- MFAAuthenticate(identity);
- }
-
- private void ShowRecovery(ZitiIdentity identity) {
- ShowMFARecoveryCodes(identity);
- }
-
-
-
-
-
- private ICommand someCommand;
- public ICommand SomeCommand {
- get {
- return someCommand
- ?? (someCommand = new ActionCommand(() => {
- if (DebugForm.Visibility == Visibility.Hidden) {
- DebugForm.Visibility = Visibility.Visible;
- } else {
- DebugForm.Visibility = Visibility.Hidden;
- }
- }));
- }
- set {
- someCommand = value;
- }
- }
-
- private void DoLoading(bool isComplete) {
- if (isComplete) HideLoad();
- else ShowLoad("Loading", "Please Wait.");
- }
-
- private void Label_MouseDoubleClick_1(object sender, MouseButtonEventArgs e) {
- ShowToast("here's a toast all rightddd...");
- }
- }
-
- public class ActionCommand : ICommand {
- private readonly Action _action;
-
- public ActionCommand(Action action) {
- _action = action;
- }
-
- public void Execute(object parameter) {
- _action();
- }
-
- public bool CanExecute(object parameter) {
- return true;
- }
+ }
+ }
+
+ private void Label_MouseDoubleClick(object sender, MouseButtonEventArgs e)
+ {
+ Placement();
+ }
+
+ int cur = 0;
+ LogLevelEnum[] levels = new LogLevelEnum[] { LogLevelEnum.FATAL, LogLevelEnum.ERROR, LogLevelEnum.WARN, LogLevelEnum.INFO, LogLevelEnum.DEBUG, LogLevelEnum.TRACE, LogLevelEnum.VERBOSE };
+ public LogLevelEnum NextLevel()
+ {
+ cur++;
+ if (cur > 6)
+ {
+ cur = 0;
+ }
+ return levels[cur];
+ }
+
+ private void IdList_LayoutUpdated(object sender, EventArgs e)
+ {
+ Placement();
+ }
+
+ async private void CollectLogFileClick(object sender, RoutedEventArgs e)
+ {
+ await CollectLogFiles();
+ }
+ async private Task CollectLogFiles()
+ {
+ MonitorServiceStatusEvent resp = await monitorClient.CaptureLogsAsync();
+ if (resp != null)
+ {
+ logger.Info("response: {0}", resp.Message);
+ }
+ else
+ {
+ ShowError("Error Collecting Feedback", "An error occurred while trying to gather feedback. Is the monitor service running?");
+ }
+ }
+
+ ///
+ /// Show the blurb as a growler notification
+ ///
+ /// The message to show
+ /// The url or action name to execute
+ public async Task ShowBlurbAsync(string message, string url, string level = "error")
+ {
+ RedBlurb.Visibility = Visibility.Collapsed;
+ InfoBlurb.Visibility = Visibility.Collapsed;
+ if (level == "error")
+ {
+ RedBlurb.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ InfoBlurb.Visibility = Visibility.Visible;
+ }
+ Blurb.Content = message;
+ _blurbUrl = url;
+ BlurbArea.Visibility = Visibility.Visible;
+ BlurbArea.Opacity = 0;
+ BlurbArea.Margin = new Thickness(0, 0, 0, 0);
+ DoubleAnimation animation = new DoubleAnimation(1, TimeSpan.FromSeconds(.3));
+ ThicknessAnimation animateThick = new ThicknessAnimation(new Thickness(15, 0, 15, 15), TimeSpan.FromSeconds(.3));
+ BlurbArea.BeginAnimation(Grid.OpacityProperty, animation);
+ BlurbArea.BeginAnimation(Grid.MarginProperty, animateThick);
+ await Task.Delay(5000);
+ HideBlurb();
+ }
+
+ ///
+ /// Execute the hide operation wihout an action from the growler
+ ///
+ /// The object that was clicked
+ /// The click event
+ private void DoHideBlurb(object sender, MouseButtonEventArgs e)
+ {
+ HideBlurb();
+ }
+
+ ///
+ /// Hide the blurb area
+ ///
+ private void HideBlurb()
+ {
+ DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3));
+ ThicknessAnimation animateThick = new ThicknessAnimation(new Thickness(0, 0, 0, 0), TimeSpan.FromSeconds(.3));
+ animation.Completed += HideComplete;
+ BlurbArea.BeginAnimation(Grid.OpacityProperty, animation);
+ BlurbArea.BeginAnimation(Grid.MarginProperty, animateThick);
+ }
+
+ ///
+ /// Hide the blurb area after the animation fades out
+ ///
+ /// The animation object
+ /// The completion event
+ private void HideComplete(object sender, EventArgs e)
+ {
+ BlurbArea.Visibility = Visibility.Collapsed;
+ }
+
+ ///
+ /// Execute a predefined action or url when the pop up is clicked
+ ///
+ /// The object that was clicked
+ /// The click event
+ private void BlurbAction(object sender, MouseButtonEventArgs e)
+ {
+ if (_blurbUrl.Length > 0)
+ {
+ // So this simply execute a url but you could do like if (_blurbUrl=="DoSomethingNifty") CallNifyFunction();
+ if (_blurbUrl == this.RECOVER)
+ {
+ this.ShowMFA(IdentityMenu.Identity, 4);
+ }
+ else
+ {
+ Process.Start(new ProcessStartInfo(_blurbUrl) { UseShellExecute = true });
+ }
+ HideBlurb();
+ }
+ else
+ {
+ HideBlurb();
+ }
+ }
+
+ private void ShowAuthenticate(ZitiIdentity identity)
+ {
+ MFAAuthenticate(identity);
+ }
+
+ private void ShowRecovery(ZitiIdentity identity)
+ {
+ ShowMFARecoveryCodes(identity);
+ }
+
+
+
+
+
+ private ICommand someCommand;
+ public ICommand SomeCommand
+ {
+ get
+ {
+ return someCommand
+ ?? (someCommand = new ActionCommand(() =>
+ {
+ if (DebugForm.Visibility == Visibility.Hidden)
+ {
+ DebugForm.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ DebugForm.Visibility = Visibility.Hidden;
+ }
+ }));
+ }
+ set
+ {
+ someCommand = value;
+ }
+ }
+
+ private void DoLoading(bool isComplete)
+ {
+ if (isComplete) HideLoad();
+ else ShowLoad("Loading", "Please Wait.");
+ }
+
+ private void Label_MouseDoubleClick_1(object sender, MouseButtonEventArgs e)
+ {
+ ShowToast("here's a toast all rightddd...");
+ }
+ }
+
+ public class ActionCommand : ICommand
+ {
+ private readonly Action _action;
+
+ public ActionCommand(Action action)
+ {
+ _action = action;
+ }
+
+ public void Execute(object parameter)
+ {
+ _action();
+ }
+
+ public bool CanExecute(object parameter)
+ {
+ return true;
+ }
#pragma warning disable CS0067 //The event 'ActionCommand.CanExecuteChanged' is never used
- public event EventHandler CanExecuteChanged;
+ public event EventHandler CanExecuteChanged;
#pragma warning restore CS0067 //The event 'ActionCommand.CanExecuteChanged' is never used
- }
+ }
}
\ No newline at end of file
diff --git a/DesktopEdge/Models/FilterData.cs b/DesktopEdge/Models/FilterData.cs
index e86c46d09..301201dd9 100644
--- a/DesktopEdge/Models/FilterData.cs
+++ b/DesktopEdge/Models/FilterData.cs
@@ -1,38 +1,41 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
*/
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace ZitiDesktopEdge.Models {
- public class FilterData {
-
- public FilterData():this("", "", "asc") { }
-
- public FilterData(string searchFor, string sortBy, string sortHow) {
- SearchFor = searchFor;
- SortBy = sortBy;
- SortHow = sortHow;
- }
-
- public string SearchFor { get; set; }
- public string SortBy { get; set; }
- public string SortHow { get; set; }
- }
-}
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ZitiDesktopEdge.Models
+{
+ public class FilterData
+ {
+
+ public FilterData() : this("", "", "asc") { }
+
+ public FilterData(string searchFor, string sortBy, string sortHow)
+ {
+ SearchFor = searchFor;
+ SortBy = sortBy;
+ SortHow = sortHow;
+ }
+
+ public string SearchFor { get; set; }
+ public string SortBy { get; set; }
+ public string SortHow { get; set; }
+ }
+}
diff --git a/DesktopEdge/Models/MFA.cs b/DesktopEdge/Models/MFA.cs
index 4e8e0b6ce..4d8535116 100644
--- a/DesktopEdge/Models/MFA.cs
+++ b/DesktopEdge/Models/MFA.cs
@@ -1,29 +1,31 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
*/
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace ZitiDesktopEdge.Models {
- public class MFA {
- public string Url { get; set; }
- public string[] RecoveryCodes { get; set; }
- public bool IsAuthenticateda { get; set; }
- }
-}
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ZitiDesktopEdge.Models
+{
+ public class MFA
+ {
+ public string Url { get; set; }
+ public string[] RecoveryCodes { get; set; }
+ public bool IsAuthenticateda { get; set; }
+ }
+}
diff --git a/DesktopEdge/Models/MessageCount.cs b/DesktopEdge/Models/MessageCount.cs
index d5905f0c7..facc75191 100644
--- a/DesktopEdge/Models/MessageCount.cs
+++ b/DesktopEdge/Models/MessageCount.cs
@@ -1,32 +1,35 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
*/
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace ZitiDesktopEdge.Models {
- public class MessageCount {
-
- public int Total { get; set; }
- public string Message { get; set; }
- public override string ToString() {
- return Total + " " + Message;
- }
- }
-}
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ZitiDesktopEdge.Models
+{
+ public class MessageCount
+ {
+
+ public int Total { get; set; }
+ public string Message { get; set; }
+ public override string ToString()
+ {
+ return Total + " " + Message;
+ }
+ }
+}
diff --git a/DesktopEdge/Models/UIModel.cs b/DesktopEdge/Models/UIModel.cs
index 5f3a04b80..4ef590d84 100644
--- a/DesktopEdge/Models/UIModel.cs
+++ b/DesktopEdge/Models/UIModel.cs
@@ -1,22 +1,23 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
namespace ZitiDesktopEdge.Models
{
- static class UIModel {
- static public bool HideOnLostFocus { get; set; } = true;
- }
+ static class UIModel
+ {
+ static public bool HideOnLostFocus { get; set; } = true;
+ }
}
diff --git a/DesktopEdge/Models/ViewState.cs b/DesktopEdge/Models/ViewState.cs
index aef73e887..ed378ed1c 100644
--- a/DesktopEdge/Models/ViewState.cs
+++ b/DesktopEdge/Models/ViewState.cs
@@ -1,41 +1,49 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-using NLog;
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+using NLog;
using System;
-namespace Ziti.Desktop.Edge.Models {
- public class ZDEWViewState {
+namespace Ziti.Desktop.Edge.Models
+{
+ public class ZDEWViewState
+ {
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private bool automaticUpdatesDisabled = false;
private string updateUrl = "not set yet";
- public bool AutomaticUpdatesDisabled {
- get {
+ public bool AutomaticUpdatesDisabled
+ {
+ get
+ {
return automaticUpdatesDisabled;
}
- set {
+ set
+ {
automaticUpdatesDisabled = value;
}
}
- public string AutomaticUpdateURL {
- get {
+ public string AutomaticUpdateURL
+ {
+ get
+ {
return updateUrl;
}
- set {
+ set
+ {
updateUrl = value;
}
}
@@ -44,12 +52,15 @@ public string AutomaticUpdateURL {
public UpdateInfo PendingUpdate { get; set; } = new UpdateInfo();
}
- public class UpdateInfo {
+ public class UpdateInfo
+ {
public DateTime InstallTime { get; set; } = DateTime.MinValue;
public string Version { get; set; } = "0.0.0.0";
- public double TimeLeft {
- get {
+ public double TimeLeft
+ {
+ get
+ {
double timeLeft = (InstallTime - DateTime.Now).TotalSeconds;
return timeLeft;
}
diff --git a/DesktopEdge/Models/ZitiIdentity.cs b/DesktopEdge/Models/ZitiIdentity.cs
index dc8be6e99..b56c3ebd7 100644
--- a/DesktopEdge/Models/ZitiIdentity.cs
+++ b/DesktopEdge/Models/ZitiIdentity.cs
@@ -1,19 +1,19 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
using NLog;
using System;
using System.Collections.Generic;
@@ -22,146 +22,166 @@ limitations under the License.
using System.Threading;
using System.Threading.Tasks;
-namespace ZitiDesktopEdge.Models {
- public class ZitiIdentity {
- private static readonly Logger logger = LogManager.GetCurrentClassLogger();
- public List Services { get; set; }
- public string Name { get; set; }
- public string ControllerUrl { get; set; }
-
- public string ContollerVersion { get; set; }
- public bool IsEnabled { get; set; }
- public string EnrollmentStatus { get; set; }
- public string Status { get; set; }
- public bool IsMFAEnabled { get; set; }
-
- public void MFADebug(string where) {
- logger.Info($"{where}\n\tIdentifiter : {Identifier}\n\tIsMFAEnabled : {IsMFAEnabled}\n\tIsMFANeeded : {IsMFANeeded}");
- //logger.Info($"{where}\n\tIdentifiter : {Identifier}\n\tIsMFAEnabled : {IsMFAEnabled}\n\tIsMFANeeded : {IsMFANeeded}\n\tShowMFA\t : {ShowMFA}");
- }
-
- private bool mfaNeeded = false;
- public bool IsMFANeeded {
- get { return mfaNeeded; }
- set {
- mfaNeeded = value;
- if (!mfaNeeded) {
- IsTimingOut = false;
- IsTimedOut = false;
- WasFullNotified = false;
- WasNotified = false;
- }
- }
- }
- public int MinTimeout { get; set; }
- public int MaxTimeout { get; set; }
- public DateTime LastUpdatedTime { get; set; }
- public string TimeoutMessage { get; set; }
- public bool WasNotified { get; set; }
- public bool WasFullNotified { get; set; }
- public string Fingerprint { get; set; }
- public string Identifier { get; set; }
- private bool isTimedOut = false;
-
- public SemaphoreSlim Mutex { get; } = new SemaphoreSlim(1);
- public bool IsTimedOut {
- get { return isTimedOut; }
- set {
- isTimedOut = value;
- WasFullNotified = false;
- }
- }
- public string[] RecoveryCodes { get; set; }
- public bool IsTimingOut { get; set; }
- public bool IsConnected { get; set; }
-
-
- private bool svcFailingPostureCheck = false;
- public bool HasServiceFailingPostureCheck {
- get {
- return svcFailingPostureCheck;
- }
- set {
- logger.Info("Identity: {0} posture change. is a posture check failing: {1}", Name, !value);
- svcFailingPostureCheck = value;
- if (!value) {
- IsMFANeeded = true;
- }
- }
- }
-
- ///
- /// Default constructor to support named initialization
- ///
- public ZitiIdentity() {
- this.IsConnected = true;
- this.Services = new List();
- }
-
- public ZitiIdentity(string Name, string ControllerUrl, bool IsEnabled, List Services) {
- this.Name = Name;
- this.Services = Services;
- this.ControllerUrl = ControllerUrl;
- this.IsEnabled = IsEnabled;
- this.EnrollmentStatus = "Enrolled";
- this.Status = "Available";
- this.MaxTimeout = -1;
- this.MinTimeout = -1;
- this.LastUpdatedTime = DateTime.Now;
- this.TimeoutMessage = "";
- this.RecoveryCodes = new string[0];
- this.IsTimingOut = false;
- this.IsTimedOut = false;
- this.IsConnected = true;
- }
-
- public static ZitiIdentity FromClient(DataStructures.Identity id) {
- ZitiIdentity zid = new ZitiIdentity() {
- ControllerUrl = (id.Config == null) ? "" : id.Config.ztAPI,
- ContollerVersion = id.ControllerVersion,
- EnrollmentStatus = "status",
- Fingerprint = id.FingerPrint,
- Identifier = id.Identifier,
- IsEnabled = id.Active,
- Name = (string.IsNullOrEmpty(id.Name) ? id.FingerPrint : id.Name),
- Status = id.Status,
- RecoveryCodes = new string[0],
- IsMFAEnabled = id.MfaEnabled,
- IsMFANeeded = id.MfaNeeded,
- IsTimedOut = false,
- IsTimingOut = false,
- MinTimeout = id.MinTimeout,
- MaxTimeout = id.MaxTimeout,
- LastUpdatedTime = id.MfaLastUpdatedTime,
- TimeoutMessage = "",
- IsConnected = true
- };
-
+namespace ZitiDesktopEdge.Models
+{
+ public class ZitiIdentity
+ {
+ private static readonly Logger logger = LogManager.GetCurrentClassLogger();
+ public List Services { get; set; }
+ public string Name { get; set; }
+ public string ControllerUrl { get; set; }
+
+ public string ContollerVersion { get; set; }
+ public bool IsEnabled { get; set; }
+ public string EnrollmentStatus { get; set; }
+ public string Status { get; set; }
+ public bool IsMFAEnabled { get; set; }
+
+ public void MFADebug(string where)
+ {
+ logger.Info($"{where}\n\tIdentifiter : {Identifier}\n\tIsMFAEnabled : {IsMFAEnabled}\n\tIsMFANeeded : {IsMFANeeded}");
+ //logger.Info($"{where}\n\tIdentifiter : {Identifier}\n\tIsMFAEnabled : {IsMFAEnabled}\n\tIsMFANeeded : {IsMFANeeded}\n\tShowMFA\t : {ShowMFA}");
+ }
+
+ private bool mfaNeeded = false;
+ public bool IsMFANeeded
+ {
+ get { return mfaNeeded; }
+ set
+ {
+ mfaNeeded = value;
+ if (!mfaNeeded)
+ {
+ IsTimingOut = false;
+ IsTimedOut = false;
+ WasFullNotified = false;
+ WasNotified = false;
+ }
+ }
+ }
+ public int MinTimeout { get; set; }
+ public int MaxTimeout { get; set; }
+ public DateTime LastUpdatedTime { get; set; }
+ public string TimeoutMessage { get; set; }
+ public bool WasNotified { get; set; }
+ public bool WasFullNotified { get; set; }
+ public string Fingerprint { get; set; }
+ public string Identifier { get; set; }
+ private bool isTimedOut = false;
+
+ public SemaphoreSlim Mutex { get; } = new SemaphoreSlim(1);
+ public bool IsTimedOut
+ {
+ get { return isTimedOut; }
+ set
+ {
+ isTimedOut = value;
+ WasFullNotified = false;
+ }
+ }
+ public string[] RecoveryCodes { get; set; }
+ public bool IsTimingOut { get; set; }
+ public bool IsConnected { get; set; }
+
+
+ private bool svcFailingPostureCheck = false;
+ public bool HasServiceFailingPostureCheck
+ {
+ get
+ {
+ return svcFailingPostureCheck;
+ }
+ set
+ {
+ logger.Info("Identity: {0} posture change. is a posture check failing: {1}", Name, !value);
+ svcFailingPostureCheck = value;
+ if (!value)
+ {
+ IsMFANeeded = true;
+ }
+ }
+ }
+
+ ///
+ /// Default constructor to support named initialization
+ ///
+ public ZitiIdentity()
+ {
+ this.IsConnected = true;
+ this.Services = new List();
+ }
+
+ public ZitiIdentity(string Name, string ControllerUrl, bool IsEnabled, List Services)
+ {
+ this.Name = Name;
+ this.Services = Services;
+ this.ControllerUrl = ControllerUrl;
+ this.IsEnabled = IsEnabled;
+ this.EnrollmentStatus = "Enrolled";
+ this.Status = "Available";
+ this.MaxTimeout = -1;
+ this.MinTimeout = -1;
+ this.LastUpdatedTime = DateTime.Now;
+ this.TimeoutMessage = "";
+ this.RecoveryCodes = new string[0];
+ this.IsTimingOut = false;
+ this.IsTimedOut = false;
+ this.IsConnected = true;
+ }
+
+ public static ZitiIdentity FromClient(DataStructures.Identity id)
+ {
+ ZitiIdentity zid = new ZitiIdentity()
+ {
+ ControllerUrl = (id.Config == null) ? "" : id.Config.ztAPI,
+ ContollerVersion = id.ControllerVersion,
+ EnrollmentStatus = "status",
+ Fingerprint = id.FingerPrint,
+ Identifier = id.Identifier,
+ IsEnabled = id.Active,
+ Name = (string.IsNullOrEmpty(id.Name) ? id.FingerPrint : id.Name),
+ Status = id.Status,
+ RecoveryCodes = new string[0],
+ IsMFAEnabled = id.MfaEnabled,
+ IsMFANeeded = id.MfaNeeded,
+ IsTimedOut = false,
+ IsTimingOut = false,
+ MinTimeout = id.MinTimeout,
+ MaxTimeout = id.MaxTimeout,
+ LastUpdatedTime = id.MfaLastUpdatedTime,
+ TimeoutMessage = "",
+ IsConnected = true
+ };
+
#if DEBUG
- zid.MFADebug("002");
+ zid.MFADebug("002");
#endif
- if (id.Services != null) {
- foreach (var svc in id.Services) {
- if (svc != null) {
- var zsvc = new ZitiService(svc);
- zsvc.TimeUpdated = zid.LastUpdatedTime;
- zid.Services.Add(zsvc);
- }
- }
- zid.HasServiceFailingPostureCheck = zid.Services.Any(p => !p.HasFailingPostureCheck());
- }
- logger.Info("Identity: {0} updated To {1}", zid.Name, Newtonsoft.Json.JsonConvert.SerializeObject(id));
- return zid;
- }
-
- public void ShowMFAToast(string message) {
- logger.Info("Showing Notification from identity " + Name + " " + message + ".");
- new Microsoft.Toolkit.Uwp.Notifications.ToastContentBuilder()
- .AddText(Name + " Service Access Warning")
- .AddText(message)
- .AddArgument("identifier", Identifier)
- .SetBackgroundActivation()
- .Show();
- }
- }
+ if (id.Services != null)
+ {
+ foreach (var svc in id.Services)
+ {
+ if (svc != null)
+ {
+ var zsvc = new ZitiService(svc);
+ zsvc.TimeUpdated = zid.LastUpdatedTime;
+ zid.Services.Add(zsvc);
+ }
+ }
+ zid.HasServiceFailingPostureCheck = zid.Services.Any(p => !p.HasFailingPostureCheck());
+ }
+ logger.Info("Identity: {0} updated To {1}", zid.Name, Newtonsoft.Json.JsonConvert.SerializeObject(id));
+ return zid;
+ }
+
+ public void ShowMFAToast(string message)
+ {
+ logger.Info("Showing Notification from identity " + Name + " " + message + ".");
+ new Microsoft.Toolkit.Uwp.Notifications.ToastContentBuilder()
+ .AddText(Name + " Service Access Warning")
+ .AddText(message)
+ .AddArgument("identifier", Identifier)
+ .SetBackgroundActivation()
+ .Show();
+ }
+ }
}
diff --git a/DesktopEdge/Models/ZitiService.cs b/DesktopEdge/Models/ZitiService.cs
index 9f032f005..7ca0b27da 100644
--- a/DesktopEdge/Models/ZitiService.cs
+++ b/DesktopEdge/Models/ZitiService.cs
@@ -1,20 +1,20 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-using NLog;
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -25,286 +25,371 @@ limitations under the License.
using ZitiDesktopEdge.DataStructures;
-namespace ZitiDesktopEdge.Models {
- public class ZitiService {
- private static readonly Logger logger = LogManager.GetCurrentClassLogger();
+namespace ZitiDesktopEdge.Models
+{
+ public class ZitiService
+ {
+ private static readonly Logger logger = LogManager.GetCurrentClassLogger();
- public string Name { get; set; }
- public string[] Protocols { get; set; }
- public Address[] Addresses { get; set; }
- public PortRange[] Ports { get; set; }
- public PostureCheck[] PostureChecks { get; set; }
- public bool OwnsIntercept { get; set; }
- public string AssignedIP { get; set; }
- public DateTime TimeUpdated { get; set; }
- public int Timeout { get; set; }
- public int TimeoutRemaining { get; set; }
- public bool IsMfaReady { get; set; }
+ public string Name { get; set; }
+ public string[] Protocols { get; set; }
+ public Address[] Addresses { get; set; }
+ public PortRange[] Ports { get; set; }
+ public PostureCheck[] PostureChecks { get; set; }
+ public bool OwnsIntercept { get; set; }
+ public string AssignedIP { get; set; }
+ public DateTime TimeUpdated { get; set; }
+ public int Timeout { get; set; }
+ public int TimeoutRemaining { get; set; }
+ public bool IsMfaReady { get; set; }
- private bool failingPostureCheck;
- public bool HasFailingPostureCheck() {
- return failingPostureCheck;
- }
- public bool IsAccessible { get; set; }
+ private bool failingPostureCheck;
+ public bool HasFailingPostureCheck()
+ {
+ return failingPostureCheck;
+ }
+ public bool IsAccessible { get; set; }
- public string Warning {
- get {
- if (this.OwnsIntercept) {
- return "";
- } else {
- return "this won't trigger right now"; //$"Another identity already mapped the specified hostname: {Host}.\nThis service is only available via IP";
- }
- }
- }
+ public string Warning
+ {
+ get
+ {
+ if (this.OwnsIntercept)
+ {
+ return "";
+ }
+ else
+ {
+ return "this won't trigger right now"; //$"Another identity already mapped the specified hostname: {Host}.\nThis service is only available via IP";
+ }
+ }
+ }
- public ZitiService() {
- }
+ public ZitiService()
+ {
+ }
- public ZitiService(Service svc) {
- this.Name = svc.Name;
- this.AssignedIP = svc.AssignedIP;
- this.Addresses = svc.Addresses;
- this.Protocols = svc.Protocols == null ? null : svc.Protocols.Select(p => p.ToUpper()).ToArray();
- this.Ports = svc.Ports;
- this.PostureChecks = svc.PostureChecks;
- this.Timeout = svc.Timeout;
- this.TimeoutRemaining = svc.TimeoutRemaining;
- this.OwnsIntercept = svc.OwnsIntercept;
- this.IsMfaReady = false;
- this.TimeUpdated = DateTime.Now;
- if (this.PostureChecks != null) {
- this.failingPostureCheck = this.PostureChecks.Any(p => !p.IsPassing);
- }
- this.IsAccessible = svc.IsAccessible;
- //commented out for now logger.Warn("SERVICE: " + this.Name + " HAS FAILING POSTURE CHECK: " + failingPostureCheck);
- }
+ public ZitiService(Service svc)
+ {
+ this.Name = svc.Name;
+ this.AssignedIP = svc.AssignedIP;
+ this.Addresses = svc.Addresses;
+ this.Protocols = svc.Protocols == null ? null : svc.Protocols.Select(p => p.ToUpper()).ToArray();
+ this.Ports = svc.Ports;
+ this.PostureChecks = svc.PostureChecks;
+ this.Timeout = svc.Timeout;
+ this.TimeoutRemaining = svc.TimeoutRemaining;
+ this.OwnsIntercept = svc.OwnsIntercept;
+ this.IsMfaReady = false;
+ this.TimeUpdated = DateTime.Now;
+ if (this.PostureChecks != null)
+ {
+ this.failingPostureCheck = this.PostureChecks.Any(p => !p.IsPassing);
+ }
+ this.IsAccessible = svc.IsAccessible;
+ //commented out for now logger.Warn("SERVICE: " + this.Name + " HAS FAILING POSTURE CHECK: " + failingPostureCheck);
+ }
- public string WarningMessage {
- get {
- string message = Warning;
- if (this.PostureChecks != null && this.PostureChecks.Length > 0) {
- List messages = new List();
- for (int i = 0; i < this.PostureChecks.Length; i++) {
- if (!this.PostureChecks[i].IsPassing) {
- messages = AppendMessage(messages, this.PostureChecks[i].QueryType);
- }
- }
- if (messages.Count > 0) {
- string checks = "";
- for (int i = 0; i < messages.Count; i++) {
- checks += ((i > 0) ? ", " : "") + messages[i].Total + " " + messages[i].Message;
- }
- message = message + " Posture Check Failing: " + checks;
- return message.Trim();
- } else return message;
- } else return message;
- }
- }
- private List AppendMessage(List items, string message) {
- bool found = false;
- for (int i = 0; i < items.Count; i++) {
- if (items[i].Message == message) {
- items[i].Total++;
- found = true;
- }
- }
- if (!found) {
- MessageCount count = new MessageCount();
- count.Total = 1;
- count.Message = message;
- items.Add(count);
- }
- return items;
- }
+ public string WarningMessage
+ {
+ get
+ {
+ string message = Warning;
+ if (this.PostureChecks != null && this.PostureChecks.Length > 0)
+ {
+ List messages = new List();
+ for (int i = 0; i < this.PostureChecks.Length; i++)
+ {
+ if (!this.PostureChecks[i].IsPassing)
+ {
+ messages = AppendMessage(messages, this.PostureChecks[i].QueryType);
+ }
+ }
+ if (messages.Count > 0)
+ {
+ string checks = "";
+ for (int i = 0; i < messages.Count; i++)
+ {
+ checks += ((i > 0) ? ", " : "") + messages[i].Total + " " + messages[i].Message;
+ }
+ message = message + " Posture Check Failing: " + checks;
+ return message.Trim();
+ }
+ else return message;
+ }
+ else return message;
+ }
+ }
+ private List AppendMessage(List items, string message)
+ {
+ bool found = false;
+ for (int i = 0; i < items.Count; i++)
+ {
+ if (items[i].Message == message)
+ {
+ items[i].Total++;
+ found = true;
+ }
+ }
+ if (!found)
+ {
+ MessageCount count = new MessageCount();
+ count.Total = 1;
+ count.Message = message;
+ items.Add(count);
+ }
+ return items;
+ }
- public int WarnWidth {
- get {
- return (HasWarning) ? 30 : 0;
- }
- set { }
- }
+ public int WarnWidth
+ {
+ get
+ {
+ return (HasWarning) ? 30 : 0;
+ }
+ set { }
+ }
- public Visibility WarningVisibility {
- get {
- return (HasWarning) ? Visibility.Visible : Visibility.Collapsed;
- }
- set { }
- }
- public int WarningWidth {
- get {
- return (HasWarning) ? 20 : 0;
- }
- set { }
- }
+ public Visibility WarningVisibility
+ {
+ get
+ {
+ return (HasWarning) ? Visibility.Visible : Visibility.Collapsed;
+ }
+ set { }
+ }
+ public int WarningWidth
+ {
+ get
+ {
+ return (HasWarning) ? 20 : 0;
+ }
+ set { }
+ }
- public Visibility TimerVisibility {
- get {
- return (IsMfaReady && TimeoutCalculated > -1 && TimeoutCalculated <= 1200 && TimeoutCalculated > 0) ? Visibility.Visible : Visibility.Collapsed;
- }
- set { }
- }
+ public Visibility TimerVisibility
+ {
+ get
+ {
+ return (IsMfaReady && TimeoutCalculated > -1 && TimeoutCalculated <= 1200 && TimeoutCalculated > 0) ? Visibility.Visible : Visibility.Collapsed;
+ }
+ set { }
+ }
- public int TimeoutCalculated {
- get {
- if (this.TimeoutRemaining == -1 || TimeoutRemaining == 0) return this.TimeoutRemaining;
- else {
- TimeSpan t = (DateTime.Now - this.TimeUpdated.ToLocalTime());
- int timeout = this.TimeoutRemaining - (int)Math.Floor(t.TotalSeconds);
- if (timeout < 0) timeout = 0;
- return timeout;
- }
- }
- set { }
- }
+ public int TimeoutCalculated
+ {
+ get
+ {
+ if (this.TimeoutRemaining == -1 || TimeoutRemaining == 0) return this.TimeoutRemaining;
+ else
+ {
+ TimeSpan t = (DateTime.Now - this.TimeUpdated.ToLocalTime());
+ int timeout = this.TimeoutRemaining - (int)Math.Floor(t.TotalSeconds);
+ if (timeout < 0) timeout = 0;
+ return timeout;
+ }
+ }
+ set { }
+ }
- public Visibility MfaVisibility {
- get {
- return (IsMfaReady && TimeoutCalculated > -1 && TimeoutCalculated == 0) ? Visibility.Visible : Visibility.Collapsed;
- }
- set { }
- }
- public int TimerWidth {
- get {
- return (TimeoutCalculated > -1 && TimeoutCalculated < 1200) ? 20 : 0;
- }
- set { }
- }
+ public Visibility MfaVisibility
+ {
+ get
+ {
+ return (IsMfaReady && TimeoutCalculated > -1 && TimeoutCalculated == 0) ? Visibility.Visible : Visibility.Collapsed;
+ }
+ set { }
+ }
+ public int TimerWidth
+ {
+ get
+ {
+ return (TimeoutCalculated > -1 && TimeoutCalculated < 1200) ? 20 : 0;
+ }
+ set { }
+ }
- public bool HasWarning {
- get {
- if (!this.OwnsIntercept) return true;
- else {
- if (this.IsAccessible) {
- return false;
- } else {
- if (this.PostureChecks==null) {
- return false;
- } else {
- for (int i = 0; i < this.PostureChecks.Length; i++) {
- if (!this.PostureChecks[i].IsPassing) {
- return true;
- }
- }
- return false;
- }
- }
- }
- }
- set { }
- }
+ public bool HasWarning
+ {
+ get
+ {
+ if (!this.OwnsIntercept) return true;
+ else
+ {
+ if (this.IsAccessible)
+ {
+ return false;
+ }
+ else
+ {
+ if (this.PostureChecks == null)
+ {
+ return false;
+ }
+ else
+ {
+ for (int i = 0; i < this.PostureChecks.Length; i++)
+ {
+ if (!this.PostureChecks[i].IsPassing)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+ }
+ }
+ set { }
+ }
- public string ProtocolString {
- get {
- string toReturn = "";
- if (this.Protocols != null) {
- for (int i = 0; i < this.Protocols.Length; i++) {
- toReturn += ((i > 0) ? "," : "") + this.Protocols[i];
- }
- }
- return toReturn;
- }
- set { }
- }
+ public string ProtocolString
+ {
+ get
+ {
+ string toReturn = "";
+ if (this.Protocols != null)
+ {
+ for (int i = 0; i < this.Protocols.Length; i++)
+ {
+ toReturn += ((i > 0) ? "," : "") + this.Protocols[i];
+ }
+ }
+ return toReturn;
+ }
+ set { }
+ }
- public string PortString {
- get {
- string toReturn = "";
- if (this.Ports != null) {
- for (int i = 0; i < this.Ports.Length; i++) {
- toReturn += ((i > 0) ? "," : "") + this.Ports[i].ToString();
- }
- }
- return toReturn;
- }
- set { }
- }
+ public string PortString
+ {
+ get
+ {
+ string toReturn = "";
+ if (this.Ports != null)
+ {
+ for (int i = 0; i < this.Ports.Length; i++)
+ {
+ toReturn += ((i > 0) ? "," : "") + this.Ports[i].ToString();
+ }
+ }
+ return toReturn;
+ }
+ set { }
+ }
- public string AddressString {
- get {
- string toReturn = "";
- if (this.Addresses != null) {
- for (int i = 0; i < this.Addresses.Length; i++) {
- toReturn += ((i > 0) ? "," : "") + this.Addresses[i].ToString();
- }
- }
- return toReturn;
- }
- set { }
- }
+ public string AddressString
+ {
+ get
+ {
+ string toReturn = "";
+ if (this.Addresses != null)
+ {
+ for (int i = 0; i < this.Addresses.Length; i++)
+ {
+ toReturn += ((i > 0) ? "," : "") + this.Addresses[i].ToString();
+ }
+ }
+ return toReturn;
+ }
+ set { }
+ }
- private ServiceMatrix builtMatrix = null;
- public ServiceMatrix Matrix {
- get {
- if (builtMatrix == null) {
- builtMatrix = new ServiceMatrix();
- List matrix = new List(this.Protocols.Length * this.Addresses.Length * this.Ports.Length);
+ private ServiceMatrix builtMatrix = null;
+ public ServiceMatrix Matrix
+ {
+ get
+ {
+ if (builtMatrix == null)
+ {
+ builtMatrix = new ServiceMatrix();
+ List matrix = new List(this.Protocols.Length * this.Addresses.Length * this.Ports.Length);
- foreach (var proto in this.Protocols) {
- foreach (var addy in this.Addresses) {
- foreach (var port in this.Ports) {
- ServiceMatrixElement m = new ServiceMatrixElement();
- m.Ports = port.ToString();
- m.Proto = proto.ToUpper();
- m.Address = addy.Hostname;
+ foreach (var proto in this.Protocols)
+ {
+ foreach (var addy in this.Addresses)
+ {
+ foreach (var port in this.Ports)
+ {
+ ServiceMatrixElement m = new ServiceMatrixElement();
+ m.Ports = port.ToString();
+ m.Proto = proto.ToUpper();
+ m.Address = addy.Hostname;
- matrix.Add(m);
- }
- }
- }
- builtMatrix.Elements = matrix;
- }
+ matrix.Add(m);
+ }
+ }
+ }
+ builtMatrix.Elements = matrix;
+ }
- return builtMatrix;
- }
- }
+ return builtMatrix;
+ }
+ }
- public override string ToString() {
- string protos = "";
- if (Protocols?.Length > 0) {
- if (Protocols.Length > 1) {
- protos = "[" + string.Join(",", Protocols.Select(p => p.ToString())) + "]";
- } else {
- protos = Protocols[0];
- }
- }
- string addys = "";
- if (Addresses?.Length > 0) {
- if (Addresses.Length > 1) {
- addys = "[" + string.Join(",", Addresses.Select(a => a.ToString()).OrderBy(o => o)) + "]";
- } else {
- addys = Addresses[0].ToString();
- }
- }
- string ranges = "";
- if (Ports?.Length > 0) {
- if (Ports.Length > 1) {
- ranges = "[" + string.Join(",", Ports.Select(a => a.ToString()).OrderBy(o => o)) + "]";
- } else {
- ranges = Ports[0].ToString();
- }
- }
+ public override string ToString()
+ {
+ string protos = "";
+ if (Protocols?.Length > 0)
+ {
+ if (Protocols.Length > 1)
+ {
+ protos = "[" + string.Join(",", Protocols.Select(p => p.ToString())) + "]";
+ }
+ else
+ {
+ protos = Protocols[0];
+ }
+ }
+ string addys = "";
+ if (Addresses?.Length > 0)
+ {
+ if (Addresses.Length > 1)
+ {
+ addys = "[" + string.Join(",", Addresses.Select(a => a.ToString()).OrderBy(o => o)) + "]";
+ }
+ else
+ {
+ addys = Addresses[0].ToString();
+ }
+ }
+ string ranges = "";
+ if (Ports?.Length > 0)
+ {
+ if (Ports.Length > 1)
+ {
+ ranges = "[" + string.Join(",", Ports.Select(a => a.ToString()).OrderBy(o => o)) + "]";
+ }
+ else
+ {
+ ranges = Ports[0].ToString();
+ }
+ }
- return protos + ":" + addys + ":" + ranges;
- }
- }
+ return protos + ":" + addys + ":" + ranges;
+ }
+ }
- public class ServiceMatrix {
- public List Elements { get; internal set; }
- }
+ public class ServiceMatrix
+ {
+ public List Elements { get; internal set; }
+ }
- public class ServiceMatrixElement {
- public ServiceMatrixElement() {
- Proto = "";
- Address = "";
- Ports = "";
- }
+ public class ServiceMatrixElement
+ {
+ public ServiceMatrixElement()
+ {
+ Proto = "";
+ Address = "";
+ Ports = "";
+ }
- public string Proto { get; set; }
- public string Address { get; set; }
- public string Ports { get; set; }
+ public string Proto { get; set; }
+ public string Address { get; set; }
+ public string Ports { get; set; }
- public override string ToString() {
- return Proto + " " + Address + " " + Ports;
- }
- }
+ public override string ToString()
+ {
+ return Proto + " " + Address + " " + Ports;
+ }
+ }
}
diff --git a/DesktopEdge/Native/NativeMethods.cs b/DesktopEdge/Native/NativeMethods.cs
index a8543304d..dc2a48e76 100644
--- a/DesktopEdge/Native/NativeMethods.cs
+++ b/DesktopEdge/Native/NativeMethods.cs
@@ -1,17 +1,80 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace ZitiDesktopEdge.Native {
public static class NativeMethods {
private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
private const uint FILE_READ_EA = 0x0008;
private const uint FILE_FLAG_BACKUP_SEMANTICS = 0x2000000;
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern uint GetFinalPathNameByHandle(IntPtr hFile, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpszFilePath, uint cchFilePath, uint dwFlags);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CreateFile(
[MarshalAs(UnmanagedType.LPTStr)] string filename,
[MarshalAs(UnmanagedType.U4)] uint access,
[MarshalAs(UnmanagedType.U4)] FileShare share,
IntPtr securityAttributes, // optional SECURITY_ATTRIBUTES struct or IntPtr.Zero
[MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
[MarshalAs(UnmanagedType.U4)] uint flagsAndAttributes,
IntPtr templateFile);
public static string GetFinalPathName(string path) {
var h = CreateFile(path,
FILE_READ_EA,
FileShare.ReadWrite | FileShare.Delete,
IntPtr.Zero,
FileMode.Open,
FILE_FLAG_BACKUP_SEMANTICS,
IntPtr.Zero);
if (h == INVALID_HANDLE_VALUE)
throw new Win32Exception();
try {
var sb = new StringBuilder(1024);
var res = GetFinalPathNameByHandle(h, sb, 1024, 0);
if (res == 0)
throw new Win32Exception();
return sb.ToString();
} finally {
CloseHandle(h);
}
}
}
}
\ No newline at end of file
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ZitiDesktopEdge.Native
+{
+
+ public static class NativeMethods
+ {
+ private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
+
+ private const uint FILE_READ_EA = 0x0008;
+ private const uint FILE_FLAG_BACKUP_SEMANTICS = 0x2000000;
+
+ [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+ static extern uint GetFinalPathNameByHandle(IntPtr hFile, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpszFilePath, uint cchFilePath, uint dwFlags);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ static extern bool CloseHandle(IntPtr hObject);
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ public static extern IntPtr CreateFile(
+ [MarshalAs(UnmanagedType.LPTStr)] string filename,
+ [MarshalAs(UnmanagedType.U4)] uint access,
+ [MarshalAs(UnmanagedType.U4)] FileShare share,
+ IntPtr securityAttributes, // optional SECURITY_ATTRIBUTES struct or IntPtr.Zero
+ [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
+ [MarshalAs(UnmanagedType.U4)] uint flagsAndAttributes,
+ IntPtr templateFile);
+
+ public static string GetFinalPathName(string path)
+ {
+ var h = CreateFile(path,
+ FILE_READ_EA,
+ FileShare.ReadWrite | FileShare.Delete,
+ IntPtr.Zero,
+ FileMode.Open,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ IntPtr.Zero);
+ if (h == INVALID_HANDLE_VALUE)
+ throw new Win32Exception();
+
+ try
+ {
+ var sb = new StringBuilder(1024);
+ var res = GetFinalPathNameByHandle(h, sb, 1024, 0);
+ if (res == 0)
+ throw new Win32Exception();
+
+ return sb.ToString();
+ }
+ finally
+ {
+ CloseHandle(h);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DesktopEdge/Native/WinAPI.cs b/DesktopEdge/Native/WinAPI.cs
index 02584d4eb..9ee71b08d 100644
--- a/DesktopEdge/Native/WinAPI.cs
+++ b/DesktopEdge/Native/WinAPI.cs
@@ -1,67 +1,74 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
*/
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Runtime.InteropServices;
-using System.Drawing;
-using System.ComponentModel;
-
-namespace ZitiDesktopEdge {
-
- public class WinAPI {
- public struct RECT {
- public int left;
- public int top;
- public int right;
- public int bottom;
-
- public override string ToString() {
- return "(" + left + ", " + top + ") --> (" + right + ", " + bottom + ")";
- }
- }
-
- [DllImport("user32.dll", CharSet = CharSet.Auto)]
- public static extern IntPtr FindWindow(string strClassName, string strWindowName);
-
- [DllImport("user32.dll", SetLastError = true)]
- public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, IntPtr windowTitle);
-
- [DllImport("user32.dll")]
- [return: MarshalAs(UnmanagedType.Bool)]
- static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
-
-
- public static IntPtr GetTrayHandle() {
- IntPtr taskBarHandle = WinAPI.FindWindow("Shell_TrayWnd", null);
- if (!taskBarHandle.Equals(IntPtr.Zero)) {
- return WinAPI.FindWindowEx(taskBarHandle, IntPtr.Zero, "TrayNotifyWnd", IntPtr.Zero);
- }
- return IntPtr.Zero;
- }
-
- public static Rectangle GetTrayRectangle() {
- WinAPI.RECT rect;
- WinAPI.GetWindowRect(WinAPI.GetTrayHandle(), out rect);
- return new Rectangle(new Point(rect.left, rect.top), new Size((rect.right - rect.left) + 1, (rect.bottom - rect.top) + 1));
- }
- }
-}
-
-
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+using System.Drawing;
+using System.ComponentModel;
+
+namespace ZitiDesktopEdge
+{
+
+ public class WinAPI
+ {
+ public struct RECT
+ {
+ public int left;
+ public int top;
+ public int right;
+ public int bottom;
+
+ public override string ToString()
+ {
+ return "(" + left + ", " + top + ") --> (" + right + ", " + bottom + ")";
+ }
+ }
+
+ [DllImport("user32.dll", CharSet = CharSet.Auto)]
+ public static extern IntPtr FindWindow(string strClassName, string strWindowName);
+
+ [DllImport("user32.dll", SetLastError = true)]
+ public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, IntPtr windowTitle);
+
+ [DllImport("user32.dll")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
+
+
+ public static IntPtr GetTrayHandle()
+ {
+ IntPtr taskBarHandle = WinAPI.FindWindow("Shell_TrayWnd", null);
+ if (!taskBarHandle.Equals(IntPtr.Zero))
+ {
+ return WinAPI.FindWindowEx(taskBarHandle, IntPtr.Zero, "TrayNotifyWnd", IntPtr.Zero);
+ }
+ return IntPtr.Zero;
+ }
+
+ public static Rectangle GetTrayRectangle()
+ {
+ WinAPI.RECT rect;
+ WinAPI.GetWindowRect(WinAPI.GetTrayHandle(), out rect);
+ return new Rectangle(new Point(rect.left, rect.top), new Size((rect.right - rect.left) + 1, (rect.bottom - rect.top) + 1));
+ }
+ }
+}
+
+
diff --git a/DesktopEdge/Properties/AssemblyInfo.cs b/DesktopEdge/Properties/AssemblyInfo.cs
index dd10fb999..1843f99ed 100644
--- a/DesktopEdge/Properties/AssemblyInfo.cs
+++ b/DesktopEdge/Properties/AssemblyInfo.cs
@@ -1,55 +1,55 @@
-using System.Reflection;
-using System.Resources;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Windows;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Ziti Desktop Edge")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Ziti Desktop Edge")]
-[assembly: AssemblyCopyright("Copyright NetFoundry © 2020")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-//In order to begin building localizable applications, set
-//CultureYouAreCodingWith in your .csproj file
-//inside a . For example, if you are using US english
-//in your source files, set the to en-US. Then uncomment
-//the NeutralResourceLanguage attribute below. Update the "en-US" in
-//the line below to match the UICulture setting in the project file.
-
-//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
-
-
-[assembly: ThemeInfo(
- ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
- //(used if a resource is not found in the page,
- // or application resource dictionaries)
- ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
- //(used if a resource is not found in the page,
- // app, or any theme specific resource dictionaries)
-)]
-
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("2.1.7.0")]
-[assembly: AssemblyVersion("2.1.6.0")]
-[assembly: AssemblyFileVersion("2.1.6.0")]
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Ziti Desktop Edge")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Ziti Desktop Edge")]
+[assembly: AssemblyCopyright("Copyright NetFoundry © 2020")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+//In order to begin building localizable applications, set
+//CultureYouAreCodingWith in your .csproj file
+//inside a . For example, if you are using US english
+//in your source files, set the to en-US. Then uncomment
+//the NeutralResourceLanguage attribute below. Update the "en-US" in
+//the line below to match the UICulture setting in the project file.
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
+
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("2.1.7.0")]
+[assembly: AssemblyVersion("2.1.6.0")]
+[assembly: AssemblyFileVersion("2.1.6.0")]
diff --git a/DesktopEdge/Utils/UIUtils.cs b/DesktopEdge/Utils/UIUtils.cs
index d42761de9..2a2e6d404 100644
--- a/DesktopEdge/Utils/UIUtils.cs
+++ b/DesktopEdge/Utils/UIUtils.cs
@@ -1,48 +1,55 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-using System;
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+using System;
using System.Threading.Tasks;
using NLog;
-namespace Ziti.Desktop.Edge.Utils {
- public class UIUtils {
-
- private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
-
- public static void SetLogLevel(string level) {
- try
- {
- Logger.Info("request to change log level received: {0}", level);
- if ((""+level).ToLower() == "verbose") {
- level = "trace";
- Logger.Info("request to change log level to verbose - but using trace instead");
- }
- var l = LogLevel.FromString(level);
- foreach (var rule in LogManager.Configuration.LoggingRules) {
- rule.EnableLoggingForLevel(l);
- rule.SetLoggingLevels(l, LogLevel.Fatal);
- }
-
- LogManager.ReconfigExistingLoggers();
- Logger.Info("logger reconfigured to log at level: {0}", l);
- } catch (Exception e) {
- Logger.Error(e, "Failed to set log level: {0}", e.Message);
- }
- }
- }
+namespace Ziti.Desktop.Edge.Utils
+{
+ public class UIUtils
+ {
+
+ private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
+
+ public static void SetLogLevel(string level)
+ {
+ try
+ {
+ Logger.Info("request to change log level received: {0}", level);
+ if (("" + level).ToLower() == "verbose")
+ {
+ level = "trace";
+ Logger.Info("request to change log level to verbose - but using trace instead");
+ }
+ var l = LogLevel.FromString(level);
+ foreach (var rule in LogManager.Configuration.LoggingRules)
+ {
+ rule.EnableLoggingForLevel(l);
+ rule.SetLoggingLevels(l, LogLevel.Fatal);
+ }
+
+ LogManager.ReconfigExistingLoggers();
+ Logger.Info("logger reconfigured to log at level: {0}", l);
+ }
+ catch (Exception e)
+ {
+ Logger.Error(e, "Failed to set log level: {0}", e.Message);
+ }
+ }
+ }
}
diff --git a/DesktopEdge/Views/Controls/StyledButton.xaml.cs b/DesktopEdge/Views/Controls/StyledButton.xaml.cs
index ff2d35e92..996861857 100644
--- a/DesktopEdge/Views/Controls/StyledButton.xaml.cs
+++ b/DesktopEdge/Views/Controls/StyledButton.xaml.cs
@@ -1,88 +1,100 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
-
-namespace ZitiDesktopEdge {
- ///
- /// Interaction logic for StyledButton.xaml
- ///
- public partial class StyledButton : UserControl {
-
- public delegate void ClickAction(object sender, MouseButtonEventArgs e);
- public event ClickAction OnClick;
- private string _label = "";
- private string bgColor = "#0069FF";
-
- public string BgColor {
- get { return bgColor; }
- set {
- bgColor = value;
- ButtonBgColor.Color = (Color)ColorConverter.ConvertFromString(bgColor);
- }
- }
-
- public string Label {
- get {
- return _label;
- }
- set {
- this._label = value;
- ButtonLabel.Content = this._label;
- }
- }
-
- public StyledButton() {
- InitializeComponent();
- }
-
- ///
- /// When the button area is entered slowly make it slightly opaque
- ///
- /// The button object
- /// The mouse event
- private void Hover(object sender, MouseEventArgs e) {
- ButtonBgDarken.Opacity = 0.0;
- ButtonBgDarken.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(0.2, TimeSpan.FromSeconds(.3)));
- }
-
- ///
- /// When the mouse leaves the button ara snap the opacity back to full
- ///
- /// The button object
- /// The mouse event
- private void Leave(object sender, MouseEventArgs e) {
- ButtonBgDarken.Opacity = 0.2;
- ButtonBgDarken.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(0.0, TimeSpan.FromSeconds(.3)));
- }
-
- ///
- /// Change the color to visualize a click event
- ///
- ///
- ///
- private void Down(object sender, MouseButtonEventArgs e) {
- // ButtonBgColor.Color = Color.FromRgb(126, 180, 255);
- }
-
- ///
- /// Execute the click operation
- ///
- ///
- ///
- private void DoClick(object sender, MouseButtonEventArgs e) {
- this.OnClick?.Invoke(sender, e);
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace ZitiDesktopEdge
+{
+ ///
+ /// Interaction logic for StyledButton.xaml
+ ///
+ public partial class StyledButton : UserControl
+ {
+
+ public delegate void ClickAction(object sender, MouseButtonEventArgs e);
+ public event ClickAction OnClick;
+ private string _label = "";
+ private string bgColor = "#0069FF";
+
+ public string BgColor
+ {
+ get { return bgColor; }
+ set
+ {
+ bgColor = value;
+ ButtonBgColor.Color = (Color)ColorConverter.ConvertFromString(bgColor);
+ }
+ }
+
+ public string Label
+ {
+ get
+ {
+ return _label;
+ }
+ set
+ {
+ this._label = value;
+ ButtonLabel.Content = this._label;
+ }
+ }
+
+ public StyledButton()
+ {
+ InitializeComponent();
+ }
+
+ ///
+ /// When the button area is entered slowly make it slightly opaque
+ ///
+ /// The button object
+ /// The mouse event
+ private void Hover(object sender, MouseEventArgs e)
+ {
+ ButtonBgDarken.Opacity = 0.0;
+ ButtonBgDarken.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(0.2, TimeSpan.FromSeconds(.3)));
+ }
+
+ ///
+ /// When the mouse leaves the button ara snap the opacity back to full
+ ///
+ /// The button object
+ /// The mouse event
+ private void Leave(object sender, MouseEventArgs e)
+ {
+ ButtonBgDarken.Opacity = 0.2;
+ ButtonBgDarken.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(0.0, TimeSpan.FromSeconds(.3)));
+ }
+
+ ///
+ /// Change the color to visualize a click event
+ ///
+ ///
+ ///
+ private void Down(object sender, MouseButtonEventArgs e)
+ {
+ // ButtonBgColor.Color = Color.FromRgb(126, 180, 255);
+ }
+
+ ///
+ /// Execute the click operation
+ ///
+ ///
+ ///
+ private void DoClick(object sender, MouseButtonEventArgs e)
+ {
+ this.OnClick?.Invoke(sender, e);
+ }
+ }
+}
diff --git a/DesktopEdge/Views/Controls/Toggler.xaml.cs b/DesktopEdge/Views/Controls/Toggler.xaml.cs
index ce05628f5..2d3c8fd69 100644
--- a/DesktopEdge/Views/Controls/Toggler.xaml.cs
+++ b/DesktopEdge/Views/Controls/Toggler.xaml.cs
@@ -1,75 +1,92 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
-using System.Windows.Media.Animation;
-
-namespace ZitiDesktopEdge {
- ///
- /// Interaction logic for Toggler.xaml
- ///
- public partial class Toggler : UserControl {
-
- public delegate void Toggled(bool on);
- public event Toggled OnToggled;
- private bool _isEnabled = false;
- public Toggler() {
- InitializeComponent();
- }
-
- public Boolean Enabled {
- get {
- return _isEnabled;
- }
- set {
- _isEnabled = value;
- if (_isEnabled) {
- // ToggleTab.BeginAnimation(Canvas.LeftProperty, new DoubleAnimation(16, TimeSpan.FromSeconds(.3)));
- // OnColor.BeginAnimation(Border.OpacityProperty, new DoubleAnimation(1.0, TimeSpan.FromSeconds(.3)));
-
- OnColor.Opacity = 1;
- Canvas.SetLeft(ToggleTab, 16);
- } else {
- // ToggleTab.BeginAnimation(Canvas.LeftProperty, new DoubleAnimation(1, TimeSpan.FromSeconds(.3)));
- // OnColor.BeginAnimation(Border.OpacityProperty, new DoubleAnimation(0, TimeSpan.FromSeconds(.3)));
-
- OnColor.Opacity = 0;
- Canvas.SetLeft(ToggleTab, 1);
- }
- }
- }
-
- public void Toggle() {
- Enabled = !Enabled;
- if (OnToggled != null) {
- OnToggled(Enabled);
- }
- }
-
- private void OnToggle(object sender, RoutedEventArgs e) {
- e.Handled = true;
- Enabled = !Enabled;
- if (OnToggled != null) {
- OnToggled(Enabled);
- }
- }
-
- private void OnLoad(object sender, RoutedEventArgs e) {
- if (_isEnabled) {
-
- } else {
-
- }
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using System.Windows.Media.Animation;
+
+namespace ZitiDesktopEdge
+{
+ ///
+ /// Interaction logic for Toggler.xaml
+ ///
+ public partial class Toggler : UserControl
+ {
+
+ public delegate void Toggled(bool on);
+ public event Toggled OnToggled;
+ private bool _isEnabled = false;
+ public Toggler()
+ {
+ InitializeComponent();
+ }
+
+ public Boolean Enabled
+ {
+ get
+ {
+ return _isEnabled;
+ }
+ set
+ {
+ _isEnabled = value;
+ if (_isEnabled)
+ {
+ // ToggleTab.BeginAnimation(Canvas.LeftProperty, new DoubleAnimation(16, TimeSpan.FromSeconds(.3)));
+ // OnColor.BeginAnimation(Border.OpacityProperty, new DoubleAnimation(1.0, TimeSpan.FromSeconds(.3)));
+
+ OnColor.Opacity = 1;
+ Canvas.SetLeft(ToggleTab, 16);
+ }
+ else
+ {
+ // ToggleTab.BeginAnimation(Canvas.LeftProperty, new DoubleAnimation(1, TimeSpan.FromSeconds(.3)));
+ // OnColor.BeginAnimation(Border.OpacityProperty, new DoubleAnimation(0, TimeSpan.FromSeconds(.3)));
+
+ OnColor.Opacity = 0;
+ Canvas.SetLeft(ToggleTab, 1);
+ }
+ }
+ }
+
+ public void Toggle()
+ {
+ Enabled = !Enabled;
+ if (OnToggled != null)
+ {
+ OnToggled(Enabled);
+ }
+ }
+
+ private void OnToggle(object sender, RoutedEventArgs e)
+ {
+ e.Handled = true;
+ Enabled = !Enabled;
+ if (OnToggled != null)
+ {
+ OnToggled(Enabled);
+ }
+ }
+
+ private void OnLoad(object sender, RoutedEventArgs e)
+ {
+ if (_isEnabled)
+ {
+
+ }
+ else
+ {
+
+ }
+ }
+ }
+}
diff --git a/DesktopEdge/Views/ItemRenderers/Filter.xaml.cs b/DesktopEdge/Views/ItemRenderers/Filter.xaml.cs
index 1c39c4b85..cd01f22ac 100644
--- a/DesktopEdge/Views/ItemRenderers/Filter.xaml.cs
+++ b/DesktopEdge/Views/ItemRenderers/Filter.xaml.cs
@@ -1,106 +1,130 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
-using System.Timers;
-using ZitiDesktopEdge.Models;
-
-namespace ZitiDesktopEdge {
- ///
- /// Interaction logic for Filter.xaml
- ///
- public partial class Filter :UserControl {
-
- public delegate void OnFilterEvent(FilterData filter);
- public event OnFilterEvent OnFilter;
- public string placeholder = "any text";
- private static Timer timeout;
-
- private FilterData filter = new FilterData("", "Name", "Asc");
- public Filter() {
- InitializeComponent();
- }
-
- public void Clear() {
- FilterFor.Text = "";
- filter.SearchFor = "";
- FilterFor.Text = placeholder;
- SortWayField.SelectedIndex = 0;
- SortByField.SelectedIndex = 0;
- }
-
- private void FilterPressed(object sender, KeyEventArgs e) {
- if (e.Key==Key.Enter) {
- OnFilter?.Invoke(filter);
- }
- }
-
- private void FilterChanged(object sender, KeyEventArgs e) {
- string search = FilterFor.Text.Trim();
- if (filter.SearchFor!=search) {
- filter.SearchFor = search;
- if (filter.SearchFor == placeholder) filter.SearchFor = "";
-
- if (e.Key==Key.Enter) {
- OnFilter?.Invoke(filter);
- } else {
- if (timeout != null && timeout.Enabled) {
- timeout.Close();
- }
- timeout = new Timer(1000);
- timeout.Elapsed += OnTimedEvent;
- timeout.AutoReset = false;
- timeout.Enabled = true;
- }
- }
- }
-
- private void SortWayChanged(object sender, SelectionChangedEventArgs e) {
- ComboBoxItem selected = (ComboBoxItem)SortWayField.SelectedValue;
- if (selected != null && selected.Content != null) {
- if (selected.Content.ToString() != filter.SortHow) {
- filter.SortHow = selected.Content.ToString();
- this.OnFilter?.Invoke(filter);
- }
- }
- }
-
- private void SortByChanged(object sender, SelectionChangedEventArgs e) {
- ComboBoxItem selected = (ComboBoxItem)SortByField.SelectedValue;
- if (selected != null && selected.Content != null) {
- if (selected.Content.ToString() != filter.SortBy) {
- filter.SortBy = selected.Content.ToString();
- this.OnFilter?.Invoke(filter);
- }
- }
- }
-
- private void FocusFilter(object sender, RoutedEventArgs e) {
- if (FilterFor.Text==placeholder) {
- FilterFor.Text = "";
- }
- }
-
- private void FocusLostFilter(object sender, RoutedEventArgs e) {
- if (FilterFor.Text.Trim() == "") {
- FilterFor.Text = placeholder;
- }
- }
-
- private void OnTimedEvent(Object source, ElapsedEventArgs e) {
- this.Dispatcher.Invoke(() => {
- OnFilter?.Invoke(filter);
- });
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using System.Timers;
+using ZitiDesktopEdge.Models;
+
+namespace ZitiDesktopEdge
+{
+ ///
+ /// Interaction logic for Filter.xaml
+ ///
+ public partial class Filter : UserControl
+ {
+
+ public delegate void OnFilterEvent(FilterData filter);
+ public event OnFilterEvent OnFilter;
+ public string placeholder = "any text";
+ private static Timer timeout;
+
+ private FilterData filter = new FilterData("", "Name", "Asc");
+ public Filter()
+ {
+ InitializeComponent();
+ }
+
+ public void Clear()
+ {
+ FilterFor.Text = "";
+ filter.SearchFor = "";
+ FilterFor.Text = placeholder;
+ SortWayField.SelectedIndex = 0;
+ SortByField.SelectedIndex = 0;
+ }
+
+ private void FilterPressed(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Enter)
+ {
+ OnFilter?.Invoke(filter);
+ }
+ }
+
+ private void FilterChanged(object sender, KeyEventArgs e)
+ {
+ string search = FilterFor.Text.Trim();
+ if (filter.SearchFor != search)
+ {
+ filter.SearchFor = search;
+ if (filter.SearchFor == placeholder) filter.SearchFor = "";
+
+ if (e.Key == Key.Enter)
+ {
+ OnFilter?.Invoke(filter);
+ }
+ else
+ {
+ if (timeout != null && timeout.Enabled)
+ {
+ timeout.Close();
+ }
+ timeout = new Timer(1000);
+ timeout.Elapsed += OnTimedEvent;
+ timeout.AutoReset = false;
+ timeout.Enabled = true;
+ }
+ }
+ }
+
+ private void SortWayChanged(object sender, SelectionChangedEventArgs e)
+ {
+ ComboBoxItem selected = (ComboBoxItem)SortWayField.SelectedValue;
+ if (selected != null && selected.Content != null)
+ {
+ if (selected.Content.ToString() != filter.SortHow)
+ {
+ filter.SortHow = selected.Content.ToString();
+ this.OnFilter?.Invoke(filter);
+ }
+ }
+ }
+
+ private void SortByChanged(object sender, SelectionChangedEventArgs e)
+ {
+ ComboBoxItem selected = (ComboBoxItem)SortByField.SelectedValue;
+ if (selected != null && selected.Content != null)
+ {
+ if (selected.Content.ToString() != filter.SortBy)
+ {
+ filter.SortBy = selected.Content.ToString();
+ this.OnFilter?.Invoke(filter);
+ }
+ }
+ }
+
+ private void FocusFilter(object sender, RoutedEventArgs e)
+ {
+ if (FilterFor.Text == placeholder)
+ {
+ FilterFor.Text = "";
+ }
+ }
+
+ private void FocusLostFilter(object sender, RoutedEventArgs e)
+ {
+ if (FilterFor.Text.Trim() == "")
+ {
+ FilterFor.Text = placeholder;
+ }
+ }
+
+ private void OnTimedEvent(Object source, ElapsedEventArgs e)
+ {
+ this.Dispatcher.Invoke(() =>
+ {
+ OnFilter?.Invoke(filter);
+ });
+ }
+ }
+}
diff --git a/DesktopEdge/Views/ItemRenderers/IdentityItem.xaml.cs b/DesktopEdge/Views/ItemRenderers/IdentityItem.xaml.cs
index 24f838b62..245dca19f 100644
--- a/DesktopEdge/Views/ItemRenderers/IdentityItem.xaml.cs
+++ b/DesktopEdge/Views/ItemRenderers/IdentityItem.xaml.cs
@@ -1,20 +1,20 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-using System;
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
@@ -25,317 +25,397 @@ limitations under the License.
using SWM = System.Windows.Media;
using Windows.UI.WebUI;
-namespace ZitiDesktopEdge {
- ///
- /// User Control to list Identities and give status
- ///
- public partial class IdentityItem:UserControl {
-
- private static readonly Logger logger = LogManager.GetCurrentClassLogger();
- public delegate void StatusChanged(bool attached);
- public event StatusChanged OnStatusChanged;
- public delegate void OnAuthenticate(ZitiIdentity identity);
- public event OnAuthenticate Authenticate;
- public delegate void OnIdentityChanged(ZitiIdentity identity);
- public event OnIdentityChanged IdentityChanged;
- private System.Windows.Forms.Timer _timer;
- private System.Windows.Forms.Timer _timingTimer;
- private float countdown = -1;
- private float countdownComplete = -1;
- private int available = 0;
-
- private static SWM.Color mfaOrange = SWM.Color.FromRgb(0xA1, 0x8B, 0x10);
- private static SWM.Color defaultBlue = SWM.Color.FromRgb(0x00, 0x68, 0xF9);
- private static SWM.Brush MFANeededBrush = new SWM.SolidColorBrush(mfaOrange);
- private static SWM.Brush DefaultBrush = new SWM.SolidColorBrush(defaultBlue);
-
- public ZitiIdentity _identity;
- public ZitiIdentity Identity {
- get {
- return _identity;
- }
- set {
- _identity = value;
- this.RefreshUI();
- }
- }
-
- ///
- /// Object constructor, setup the events for the control
- ///
- public IdentityItem() {
- InitializeComponent();
- ToggleSwitch.OnToggled += ToggleIdentity;
- }
-
- public void StopTimers() {
- _timer?.Stop();
- _timingTimer?.Stop();
- }
-
- public int GetMaxTimeout() {
- int maxto = -1;
- for (int i=0; i<_identity.Services.Count; i++) {
- ZitiService info = _identity.Services[i];
-
- if (info.TimeoutCalculated > -1) {
- if (info.TimeoutCalculated==0) {
- available--;
- }
- if (info.TimeoutCalculated > maxto) maxto = info.TimeoutCalculated;
-
- }
- logger.Trace("Max: " + _identity.Name + " "+maxto+" " + info.Name + " " + info.Timeout + " " + info.TimeoutCalculated + " " + info.TimeoutRemaining + " " + info.TimeUpdated+" "+ DateTime.Now);
- }
- return maxto;
- }
- public int GetMinTimeout() {
- int minto = int.MaxValue;
- for (int i = 0; i < _identity.Services.Count; i++) {
- ZitiService info = _identity.Services[i];
- if (info.TimeoutCalculated > -1) {
- if (info.TimeoutCalculated < minto) minto = info.TimeoutCalculated;
- }
- // logger.Trace("Min: " + _identity.Name + " " + minto + " " + info.Name + " " + info.Timeout + " " + info.TimeoutCalculated + " " + info.TimeoutRemaining + " " + info.TimeUpdated+" "+ DateTime.Now);
- }
- if (minto == int.MaxValue) minto = 0;
- return minto;
- }
-
- private void MFAEnabledAndNeeded() {
- MfaRequired.Visibility = Visibility.Visible;
- ServiceCountArea.Visibility = Visibility.Collapsed;
- MainArea.Opacity = 0.6;
- ServiceCountAreaLabel.Content = "authorize";
-
- float maxto = GetMaxTimeout();
- if (maxto > -1) {
- if (maxto > 0) {
- if (_timer != null) _timer.Stop();
- countdownComplete = maxto;
- _timer = new System.Windows.Forms.Timer();
- _timer.Interval = 1000;
- _timer.Tick += TimerTicked;
- _timer.Start();
- logger.Info("Timer Started for full timout in " + maxto + " seconds from identity " + _identity.Name + ".");
- } else {
- //if (maxto == 0) ShowTimedOut();
- }
- }
- float minto = GetMinTimeout();
- logger.Info("Min/Max For " + _identity.Name + " " + minto + " " + maxto);
- if (minto > -1) {
- if (minto > 0) {
- if (_timingTimer != null) _timingTimer.Stop();
- countdown = minto;
- _timingTimer = new System.Windows.Forms.Timer();
- _timingTimer.Interval = 1000;
- _timingTimer.Tick += TimingTimerTick;
- _timingTimer.Start();
- logger.Info("Timer Started for first timout in " + minto + " seconds from identity " + _identity.Name + " value with " + _identity.MinTimeout + ".");
- } else {
- if (maxto > 0) {
- ShowTimeout();
- }
- }
- }
- logger.Info("RefreshUI " + _identity.Name + " Min: " + minto + " Max: " + maxto);
- }
-
- private void MFAEnabledAndNotNeeded() {
- if (_identity.IsTimedOut) {
- PostureTimedOut.Visibility = Visibility.Visible;
- ServiceCountAreaLabel.Content = "authorize2";
- MainArea.Opacity = 1.0;
- } else {
- //MfaRequired.Visibility = Visibility.Visible;
- //ServiceCountAreaLabel.Content = "authenticate1";
- //MainArea.Opacity = 0.6;
- MfaRequired.Visibility = Visibility.Collapsed;
- }
- ServiceCountBorder.Background = DefaultBrush;
- }
-
- private void MFANotEnabledAndNotNeeded() {
- ServiceCountAreaLabel.Content = "services";
- MainArea.Opacity = 1.0;
- }
-
- private void MFANotEnabledAndNeeded() {
- ServiceCount.Content = "MFA";
- ServiceCountBorder.Background = MFANeededBrush;
- ServiceCountAreaLabel.Content = "disabled";
- }
-
- public void RefreshUI () {
- if (_identity.IsConnected) {
- this.IsEnabled = true;
- this.Opacity = 1.0;
- } else {
- this.IsEnabled = false;
- this.Opacity = 0.3;
- }
- TimerCountdown.Visibility = Visibility.Collapsed;
- PostureTimedOut.Visibility = Visibility.Collapsed;
- MfaRequired.Visibility = Visibility.Collapsed;
- available = _identity.Services.Count;
- ToggleSwitch.Enabled = _identity.IsEnabled;
- ServiceCountAreaLabel.Content = "services";
- ServiceCount.Content = _identity.Services.Count.ToString();
- MainArea.Opacity = 1.0;
- ServiceCountArea.Visibility = Visibility.Visible;
- ServiceCountAreaLabel.Content = "services";
- // logger.Info("RefreshUI " + _identity.Name + " MFA: "+ _identity.IsMFAEnabled+" Authenticated: "+_identity.IsAuthenticated);
-
- ServiceCount.Content = _identity.Services.Count.ToString();
- if (_identity.IsMFAEnabled) {
- if (_identity.IsMFANeeded) {
- // enabled and needed = needs to be authorized. show the lock icon and tell the user to auth
- MFAEnabledAndNeeded();
- } else {
- // enabled and not needed = authorized. show the services should be enabled and authorized
- MFAEnabledAndNotNeeded();
- }
- } else {
- if (_identity.IsMFANeeded) {
- // not enabled and needed = show the user the MFA disabled so they can enable it
- MFANotEnabledAndNeeded();
- } else {
- // normal case. means no lock icon needs to be shown
- MFANotEnabledAndNotNeeded();
- }
- }
-
- IdName.Content = _identity.Name;
- IdUrl.Content = _identity.ControllerUrl;
- if (_identity.ContollerVersion != null && _identity.ContollerVersion.Length > 0) IdUrl.Content = _identity.ControllerUrl + " at " + _identity.ContollerVersion;
-
- ToggleStatus.Content = ((ToggleSwitch.Enabled) ? "ENABLED" : "DISABLED");
- }
-
- private void TimingTimerTick(object sender, EventArgs e) {
- available = _identity.Services.Count;
- GetMaxTimeout();
- TimerCountdown.Visibility = Visibility.Collapsed;
- if (countdown>-1) {
- countdown--;
- logger.Trace("CountDown " + countdown + " seconds from identity " + _identity.Name + ".");
- if (countdown > 0) {
- TimeSpan t = TimeSpan.FromSeconds(countdown);
- string answer = t.Seconds + " seconds";
- if (t.Days > 0) answer = t.Days + " days " + t.Hours + " hours " + t.Minutes + " minutes " + t.Seconds + " seconds";
- else {
- if (t.Hours > 0) answer = t.Hours + " hours " + t.Minutes + " minutes " + t.Seconds + " seconds";
- else {
- if (t.Minutes > 0) answer = t.Minutes + " minutes " + t.Seconds + " seconds";
- }
- }
- if (countdown<=1200) {
- ShowTimeout();
-
- if (!_identity.WasNotified) {
- _identity.WasNotified = true;
- _identity.ShowMFAToast("The services for " + _identity.Name + " will start to time out in " + answer);
- }
- }
-
- if (available<_identity.Services.Count) MainArea.ToolTip = (_identity.Services.Count-available) + " of " + _identity.Services.Count + " services have timed out.";
- else MainArea.ToolTip = "Some or all of the services will be timing out in " + answer;
- } else {
- ShowTimeout();
- MainArea.ToolTip = (_identity.Services.Count - available) + " of " + _identity.Services.Count+" services have timed out.";
- ServiceCountAreaLabel.Content = available + "/" + _identity.Services.Count;
- }
- } else {
- ShowTimeout();
- MainArea.ToolTip = "Some or all of the services have timed out.";
- ServiceCountAreaLabel.Content = available + "/" + _identity.Services.Count;
- }
- }
-
- private void ShowTimeout() {
- TimerCountdown.Visibility = Visibility.Visible;
- ServiceCountArea.Visibility = Visibility.Collapsed;
- MfaRequired.Visibility = Visibility.Collapsed;
- ServiceCountAreaLabel.Content = available + "/" + _identity.Services.Count;
- if (!_identity.WasNotified) {
- if (available < _identity.Services.Count) {
- _identity.WasNotified = true;
- _identity.ShowMFAToast((_identity.Services.Count - available) + " of " + _identity.Services.Count + " services have timed out.");
- }
- _identity.IsTimingOut = true;
-
- this.IdentityChanged?.Invoke(_identity);
- }
- }
-
- private void ShowTimedOut() {
- _identity.Mutex.Wait();
- Console.WriteLine(_identity.Mutex.GetHashCode());
- if (!_identity.WasFullNotified) {
- _identity.WasFullNotified = true;
- _identity.ShowMFAToast("All of the services with a timeout set for the identity " + _identity.Name + " have timed out");
- RefreshUI();
- if (_timer != null) _timer.Stop();
- }
- _identity.Mutex.Release();
- }
-
- private void TimerTicked(object sender, EventArgs e) {
- if (countdownComplete > -1) {
- countdownComplete--;
- if (countdownComplete <= 0) ShowTimedOut();
- }
- }
-
- async private void ToggleIdentity(bool on) {
- try {
- if (OnStatusChanged != null) {
- OnStatusChanged(on);
- }
- DataClient client = (DataClient)Application.Current.Properties["ServiceClient"];
- DataStructures.Identity id = await client.IdentityOnOffAsync(_identity.Identifier, on);
- this.Identity.IsEnabled = on;
- if (on) {
- ToggleStatus.Content = "ENABLED";
- } else {
- ToggleStatus.Content = "DISABLED";
- }
- } catch (DataStructures.ServiceException se) {
- MessageBox.Show(se.AdditionalInfo, se.Message);
- } catch (Exception ex) {
- MessageBox.Show("Error", ex.Message);
- }
- }
-
- private void Canvas_MouseEnter(object sender, MouseEventArgs e) {
- OverState.Opacity = 0.2;
- }
-
- private void Canvas_MouseLeave(object sender, MouseEventArgs e) {
- OverState.Opacity = 0;
- }
-
- private void OpenDetails(object sender, MouseButtonEventArgs e) {
- IdentityDetails deets = ((MainWindow)Application.Current.MainWindow).IdentityMenu;
- deets.SelectedIdentity = this;
- deets.Identity = this.Identity;
- }
-
- private void MFAAuthenticate(object sender, MouseButtonEventArgs e) {
- this.Authenticate?.Invoke(_identity);
- }
-
- private void ToggledSwitch(object sender, MouseButtonEventArgs e) {
- ToggleSwitch.Toggle();
- }
-
- private void DoMFAOrOpen(object sender, MouseButtonEventArgs e) {
- if (MfaRequired.Visibility==Visibility.Visible || TimerCountdown.Visibility == Visibility.Visible || PostureTimedOut.Visibility == Visibility.Visible) {
- MFAAuthenticate(sender, e);
- } else {
- OpenDetails(sender, e);
- }
- }
- }
+namespace ZitiDesktopEdge
+{
+ ///
+ /// User Control to list Identities and give status
+ ///
+ public partial class IdentityItem : UserControl
+ {
+
+ private static readonly Logger logger = LogManager.GetCurrentClassLogger();
+ public delegate void StatusChanged(bool attached);
+ public event StatusChanged OnStatusChanged;
+ public delegate void OnAuthenticate(ZitiIdentity identity);
+ public event OnAuthenticate Authenticate;
+ public delegate void OnIdentityChanged(ZitiIdentity identity);
+ public event OnIdentityChanged IdentityChanged;
+ private System.Windows.Forms.Timer _timer;
+ private System.Windows.Forms.Timer _timingTimer;
+ private float countdown = -1;
+ private float countdownComplete = -1;
+ private int available = 0;
+
+ private static SWM.Color mfaOrange = SWM.Color.FromRgb(0xA1, 0x8B, 0x10);
+ private static SWM.Color defaultBlue = SWM.Color.FromRgb(0x00, 0x68, 0xF9);
+ private static SWM.Brush MFANeededBrush = new SWM.SolidColorBrush(mfaOrange);
+ private static SWM.Brush DefaultBrush = new SWM.SolidColorBrush(defaultBlue);
+
+ public ZitiIdentity _identity;
+ public ZitiIdentity Identity
+ {
+ get
+ {
+ return _identity;
+ }
+ set
+ {
+ _identity = value;
+ this.RefreshUI();
+ }
+ }
+
+ ///
+ /// Object constructor, setup the events for the control
+ ///
+ public IdentityItem()
+ {
+ InitializeComponent();
+ ToggleSwitch.OnToggled += ToggleIdentity;
+ }
+
+ public void StopTimers()
+ {
+ _timer?.Stop();
+ _timingTimer?.Stop();
+ }
+
+ public int GetMaxTimeout()
+ {
+ int maxto = -1;
+ for (int i = 0; i < _identity.Services.Count; i++)
+ {
+ ZitiService info = _identity.Services[i];
+
+ if (info.TimeoutCalculated > -1)
+ {
+ if (info.TimeoutCalculated == 0)
+ {
+ available--;
+ }
+ if (info.TimeoutCalculated > maxto) maxto = info.TimeoutCalculated;
+
+ }
+ logger.Trace("Max: " + _identity.Name + " " + maxto + " " + info.Name + " " + info.Timeout + " " + info.TimeoutCalculated + " " + info.TimeoutRemaining + " " + info.TimeUpdated + " " + DateTime.Now);
+ }
+ return maxto;
+ }
+ public int GetMinTimeout()
+ {
+ int minto = int.MaxValue;
+ for (int i = 0; i < _identity.Services.Count; i++)
+ {
+ ZitiService info = _identity.Services[i];
+ if (info.TimeoutCalculated > -1)
+ {
+ if (info.TimeoutCalculated < minto) minto = info.TimeoutCalculated;
+ }
+ // logger.Trace("Min: " + _identity.Name + " " + minto + " " + info.Name + " " + info.Timeout + " " + info.TimeoutCalculated + " " + info.TimeoutRemaining + " " + info.TimeUpdated+" "+ DateTime.Now);
+ }
+ if (minto == int.MaxValue) minto = 0;
+ return minto;
+ }
+
+ private void MFAEnabledAndNeeded()
+ {
+ MfaRequired.Visibility = Visibility.Visible;
+ ServiceCountArea.Visibility = Visibility.Collapsed;
+ MainArea.Opacity = 0.6;
+ ServiceCountAreaLabel.Content = "authorize";
+
+ float maxto = GetMaxTimeout();
+ if (maxto > -1)
+ {
+ if (maxto > 0)
+ {
+ if (_timer != null) _timer.Stop();
+ countdownComplete = maxto;
+ _timer = new System.Windows.Forms.Timer();
+ _timer.Interval = 1000;
+ _timer.Tick += TimerTicked;
+ _timer.Start();
+ logger.Info("Timer Started for full timout in " + maxto + " seconds from identity " + _identity.Name + ".");
+ }
+ else
+ {
+ //if (maxto == 0) ShowTimedOut();
+ }
+ }
+ float minto = GetMinTimeout();
+ logger.Info("Min/Max For " + _identity.Name + " " + minto + " " + maxto);
+ if (minto > -1)
+ {
+ if (minto > 0)
+ {
+ if (_timingTimer != null) _timingTimer.Stop();
+ countdown = minto;
+ _timingTimer = new System.Windows.Forms.Timer();
+ _timingTimer.Interval = 1000;
+ _timingTimer.Tick += TimingTimerTick;
+ _timingTimer.Start();
+ logger.Info("Timer Started for first timout in " + minto + " seconds from identity " + _identity.Name + " value with " + _identity.MinTimeout + ".");
+ }
+ else
+ {
+ if (maxto > 0)
+ {
+ ShowTimeout();
+ }
+ }
+ }
+ logger.Info("RefreshUI " + _identity.Name + " Min: " + minto + " Max: " + maxto);
+ }
+
+ private void MFAEnabledAndNotNeeded()
+ {
+ if (_identity.IsTimedOut)
+ {
+ PostureTimedOut.Visibility = Visibility.Visible;
+ ServiceCountAreaLabel.Content = "authorize2";
+ MainArea.Opacity = 1.0;
+ }
+ else
+ {
+ //MfaRequired.Visibility = Visibility.Visible;
+ //ServiceCountAreaLabel.Content = "authenticate1";
+ //MainArea.Opacity = 0.6;
+ MfaRequired.Visibility = Visibility.Collapsed;
+ }
+ ServiceCountBorder.Background = DefaultBrush;
+ }
+
+ private void MFANotEnabledAndNotNeeded()
+ {
+ ServiceCountAreaLabel.Content = "services";
+ MainArea.Opacity = 1.0;
+ }
+
+ private void MFANotEnabledAndNeeded()
+ {
+ ServiceCount.Content = "MFA";
+ ServiceCountBorder.Background = MFANeededBrush;
+ ServiceCountAreaLabel.Content = "disabled";
+ }
+
+ public void RefreshUI()
+ {
+ if (_identity.IsConnected)
+ {
+ this.IsEnabled = true;
+ this.Opacity = 1.0;
+ }
+ else
+ {
+ this.IsEnabled = false;
+ this.Opacity = 0.3;
+ }
+ TimerCountdown.Visibility = Visibility.Collapsed;
+ PostureTimedOut.Visibility = Visibility.Collapsed;
+ MfaRequired.Visibility = Visibility.Collapsed;
+ available = _identity.Services.Count;
+ ToggleSwitch.Enabled = _identity.IsEnabled;
+ ServiceCountAreaLabel.Content = "services";
+ ServiceCount.Content = _identity.Services.Count.ToString();
+ MainArea.Opacity = 1.0;
+ ServiceCountArea.Visibility = Visibility.Visible;
+ ServiceCountAreaLabel.Content = "services";
+ // logger.Info("RefreshUI " + _identity.Name + " MFA: "+ _identity.IsMFAEnabled+" Authenticated: "+_identity.IsAuthenticated);
+
+ ServiceCount.Content = _identity.Services.Count.ToString();
+ if (_identity.IsMFAEnabled)
+ {
+ if (_identity.IsMFANeeded)
+ {
+ // enabled and needed = needs to be authorized. show the lock icon and tell the user to auth
+ MFAEnabledAndNeeded();
+ }
+ else
+ {
+ // enabled and not needed = authorized. show the services should be enabled and authorized
+ MFAEnabledAndNotNeeded();
+ }
+ }
+ else
+ {
+ if (_identity.IsMFANeeded)
+ {
+ // not enabled and needed = show the user the MFA disabled so they can enable it
+ MFANotEnabledAndNeeded();
+ }
+ else
+ {
+ // normal case. means no lock icon needs to be shown
+ MFANotEnabledAndNotNeeded();
+ }
+ }
+
+ IdName.Content = _identity.Name;
+ IdUrl.Content = _identity.ControllerUrl;
+ if (_identity.ContollerVersion != null && _identity.ContollerVersion.Length > 0) IdUrl.Content = _identity.ControllerUrl + " at " + _identity.ContollerVersion;
+
+ ToggleStatus.Content = ((ToggleSwitch.Enabled) ? "ENABLED" : "DISABLED");
+ }
+
+ private void TimingTimerTick(object sender, EventArgs e)
+ {
+ available = _identity.Services.Count;
+ GetMaxTimeout();
+ TimerCountdown.Visibility = Visibility.Collapsed;
+ if (countdown > -1)
+ {
+ countdown--;
+ logger.Trace("CountDown " + countdown + " seconds from identity " + _identity.Name + ".");
+ if (countdown > 0)
+ {
+ TimeSpan t = TimeSpan.FromSeconds(countdown);
+ string answer = t.Seconds + " seconds";
+ if (t.Days > 0) answer = t.Days + " days " + t.Hours + " hours " + t.Minutes + " minutes " + t.Seconds + " seconds";
+ else
+ {
+ if (t.Hours > 0) answer = t.Hours + " hours " + t.Minutes + " minutes " + t.Seconds + " seconds";
+ else
+ {
+ if (t.Minutes > 0) answer = t.Minutes + " minutes " + t.Seconds + " seconds";
+ }
+ }
+ if (countdown <= 1200)
+ {
+ ShowTimeout();
+
+ if (!_identity.WasNotified)
+ {
+ _identity.WasNotified = true;
+ _identity.ShowMFAToast("The services for " + _identity.Name + " will start to time out in " + answer);
+ }
+ }
+
+ if (available < _identity.Services.Count) MainArea.ToolTip = (_identity.Services.Count - available) + " of " + _identity.Services.Count + " services have timed out.";
+ else MainArea.ToolTip = "Some or all of the services will be timing out in " + answer;
+ }
+ else
+ {
+ ShowTimeout();
+ MainArea.ToolTip = (_identity.Services.Count - available) + " of " + _identity.Services.Count + " services have timed out.";
+ ServiceCountAreaLabel.Content = available + "/" + _identity.Services.Count;
+ }
+ }
+ else
+ {
+ ShowTimeout();
+ MainArea.ToolTip = "Some or all of the services have timed out.";
+ ServiceCountAreaLabel.Content = available + "/" + _identity.Services.Count;
+ }
+ }
+
+ private void ShowTimeout()
+ {
+ TimerCountdown.Visibility = Visibility.Visible;
+ ServiceCountArea.Visibility = Visibility.Collapsed;
+ MfaRequired.Visibility = Visibility.Collapsed;
+ ServiceCountAreaLabel.Content = available + "/" + _identity.Services.Count;
+ if (!_identity.WasNotified)
+ {
+ if (available < _identity.Services.Count)
+ {
+ _identity.WasNotified = true;
+ _identity.ShowMFAToast((_identity.Services.Count - available) + " of " + _identity.Services.Count + " services have timed out.");
+ }
+ _identity.IsTimingOut = true;
+
+ this.IdentityChanged?.Invoke(_identity);
+ }
+ }
+
+ private void ShowTimedOut()
+ {
+ _identity.Mutex.Wait();
+ Console.WriteLine(_identity.Mutex.GetHashCode());
+ if (!_identity.WasFullNotified)
+ {
+ _identity.WasFullNotified = true;
+ _identity.ShowMFAToast("All of the services with a timeout set for the identity " + _identity.Name + " have timed out");
+ RefreshUI();
+ if (_timer != null) _timer.Stop();
+ }
+ _identity.Mutex.Release();
+ }
+
+ private void TimerTicked(object sender, EventArgs e)
+ {
+ if (countdownComplete > -1)
+ {
+ countdownComplete--;
+ if (countdownComplete <= 0) ShowTimedOut();
+ }
+ }
+
+ async private void ToggleIdentity(bool on)
+ {
+ try
+ {
+ if (OnStatusChanged != null)
+ {
+ OnStatusChanged(on);
+ }
+ DataClient client = (DataClient)Application.Current.Properties["ServiceClient"];
+ DataStructures.Identity id = await client.IdentityOnOffAsync(_identity.Identifier, on);
+ this.Identity.IsEnabled = on;
+ if (on)
+ {
+ ToggleStatus.Content = "ENABLED";
+ }
+ else
+ {
+ ToggleStatus.Content = "DISABLED";
+ }
+ }
+ catch (DataStructures.ServiceException se)
+ {
+ MessageBox.Show(se.AdditionalInfo, se.Message);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show("Error", ex.Message);
+ }
+ }
+
+ private void Canvas_MouseEnter(object sender, MouseEventArgs e)
+ {
+ OverState.Opacity = 0.2;
+ }
+
+ private void Canvas_MouseLeave(object sender, MouseEventArgs e)
+ {
+ OverState.Opacity = 0;
+ }
+
+ private void OpenDetails(object sender, MouseButtonEventArgs e)
+ {
+ IdentityDetails deets = ((MainWindow)Application.Current.MainWindow).IdentityMenu;
+ deets.SelectedIdentity = this;
+ deets.Identity = this.Identity;
+ }
+
+ private void MFAAuthenticate(object sender, MouseButtonEventArgs e)
+ {
+ this.Authenticate?.Invoke(_identity);
+ }
+
+ private void ToggledSwitch(object sender, MouseButtonEventArgs e)
+ {
+ ToggleSwitch.Toggle();
+ }
+
+ private void DoMFAOrOpen(object sender, MouseButtonEventArgs e)
+ {
+ if (MfaRequired.Visibility == Visibility.Visible || TimerCountdown.Visibility == Visibility.Visible || PostureTimedOut.Visibility == Visibility.Visible)
+ {
+ MFAAuthenticate(sender, e);
+ }
+ else
+ {
+ OpenDetails(sender, e);
+ }
+ }
+ }
}
diff --git a/DesktopEdge/Views/ItemRenderers/MenuEditItem.xaml.cs b/DesktopEdge/Views/ItemRenderers/MenuEditItem.xaml.cs
index 243cb4c94..6ef94f654 100644
--- a/DesktopEdge/Views/ItemRenderers/MenuEditItem.xaml.cs
+++ b/DesktopEdge/Views/ItemRenderers/MenuEditItem.xaml.cs
@@ -1,60 +1,73 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
-
-namespace ZitiDesktopEdge {
- ///
- /// Interaction logic for MenuItem.xaml
- ///
- public partial class MenuEditItem: UserControl {
-
- private string _label = "";
-
- public string Label {
- get {
- return _label;
- }
- set {
- this._label = value;
- MainLabel.Text = this._label;
- }
- }
- public string Value {
- get {
- return MainEdit.Text;
- }
- set {
- MainEdit.Text = value;
- }
- }
- public bool IsLocked {
- get {
- return MainEdit.IsReadOnly;
- }
- set {
- MainEdit.IsReadOnly = value;
- }
- }
-
- public MenuEditItem() {
- InitializeComponent();
- }
-
- private void MainEdit_PreviewMouseUp(object sender, MouseButtonEventArgs e) {
- var textbox = (sender as TextBox);
- textbox.SelectAll();
-
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace ZitiDesktopEdge
+{
+ ///
+ /// Interaction logic for MenuItem.xaml
+ ///
+ public partial class MenuEditItem : UserControl
+ {
+
+ private string _label = "";
+
+ public string Label
+ {
+ get
+ {
+ return _label;
+ }
+ set
+ {
+ this._label = value;
+ MainLabel.Text = this._label;
+ }
+ }
+ public string Value
+ {
+ get
+ {
+ return MainEdit.Text;
+ }
+ set
+ {
+ MainEdit.Text = value;
+ }
+ }
+ public bool IsLocked
+ {
+ get
+ {
+ return MainEdit.IsReadOnly;
+ }
+ set
+ {
+ MainEdit.IsReadOnly = value;
+ }
+ }
+
+ public MenuEditItem()
+ {
+ InitializeComponent();
+ }
+
+ private void MainEdit_PreviewMouseUp(object sender, MouseButtonEventArgs e)
+ {
+ var textbox = (sender as TextBox);
+ textbox.SelectAll();
+
+ }
+ }
+}
diff --git a/DesktopEdge/Views/ItemRenderers/MenuEditSearch.xaml.cs b/DesktopEdge/Views/ItemRenderers/MenuEditSearch.xaml.cs
index 78f8edd09..bfc1f1e33 100644
--- a/DesktopEdge/Views/ItemRenderers/MenuEditSearch.xaml.cs
+++ b/DesktopEdge/Views/ItemRenderers/MenuEditSearch.xaml.cs
@@ -1,70 +1,85 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
-
-namespace ZitiDesktopEdge {
- ///
- /// Interaction logic for MenuItem.xaml
- ///
- public partial class MenuEditSearch : UserControl {
-
- public delegate void OnFilter(string filter);
- public event OnFilter Filter;
-
- private string _label = "";
-
- public string Label {
- get {
- return _label;
- }
- set {
- this._label = value;
- MainLabel.Text = this._label;
- }
- }
- public string Value {
- get {
- return MainEdit.Text;
- }
- set {
- MainEdit.Text = value;
- }
- }
-
- public MenuEditSearch() {
- InitializeComponent();
- }
-
- private void MainEdit_KeyUp(object sender, KeyEventArgs e) {
- if (MainEdit.Text.Trim().Length>0) {
- ClearButton.Content = "clear";
- } else {
- ClearButton.Content = "search";
- }
- Filter(MainEdit.Text);
- }
-
- private void Label_MouseUp(object sender, MouseButtonEventArgs e) {
- MainEdit.Text = "";
- ClearButton.Content = "search";
- Filter(MainEdit.Text);
- }
-
- public void Clear() {
- MainEdit.Text = "";
- ClearButton.Content = "search";
- Filter(MainEdit.Text);
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace ZitiDesktopEdge
+{
+ ///
+ /// Interaction logic for MenuItem.xaml
+ ///
+ public partial class MenuEditSearch : UserControl
+ {
+
+ public delegate void OnFilter(string filter);
+ public event OnFilter Filter;
+
+ private string _label = "";
+
+ public string Label
+ {
+ get
+ {
+ return _label;
+ }
+ set
+ {
+ this._label = value;
+ MainLabel.Text = this._label;
+ }
+ }
+ public string Value
+ {
+ get
+ {
+ return MainEdit.Text;
+ }
+ set
+ {
+ MainEdit.Text = value;
+ }
+ }
+
+ public MenuEditSearch()
+ {
+ InitializeComponent();
+ }
+
+ private void MainEdit_KeyUp(object sender, KeyEventArgs e)
+ {
+ if (MainEdit.Text.Trim().Length > 0)
+ {
+ ClearButton.Content = "clear";
+ }
+ else
+ {
+ ClearButton.Content = "search";
+ }
+ Filter(MainEdit.Text);
+ }
+
+ private void Label_MouseUp(object sender, MouseButtonEventArgs e)
+ {
+ MainEdit.Text = "";
+ ClearButton.Content = "search";
+ Filter(MainEdit.Text);
+ }
+
+ public void Clear()
+ {
+ MainEdit.Text = "";
+ ClearButton.Content = "search";
+ Filter(MainEdit.Text);
+ }
+ }
+}
diff --git a/DesktopEdge/Views/ItemRenderers/MenuEditToggle.xaml.cs b/DesktopEdge/Views/ItemRenderers/MenuEditToggle.xaml.cs
index ffbc2da07..9cc8b1cae 100644
--- a/DesktopEdge/Views/ItemRenderers/MenuEditToggle.xaml.cs
+++ b/DesktopEdge/Views/ItemRenderers/MenuEditToggle.xaml.cs
@@ -1,78 +1,93 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
-using ZitiDesktopEdge.Models;
-using ZitiDesktopEdge.ServiceClient;
-
-namespace ZitiDesktopEdge {
- ///
- /// Interaction logic for MenuItem.xaml
- ///
- public partial class MenuEditToggle: UserControl {
-
- public delegate void OnToggle(bool isOn);
- public event OnToggle Toggle;
- public delegate void OnAuthenticate();
- public event OnAuthenticate Authenticate;
- public delegate void OnRecovery();
- public event OnRecovery Recovery;
- private ZitiIdentity _identity;
-
- private string _label = "";
-
- public string Label {
- get {
- return _label;
- }
- set {
- this._label = value;
- this.MainLabel.Text = this._label;
- }
- }
- public bool IsOn {
- get {
- return ToggleField.Enabled;
- }
- set {
- ToggleField.Enabled = value;
- }
- }
-
- public ZitiIdentity Identity {
- get {
- return _identity;
- }
- set {
- _identity = value;
- }
- }
-
- public MenuEditToggle() {
- InitializeComponent();
- }
-
- public void Toggled(Boolean isOn) {
- this.ToggleField.Enabled = isOn;
- this.Toggle?.Invoke(isOn);
- }
-
- private void MFAAuthenticate(object sender, MouseButtonEventArgs e) {
- this.Authenticate?.Invoke();
- }
-
- private void MFARecovery(object sender, MouseButtonEventArgs e) {
- this.Recovery?.Invoke();
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using ZitiDesktopEdge.Models;
+using ZitiDesktopEdge.ServiceClient;
+
+namespace ZitiDesktopEdge
+{
+ ///
+ /// Interaction logic for MenuItem.xaml
+ ///
+ public partial class MenuEditToggle : UserControl
+ {
+
+ public delegate void OnToggle(bool isOn);
+ public event OnToggle Toggle;
+ public delegate void OnAuthenticate();
+ public event OnAuthenticate Authenticate;
+ public delegate void OnRecovery();
+ public event OnRecovery Recovery;
+ private ZitiIdentity _identity;
+
+ private string _label = "";
+
+ public string Label
+ {
+ get
+ {
+ return _label;
+ }
+ set
+ {
+ this._label = value;
+ this.MainLabel.Text = this._label;
+ }
+ }
+ public bool IsOn
+ {
+ get
+ {
+ return ToggleField.Enabled;
+ }
+ set
+ {
+ ToggleField.Enabled = value;
+ }
+ }
+
+ public ZitiIdentity Identity
+ {
+ get
+ {
+ return _identity;
+ }
+ set
+ {
+ _identity = value;
+ }
+ }
+
+ public MenuEditToggle()
+ {
+ InitializeComponent();
+ }
+
+ public void Toggled(Boolean isOn)
+ {
+ this.ToggleField.Enabled = isOn;
+ this.Toggle?.Invoke(isOn);
+ }
+
+ private void MFAAuthenticate(object sender, MouseButtonEventArgs e)
+ {
+ this.Authenticate?.Invoke();
+ }
+
+ private void MFARecovery(object sender, MouseButtonEventArgs e)
+ {
+ this.Recovery?.Invoke();
+ }
+ }
+}
diff --git a/DesktopEdge/Views/ItemRenderers/MenuIdentityItem.xaml.cs b/DesktopEdge/Views/ItemRenderers/MenuIdentityItem.xaml.cs
index 0b72af20e..1314d6e2c 100644
--- a/DesktopEdge/Views/ItemRenderers/MenuIdentityItem.xaml.cs
+++ b/DesktopEdge/Views/ItemRenderers/MenuIdentityItem.xaml.cs
@@ -1,70 +1,86 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
-using ZitiDesktopEdge.Models;
-using ZitiDesktopEdge.DataStructures;
-using ZitiDesktopEdge.ServiceClient;
-
-namespace ZitiDesktopEdge {
- ///
- /// Interaction logic for MenuItem.xaml
- ///
- public partial class MenuIdentityItem : UserControl {
-
- private string _label = "";
- private ZitiIdentity _identity;
-
- public string Label {
- get {
- return _label;
- }
- set {
- this._label = value;
- MainLabel.Text = this._label;
- }
- }
-
- public ZitiIdentity Identity {
- get {
- return _identity;
- }
- set {
- _identity = value;
- }
- }
-
- public MenuIdentityItem() {
- InitializeComponent();
- ToggleSwitch.OnToggled += ToggleIdentity;
- }
-
- async private void ToggleIdentity(bool on) {
- try {
- DataClient client = (DataClient)Application.Current.Properties["ServiceClient"];
- DataStructures.Identity id = await client.IdentityOnOffAsync(_identity.Identifier, on);
- this.Identity.IsEnabled = on;
- } catch (DataStructures.ServiceException se) {
- MessageBox.Show(se.AdditionalInfo, se.Message);
- } catch (Exception ex) {
- MessageBox.Show("Error", ex.Message);
- }
- }
-
- private void ShowIdentity(object sender, MouseButtonEventArgs e) {
- IdentityDetails deets = ((MainWindow)Application.Current.MainWindow).IdentityMenu;
- deets.SelectedIdentityMenu = this;
- deets.Identity = this.Identity;
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using ZitiDesktopEdge.Models;
+using ZitiDesktopEdge.DataStructures;
+using ZitiDesktopEdge.ServiceClient;
+
+namespace ZitiDesktopEdge
+{
+ ///
+ /// Interaction logic for MenuItem.xaml
+ ///
+ public partial class MenuIdentityItem : UserControl
+ {
+
+ private string _label = "";
+ private ZitiIdentity _identity;
+
+ public string Label
+ {
+ get
+ {
+ return _label;
+ }
+ set
+ {
+ this._label = value;
+ MainLabel.Text = this._label;
+ }
+ }
+
+ public ZitiIdentity Identity
+ {
+ get
+ {
+ return _identity;
+ }
+ set
+ {
+ _identity = value;
+ }
+ }
+
+ public MenuIdentityItem()
+ {
+ InitializeComponent();
+ ToggleSwitch.OnToggled += ToggleIdentity;
+ }
+
+ async private void ToggleIdentity(bool on)
+ {
+ try
+ {
+ DataClient client = (DataClient)Application.Current.Properties["ServiceClient"];
+ DataStructures.Identity id = await client.IdentityOnOffAsync(_identity.Identifier, on);
+ this.Identity.IsEnabled = on;
+ }
+ catch (DataStructures.ServiceException se)
+ {
+ MessageBox.Show(se.AdditionalInfo, se.Message);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show("Error", ex.Message);
+ }
+ }
+
+ private void ShowIdentity(object sender, MouseButtonEventArgs e)
+ {
+ IdentityDetails deets = ((MainWindow)Application.Current.MainWindow).IdentityMenu;
+ deets.SelectedIdentityMenu = this;
+ deets.Identity = this.Identity;
+ }
+ }
+}
diff --git a/DesktopEdge/Views/ItemRenderers/MenuItem.xaml.cs b/DesktopEdge/Views/ItemRenderers/MenuItem.xaml.cs
index dd4da3c37..c256a957b 100644
--- a/DesktopEdge/Views/ItemRenderers/MenuItem.xaml.cs
+++ b/DesktopEdge/Views/ItemRenderers/MenuItem.xaml.cs
@@ -1,56 +1,67 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
-
-namespace ZitiDesktopEdge {
- ///
- /// Interaction logic for MenuItem.xaml
- ///
- public partial class MenuItem : UserControl {
-
- private string _label = "";
- private string _icon = "";
-
- public string Label {
- get {
- return _label;
- }
- set {
- this._label = value;
- MainLabel.Content = this._label;
- }
- }
- public string Icon {
- get {
- return _icon;
- }
- set {
- this._icon = value;
- MainSource.Source = new BitmapImage(new Uri(this._icon, UriKind.Relative));
- }
- }
-
- public MenuItem() {
- InitializeComponent();
- }
-
- private void UserControl_MouseEnter(object sender, MouseEventArgs e) {
-
- }
-
- private void UserControl_MouseLeave(object sender, MouseEventArgs e) {
-
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace ZitiDesktopEdge
+{
+ ///
+ /// Interaction logic for MenuItem.xaml
+ ///
+ public partial class MenuItem : UserControl
+ {
+
+ private string _label = "";
+ private string _icon = "";
+
+ public string Label
+ {
+ get
+ {
+ return _label;
+ }
+ set
+ {
+ this._label = value;
+ MainLabel.Content = this._label;
+ }
+ }
+ public string Icon
+ {
+ get
+ {
+ return _icon;
+ }
+ set
+ {
+ this._icon = value;
+ MainSource.Source = new BitmapImage(new Uri(this._icon, UriKind.Relative));
+ }
+ }
+
+ public MenuItem()
+ {
+ InitializeComponent();
+ }
+
+ private void UserControl_MouseEnter(object sender, MouseEventArgs e)
+ {
+
+ }
+
+ private void UserControl_MouseLeave(object sender, MouseEventArgs e)
+ {
+
+ }
+ }
+}
diff --git a/DesktopEdge/Views/ItemRenderers/SubMenuItem.xaml.cs b/DesktopEdge/Views/ItemRenderers/SubMenuItem.xaml.cs
index 5c9de79e5..d08b56d00 100644
--- a/DesktopEdge/Views/ItemRenderers/SubMenuItem.xaml.cs
+++ b/DesktopEdge/Views/ItemRenderers/SubMenuItem.xaml.cs
@@ -1,38 +1,44 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
-
-namespace ZitiDesktopEdge {
- ///
- /// Interaction logic for MenuItem.xaml
- ///
- public partial class SubMenuItem : UserControl {
-
- private string _label = "";
-
- public string Label {
- get {
- return _label;
- }
- set {
- this._label = value;
- MainLabel.Content = this._label;
- }
- }
-
- public SubMenuItem() {
- InitializeComponent();
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace ZitiDesktopEdge
+{
+ ///
+ /// Interaction logic for MenuItem.xaml
+ ///
+ public partial class SubMenuItem : UserControl
+ {
+
+ private string _label = "";
+
+ public string Label
+ {
+ get
+ {
+ return _label;
+ }
+ set
+ {
+ this._label = value;
+ MainLabel.Content = this._label;
+ }
+ }
+
+ public SubMenuItem()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/DesktopEdge/Views/ItemRenderers/SubOptionItem.xaml.cs b/DesktopEdge/Views/ItemRenderers/SubOptionItem.xaml.cs
index 8a4467e82..0b7d91fc3 100644
--- a/DesktopEdge/Views/ItemRenderers/SubOptionItem.xaml.cs
+++ b/DesktopEdge/Views/ItemRenderers/SubOptionItem.xaml.cs
@@ -1,50 +1,59 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
-
-namespace ZitiDesktopEdge {
- ///
- /// Interaction logic for MenuItem.xaml
- ///
- public partial class SubOptionItem : UserControl {
-
- private string _label = "";
- private bool _isSelected = false;
-
- public string Label {
- get {
- return _label;
- }
- set {
- this._label = value;
- MainLabel.Content = this._label;
- }
- }
-
- public bool IsSelected {
- get {
- return _isSelected;
- }
- set {
- this._isSelected = value;
- if (this._isSelected) SelectedCheck.Visibility = Visibility.Visible;
- else SelectedCheck.Visibility = Visibility.Collapsed;
- }
- }
-
- public SubOptionItem() {
- InitializeComponent();
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace ZitiDesktopEdge
+{
+ ///
+ /// Interaction logic for MenuItem.xaml
+ ///
+ public partial class SubOptionItem : UserControl
+ {
+
+ private string _label = "";
+ private bool _isSelected = false;
+
+ public string Label
+ {
+ get
+ {
+ return _label;
+ }
+ set
+ {
+ this._label = value;
+ MainLabel.Content = this._label;
+ }
+ }
+
+ public bool IsSelected
+ {
+ get
+ {
+ return _isSelected;
+ }
+ set
+ {
+ this._isSelected = value;
+ if (this._isSelected) SelectedCheck.Visibility = Visibility.Visible;
+ else SelectedCheck.Visibility = Visibility.Collapsed;
+ }
+ }
+
+ public SubOptionItem()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/DesktopEdge/Views/Screens/Debugging.xaml.cs b/DesktopEdge/Views/Screens/Debugging.xaml.cs
index fcab8199c..fe0caa1f8 100644
--- a/DesktopEdge/Views/Screens/Debugging.xaml.cs
+++ b/DesktopEdge/Views/Screens/Debugging.xaml.cs
@@ -1,20 +1,20 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-using System;
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -30,37 +30,46 @@ limitations under the License.
using System.Windows.Shapes;
using ZitiDesktopEdge.ServiceClient;
-namespace Ziti.Desktop.Edge.Views.Screens {
+namespace Ziti.Desktop.Edge.Views.Screens
+{
///
/// Interaction logic for Debugging.xaml
///
- public partial class Debugging : UserControl {
+ public partial class Debugging : UserControl
+ {
DataClient client = null;
- public Debugging() {
+ public Debugging()
+ {
InitializeComponent();
}
- async private void btn1_Click(object sender, RoutedEventArgs e) {
+ async private void btn1_Click(object sender, RoutedEventArgs e)
+ {
await client.EnableMFA(FingerPrint.Text);
}
- async private void btn2_Click(object sender, RoutedEventArgs e) {
+ async private void btn2_Click(object sender, RoutedEventArgs e)
+ {
await client.VerifyMFA(FingerPrint.Text, TheMFACode.Text);
}
- async private void btn3_Click(object sender, RoutedEventArgs e) {
+ async private void btn3_Click(object sender, RoutedEventArgs e)
+ {
await client.AuthMFA(FingerPrint.Text, TheMFACode.Text);
}
- async private void btn4_Click(object sender, RoutedEventArgs e) {
+ async private void btn4_Click(object sender, RoutedEventArgs e)
+ {
await client.RemoveMFA(FingerPrint.Text, TheMFACode.Text);
}
bool initialized = false;
- private void UserControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) {
- if (!initialized) {
+ private void UserControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
+ {
+ if (!initialized)
+ {
initialized = true;
client = (DataClient)Application.Current.Properties["ServiceClient"];
client.OnMfaEvent += Client_OnMfaEvent;
@@ -68,28 +77,36 @@ private void UserControl_IsVisibleChanged(object sender, DependencyPropertyChang
}
}
- private void Client_OnCommunicationError(object sender, Exception e) {
+ private void Client_OnCommunicationError(object sender, Exception e)
+ {
MessageBox.Show("debug error: " + e.Message);
}
- private void Client_OnMfaEvent(object sender, ZitiDesktopEdge.DataStructures.MfaEvent mfa) {
- this.Dispatcher.Invoke(() => {
+ private void Client_OnMfaEvent(object sender, ZitiDesktopEdge.DataStructures.MfaEvent mfa)
+ {
+ this.Dispatcher.Invoke(() =>
+ {
MfaActionOp.Text = mfa.Action + " - " + mfa.Op;
MfaIsVerified.Text = "verified: " + mfa.Successful;
MfaProvisioningUrl.Text = mfa.ProvisioningUrl;
- if (mfa.RecoveryCodes != null) {
+ if (mfa.RecoveryCodes != null)
+ {
MfaRecoveryCodes.Text = string.Join(",", mfa.RecoveryCodes);
- } else {
+ }
+ else
+ {
MfaRecoveryCodes.Text = "";
}
});
}
- async private void btn5_Click(object sender, RoutedEventArgs e) {
+ async private void btn5_Click(object sender, RoutedEventArgs e)
+ {
await client.GetMFACodes(FingerPrint.Text, TheMFACode.Text);
}
- async private void btn6_Click(object sender, RoutedEventArgs e) {
+ async private void btn6_Click(object sender, RoutedEventArgs e)
+ {
await client.GenerateMFACodes(FingerPrint.Text, TheMFACode.Text);
}
}
diff --git a/DesktopEdge/Views/Screens/IdentityDetails.xaml.cs b/DesktopEdge/Views/Screens/IdentityDetails.xaml.cs
index ba4336e54..fde924ccc 100644
--- a/DesktopEdge/Views/Screens/IdentityDetails.xaml.cs
+++ b/DesktopEdge/Views/Screens/IdentityDetails.xaml.cs
@@ -1,20 +1,20 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-using System;
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
@@ -31,530 +31,633 @@ limitations under the License.
using System.Windows.Data;
using System.Diagnostics.Eventing.Reader;
-namespace ZitiDesktopEdge {
- ///
- /// Interaction logic for IdentityDetails.xaml
- ///
- public partial class IdentityDetails:UserControl {
- private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
-
- private bool _isAttached = true;
- public delegate void Forgot(ZitiIdentity forgotten);
- public event Forgot OnForgot;
- public delegate void ErrorOccurred(string message);
- public event ErrorOccurred OnError;
- public delegate void MFAToggled(bool isOn);
- public event MFAToggled OnMFAToggled;
- public delegate void Detched(MouseButtonEventArgs e);
- public event Detched OnDetach;
- public delegate void Mesage(string message);
- public event Mesage OnMessage;
- public delegate void OnAuthenticate(ZitiIdentity identity);
- public event OnAuthenticate Authenticate;
- public delegate void OnRecovery(ZitiIdentity identity);
- public event OnRecovery Recovery;
- public delegate void LoadingEvent(bool isComplete);
- public event LoadingEvent OnLoading;
- public delegate void ShowMFAEvent(ZitiIdentity identity);
- public event ShowMFAEvent OnShowMFA;
-
- private System.Windows.Forms.Timer _timer;
- public double MainHeight = 500;
- public string filter = "";
- public int Page = 1;
- public int PerPage = 50;
- public int TotalPages = 1;
- public string SortBy = "Name";
- public string SortWay = "Asc";
- private bool _loaded = false;
- private double scrolledTo = 0;
- public int totalServices = 0;
- private ScrollViewer _scroller;
- private ZitiService _info;
-
- public ObservableCollection _services = new ObservableCollection();
- public ObservableCollection ZitiServices { get { return _services; } }
-
- internal MainWindow MainWindow { get; set; }
-
- private List identities {
- get {
- return (List)Application.Current.Properties["Identities"];
- }
- }
-
- private ZitiIdentity _identity;
-
- public ZitiIdentity Identity {
- get {
- return _identity;
- }
- set {
- _loaded = false;
- FilterServices.Clear();
- scrolledTo = 0;
- _identity = value;
- ServiceCount.Content = _identity.Services.Count + " service"+((_identity.Services.Count!=1)?"s":"");
- Page = 1;
- SortBy = "Name";
- SortWay = "Asc";
- filter = "";
- UpdateView();
- IdentityArea.Opacity = 1.0;
- IdentityArea.Visibility = Visibility.Visible;
- this.Visibility = Visibility.Visible;
- }
- }
-
- public IdentityItem SelectedIdentity { get; set; }
- public MenuIdentityItem SelectedIdentityMenu { get; set; }
-
- private void Window_MouseDown(object sender, MouseButtonEventArgs e) {
- if (e.ChangedButton == MouseButton.Left) {
- _isAttached = false;
- OnDetach(e);
- }
- }
-
-
- public bool IsAttached {
- get {
- return _isAttached;
- }
- set {
- _isAttached = value;
- if (_isAttached) {
- Arrow.Visibility = Visibility.Visible;
- ConfirmArrow.Visibility = Visibility.Visible;
- } else {
- Arrow.Visibility = Visibility.Collapsed;
- ConfirmArrow.Visibility = Visibility.Collapsed;
- }
- }
- }
-
-
- private void MFAEnabledAndNeeded() {
- if (_identity.Services.Count > 0) {
- MainDetailScroll.Visibility = Visibility.Visible;
- } else {
- IdentityMFA.AuthOff.Visibility = Visibility.Visible;
- AuthMessageBg.Visibility = Visibility.Visible;
- AuthMessageLabel.Visibility = Visibility.Visible;
- NoAuthServices.Visibility = Visibility.Visible;
- NoAuthServices.Text = "You must authenticate to access services";
- }
- }
-
- private void MFAEnabledAndNotNeeded() {
- MainDetailScroll.Visibility = Visibility.Visible;
- IdentityMFA.AuthOn.Visibility = Visibility.Visible;
- }
-
- private void MFANotEnabledAndNotNeeded() {
- MainDetailScroll.Visibility = Visibility.Visible;
- }
-
- private void MFANotEnabledAndNeeded() {
- if (_identity.Services.Count > 0) {
- MainDetailScroll.Visibility = Visibility.Visible;
- } else {
- AuthMessageLabel.Visibility = Visibility.Visible;
- NoAuthServices.Visibility = Visibility.Visible;
- NoAuthServices.Text = "You must enable MFA to access services";
- ServiceCount.Visibility = Visibility.Collapsed;
- }
- }
-
- public void UpdateView() {
- if (_scroller==null) {
- _scroller = GetScrollViewer(ServiceList) as ScrollViewer;
- }
- if (_scroller != null) {
- _scroller.InvalidateScrollInfo();
- _scroller.ScrollToVerticalOffset(0);
- _scroller.InvalidateScrollInfo();
- }
-
- IsConnected.Visibility = Visibility.Collapsed;
- IsDisconnected.Visibility = Visibility.Collapsed;
- IsConnected.Visibility = Visibility.Collapsed;
- IsDisconnected.Visibility = Visibility.Collapsed;
- MainDetailScroll.Visibility = Visibility.Collapsed;
- AuthMessageBg.Visibility = Visibility.Collapsed;
- AuthMessageLabel.Visibility = Visibility.Collapsed;
- NoAuthServices.Visibility = Visibility.Collapsed;
- IdentityMFA.AuthOn.Visibility = Visibility.Collapsed;
- IdentityMFA.AuthOff.Visibility = Visibility.Collapsed;
- IdentityMFA.RecoveryButton.Visibility = Visibility.Collapsed;
- ServiceCount.Visibility = Visibility.Visible;
-
- scrolledTo = 0;
- IdDetailName.Text = _identity.Name;
- IdDetailName.ToolTip = _identity.Name;
- IdentityMFA.IsOn = _identity.IsMFAEnabled;
- IdentityMFA.ToggleField.IsEnabled = true;
- IdentityMFA.ToggleField.Opacity = 1;
- IsConnected.ToolTip = "Enabled - Click To Disable";
- IsDisconnected.ToolTip = "Disabled - Click to Enable";
- IdServer.Value = _identity.ControllerUrl;
- IdName.Value = _identity.Name;
+namespace ZitiDesktopEdge
+{
+ ///
+ /// Interaction logic for IdentityDetails.xaml
+ ///
+ public partial class IdentityDetails : UserControl
+ {
+ private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
+
+ private bool _isAttached = true;
+ public delegate void Forgot(ZitiIdentity forgotten);
+ public event Forgot OnForgot;
+ public delegate void ErrorOccurred(string message);
+ public event ErrorOccurred OnError;
+ public delegate void MFAToggled(bool isOn);
+ public event MFAToggled OnMFAToggled;
+ public delegate void Detched(MouseButtonEventArgs e);
+ public event Detched OnDetach;
+ public delegate void Mesage(string message);
+ public event Mesage OnMessage;
+ public delegate void OnAuthenticate(ZitiIdentity identity);
+ public event OnAuthenticate Authenticate;
+ public delegate void OnRecovery(ZitiIdentity identity);
+ public event OnRecovery Recovery;
+ public delegate void LoadingEvent(bool isComplete);
+ public event LoadingEvent OnLoading;
+ public delegate void ShowMFAEvent(ZitiIdentity identity);
+ public event ShowMFAEvent OnShowMFA;
+
+ private System.Windows.Forms.Timer _timer;
+ public double MainHeight = 500;
+ public string filter = "";
+ public int Page = 1;
+ public int PerPage = 50;
+ public int TotalPages = 1;
+ public string SortBy = "Name";
+ public string SortWay = "Asc";
+ private bool _loaded = false;
+ private double scrolledTo = 0;
+ public int totalServices = 0;
+ private ScrollViewer _scroller;
+ private ZitiService _info;
+
+ public ObservableCollection _services = new ObservableCollection();
+ public ObservableCollection ZitiServices { get { return _services; } }
+
+ internal MainWindow MainWindow { get; set; }
+
+ private List identities
+ {
+ get
+ {
+ return (List)Application.Current.Properties["Identities"];
+ }
+ }
+
+ private ZitiIdentity _identity;
+
+ public ZitiIdentity Identity
+ {
+ get
+ {
+ return _identity;
+ }
+ set
+ {
+ _loaded = false;
+ FilterServices.Clear();
+ scrolledTo = 0;
+ _identity = value;
+ ServiceCount.Content = _identity.Services.Count + " service" + ((_identity.Services.Count != 1) ? "s" : "");
+ Page = 1;
+ SortBy = "Name";
+ SortWay = "Asc";
+ filter = "";
+ UpdateView();
+ IdentityArea.Opacity = 1.0;
+ IdentityArea.Visibility = Visibility.Visible;
+ this.Visibility = Visibility.Visible;
+ }
+ }
+
+ public IdentityItem SelectedIdentity { get; set; }
+ public MenuIdentityItem SelectedIdentityMenu { get; set; }
+
+ private void Window_MouseDown(object sender, MouseButtonEventArgs e)
+ {
+ if (e.ChangedButton == MouseButton.Left)
+ {
+ _isAttached = false;
+ OnDetach(e);
+ }
+ }
+
+
+ public bool IsAttached
+ {
+ get
+ {
+ return _isAttached;
+ }
+ set
+ {
+ _isAttached = value;
+ if (_isAttached)
+ {
+ Arrow.Visibility = Visibility.Visible;
+ ConfirmArrow.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ Arrow.Visibility = Visibility.Collapsed;
+ ConfirmArrow.Visibility = Visibility.Collapsed;
+ }
+ }
+ }
+
+
+ private void MFAEnabledAndNeeded()
+ {
+ if (_identity.Services.Count > 0)
+ {
+ MainDetailScroll.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ IdentityMFA.AuthOff.Visibility = Visibility.Visible;
+ AuthMessageBg.Visibility = Visibility.Visible;
+ AuthMessageLabel.Visibility = Visibility.Visible;
+ NoAuthServices.Visibility = Visibility.Visible;
+ NoAuthServices.Text = "You must authenticate to access services";
+ }
+ }
+
+ private void MFAEnabledAndNotNeeded()
+ {
+ MainDetailScroll.Visibility = Visibility.Visible;
+ IdentityMFA.AuthOn.Visibility = Visibility.Visible;
+ }
+
+ private void MFANotEnabledAndNotNeeded()
+ {
+ MainDetailScroll.Visibility = Visibility.Visible;
+ }
+
+ private void MFANotEnabledAndNeeded()
+ {
+ if (_identity.Services.Count > 0)
+ {
+ MainDetailScroll.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ AuthMessageLabel.Visibility = Visibility.Visible;
+ NoAuthServices.Visibility = Visibility.Visible;
+ NoAuthServices.Text = "You must enable MFA to access services";
+ ServiceCount.Visibility = Visibility.Collapsed;
+ }
+ }
+
+ public void UpdateView()
+ {
+ if (_scroller == null)
+ {
+ _scroller = GetScrollViewer(ServiceList) as ScrollViewer;
+ }
+ if (_scroller != null)
+ {
+ _scroller.InvalidateScrollInfo();
+ _scroller.ScrollToVerticalOffset(0);
+ _scroller.InvalidateScrollInfo();
+ }
+
+ IsConnected.Visibility = Visibility.Collapsed;
+ IsDisconnected.Visibility = Visibility.Collapsed;
+ IsConnected.Visibility = Visibility.Collapsed;
+ IsDisconnected.Visibility = Visibility.Collapsed;
+ MainDetailScroll.Visibility = Visibility.Collapsed;
+ AuthMessageBg.Visibility = Visibility.Collapsed;
+ AuthMessageLabel.Visibility = Visibility.Collapsed;
+ NoAuthServices.Visibility = Visibility.Collapsed;
+ IdentityMFA.AuthOn.Visibility = Visibility.Collapsed;
+ IdentityMFA.AuthOff.Visibility = Visibility.Collapsed;
+ IdentityMFA.RecoveryButton.Visibility = Visibility.Collapsed;
+ ServiceCount.Visibility = Visibility.Visible;
+
+ scrolledTo = 0;
+ IdDetailName.Text = _identity.Name;
+ IdDetailName.ToolTip = _identity.Name;
+ IdentityMFA.IsOn = _identity.IsMFAEnabled;
+ IdentityMFA.ToggleField.IsEnabled = true;
+ IdentityMFA.ToggleField.Opacity = 1;
+ IsConnected.ToolTip = "Enabled - Click To Disable";
+ IsDisconnected.ToolTip = "Disabled - Click to Enable";
+ IdServer.Value = _identity.ControllerUrl;
+ IdName.Value = _identity.Name;
#if DEBUG
- _identity.MFADebug("UpdateView");
+ _identity.MFADebug("UpdateView");
#endif
- if (_identity.IsMFAEnabled) {
- if (_identity.IsMFANeeded) {
- // enabled and needed = needs to be authorized. show the lock icon and tell the user to auth
- MFAEnabledAndNeeded();
- } else {
- // enabled and not needed = authorized. show the services should be enabled and authorized
- MFAEnabledAndNotNeeded();
- }
- } else {
- if (_identity.IsMFANeeded) {
- // not enabled and needed = show the user the MFA disabled so they can enable it
- MFANotEnabledAndNeeded();
- } else {
- // normal case. means no lock icon needs to be shown
- MFANotEnabledAndNotNeeded();
- }
- }
-
- //change icon to timed out if it's timed out
-
-
- totalServices = _identity.Services.Count;
-
- if (_identity.Services.Count>0) {
- int index = 0;
- int total = 0;
- ZitiService[] services = new ZitiService[0];
- _services = null;
- _services = new ObservableCollection();
- if (SortBy == "Name") services = _identity.Services.OrderBy(s => s.Name.ToLower()).ToArray();
- else if (SortBy == "Address") services = _identity.Services.OrderBy(s => s.Addresses.ToString()).ToArray();
- else if (SortBy == "Protocol") services = _identity.Services.OrderBy(s => s.Protocols.ToString()).ToArray();
- else if (SortBy == "Port") services = _identity.Services.OrderBy(s => s.Ports.ToString()).ToArray();
- if (SortWay == "Desc") services = services.Reverse().ToArray();
- int startIndex = (Page - 1) * PerPage;
- for (int i = startIndex; i < services.Length; i++) {
- ZitiService zitiSvc = services[i];
- total++;
- if (index < PerPage) {
- if (zitiSvc.Name.ToLower().IndexOf(filter.ToLower()) >= 0 || zitiSvc.ToString().ToLower().IndexOf(filter.ToLower()) >= 0) {
- zitiSvc.TimeUpdated = _identity.LastUpdatedTime;
- zitiSvc.IsMfaReady = _identity.IsMFAEnabled;
- _services.Add(zitiSvc);
- index++;
- }
- }
- }
- ServiceList.ItemsSource = ZitiServices;
-
- TotalPages = (total / PerPage) + 1;
-
- double newHeight = MainHeight - 330;
- MainDetailScroll.MaxHeight = newHeight;
- MainDetailScroll.Height = newHeight;
-
-
- }
- ConfirmView.Visibility = Visibility.Collapsed;
- _loaded = true;
- }
-
- private void ShowDetails(ZitiService info) {
- _info = info;
- DetailName.Text = info.Name;
- DetailProtocols.Text = info.ProtocolString;
- DetailAddress.Text = info.AddressString;
- DetailPorts.Text = info.PortString;
- DetailUrl.Text = info.ToString();
-
- UpdateClock(info);
- if (_identity.IsMFAEnabled) {
- if (_timer != null) _timer.Stop();
- _timer = new System.Windows.Forms.Timer();
- _timer.Interval = 1000;
- _timer.Tick += Ticked; ;
- _timer.Start();
- }
-
- DetailsArea.Visibility = Visibility.Visible;
- DetailsArea.Opacity = 0;
- DetailsArea.Margin = new Thickness(0, 0, 0, 0);
- DoubleAnimation animation = new DoubleAnimation(1, TimeSpan.FromSeconds(.3));
- animation.Completed += ShowCompleted;
- DetailsArea.BeginAnimation(Grid.OpacityProperty, animation);
- DetailsArea.BeginAnimation(Grid.MarginProperty, new ThicknessAnimation(new Thickness(30, 30, 30, 30), TimeSpan.FromSeconds(.3)));
-
- ShowModal();
- }
-
- private void Ticked(object sender, EventArgs e) {
- UpdateClock(_info);
- }
-
- private void UpdateClock(ZitiService info) {
- try {
- if (_identity.IsMFAEnabled) {
- if (info.TimeoutCalculated > 0) {
- TimeSpan t = TimeSpan.FromSeconds(info.TimeoutCalculated);
- string answer = t.Seconds + " seconds";
- if (t.Days > 0) answer = t.Days + " days " + t.Hours + " hours " + t.Minutes + " minutes " + t.Seconds + " seconds";
- else {
- if (t.Hours > 0) answer = t.Hours + " hours " + t.Minutes + " minutes " + t.Seconds + " seconds";
- else {
- if (t.Minutes > 0) answer = t.Minutes + " minutes " + t.Seconds + " seconds";
- }
- }
- TimeoutDetails.Text = answer;
- } else {
- if (info.TimeoutCalculated == 0) TimeoutDetails.Text = "Timed Out";
- else TimeoutDetails.Text = "Never";
- }
- } else {
- TimeoutDetails.Text = "Never";
- }
- } catch (Exception e) {
- TimeoutDetails.Text = "Never";
- Console.WriteLine("Error: " + e.ToString());
- }
- }
-
- private void ShowCompleted(object sender, EventArgs e) {
- DoubleAnimation animation = new DoubleAnimation(DetailPanel.ActualHeight + 60, TimeSpan.FromSeconds(.3));
- DetailsArea.BeginAnimation(Grid.HeightProperty, animation);
- //DetailsArea.Height = DetailPanel.ActualHeight + 60;
- }
-
- private void CloseDetails(object sender, MouseButtonEventArgs e) {
- DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3));
- ThicknessAnimation animateThick = new ThicknessAnimation(new Thickness(0, 0, 0, 0), TimeSpan.FromSeconds(.3));
- DoubleAnimation animation2 = new DoubleAnimation(DetailPanel.ActualHeight + 100, TimeSpan.FromSeconds(.3));
- animation.Completed += HideComplete;
- DetailsArea.BeginAnimation(Grid.HeightProperty, animation2);
- DetailsArea.BeginAnimation(Grid.OpacityProperty, animation);
- DetailsArea.BeginAnimation(Grid.MarginProperty, animateThick);
- HideModal();
- }
-
- private void HideComplete(object sender, EventArgs e) {
- DetailsArea.Visibility = Visibility.Collapsed;
- ModalBg.Visibility = Visibility.Collapsed;
- }
-
- private void Info_OnMessage(string message) {
- OnMessage?.Invoke(message);
- }
-
- public IdentityDetails() {
- InitializeComponent();
- }
- private void HideMenu(object sender, MouseButtonEventArgs e) {
- this.Visibility = Visibility.Collapsed;
- }
-
- public void SetHeight(double height) {
- MainDetailScroll.Height = height;
- }
-
- private void ForgetIdentity(object sender, MouseButtonEventArgs e) {
- if (this.Visibility==Visibility.Visible&&ConfirmView.Visibility==Visibility.Collapsed) {
- ConfirmView.Visibility = Visibility.Visible;
- }
- }
-
- private void CancelConfirmButton_Click(object sender, RoutedEventArgs e) {
- ConfirmView.Visibility = Visibility.Collapsed;
- }
-
- async private void ConfirmButton_Click(object sender, RoutedEventArgs e) {
- this.Visibility = Visibility.Collapsed;
- DataClient client = (DataClient)Application.Current.Properties["ServiceClient"];
- try {
- ConfirmView.Visibility = Visibility.Collapsed;
- await client.RemoveIdentityAsync(_identity.Identifier);
-
- ZitiIdentity forgotten = new ZitiIdentity();
- foreach (var id in identities) {
- if (id.Identifier == _identity.Identifier) {
- forgotten = id;
- identities.Remove(id);
- break;
- }
- }
-
- OnForgot?.Invoke(forgotten);
- } catch (DataStructures.ServiceException se) {
- Logger.Error(se, se.Message);
- OnError(se.Message);
- } catch (Exception ex) {
- Logger.Error(ex, "Unexpected: "+ ex.Message);
- OnError("An unexpected error has occured while removing the identity. Please verify the service is still running and try again.");
- }
- }
-
- private void ToggleMFA(bool isOn) {
- this.OnMFAToggled?.Invoke(isOn);
- }
-
- /* Modal UI Background visibility */
-
- ///
- /// Show the modal, aniimating opacity
- ///
- private void ShowModal() {
- ModalBg.Visibility = Visibility.Visible;
- ModalBg.Opacity = 0;
- ModalBg.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(.8, TimeSpan.FromSeconds(.3)));
- }
-
- ///
- /// Hide the modal animating the opacity
- ///
- private void HideModal() {
- DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3));
- animation.Completed += ModalHideComplete;
- ModalBg.BeginAnimation(Grid.OpacityProperty, animation);
- }
-
- ///
- /// When the animation completes, set the visibility to avoid UI object conflicts
- ///
- /// The animation
- /// The event
- private void ModalHideComplete(object sender, EventArgs e) {
- ModalBg.Visibility = Visibility.Collapsed;
- }
-
- private void MFARecovery() {
- this.Recovery?.Invoke(this.Identity);
- }
-
- private void MFAAuthenticate() {
- this.Authenticate.Invoke(this.Identity);
- }
-
- private void AuthFromMessage(object sender, MouseButtonEventArgs e) {
- this.Authenticate.Invoke(this.Identity);
- }
-
- public static DependencyObject GetScrollViewer(DependencyObject o) {
- if (o is ScrollViewer) { return o; }
- for (int i = 0; i < VisualTreeHelper.GetChildrenCount(o); i++) {
- var child = VisualTreeHelper.GetChild(o, i);
- var result = GetScrollViewer(child);
- if (result == null) {
- continue;
- } else {
- return result;
- }
- }
- return null;
- }
-
- private void Scrolled(object sender, ScrollChangedEventArgs e) {
- if (_loaded) {
- if (_scroller == null) {
- _scroller = GetScrollViewer(ServiceList) as ScrollViewer;
- }
- var verticalOffset = _scroller.VerticalOffset;
- var maxVerticalOffset = _scroller.ScrollableHeight;
-
- if ((maxVerticalOffset < 0 || verticalOffset == maxVerticalOffset) && verticalOffset>0 && scrolledTo s.Name.ToLower()).ToArray();
- else if (SortBy == "Address") services = _identity.Services.OrderBy(s => s.Addresses.ToString()).ToArray();
- else if (SortBy == "Protocol") services = _identity.Services.OrderBy(s => s.Protocols.ToString()).ToArray();
- else if (SortBy == "Port") services = _identity.Services.OrderBy(s => s.Ports.ToString()).ToArray();
- if (SortWay == "Desc") services = services.Reverse().ToArray();
- int startIndex = (Page - 1) * PerPage;
- for (int i = startIndex; i < services.Length; i++) {
- ZitiService zitiSvc = services[i];
- if (index < PerPage) {
- if (zitiSvc.Name.ToLower().IndexOf(filter.ToLower()) >= 0 || zitiSvc.ToString().ToLower().IndexOf(filter.ToLower()) >= 0) {
- zitiSvc.TimeUpdated = _identity.LastUpdatedTime;
- ZitiServices.Add(zitiSvc);
- index++;
- }
- }
- }
- double totalOffset = _scroller.VerticalOffset;
- double toNegate = index * 33;
- double scrollTo = (totalOffset - toNegate);
- _scroller.InvalidateScrollInfo();
- _scroller.ScrollToVerticalOffset(verticalOffset);
- _scroller.InvalidateScrollInfo();
- _loaded = true;
- // scrollViewer.ScrollChanged += Scrolled;
- }
- }
- }
- }
-
- private void DoFilter(FilterData filterData) {
- filter = filterData.SearchFor;
- SortBy = filterData.SortBy;
- SortWay = filterData.SortHow;
- UpdateView();
- }
-
- async private void DoConnect(object sender, MouseButtonEventArgs e) {
- this.OnLoading?.Invoke(false);
- DataClient client = (DataClient)Application.Current.Properties["ServiceClient"];
- await client.IdentityOnOffAsync(_identity.Identifier, true);
- if (SelectedIdentity != null) SelectedIdentity.ToggleSwitch.Enabled = true;
- if (SelectedIdentityMenu != null) SelectedIdentityMenu.ToggleSwitch.Enabled = true;
- _identity.IsEnabled = true;
- IsConnected.Visibility = Visibility.Visible;
- IsDisconnected.Visibility = Visibility.Collapsed;
- this.OnLoading?.Invoke(true);
- }
-
- async private void DoDisconnect(object sender, MouseButtonEventArgs e) {
- this.OnLoading?.Invoke(false);
- DataClient client = (DataClient)Application.Current.Properties["ServiceClient"];
- await client.IdentityOnOffAsync(_identity.Identifier, false);
- if (SelectedIdentity != null) SelectedIdentity.ToggleSwitch.Enabled = false;
- if (SelectedIdentityMenu != null) SelectedIdentityMenu.ToggleSwitch.Enabled = false;
- _identity.IsEnabled = false;
- IsConnected.Visibility = Visibility.Collapsed;
- IsDisconnected.Visibility = Visibility.Visible;
- this.OnLoading?.Invoke(true);
- }
-
- private void WarnClicked(object sender, MouseButtonEventArgs e) {
- ZitiService item = (ZitiService)(sender as FrameworkElement).DataContext;
- OnMessage?.Invoke(item.WarningMessage);
- }
-
- private void DetailsClicked(object sender, MouseButtonEventArgs e) {
- ZitiService item = (ZitiService)(sender as FrameworkElement).DataContext;
- ShowDetails(item);
- }
-
- private void VisibilityChanged(object sender, DependencyPropertyChangedEventArgs e) {
- if (this.Visibility==Visibility.Collapsed) {
- ServiceList.DataContext = null;
- if (_services!=null) {
- _services.Clear();
- _services = null;
- }
- }
- }
-
- private void DoMFA(object sender, MouseButtonEventArgs e) {
- this.OnShowMFA?.Invoke(this._identity);
- }
- }
+ if (_identity.IsMFAEnabled)
+ {
+ if (_identity.IsMFANeeded)
+ {
+ // enabled and needed = needs to be authorized. show the lock icon and tell the user to auth
+ MFAEnabledAndNeeded();
+ }
+ else
+ {
+ // enabled and not needed = authorized. show the services should be enabled and authorized
+ MFAEnabledAndNotNeeded();
+ }
+ }
+ else
+ {
+ if (_identity.IsMFANeeded)
+ {
+ // not enabled and needed = show the user the MFA disabled so they can enable it
+ MFANotEnabledAndNeeded();
+ }
+ else
+ {
+ // normal case. means no lock icon needs to be shown
+ MFANotEnabledAndNotNeeded();
+ }
+ }
+
+ //change icon to timed out if it's timed out
+
+
+ totalServices = _identity.Services.Count;
+
+ if (_identity.Services.Count > 0)
+ {
+ int index = 0;
+ int total = 0;
+ ZitiService[] services = new ZitiService[0];
+ _services = null;
+ _services = new ObservableCollection();
+ if (SortBy == "Name") services = _identity.Services.OrderBy(s => s.Name.ToLower()).ToArray();
+ else if (SortBy == "Address") services = _identity.Services.OrderBy(s => s.Addresses.ToString()).ToArray();
+ else if (SortBy == "Protocol") services = _identity.Services.OrderBy(s => s.Protocols.ToString()).ToArray();
+ else if (SortBy == "Port") services = _identity.Services.OrderBy(s => s.Ports.ToString()).ToArray();
+ if (SortWay == "Desc") services = services.Reverse().ToArray();
+ int startIndex = (Page - 1) * PerPage;
+ for (int i = startIndex; i < services.Length; i++)
+ {
+ ZitiService zitiSvc = services[i];
+ total++;
+ if (index < PerPage)
+ {
+ if (zitiSvc.Name.ToLower().IndexOf(filter.ToLower()) >= 0 || zitiSvc.ToString().ToLower().IndexOf(filter.ToLower()) >= 0)
+ {
+ zitiSvc.TimeUpdated = _identity.LastUpdatedTime;
+ zitiSvc.IsMfaReady = _identity.IsMFAEnabled;
+ _services.Add(zitiSvc);
+ index++;
+ }
+ }
+ }
+ ServiceList.ItemsSource = ZitiServices;
+
+ TotalPages = (total / PerPage) + 1;
+
+ double newHeight = MainHeight - 330;
+ MainDetailScroll.MaxHeight = newHeight;
+ MainDetailScroll.Height = newHeight;
+
+
+ }
+ ConfirmView.Visibility = Visibility.Collapsed;
+ _loaded = true;
+ }
+
+ private void ShowDetails(ZitiService info)
+ {
+ _info = info;
+ DetailName.Text = info.Name;
+ DetailProtocols.Text = info.ProtocolString;
+ DetailAddress.Text = info.AddressString;
+ DetailPorts.Text = info.PortString;
+ DetailUrl.Text = info.ToString();
+
+ UpdateClock(info);
+ if (_identity.IsMFAEnabled)
+ {
+ if (_timer != null) _timer.Stop();
+ _timer = new System.Windows.Forms.Timer();
+ _timer.Interval = 1000;
+ _timer.Tick += Ticked; ;
+ _timer.Start();
+ }
+
+ DetailsArea.Visibility = Visibility.Visible;
+ DetailsArea.Opacity = 0;
+ DetailsArea.Margin = new Thickness(0, 0, 0, 0);
+ DoubleAnimation animation = new DoubleAnimation(1, TimeSpan.FromSeconds(.3));
+ animation.Completed += ShowCompleted;
+ DetailsArea.BeginAnimation(Grid.OpacityProperty, animation);
+ DetailsArea.BeginAnimation(Grid.MarginProperty, new ThicknessAnimation(new Thickness(30, 30, 30, 30), TimeSpan.FromSeconds(.3)));
+
+ ShowModal();
+ }
+
+ private void Ticked(object sender, EventArgs e)
+ {
+ UpdateClock(_info);
+ }
+
+ private void UpdateClock(ZitiService info)
+ {
+ try
+ {
+ if (_identity.IsMFAEnabled)
+ {
+ if (info.TimeoutCalculated > 0)
+ {
+ TimeSpan t = TimeSpan.FromSeconds(info.TimeoutCalculated);
+ string answer = t.Seconds + " seconds";
+ if (t.Days > 0) answer = t.Days + " days " + t.Hours + " hours " + t.Minutes + " minutes " + t.Seconds + " seconds";
+ else
+ {
+ if (t.Hours > 0) answer = t.Hours + " hours " + t.Minutes + " minutes " + t.Seconds + " seconds";
+ else
+ {
+ if (t.Minutes > 0) answer = t.Minutes + " minutes " + t.Seconds + " seconds";
+ }
+ }
+ TimeoutDetails.Text = answer;
+ }
+ else
+ {
+ if (info.TimeoutCalculated == 0) TimeoutDetails.Text = "Timed Out";
+ else TimeoutDetails.Text = "Never";
+ }
+ }
+ else
+ {
+ TimeoutDetails.Text = "Never";
+ }
+ }
+ catch (Exception e)
+ {
+ TimeoutDetails.Text = "Never";
+ Console.WriteLine("Error: " + e.ToString());
+ }
+ }
+
+ private void ShowCompleted(object sender, EventArgs e)
+ {
+ DoubleAnimation animation = new DoubleAnimation(DetailPanel.ActualHeight + 60, TimeSpan.FromSeconds(.3));
+ DetailsArea.BeginAnimation(Grid.HeightProperty, animation);
+ //DetailsArea.Height = DetailPanel.ActualHeight + 60;
+ }
+
+ private void CloseDetails(object sender, MouseButtonEventArgs e)
+ {
+ DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3));
+ ThicknessAnimation animateThick = new ThicknessAnimation(new Thickness(0, 0, 0, 0), TimeSpan.FromSeconds(.3));
+ DoubleAnimation animation2 = new DoubleAnimation(DetailPanel.ActualHeight + 100, TimeSpan.FromSeconds(.3));
+ animation.Completed += HideComplete;
+ DetailsArea.BeginAnimation(Grid.HeightProperty, animation2);
+ DetailsArea.BeginAnimation(Grid.OpacityProperty, animation);
+ DetailsArea.BeginAnimation(Grid.MarginProperty, animateThick);
+ HideModal();
+ }
+
+ private void HideComplete(object sender, EventArgs e)
+ {
+ DetailsArea.Visibility = Visibility.Collapsed;
+ ModalBg.Visibility = Visibility.Collapsed;
+ }
+
+ private void Info_OnMessage(string message)
+ {
+ OnMessage?.Invoke(message);
+ }
+
+ public IdentityDetails()
+ {
+ InitializeComponent();
+ }
+ private void HideMenu(object sender, MouseButtonEventArgs e)
+ {
+ this.Visibility = Visibility.Collapsed;
+ }
+
+ public void SetHeight(double height)
+ {
+ MainDetailScroll.Height = height;
+ }
+
+ private void ForgetIdentity(object sender, MouseButtonEventArgs e)
+ {
+ if (this.Visibility == Visibility.Visible && ConfirmView.Visibility == Visibility.Collapsed)
+ {
+ ConfirmView.Visibility = Visibility.Visible;
+ }
+ }
+
+ private void CancelConfirmButton_Click(object sender, RoutedEventArgs e)
+ {
+ ConfirmView.Visibility = Visibility.Collapsed;
+ }
+
+ async private void ConfirmButton_Click(object sender, RoutedEventArgs e)
+ {
+ this.Visibility = Visibility.Collapsed;
+ DataClient client = (DataClient)Application.Current.Properties["ServiceClient"];
+ try
+ {
+ ConfirmView.Visibility = Visibility.Collapsed;
+ await client.RemoveIdentityAsync(_identity.Identifier);
+
+ ZitiIdentity forgotten = new ZitiIdentity();
+ foreach (var id in identities)
+ {
+ if (id.Identifier == _identity.Identifier)
+ {
+ forgotten = id;
+ identities.Remove(id);
+ break;
+ }
+ }
+
+ OnForgot?.Invoke(forgotten);
+ }
+ catch (DataStructures.ServiceException se)
+ {
+ Logger.Error(se, se.Message);
+ OnError(se.Message);
+ }
+ catch (Exception ex)
+ {
+ Logger.Error(ex, "Unexpected: " + ex.Message);
+ OnError("An unexpected error has occured while removing the identity. Please verify the service is still running and try again.");
+ }
+ }
+
+ private void ToggleMFA(bool isOn)
+ {
+ this.OnMFAToggled?.Invoke(isOn);
+ }
+
+ /* Modal UI Background visibility */
+
+ ///
+ /// Show the modal, aniimating opacity
+ ///
+ private void ShowModal()
+ {
+ ModalBg.Visibility = Visibility.Visible;
+ ModalBg.Opacity = 0;
+ ModalBg.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(.8, TimeSpan.FromSeconds(.3)));
+ }
+
+ ///
+ /// Hide the modal animating the opacity
+ ///
+ private void HideModal()
+ {
+ DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3));
+ animation.Completed += ModalHideComplete;
+ ModalBg.BeginAnimation(Grid.OpacityProperty, animation);
+ }
+
+ ///
+ /// When the animation completes, set the visibility to avoid UI object conflicts
+ ///
+ /// The animation
+ /// The event
+ private void ModalHideComplete(object sender, EventArgs e)
+ {
+ ModalBg.Visibility = Visibility.Collapsed;
+ }
+
+ private void MFARecovery()
+ {
+ this.Recovery?.Invoke(this.Identity);
+ }
+
+ private void MFAAuthenticate()
+ {
+ this.Authenticate.Invoke(this.Identity);
+ }
+
+ private void AuthFromMessage(object sender, MouseButtonEventArgs e)
+ {
+ this.Authenticate.Invoke(this.Identity);
+ }
+
+ public static DependencyObject GetScrollViewer(DependencyObject o)
+ {
+ if (o is ScrollViewer) { return o; }
+ for (int i = 0; i < VisualTreeHelper.GetChildrenCount(o); i++)
+ {
+ var child = VisualTreeHelper.GetChild(o, i);
+ var result = GetScrollViewer(child);
+ if (result == null)
+ {
+ continue;
+ }
+ else
+ {
+ return result;
+ }
+ }
+ return null;
+ }
+
+ private void Scrolled(object sender, ScrollChangedEventArgs e)
+ {
+ if (_loaded)
+ {
+ if (_scroller == null)
+ {
+ _scroller = GetScrollViewer(ServiceList) as ScrollViewer;
+ }
+ var verticalOffset = _scroller.VerticalOffset;
+ var maxVerticalOffset = _scroller.ScrollableHeight;
+
+ if ((maxVerticalOffset < 0 || verticalOffset == maxVerticalOffset) && verticalOffset > 0 && scrolledTo < verticalOffset)
+ {
+ if (Page < TotalPages)
+ {
+ scrolledTo = verticalOffset;
+ // scrollViewer.ScrollChanged -= Scrolled;
+ Logger.Trace("Paging: " + Page);
+ _loaded = false;
+ Page += 1;
+ int index = 0;
+ ZitiService[] services = new ZitiService[0];
+ if (SortBy == "Name") services = _identity.Services.OrderBy(s => s.Name.ToLower()).ToArray();
+ else if (SortBy == "Address") services = _identity.Services.OrderBy(s => s.Addresses.ToString()).ToArray();
+ else if (SortBy == "Protocol") services = _identity.Services.OrderBy(s => s.Protocols.ToString()).ToArray();
+ else if (SortBy == "Port") services = _identity.Services.OrderBy(s => s.Ports.ToString()).ToArray();
+ if (SortWay == "Desc") services = services.Reverse().ToArray();
+ int startIndex = (Page - 1) * PerPage;
+ for (int i = startIndex; i < services.Length; i++)
+ {
+ ZitiService zitiSvc = services[i];
+ if (index < PerPage)
+ {
+ if (zitiSvc.Name.ToLower().IndexOf(filter.ToLower()) >= 0 || zitiSvc.ToString().ToLower().IndexOf(filter.ToLower()) >= 0)
+ {
+ zitiSvc.TimeUpdated = _identity.LastUpdatedTime;
+ ZitiServices.Add(zitiSvc);
+ index++;
+ }
+ }
+ }
+ double totalOffset = _scroller.VerticalOffset;
+ double toNegate = index * 33;
+ double scrollTo = (totalOffset - toNegate);
+ _scroller.InvalidateScrollInfo();
+ _scroller.ScrollToVerticalOffset(verticalOffset);
+ _scroller.InvalidateScrollInfo();
+ _loaded = true;
+ // scrollViewer.ScrollChanged += Scrolled;
+ }
+ }
+ }
+ }
+
+ private void DoFilter(FilterData filterData)
+ {
+ filter = filterData.SearchFor;
+ SortBy = filterData.SortBy;
+ SortWay = filterData.SortHow;
+ UpdateView();
+ }
+
+ async private void DoConnect(object sender, MouseButtonEventArgs e)
+ {
+ this.OnLoading?.Invoke(false);
+ DataClient client = (DataClient)Application.Current.Properties["ServiceClient"];
+ await client.IdentityOnOffAsync(_identity.Identifier, true);
+ if (SelectedIdentity != null) SelectedIdentity.ToggleSwitch.Enabled = true;
+ if (SelectedIdentityMenu != null) SelectedIdentityMenu.ToggleSwitch.Enabled = true;
+ _identity.IsEnabled = true;
+ IsConnected.Visibility = Visibility.Visible;
+ IsDisconnected.Visibility = Visibility.Collapsed;
+ this.OnLoading?.Invoke(true);
+ }
+
+ async private void DoDisconnect(object sender, MouseButtonEventArgs e)
+ {
+ this.OnLoading?.Invoke(false);
+ DataClient client = (DataClient)Application.Current.Properties["ServiceClient"];
+ await client.IdentityOnOffAsync(_identity.Identifier, false);
+ if (SelectedIdentity != null) SelectedIdentity.ToggleSwitch.Enabled = false;
+ if (SelectedIdentityMenu != null) SelectedIdentityMenu.ToggleSwitch.Enabled = false;
+ _identity.IsEnabled = false;
+ IsConnected.Visibility = Visibility.Collapsed;
+ IsDisconnected.Visibility = Visibility.Visible;
+ this.OnLoading?.Invoke(true);
+ }
+
+ private void WarnClicked(object sender, MouseButtonEventArgs e)
+ {
+ ZitiService item = (ZitiService)(sender as FrameworkElement).DataContext;
+ OnMessage?.Invoke(item.WarningMessage);
+ }
+
+ private void DetailsClicked(object sender, MouseButtonEventArgs e)
+ {
+ ZitiService item = (ZitiService)(sender as FrameworkElement).DataContext;
+ ShowDetails(item);
+ }
+
+ private void VisibilityChanged(object sender, DependencyPropertyChangedEventArgs e)
+ {
+ if (this.Visibility == Visibility.Collapsed)
+ {
+ ServiceList.DataContext = null;
+ if (_services != null)
+ {
+ _services.Clear();
+ _services = null;
+ }
+ }
+ }
+
+ private void DoMFA(object sender, MouseButtonEventArgs e)
+ {
+ this.OnShowMFA?.Invoke(this._identity);
+ }
+ }
}
\ No newline at end of file
diff --git a/DesktopEdge/Views/Screens/MFAScreen.xaml.cs b/DesktopEdge/Views/Screens/MFAScreen.xaml.cs
index 3015ebbcb..487e05f70 100644
--- a/DesktopEdge/Views/Screens/MFAScreen.xaml.cs
+++ b/DesktopEdge/Views/Screens/MFAScreen.xaml.cs
@@ -1,20 +1,20 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-using System;
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -40,305 +40,367 @@ limitations under the License.
using QRCoder;
using System.Text.RegularExpressions;
-namespace ZitiDesktopEdge {
- ///
- /// Interaction logic for MFA.xaml
- ///
- public partial class MFAScreen : UserControl {
- private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
-
- public delegate void LoadEvent(bool isComplete, string title, string message);
- public event LoadEvent OnLoad;
- public delegate void CloseAction(bool isComplete);
- public event CloseAction OnClose;
- private string _url = "";
- public delegate void ErrorOccurred(string message);
- public event ErrorOccurred OnError;
- private string[] _codes = new string[0];
- private ZitiIdentity zid;
- private bool _executing = false;
- public int Type { get; set; }
-
- public ZitiIdentity Identity {
- get {
- return this.zid;
- }
- set {
- this.zid = value;
- }
- }
-
- public MFAScreen() {
- InitializeComponent();
- }
-
- private void ExecuteClose(object sender, MouseButtonEventArgs e) {
- this.OnClose?.Invoke(false);
- }
-
- private void ShowError(string message) {
- this.OnError?.Invoke(message);
- }
-
- private BitmapImage CreateQRFromUrl(string url) {
- QRCodeGenerator qrGenerator = new QRCodeGenerator();
- QRCodeData qrCodeData = qrGenerator.CreateQrCode(url, QRCodeGenerator.ECCLevel.Q);
- QRCode qrCode = new QRCode(qrCodeData);
- System.Drawing.Bitmap qrCodeImage = qrCode.GetGraphic(20);
-
- MemoryStream ms = new MemoryStream();
- ((System.Drawing.Bitmap)qrCodeImage).Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
- BitmapImage image = new BitmapImage();
- image.BeginInit();
- ms.Seek(0, SeekOrigin.Begin);
- image.StreamSource = ms;
- image.EndInit();
- return image;
- }
-
- public void ShowSetup(ZitiIdentity identity, string url, string secret) {
- SetupCode.Text = "";
- this.zid = identity;
- MFAImage.Visibility = Visibility.Visible;
- SecretCode.Visibility = Visibility.Collapsed;
- CloseBlack.Visibility = Visibility.Visible;
- CloseWhite.Visibility = Visibility.Collapsed;
- SecretButton.Content = "Show Secret";
- IdName.Content = identity.Name;
- Logger.Debug($"MFA Url: {url}");
- AuthBrush.Visibility = Visibility.Collapsed;
- MainBrush.Visibility = Visibility.Visible;
-
- MFAImage.Source = CreateQRFromUrl(url);
- SecretCode.Text = secret;
-
- _url = url;
- MFAArea.Height = 515;
- MFAAuthArea.Visibility = Visibility.Collapsed;
- MFASetupArea.Visibility = Visibility.Visible;
- MFARecoveryArea.Visibility = Visibility.Collapsed;
- SeperationColor.Visibility = Visibility.Visible;
- SetupCode.Focus();
- }
-
- public void ShowRecovery(string[] codes, ZitiIdentity identity) {
- this.zid = identity;
- MFASetupArea.Visibility = Visibility.Collapsed;
- MFAAuthArea.Visibility = Visibility.Collapsed;
- SeperationColor.Visibility = Visibility.Collapsed;
- MFARecoveryArea.Visibility = Visibility.Visible;
- RecoveryList.Children.Clear();
- _codes = codes;
- AuthBrush.Visibility = Visibility.Collapsed;
- MainBrush.Visibility = Visibility.Visible;
- CloseBlack.Visibility = Visibility.Visible;
- CloseWhite.Visibility = Visibility.Collapsed;
- MFAArea.Height = 380;
- if (codes.Length>0) {
- for (int i = 0; i < codes.Length; i++) {
- TextBox label = new TextBox();
- label.Text = codes[i];
- label.BorderThickness = new Thickness(0);
- label.Background = new SolidColorBrush();
- label.Background.Opacity = 0;
- label.HorizontalAlignment = HorizontalAlignment.Center;
- label.HorizontalContentAlignment = HorizontalAlignment.Center;
- label.VerticalAlignment = VerticalAlignment.Center;
- label.VerticalContentAlignment = VerticalAlignment.Center;
- RecoveryList.Children.Add(label);
- }
- RecoveryList.Visibility = Visibility.Visible;
- NoRecovery.Visibility = Visibility.Collapsed;
- SaveButton.Visibility = Visibility.Visible;
- } else {
-
- ShowMFA(this.zid, 2);
- SaveButton.Visibility = Visibility.Collapsed;
- RecoveryList.Visibility = Visibility.Collapsed;
- NoRecovery.Visibility = Visibility.Visible;
- }
- }
-
- public void ShowMFA(ZitiIdentity identity, int type) {
- this.Type = type;
- AuthCode.Text = "";
- AuthBrush.Visibility = Visibility.Visible;
- MainBrush.Visibility = Visibility.Collapsed;
- CloseBlack.Visibility = Visibility.Collapsed;
- CloseWhite.Visibility = Visibility.Visible;
- this.zid = identity;
- MFASetupArea.Visibility = Visibility.Collapsed;
- MFARecoveryArea.Visibility = Visibility.Collapsed;
- SeperationColor.Visibility = Visibility.Collapsed;
- MFAAuthArea.Visibility = Visibility.Visible;
- MFAArea.Height = 220;
- AuthCode.Focusable = true;
- AuthCode.Focus();
- }
-
- private BitmapImage LoadImage(string url) {
- var imgUrl = new Uri(url);
- var imageData = new WebClient().DownloadData(imgUrl);
- var bitmapImage = new BitmapImage { CacheOption = BitmapCacheOption.OnLoad };
- bitmapImage.BeginInit();
- bitmapImage.StreamSource = new MemoryStream(imageData);
- bitmapImage.EndInit();
- return bitmapImage;
- }
-
- private void GoTo(object sender, MouseButtonEventArgs e) {
- if (_url!=null&&_url.Length>0) {
- Process.Start(new ProcessStartInfo(_url) { UseShellExecute = true });
- } else {
- this.OnError?.Invoke("Invalid MFA Url");
- }
- }
-
- async private void GetMFACodes(object sender, MouseButtonEventArgs e) {
- DataClient serviceClient = serviceClient = (DataClient)Application.Current.Properties["ServiceClient"];
- string code = AuthCode.Text;
- Logger.Debug("AuthMFA successful.");
- MfaRecoveryCodesResponse getcodes = await serviceClient.GetMFACodes(this.zid.Identifier, code);
- if (getcodes.Code != 0) {
- Logger.Error("AuthMFA failed. " + getcodes.Error);
- }
- Logger.Error("DATA: {0}", getcodes.Data);
- }
- async private void GenerateMFACodes(object sender, MouseButtonEventArgs e) {
- DataClient serviceClient = serviceClient = (DataClient)Application.Current.Properties["ServiceClient"];
- string code = AuthCode.Text;
- MfaRecoveryCodesResponse gencodes = await serviceClient.GenerateMFACodes(this.zid.Identifier, code);
- if (gencodes.Code != 0) {
- Logger.Error("AuthMFA failed. " + gencodes.Error);
- }
- Logger.Error("DATA: {0}", gencodes.Data);
- }
-
- private void SaveCodes(object sender, MouseButtonEventArgs e) {
- string fileText = string.Join("\n", _codes);
- string name = Regex.Replace(this.zid.Name, "[^a-zA-Z0-9]", String.Empty);
-
- System.Windows.Forms.SaveFileDialog dialog = new System.Windows.Forms.SaveFileDialog();
- dialog.Filter = "Text Files(*.txt)|*.txt|All(*.*)|*";
- dialog.Title = "Save Recovery Codes";
- dialog.FileName = name + "RecoveryCodes.txt";
-
- if (dialog.ShowDialog() != System.Windows.Forms.DialogResult.Cancel) {
- File.WriteAllText(dialog.FileName, fileText);
- }
- }
-
- async private void DoSetupAuthenticate(object sender, MouseButtonEventArgs e) {
- string code = SetupCode.Text;
-
- DataClient serviceClient = serviceClient = (DataClient)Application.Current.Properties["ServiceClient"];
- SvcResponse resp = await serviceClient.VerifyMFA(this.zid.Identifier, code);
- if (resp.Code != 0) {
- this.OnClose?.Invoke(false);
- } else {
- this.OnClose?.Invoke(false);
- }
- }
-
- ///
- /// Call the MFA Functions
- ///
- /// Types:
- /// 1 = Normal MFA Authentication
- /// 2 = Get Recovery Codes
- /// 3 = Remove MFA
- /// 4 = Generate New MFA Codes
- ///
- async private void DoAuthenticate(object sender, MouseButtonEventArgs e) {
- if (!this._executing) {
-
- this._executing = true;
- string code = AuthCode.Text;
-
- if (code.Trim().Length>0) {
-
- DataClient serviceClient = (DataClient)Application.Current.Properties["ServiceClient"];
- this.OnLoad?.Invoke(false, "Authentication", "One Moment Please...");
- if (this.Type == 1) {
- SvcResponse authResult = await serviceClient.AuthMFA(this.zid.Identifier, code);
- if (authResult?.Code != 0) {
- Logger.Error("AuthMFA failed. " + authResult.Error);
- this.OnError?.Invoke("Authentication Failed");
- this._executing = false;
- } else {
- this.zid.IsMFANeeded = true;
- this.OnClose?.Invoke(true);
- this._executing = false;
- }
- this.OnLoad?.Invoke(true, "", "");
- } else if (this.Type == 2) {
- MfaRecoveryCodesResponse codeResponse = await serviceClient.GetMFACodes(this.zid.Identifier, code);
- if (codeResponse?.Code != 0) {
- Logger.Error("AuthMFA failed. " + codeResponse.Error);
- AuthCode.Text = "";
- this.OnError?.Invoke("Authentication Failed");
- this._executing = false;
- } else {
- this.zid.RecoveryCodes = codeResponse.Data.RecoveryCodes;
- this.OnClose?.Invoke(true);
- this._executing = false;
- }
- this.OnLoad?.Invoke(true, "", "");
- } else if (this.Type == 3) {
- SvcResponse authResult = await serviceClient.RemoveMFA(this.zid.Identifier, code);
- if (authResult?.Code != 0) {
- Logger.Error("AuthMFA failed. " + authResult.Error);
- AuthCode.Text = "";
- this.OnError?.Invoke("Authentication Failed");
- this._executing = false;
- } else {
- this.OnClose?.Invoke(true);
- this._executing = false;
- }
- this.OnLoad?.Invoke(true, "", "");
- } else if (this.Type == 4) {
- MfaRecoveryCodesResponse codeResponse = await serviceClient.GenerateMFACodes(this.zid.Identifier, code);
- if (codeResponse?.Code != 0) {
- Logger.Error("AuthMFA failed. " + codeResponse?.Error);
- AuthCode.Text = "";
- this.OnError?.Invoke("Authentication Failed");
- } else {
- this.zid.RecoveryCodes = codeResponse.Data.RecoveryCodes;
- this.OnClose?.Invoke(true);
- }
- this._executing = false;
- this.OnLoad?.Invoke(true, "", "");
- }
- }
- }
- }
-
- private void RegenerateCodes(object sender, MouseButtonEventArgs e) {
- ShowMFA(this.zid, 4);
- }
-
- private void ShowSecret(object sender, MouseButtonEventArgs e) {
- if (SecretCode.Visibility==Visibility.Visible) {
- MFAImage.Visibility = Visibility.Visible;
- SecretCode.Visibility = Visibility.Collapsed;
- SecretButton.Content = "Show Secret";
- } else {
- MFAImage.Visibility = Visibility.Collapsed;
- SecretCode.Visibility = Visibility.Visible;
- SecretButton.Content = "Show QR Code";
- }
- }
-
- private void HandleKey(object sender, KeyEventArgs e) {
- if (e.Key == Key.Return) {
- DoSetupAuthenticate(sender, null);
- }
- }
-
- private void AuthCode_KeyUp(object sender, KeyEventArgs e) {
- if (e.Key == Key.Return) {
- DoAuthenticate(sender, null);
- }
- }
- }
+namespace ZitiDesktopEdge
+{
+ ///
+ /// Interaction logic for MFA.xaml
+ ///
+ public partial class MFAScreen : UserControl
+ {
+ private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
+
+ public delegate void LoadEvent(bool isComplete, string title, string message);
+ public event LoadEvent OnLoad;
+ public delegate void CloseAction(bool isComplete);
+ public event CloseAction OnClose;
+ private string _url = "";
+ public delegate void ErrorOccurred(string message);
+ public event ErrorOccurred OnError;
+ private string[] _codes = new string[0];
+ private ZitiIdentity zid;
+ private bool _executing = false;
+ public int Type { get; set; }
+
+ public ZitiIdentity Identity
+ {
+ get
+ {
+ return this.zid;
+ }
+ set
+ {
+ this.zid = value;
+ }
+ }
+
+ public MFAScreen()
+ {
+ InitializeComponent();
+ }
+
+ private void ExecuteClose(object sender, MouseButtonEventArgs e)
+ {
+ this.OnClose?.Invoke(false);
+ }
+
+ private void ShowError(string message)
+ {
+ this.OnError?.Invoke(message);
+ }
+
+ private BitmapImage CreateQRFromUrl(string url)
+ {
+ QRCodeGenerator qrGenerator = new QRCodeGenerator();
+ QRCodeData qrCodeData = qrGenerator.CreateQrCode(url, QRCodeGenerator.ECCLevel.Q);
+ QRCode qrCode = new QRCode(qrCodeData);
+ System.Drawing.Bitmap qrCodeImage = qrCode.GetGraphic(20);
+
+ MemoryStream ms = new MemoryStream();
+ ((System.Drawing.Bitmap)qrCodeImage).Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
+ BitmapImage image = new BitmapImage();
+ image.BeginInit();
+ ms.Seek(0, SeekOrigin.Begin);
+ image.StreamSource = ms;
+ image.EndInit();
+ return image;
+ }
+
+ public void ShowSetup(ZitiIdentity identity, string url, string secret)
+ {
+ SetupCode.Text = "";
+ this.zid = identity;
+ MFAImage.Visibility = Visibility.Visible;
+ SecretCode.Visibility = Visibility.Collapsed;
+ CloseBlack.Visibility = Visibility.Visible;
+ CloseWhite.Visibility = Visibility.Collapsed;
+ SecretButton.Content = "Show Secret";
+ IdName.Content = identity.Name;
+ Logger.Debug($"MFA Url: {url}");
+ AuthBrush.Visibility = Visibility.Collapsed;
+ MainBrush.Visibility = Visibility.Visible;
+
+ MFAImage.Source = CreateQRFromUrl(url);
+ SecretCode.Text = secret;
+
+ _url = url;
+ MFAArea.Height = 515;
+ MFAAuthArea.Visibility = Visibility.Collapsed;
+ MFASetupArea.Visibility = Visibility.Visible;
+ MFARecoveryArea.Visibility = Visibility.Collapsed;
+ SeperationColor.Visibility = Visibility.Visible;
+ SetupCode.Focus();
+ }
+
+ public void ShowRecovery(string[] codes, ZitiIdentity identity)
+ {
+ this.zid = identity;
+ MFASetupArea.Visibility = Visibility.Collapsed;
+ MFAAuthArea.Visibility = Visibility.Collapsed;
+ SeperationColor.Visibility = Visibility.Collapsed;
+ MFARecoveryArea.Visibility = Visibility.Visible;
+ RecoveryList.Children.Clear();
+ _codes = codes;
+ AuthBrush.Visibility = Visibility.Collapsed;
+ MainBrush.Visibility = Visibility.Visible;
+ CloseBlack.Visibility = Visibility.Visible;
+ CloseWhite.Visibility = Visibility.Collapsed;
+ MFAArea.Height = 380;
+ if (codes.Length > 0)
+ {
+ for (int i = 0; i < codes.Length; i++)
+ {
+ TextBox label = new TextBox();
+ label.Text = codes[i];
+ label.BorderThickness = new Thickness(0);
+ label.Background = new SolidColorBrush();
+ label.Background.Opacity = 0;
+ label.HorizontalAlignment = HorizontalAlignment.Center;
+ label.HorizontalContentAlignment = HorizontalAlignment.Center;
+ label.VerticalAlignment = VerticalAlignment.Center;
+ label.VerticalContentAlignment = VerticalAlignment.Center;
+ RecoveryList.Children.Add(label);
+ }
+ RecoveryList.Visibility = Visibility.Visible;
+ NoRecovery.Visibility = Visibility.Collapsed;
+ SaveButton.Visibility = Visibility.Visible;
+ }
+ else
+ {
+
+ ShowMFA(this.zid, 2);
+ SaveButton.Visibility = Visibility.Collapsed;
+ RecoveryList.Visibility = Visibility.Collapsed;
+ NoRecovery.Visibility = Visibility.Visible;
+ }
+ }
+
+ public void ShowMFA(ZitiIdentity identity, int type)
+ {
+ this.Type = type;
+ AuthCode.Text = "";
+ AuthBrush.Visibility = Visibility.Visible;
+ MainBrush.Visibility = Visibility.Collapsed;
+ CloseBlack.Visibility = Visibility.Collapsed;
+ CloseWhite.Visibility = Visibility.Visible;
+ this.zid = identity;
+ MFASetupArea.Visibility = Visibility.Collapsed;
+ MFARecoveryArea.Visibility = Visibility.Collapsed;
+ SeperationColor.Visibility = Visibility.Collapsed;
+ MFAAuthArea.Visibility = Visibility.Visible;
+ MFAArea.Height = 220;
+ AuthCode.Focusable = true;
+ AuthCode.Focus();
+ }
+
+ private BitmapImage LoadImage(string url)
+ {
+ var imgUrl = new Uri(url);
+ var imageData = new WebClient().DownloadData(imgUrl);
+ var bitmapImage = new BitmapImage { CacheOption = BitmapCacheOption.OnLoad };
+ bitmapImage.BeginInit();
+ bitmapImage.StreamSource = new MemoryStream(imageData);
+ bitmapImage.EndInit();
+ return bitmapImage;
+ }
+
+ private void GoTo(object sender, MouseButtonEventArgs e)
+ {
+ if (_url != null && _url.Length > 0)
+ {
+ Process.Start(new ProcessStartInfo(_url) { UseShellExecute = true });
+ }
+ else
+ {
+ this.OnError?.Invoke("Invalid MFA Url");
+ }
+ }
+
+ async private void GetMFACodes(object sender, MouseButtonEventArgs e)
+ {
+ DataClient serviceClient = serviceClient = (DataClient)Application.Current.Properties["ServiceClient"];
+ string code = AuthCode.Text;
+ Logger.Debug("AuthMFA successful.");
+ MfaRecoveryCodesResponse getcodes = await serviceClient.GetMFACodes(this.zid.Identifier, code);
+ if (getcodes.Code != 0)
+ {
+ Logger.Error("AuthMFA failed. " + getcodes.Error);
+ }
+ Logger.Error("DATA: {0}", getcodes.Data);
+ }
+ async private void GenerateMFACodes(object sender, MouseButtonEventArgs e)
+ {
+ DataClient serviceClient = serviceClient = (DataClient)Application.Current.Properties["ServiceClient"];
+ string code = AuthCode.Text;
+ MfaRecoveryCodesResponse gencodes = await serviceClient.GenerateMFACodes(this.zid.Identifier, code);
+ if (gencodes.Code != 0)
+ {
+ Logger.Error("AuthMFA failed. " + gencodes.Error);
+ }
+ Logger.Error("DATA: {0}", gencodes.Data);
+ }
+
+ private void SaveCodes(object sender, MouseButtonEventArgs e)
+ {
+ string fileText = string.Join("\n", _codes);
+ string name = Regex.Replace(this.zid.Name, "[^a-zA-Z0-9]", String.Empty);
+
+ System.Windows.Forms.SaveFileDialog dialog = new System.Windows.Forms.SaveFileDialog();
+ dialog.Filter = "Text Files(*.txt)|*.txt|All(*.*)|*";
+ dialog.Title = "Save Recovery Codes";
+ dialog.FileName = name + "RecoveryCodes.txt";
+
+ if (dialog.ShowDialog() != System.Windows.Forms.DialogResult.Cancel)
+ {
+ File.WriteAllText(dialog.FileName, fileText);
+ }
+ }
+
+ async private void DoSetupAuthenticate(object sender, MouseButtonEventArgs e)
+ {
+ string code = SetupCode.Text;
+
+ DataClient serviceClient = serviceClient = (DataClient)Application.Current.Properties["ServiceClient"];
+ SvcResponse resp = await serviceClient.VerifyMFA(this.zid.Identifier, code);
+ if (resp.Code != 0)
+ {
+ this.OnClose?.Invoke(false);
+ }
+ else
+ {
+ this.OnClose?.Invoke(false);
+ }
+ }
+
+ ///
+ /// Call the MFA Functions
+ ///
+ /// Types:
+ /// 1 = Normal MFA Authentication
+ /// 2 = Get Recovery Codes
+ /// 3 = Remove MFA
+ /// 4 = Generate New MFA Codes
+ ///
+ async private void DoAuthenticate(object sender, MouseButtonEventArgs e)
+ {
+ if (!this._executing)
+ {
+
+ this._executing = true;
+ string code = AuthCode.Text;
+
+ if (code.Trim().Length > 0)
+ {
+
+ DataClient serviceClient = (DataClient)Application.Current.Properties["ServiceClient"];
+ this.OnLoad?.Invoke(false, "Authentication", "One Moment Please...");
+ if (this.Type == 1)
+ {
+ SvcResponse authResult = await serviceClient.AuthMFA(this.zid.Identifier, code);
+ if (authResult?.Code != 0)
+ {
+ Logger.Error("AuthMFA failed. " + authResult.Error);
+ this.OnError?.Invoke("Authentication Failed");
+ this._executing = false;
+ }
+ else
+ {
+ this.zid.IsMFANeeded = true;
+ this.OnClose?.Invoke(true);
+ this._executing = false;
+ }
+ this.OnLoad?.Invoke(true, "", "");
+ }
+ else if (this.Type == 2)
+ {
+ MfaRecoveryCodesResponse codeResponse = await serviceClient.GetMFACodes(this.zid.Identifier, code);
+ if (codeResponse?.Code != 0)
+ {
+ Logger.Error("AuthMFA failed. " + codeResponse.Error);
+ AuthCode.Text = "";
+ this.OnError?.Invoke("Authentication Failed");
+ this._executing = false;
+ }
+ else
+ {
+ this.zid.RecoveryCodes = codeResponse.Data.RecoveryCodes;
+ this.OnClose?.Invoke(true);
+ this._executing = false;
+ }
+ this.OnLoad?.Invoke(true, "", "");
+ }
+ else if (this.Type == 3)
+ {
+ SvcResponse authResult = await serviceClient.RemoveMFA(this.zid.Identifier, code);
+ if (authResult?.Code != 0)
+ {
+ Logger.Error("AuthMFA failed. " + authResult.Error);
+ AuthCode.Text = "";
+ this.OnError?.Invoke("Authentication Failed");
+ this._executing = false;
+ }
+ else
+ {
+ this.OnClose?.Invoke(true);
+ this._executing = false;
+ }
+ this.OnLoad?.Invoke(true, "", "");
+ }
+ else if (this.Type == 4)
+ {
+ MfaRecoveryCodesResponse codeResponse = await serviceClient.GenerateMFACodes(this.zid.Identifier, code);
+ if (codeResponse?.Code != 0)
+ {
+ Logger.Error("AuthMFA failed. " + codeResponse?.Error);
+ AuthCode.Text = "";
+ this.OnError?.Invoke("Authentication Failed");
+ }
+ else
+ {
+ this.zid.RecoveryCodes = codeResponse.Data.RecoveryCodes;
+ this.OnClose?.Invoke(true);
+ }
+ this._executing = false;
+ this.OnLoad?.Invoke(true, "", "");
+ }
+ }
+ }
+ }
+
+ private void RegenerateCodes(object sender, MouseButtonEventArgs e)
+ {
+ ShowMFA(this.zid, 4);
+ }
+
+ private void ShowSecret(object sender, MouseButtonEventArgs e)
+ {
+ if (SecretCode.Visibility == Visibility.Visible)
+ {
+ MFAImage.Visibility = Visibility.Visible;
+ SecretCode.Visibility = Visibility.Collapsed;
+ SecretButton.Content = "Show Secret";
+ }
+ else
+ {
+ MFAImage.Visibility = Visibility.Collapsed;
+ SecretCode.Visibility = Visibility.Visible;
+ SecretButton.Content = "Show QR Code";
+ }
+ }
+
+ private void HandleKey(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Return)
+ {
+ DoSetupAuthenticate(sender, null);
+ }
+ }
+
+ private void AuthCode_KeyUp(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Return)
+ {
+ DoAuthenticate(sender, null);
+ }
+ }
+ }
}
diff --git a/DesktopEdge/Views/Screens/MainMenu.xaml.cs b/DesktopEdge/Views/Screens/MainMenu.xaml.cs
index 1aef73bd4..01a6d18e4 100644
--- a/DesktopEdge/Views/Screens/MainMenu.xaml.cs
+++ b/DesktopEdge/Views/Screens/MainMenu.xaml.cs
@@ -1,19 +1,19 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
@@ -34,748 +34,927 @@ limitations under the License.
using System.Threading.Tasks;
using ZitiDesktopEdge.Utility;
-namespace ZitiDesktopEdge {
- ///
- /// Interaction logic for MainMenu.xaml
- ///
- public partial class MainMenu : UserControl {
- private static readonly Logger logger = LogManager.GetCurrentClassLogger();
-
- public delegate void AttachementChanged(bool attached);
- public event AttachementChanged OnAttachmentChange;
- public delegate Task LogLevelChanged(string level);
- public event LogLevelChanged OnLogLevelChanged;
- public delegate void Detched(MouseButtonEventArgs e);
- public event Detched OnDetach;
- public delegate void ShowBlurb(string message);
- public event ShowBlurb OnShowBlurb;
- public string menuState = "Main";
- public string licenseData = "it's open source.";
- public string LogLevel = "";
- private string appVersion = null;
- public double MainHeight = 500;
-
- private ZDEWViewState state;
-
- public bool ShowUnexpectedFailure { get; set; }
-
- public void ShowUpdateAvailable() {
- if (state.UpdateAvailable) {
- ForceUpdate.Visibility = Visibility.Visible;
- }
-
- if (state.PendingUpdate.TimeLeft > 0) {
- UpdateTimeLeft.Visibility = Visibility.Visible;
- if (!state.AutomaticUpdatesDisabled) {
- UpdateTimeLeft.Content = $"Automatic update to {state.PendingUpdate.Version} will occur on or after {state.PendingUpdate.InstallTime.ToString("g")}";
+namespace ZitiDesktopEdge
+{
+ ///
+ /// Interaction logic for MainMenu.xaml
+ ///
+ public partial class MainMenu : UserControl
+ {
+ private static readonly Logger logger = LogManager.GetCurrentClassLogger();
+
+ public delegate void AttachementChanged(bool attached);
+ public event AttachementChanged OnAttachmentChange;
+ public delegate Task LogLevelChanged(string level);
+ public event LogLevelChanged OnLogLevelChanged;
+ public delegate void Detched(MouseButtonEventArgs e);
+ public event Detched OnDetach;
+ public delegate void ShowBlurb(string message);
+ public event ShowBlurb OnShowBlurb;
+ public string menuState = "Main";
+ public string licenseData = "it's open source.";
+ public string LogLevel = "";
+ private string appVersion = null;
+ public double MainHeight = 500;
+
+ private ZDEWViewState state;
+
+ public bool ShowUnexpectedFailure { get; set; }
+
+ public void ShowUpdateAvailable()
+ {
+ if (state.UpdateAvailable)
+ {
+ ForceUpdate.Visibility = Visibility.Visible;
+ }
+
+ if (state.PendingUpdate.TimeLeft > 0)
+ {
+ UpdateTimeLeft.Visibility = Visibility.Visible;
+ if (!state.AutomaticUpdatesDisabled)
+ {
+ UpdateTimeLeft.Content = $"Automatic update to {state.PendingUpdate.Version} will occur on or after {state.PendingUpdate.InstallTime.ToString("g")}";
CheckForUpdateStatus.Content = $"update {state.PendingUpdate.Version} is available";
- } else {
- UpdateTimeLeft.Content = "";
+ }
+ else
+ {
+ UpdateTimeLeft.Content = "";
}
CheckForUpdateStatus.Visibility = UpdateTimeLeft.Visibility;
}
- SetAutomaticUpgradesState();
- }
-
- internal MainWindow MainWindow { get; set; }
-
- public MainMenu() {
- InitializeComponent();
- Application.Current.MainWindow.Title = "Ziti Desktop Edge";
- state = (ZDEWViewState)Application.Current.Properties["ZDEWViewState"];
-
- try {
- ShowUnexpectedFailure = bool.Parse(ConfigurationManager.AppSettings.Get("ShowUnexpectedFailure"));
- } catch {
- //if we can't parse the config - leave it as false...
- ShowUnexpectedFailure = false; //setting it here in case anyone changes the default above
- }
-
- 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 ShowIdentities(object sender, MouseButtonEventArgs e) {
- menuState = "Identities";
- 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();
- }
-
- private void ShowAutomaticUpgradesMenuAction(object sender, MouseButtonEventArgs e) {
- menuState = "ConfigureAutomaticUpgrades";
- UpdateState();
- }
-
- async private void SetAutomaticUpgradesMenuAction(object sender, MouseButtonEventArgs e) {
- bool disableAutomaticUpgrades = false;
- if (sender == AutomaticUpgradesItemOff) {
- disableAutomaticUpgrades = true;
- }
- var monitorClient = (MonitorClient)Application.Current.Properties["MonitorClient"];
- try {
- SvcResponse r = await monitorClient.SetAutomaticUpgradeDisabledAsync(disableAutomaticUpgrades);
- if (r.Code != 0) {
- logger.Error(r?.Error);
- }
- } catch (MonitorServiceException) {
- MainWindow.ShowError("Could Not Set Automatic Update", "The monitor service is offline");
- } catch (Exception ex) {
- logger.Error("unexpected error when setting automatic upgrade enabled", ex);
- }
- SetAutomaticUpgradesState();
- }
-
- private void checkResponse(SvcResponse r, string titleOnErr, string msgOnErr) {
- if (r == null) {
- MainWindow.ShowError(titleOnErr, msgOnErr);
- } else {
- logger.Info(r?.ToString());
- }
- }
-
- private void SetLogLevel(object sender, MouseButtonEventArgs e) {
- menuState = "LogLevel";
- UpdateState();
- }
-
- private void UpdateState() {
- double h = this.ActualHeight - 100.00;
- if (h > 0) {
- IdListScrollView.Height = h;
- }
- IdListScrollView.Visibility = Visibility.Collapsed;
- 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;
- AutomaticUpgradesItems.Visibility = Visibility.Collapsed;
- Visibility visibilityFromUpdateAvail = state.UpdateAvailable ? Visibility.Visible : Visibility.Collapsed;
- TriggerUpdateButton.Visibility = visibilityFromUpdateAvail;
- ForceUpdate.Visibility = visibilityFromUpdateAvail;
- CheckForUpdateStatus.Visibility = visibilityFromUpdateAvail;
-
- 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;
- } 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);
- 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 == "ConfigureAutomaticUpgrades") {
- SetAutomaticUpgradesState();
-
- MenuTitle.Content = "Automatic Upgrades";
- AutomaticUpgradesItems.Visibility = Visibility.Visible;
- BackArrow.Visibility = Visibility.Visible;
- } else if (menuState == "Config") {
- MenuTitle.Content = "Tunnel Configuration";
- ConfigItems.Visibility = Visibility.Visible;
- BackArrow.Visibility = Visibility.Visible;
-
- ConfigPageSize.Value = ((Application.Current.Properties.Contains("ApiPageSize")) ? Application.Current.Properties["ApiPageSize"].ToString() : "25");
- 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();
- ConfigDnsEnabled.Value = Application.Current.Properties["dnsenabled"]?.ToString();
- } else if (menuState == "Identities") {
- MenuTitle.Content = "Identities";
- IdListScrollView.Visibility = Visibility.Visible;
- BackArrow.Visibility = Visibility.Visible;
- } else {
- MenuTitle.Content = "Main Menu";
- MainItems.Visibility = Visibility.Visible;
- MainItemsButton.Visibility = Visibility.Visible;
- }
-
- // ShowUpdateAvailable();
- }
-
- private void OpenLogFile(string which, string logFile) {
- var whichRoot = Path.Combine(MainWindow.ExpectedLogPathRoot, which);
- try {
- string target = Native.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 == "ConfigureAutomaticUpgrades") {
- 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 public void CollectFeedbackLogs(object sender, MouseButtonEventArgs e) {
- try {
- MainWindow.ShowLoad("Collecting Information", "Please wait while we run some commands\nand collect some diagnostic information");
-
- System.Text.StringBuilder sb = new System.Text.StringBuilder();
- sb.Append("Logs collected at : " + DateTime.Now.ToString());
- sb.Append(". client version : " + appVersion);
-
- string timestamp = DateTime.Now.ToFileTime().ToString();
-
- var dataClient = (DataClient)Application.Current.Properties["ServiceClient"];
-
- string exeLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
- string logLocation = Path.Combine(exeLocation, "logs");
- string serviceLogsLocation = Path.Combine(logLocation, "service");
- await dataClient.zitiDump(serviceLogsLocation);
-
- var monitorClient = (MonitorClient)Application.Current.Properties["MonitorClient"];
- MonitorServiceStatusEvent resp = await monitorClient.CaptureLogsAsync();
- if (resp == null) {
- logger.Error("no response from monitorClient?");
- MainWindow mw = (MainWindow)Application.Current.MainWindow;
- mw?.ShowError("Error Collecting Feedback", "An error occurred while trying to gather feedback.\nIs the monitor service running?");
- return;
- }
- string pathToLogs = resp.Message;
- logger.Info("Log files found at : {0}", resp.Message);
- string args = string.Format("/Select, \"{0}\"", pathToLogs);
-
- ProcessStartInfo pfi = new ProcessStartInfo("Explorer.exe", args);
- Process.Start(pfi);
- } catch (MonitorServiceException) {
- MainWindow.ShowError("Could Not Collect Feedback", "The monitor service is offline");
- } catch (Exception ex) {
- logger.Warn(ex, "An unexpected error has occurred when submitting feedback? {0}", ex.Message);
- MainWindow.ShowError("Could Not Collect Feedback", "The monitor service is offline");
- }
- MainWindow.HideLoad();
- }
-
- 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;
- 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 == "warn") LogWarn.IsSelected = true;
- else if (this.LogLevel == "trace") LogTrace.IsSelected = true;
- }
-
- async private void SetLevel(object sender, MouseButtonEventArgs e) {
- SubOptionItem item = (SubOptionItem)sender;
- if (OnLogLevelChanged != null) {
- if(await OnLogLevelChanged(this.LogLevel)) {
- this.LogLevel = item.Label.ToLower();
- }
- }
- ResetLevels();
- }
-
- private void SetAutomaticUpgradesState() {
- bool disabled = state.AutomaticUpdatesDisabled;
- this.AutomaticUpgradesItemOn.IsSelected = !disabled;
- this.AutomaticUpgradesItemOff.IsSelected = disabled;
- this.UpdateUrl.Text = state.AutomaticUpdateURL;
- }
-
- async private void CheckForUpdate_OnClick(object sender, MouseButtonEventArgs e) {
- logger.Info("checking for update...");
- CheckForUpdateStatus.Content = "Checking for updates...";
- await Task.Delay(1000);
- if (state.AutomaticUpdateURL != this.UpdateUrl.Text) {
- SetUpdateUrlButton_Click(sender, e);
- }
- try {
- CheckForUpdate.IsEnabled = false;
- CheckForUpdateStatus.Visibility = Visibility.Visible;
- var monitorClient = (MonitorClient)Application.Current.Properties["MonitorClient"];
- var r = await monitorClient.DoUpdateCheck();
- checkResponse(r, "Error When Checking for Update", "An error occurred while trying check for update.");
- CheckForUpdateStatus.Content = r.Message;
- if (r.UpdateAvailable) {
- TriggerUpdateButton.Visibility = Visibility.Visible;
- ForceUpdate.Visibility = Visibility.Visible;
- } else {
- TriggerUpdateButton.Visibility = Visibility.Collapsed;
- ForceUpdate.Visibility = Visibility.Collapsed;
- }
- } catch (MonitorServiceException) {
- CheckForUpdateStatus.Content = "Monitor service is offline";
- } catch (Exception ex) {
- logger.Error(ex, "unexpected error in update check: {0}", ex.Message);
- CheckForUpdateStatus.Content = "Error checking for updates. See logs.";
- }
- CheckForUpdate.IsEnabled = true;
- }
-
- async private void TriggerUpdate_RoutedEventArgs_Click(object sender, RoutedEventArgs e) {
- Button src = null;
- if (sender is Button) {
- src = sender as Button;
- }
- try {
- CheckForUpdateStatus.Content = "Requesting automatic update...";
- var monitorClient = (MonitorClient)Application.Current.Properties["MonitorClient"];
- var r = await monitorClient.TriggerUpdate();
- CheckForUpdateStatus.Content = "Automatic update requested...";
- if (r == null) {
- MainWindow.ShowError("Error When Triggering Update", "An error occurred while trying to trigger the update.");
- if (src != null) src.IsEnabled = true;
- } else {
- this.OnShowBlurb?.Invoke("Update Requested");
- if (src != null) src.Content = "Request Update Again";
- UpdateTimeLeft.Content = "Update Requested at " + DateTime.Now;
- TriggerUpdateButton.Visibility = Visibility.Collapsed;
- logger.Info(r?.ToString());
- menuState = "Menu";
- UpdateState();
- MainMenuArea.Visibility = Visibility.Collapsed;
- }
- } catch (Exception ex) {
- logger.Error(ex, "unexpected error in update check: {0}", ex.Message);
- MainWindow.ShowError("Error When Triggering Update", "An error occurred while trying to trigger the update.");
- if (src != null) src.IsEnabled = true;
- }
- }
-
- public void SetupIdList(ZitiIdentity[] ids) {
- IdListView.Children.Clear();
- for (int i = 0; i < ids.Length; i++) {
- MenuIdentityItem item = new MenuIdentityItem();
- item.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
- item.Label = ids[i].Name;
- item.Identity = ids[i];
- item.ToggleSwitch.Enabled = ids[i].IsEnabled;
- IdListView.Children.Add(item);
- }
- }
-
- public void SetAppUpgradeAvailableText(string msg) {
- this.Dispatcher.Invoke(() => {
- VersionOlder.Content = msg;
- VersionNewer.Content = "";
- VersionOlder.Visibility = Visibility.Visible;
- VersionNewer.Visibility = Visibility.Collapsed;
- });
- }
- public void SetAppIsNewer(string msg) {
- this.Dispatcher.Invoke(() => {
- VersionNewer.Content = msg;
- VersionOlder.Content = "";
- VersionNewer.Visibility = Visibility.Visible;
- VersionOlder.Visibility = Visibility.Collapsed;
- });
- }
-
- public void Disconnected() {
- ConfigItems.IsEnabled = false;
- ConfigItems.Opacity = 0.3;
- LogLevelItems.IsEnabled = false;
- LogLevelItems.Opacity = 0.3;
- }
-
- public void Connected() {
- ConfigItems.IsEnabled = true;
- ConfigItems.Opacity = 1.0;
- LogLevelItems.IsEnabled = true;
- LogLevelItems.Opacity = 1.0;
- }
-
- ///
- /// Save the config information to the properties and queue for update.
- ///
- async private void UpdateConfig() {
- logger.Info("updating config...");
- DataClient client = (DataClient)Application.Current.Properties["ServiceClient"];
- try {
- ComboBoxItem item = (ComboBoxItem)ConfigMaskNew.SelectedValue;
- var newMaskVar = Int32.Parse(item.Tag.ToString());
- var addDnsNewVar = Convert.ToBoolean(AddDnsNew.IsChecked);
- CheckRange();
- int pageSize = Int32.Parse(ConfigePageSizeNew.Text);
- ConfigPageSize.Value = ConfigePageSizeNew.Text;
-
- var r = await client.UpdateConfigAsync(ConfigIpNew.Text, newMaskVar, addDnsNewVar, pageSize);
- if (r.Code != 0) {
- this.OnShowBlurb?.Invoke("Error: " + r.Error);
- logger.Debug("ERROR: {0} : {1}", r.Message, r.Error);
- } else {
- this.OnShowBlurb?.Invoke("Config Save, Please Restart Ziti to Update");
- this.CloseEdit();
- }
- logger.Info("Got response from update config task : {0}", r);
- } catch (DataStructures.ServiceException se) {
- this.OnShowBlurb?.Invoke("Error: " + se.Message);
- logger.Error(se, "service exception in update check: {0}", se.Message);
- } catch (Exception ex) {
- this.OnShowBlurb?.Invoke("Error: " + ex.Message);
- logger.Error(ex, "unexpected error in update check: {0}", ex.Message);
- }
- }
-
- ///
- /// Save the frequency information to the properties and queue for update.
- ///
- async private void UpdateFrequency() {
- logger.Info("updating frequency...");
- DataClient client = (DataClient)Application.Current.Properties["ServiceClient"];
- try {
- var newFrequencyVar = Int32.Parse(Frequency.Text);
-
- var r = await client.NotificationFrequencyPayloadAsync(newFrequencyVar);
- if (r.Code != 0) {
- this.OnShowBlurb?.Invoke("Error: " + r.Error);
- logger.Debug("ERROR: {0} : {1}", r.Message, r.Error);
- } else {
- this.OnShowBlurb?.Invoke("Frequency Saved");
- this.CloseFrequency();
- }
- logger.Info("Got response from update frequency task : {0}", r);
- } catch (DataStructures.ServiceException se) {
- this.OnShowBlurb?.Invoke("Error: " + se.Message);
- logger.Error(se, "service exception in update frequency check: {0}", se.Message);
- } catch (Exception ex) {
- this.OnShowBlurb?.Invoke("Error: " + ex.Message);
- logger.Error(ex, "unexpected error in update frequency check: {0}", ex.Message);
- }
- }
-
-
- ///
- /// Show the Edit Modal and blur the background
- ///
- private void ShowEdit_Click(object sender, MouseButtonEventArgs e) {
- ConfigIpNew.Text = ConfigIp.Value;
- ConfigePageSizeNew.Text = ConfigPageSize.Value;
- CheckRange();
- for (int i = 0; i < ConfigMaskNew.Items.Count; i++) {
- ComboBoxItem item = (ComboBoxItem)ConfigMaskNew.Items.GetItemAt(i);
- if (item.Content.ToString().IndexOf(ConfigSubnet.Value) > 0) {
- ConfigMaskNew.SelectedIndex = i;
- break;
- }
- }
- AddDnsNew.IsChecked = false;
- if (Application.Current.Properties.Contains("dnsenabled")) {
- AddDnsNew.IsChecked = (bool)Application.Current.Properties["dnsenabled"];
- }
- EditArea.Opacity = 0;
- EditArea.Visibility = Visibility.Visible;
- EditArea.Margin = new Thickness(0, 0, 0, 0);
- EditArea.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(1, TimeSpan.FromSeconds(.3)));
- EditArea.BeginAnimation(Grid.MarginProperty, new ThicknessAnimation(new Thickness(30, 30, 30, 30), TimeSpan.FromSeconds(.3)));
- ShowModal();
- }
-
- ///
- /// Show the Frequency Modal and blur the background
- ///
- private void ShowFrequency() {
- Frequency.Text = "";
- FrequencyArea.Opacity = 0;
- FrequencyArea.Visibility = Visibility.Visible;
- FrequencyArea.Margin = new Thickness(0, 0, 0, 0);
- FrequencyArea.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(1, TimeSpan.FromSeconds(.3)));
- FrequencyArea.BeginAnimation(Grid.MarginProperty, new ThicknessAnimation(new Thickness(30, 30, 30, 30), TimeSpan.FromSeconds(.3)));
- ShowModal();
- }
-
- ///
- /// Hide the Edit Config
- ///
- private void CloseFrequency() {
- DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3));
- ThicknessAnimation animateThick = new ThicknessAnimation(new Thickness(0, 0, 0, 0), TimeSpan.FromSeconds(.3));
- animation.Completed += CloseFrequencyComplete;
- FrequencyArea.BeginAnimation(Grid.OpacityProperty, animation);
- FrequencyArea.BeginAnimation(Grid.MarginProperty, animateThick);
- HideModal();
- }
-
- ///
- /// Close the config window
- ///
- /// The close button
- /// The event arguments
- private void CloseFrequencyComplete(object sender, EventArgs e) {
- FrequencyArea.Visibility = Visibility.Collapsed;
- }
-
- ///
- /// Hide the Edit Config
- ///
- private void CloseEdit() {
- DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3));
- ThicknessAnimation animateThick = new ThicknessAnimation(new Thickness(0, 0, 0, 0), TimeSpan.FromSeconds(.3));
- animation.Completed += CloseComplete;
- EditArea.BeginAnimation(Grid.OpacityProperty, animation);
- EditArea.BeginAnimation(Grid.MarginProperty, animateThick);
- HideModal();
- }
-
- ///
- /// Show the modal, aniimating opacity
- ///
- private void ShowModal() {
- ModalBg.Visibility = Visibility.Visible;
- ModalBg.Opacity = 0;
- DoubleAnimation animation = new DoubleAnimation(.8, TimeSpan.FromSeconds(.3));
- ModalBg.BeginAnimation(Grid.OpacityProperty, animation);
- }
-
- ///
- /// Close the config window
- ///
- /// The close button
- /// The event arguments
- private void CloseComplete(object sender, EventArgs e) {
- EditArea.Visibility = Visibility.Collapsed;
- }
-
- ///
- /// Hide the modal animating the opacity
- ///
- private void HideModal() {
- DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3));
- animation.Completed += ModalHideComplete;
- ModalBg.BeginAnimation(Grid.OpacityProperty, animation);
- }
-
- ///
- /// When the animation completes, set the visibility to avoid UI object conflicts
- ///
- /// The animation
- /// The event
- private void ModalHideComplete(object sender, EventArgs e) {
- ModalBg.Visibility = Visibility.Collapsed;
- }
-
- ///
- /// Close the config editor without saving
- ///
- /// The image button
- /// The click event
- private void CloseEditConfig(object sender, MouseButtonEventArgs e) {
- CloseEdit();
- }
-
- private void SaveConfig_Click(object sender, MouseButtonEventArgs e) {
- this.UpdateConfig();
- }
-
- private void SaveFrequencyButton_OnClick(object sender, MouseButtonEventArgs e) {
- UpdateFrequency();
- }
-
- private void CloseFrequencyArea(object sender, MouseButtonEventArgs e) {
- CloseFrequency();
- }
-
- private void EditFreqButton_OnClick(object sender, MouseButtonEventArgs e) {
- ShowFrequency();
- }
-
- private void Frequency_KeyUp(object sender, KeyEventArgs e) {
- if (e.Key == Key.Return) {
- UpdateFrequency();
- }
- }
-
- private void ConfigePageSizeNew_KeyDown(object sender, KeyEventArgs e) {
- }
-
- private void ConfigePageSizeNew_LostFocus(object sender, RoutedEventArgs e) {
- CheckRange();
- }
-
- private void CheckRange() {
- int defaultVal = 250;
- string setVal = ConfigePageSizeNew.Text;
- int value = defaultVal;
- if (Int32.TryParse(ConfigePageSizeNew.Text, out value)) {
- }
- if (value < 10 || value > 500) value = defaultVal;
- ConfigePageSizeNew.Text = value.ToString();
- }
-
- private void ResetUrlButton_Click(object sender, RoutedEventArgs e) {
- UpdateUrl.Text = GithubAPI.ProdUrl;
- }
-
- private async void SetUpdateUrlButton_Click(object sender, MouseButtonEventArgs e) {
- try {
- var monitorClient = (MonitorClient)Application.Current.Properties["MonitorClient"];
-
- SvcResponse r = await monitorClient.SetAutomaticUpgradeURLAsync(UpdateUrl.Text);
- if (r == null) {
- logger.Error("Failed to set automatic upgrade url! SvcResponse was null?!?!?");
- MainWindow.ShowError("Could not set url!", "Is the monitor service running?");
- } else if (r.Code != 0) {
- logger.Error(r?.Error);
- MainWindow.ShowError("Could not set url", r?.Error);
- } else {
- this.OnShowBlurb?.Invoke("Config Saved.");
- }
- } catch (MonitorServiceException) {
- MainWindow.ShowError("Could Not Set URL", "The monitor service is offline");
- } catch (Exception ex) {
- logger.Error("unexpected error when setting automatic upgrade enabled", ex);
- }
- }
-
- private void UpdateUrl_TextChanged(object sender, TextChangedEventArgs e) {
- logger.Info("url: {}", state.AutomaticUpdateURL);
- }
-
- private void Button_Click(object sender, RoutedEventArgs e) {
- logger.Info("sender name: {}", sender);
-
- }
- }
+ SetAutomaticUpgradesState();
+ }
+
+ internal MainWindow MainWindow { get; set; }
+
+ public MainMenu()
+ {
+ InitializeComponent();
+ Application.Current.MainWindow.Title = "Ziti Desktop Edge";
+ state = (ZDEWViewState)Application.Current.Properties["ZDEWViewState"];
+
+ try
+ {
+ ShowUnexpectedFailure = bool.Parse(ConfigurationManager.AppSettings.Get("ShowUnexpectedFailure"));
+ }
+ catch
+ {
+ //if we can't parse the config - leave it as false...
+ ShowUnexpectedFailure = false; //setting it here in case anyone changes the default above
+ }
+
+ 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 ShowIdentities(object sender, MouseButtonEventArgs e)
+ {
+ menuState = "Identities";
+ 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();
+ }
+
+ private void ShowAutomaticUpgradesMenuAction(object sender, MouseButtonEventArgs e)
+ {
+ menuState = "ConfigureAutomaticUpgrades";
+ UpdateState();
+ }
+
+ async private void SetAutomaticUpgradesMenuAction(object sender, MouseButtonEventArgs e)
+ {
+ bool disableAutomaticUpgrades = false;
+ if (sender == AutomaticUpgradesItemOff)
+ {
+ disableAutomaticUpgrades = true;
+ }
+ var monitorClient = (MonitorClient)Application.Current.Properties["MonitorClient"];
+ try
+ {
+ SvcResponse r = await monitorClient.SetAutomaticUpgradeDisabledAsync(disableAutomaticUpgrades);
+ if (r.Code != 0)
+ {
+ logger.Error(r?.Error);
+ }
+ }
+ catch (MonitorServiceException)
+ {
+ MainWindow.ShowError("Could Not Set Automatic Update", "The monitor service is offline");
+ }
+ catch (Exception ex)
+ {
+ logger.Error("unexpected error when setting automatic upgrade enabled", ex);
+ }
+ SetAutomaticUpgradesState();
+ }
+
+ private void checkResponse(SvcResponse r, string titleOnErr, string msgOnErr)
+ {
+ if (r == null)
+ {
+ MainWindow.ShowError(titleOnErr, msgOnErr);
+ }
+ else
+ {
+ logger.Info(r?.ToString());
+ }
+ }
+
+ private void SetLogLevel(object sender, MouseButtonEventArgs e)
+ {
+ menuState = "LogLevel";
+ UpdateState();
+ }
+
+ private void UpdateState()
+ {
+ double h = this.ActualHeight - 100.00;
+ if (h > 0)
+ {
+ IdListScrollView.Height = h;
+ }
+ IdListScrollView.Visibility = Visibility.Collapsed;
+ 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;
+ AutomaticUpgradesItems.Visibility = Visibility.Collapsed;
+ Visibility visibilityFromUpdateAvail = state.UpdateAvailable ? Visibility.Visible : Visibility.Collapsed;
+ TriggerUpdateButton.Visibility = visibilityFromUpdateAvail;
+ ForceUpdate.Visibility = visibilityFromUpdateAvail;
+ CheckForUpdateStatus.Visibility = visibilityFromUpdateAvail;
+
+ 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;
+ }
+ 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);
+ 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 == "ConfigureAutomaticUpgrades")
+ {
+ SetAutomaticUpgradesState();
+
+ MenuTitle.Content = "Automatic Upgrades";
+ AutomaticUpgradesItems.Visibility = Visibility.Visible;
+ BackArrow.Visibility = Visibility.Visible;
+ }
+ else if (menuState == "Config")
+ {
+ MenuTitle.Content = "Tunnel Configuration";
+ ConfigItems.Visibility = Visibility.Visible;
+ BackArrow.Visibility = Visibility.Visible;
+
+ ConfigPageSize.Value = ((Application.Current.Properties.Contains("ApiPageSize")) ? Application.Current.Properties["ApiPageSize"].ToString() : "25");
+ 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();
+ ConfigDnsEnabled.Value = Application.Current.Properties["dnsenabled"]?.ToString();
+ }
+ else if (menuState == "Identities")
+ {
+ MenuTitle.Content = "Identities";
+ IdListScrollView.Visibility = Visibility.Visible;
+ BackArrow.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ MenuTitle.Content = "Main Menu";
+ MainItems.Visibility = Visibility.Visible;
+ MainItemsButton.Visibility = Visibility.Visible;
+ }
+
+ // ShowUpdateAvailable();
+ }
+
+ private void OpenLogFile(string which, string logFile)
+ {
+ var whichRoot = Path.Combine(MainWindow.ExpectedLogPathRoot, which);
+ try
+ {
+ string target = Native.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 == "ConfigureAutomaticUpgrades")
+ {
+ 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 public void CollectFeedbackLogs(object sender, MouseButtonEventArgs e)
+ {
+ try
+ {
+ MainWindow.ShowLoad("Collecting Information", "Please wait while we run some commands\nand collect some diagnostic information");
+
+ System.Text.StringBuilder sb = new System.Text.StringBuilder();
+ sb.Append("Logs collected at : " + DateTime.Now.ToString());
+ sb.Append(". client version : " + appVersion);
+
+ string timestamp = DateTime.Now.ToFileTime().ToString();
+
+ var dataClient = (DataClient)Application.Current.Properties["ServiceClient"];
+
+ string exeLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ string logLocation = Path.Combine(exeLocation, "logs");
+ string serviceLogsLocation = Path.Combine(logLocation, "service");
+ await dataClient.zitiDump(serviceLogsLocation);
+
+ var monitorClient = (MonitorClient)Application.Current.Properties["MonitorClient"];
+ MonitorServiceStatusEvent resp = await monitorClient.CaptureLogsAsync();
+ if (resp == null)
+ {
+ logger.Error("no response from monitorClient?");
+ MainWindow mw = (MainWindow)Application.Current.MainWindow;
+ mw?.ShowError("Error Collecting Feedback", "An error occurred while trying to gather feedback.\nIs the monitor service running?");
+ return;
+ }
+ string pathToLogs = resp.Message;
+ logger.Info("Log files found at : {0}", resp.Message);
+ string args = string.Format("/Select, \"{0}\"", pathToLogs);
+
+ ProcessStartInfo pfi = new ProcessStartInfo("Explorer.exe", args);
+ Process.Start(pfi);
+ }
+ catch (MonitorServiceException)
+ {
+ MainWindow.ShowError("Could Not Collect Feedback", "The monitor service is offline");
+ }
+ catch (Exception ex)
+ {
+ logger.Warn(ex, "An unexpected error has occurred when submitting feedback? {0}", ex.Message);
+ MainWindow.ShowError("Could Not Collect Feedback", "The monitor service is offline");
+ }
+ MainWindow.HideLoad();
+ }
+
+ 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;
+ 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 == "warn") LogWarn.IsSelected = true;
+ else if (this.LogLevel == "trace") LogTrace.IsSelected = true;
+ }
+
+ async private void SetLevel(object sender, MouseButtonEventArgs e)
+ {
+ SubOptionItem item = (SubOptionItem)sender;
+ if (OnLogLevelChanged != null)
+ {
+ if (await OnLogLevelChanged(this.LogLevel))
+ {
+ this.LogLevel = item.Label.ToLower();
+ }
+ }
+ ResetLevels();
+ }
+
+ private void SetAutomaticUpgradesState()
+ {
+ bool disabled = state.AutomaticUpdatesDisabled;
+ this.AutomaticUpgradesItemOn.IsSelected = !disabled;
+ this.AutomaticUpgradesItemOff.IsSelected = disabled;
+ this.UpdateUrl.Text = state.AutomaticUpdateURL;
+ }
+
+ async private void CheckForUpdate_OnClick(object sender, MouseButtonEventArgs e)
+ {
+ logger.Info("checking for update...");
+ CheckForUpdateStatus.Content = "Checking for updates...";
+ await Task.Delay(1000);
+ if (state.AutomaticUpdateURL != this.UpdateUrl.Text)
+ {
+ SetUpdateUrlButton_Click(sender, e);
+ }
+ try
+ {
+ CheckForUpdate.IsEnabled = false;
+ CheckForUpdateStatus.Visibility = Visibility.Visible;
+ var monitorClient = (MonitorClient)Application.Current.Properties["MonitorClient"];
+ var r = await monitorClient.DoUpdateCheck();
+ checkResponse(r, "Error When Checking for Update", "An error occurred while trying check for update.");
+ CheckForUpdateStatus.Content = r.Message;
+ if (r.UpdateAvailable)
+ {
+ TriggerUpdateButton.Visibility = Visibility.Visible;
+ ForceUpdate.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ TriggerUpdateButton.Visibility = Visibility.Collapsed;
+ ForceUpdate.Visibility = Visibility.Collapsed;
+ }
+ }
+ catch (MonitorServiceException)
+ {
+ CheckForUpdateStatus.Content = "Monitor service is offline";
+ }
+ catch (Exception ex)
+ {
+ logger.Error(ex, "unexpected error in update check: {0}", ex.Message);
+ CheckForUpdateStatus.Content = "Error checking for updates. See logs.";
+ }
+ CheckForUpdate.IsEnabled = true;
+ }
+
+ async private void TriggerUpdate_RoutedEventArgs_Click(object sender, RoutedEventArgs e)
+ {
+ Button src = null;
+ if (sender is Button)
+ {
+ src = sender as Button;
+ }
+ try
+ {
+ CheckForUpdateStatus.Content = "Requesting automatic update...";
+ var monitorClient = (MonitorClient)Application.Current.Properties["MonitorClient"];
+ var r = await monitorClient.TriggerUpdate();
+ CheckForUpdateStatus.Content = "Automatic update requested...";
+ if (r == null)
+ {
+ MainWindow.ShowError("Error When Triggering Update", "An error occurred while trying to trigger the update.");
+ if (src != null) src.IsEnabled = true;
+ }
+ else
+ {
+ this.OnShowBlurb?.Invoke("Update Requested");
+ if (src != null) src.Content = "Request Update Again";
+ UpdateTimeLeft.Content = "Update Requested at " + DateTime.Now;
+ TriggerUpdateButton.Visibility = Visibility.Collapsed;
+ logger.Info(r?.ToString());
+ menuState = "Menu";
+ UpdateState();
+ MainMenuArea.Visibility = Visibility.Collapsed;
+ }
+ }
+ catch (Exception ex)
+ {
+ logger.Error(ex, "unexpected error in update check: {0}", ex.Message);
+ MainWindow.ShowError("Error When Triggering Update", "An error occurred while trying to trigger the update.");
+ if (src != null) src.IsEnabled = true;
+ }
+ }
+
+ public void SetupIdList(ZitiIdentity[] ids)
+ {
+ IdListView.Children.Clear();
+ for (int i = 0; i < ids.Length; i++)
+ {
+ MenuIdentityItem item = new MenuIdentityItem();
+ item.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
+ item.Label = ids[i].Name;
+ item.Identity = ids[i];
+ item.ToggleSwitch.Enabled = ids[i].IsEnabled;
+ IdListView.Children.Add(item);
+ }
+ }
+
+ public void SetAppUpgradeAvailableText(string msg)
+ {
+ this.Dispatcher.Invoke(() =>
+ {
+ VersionOlder.Content = msg;
+ VersionNewer.Content = "";
+ VersionOlder.Visibility = Visibility.Visible;
+ VersionNewer.Visibility = Visibility.Collapsed;
+ });
+ }
+ public void SetAppIsNewer(string msg)
+ {
+ this.Dispatcher.Invoke(() =>
+ {
+ VersionNewer.Content = msg;
+ VersionOlder.Content = "";
+ VersionNewer.Visibility = Visibility.Visible;
+ VersionOlder.Visibility = Visibility.Collapsed;
+ });
+ }
+
+ public void Disconnected()
+ {
+ ConfigItems.IsEnabled = false;
+ ConfigItems.Opacity = 0.3;
+ LogLevelItems.IsEnabled = false;
+ LogLevelItems.Opacity = 0.3;
+ }
+
+ public void Connected()
+ {
+ ConfigItems.IsEnabled = true;
+ ConfigItems.Opacity = 1.0;
+ LogLevelItems.IsEnabled = true;
+ LogLevelItems.Opacity = 1.0;
+ }
+
+ ///
+ /// Save the config information to the properties and queue for update.
+ ///
+ async private void UpdateConfig()
+ {
+ logger.Info("updating config...");
+ DataClient client = (DataClient)Application.Current.Properties["ServiceClient"];
+ try
+ {
+ ComboBoxItem item = (ComboBoxItem)ConfigMaskNew.SelectedValue;
+ var newMaskVar = Int32.Parse(item.Tag.ToString());
+ var addDnsNewVar = Convert.ToBoolean(AddDnsNew.IsChecked);
+ CheckRange();
+ int pageSize = Int32.Parse(ConfigePageSizeNew.Text);
+ ConfigPageSize.Value = ConfigePageSizeNew.Text;
+
+ var r = await client.UpdateConfigAsync(ConfigIpNew.Text, newMaskVar, addDnsNewVar, pageSize);
+ if (r.Code != 0)
+ {
+ this.OnShowBlurb?.Invoke("Error: " + r.Error);
+ logger.Debug("ERROR: {0} : {1}", r.Message, r.Error);
+ }
+ else
+ {
+ this.OnShowBlurb?.Invoke("Config Save, Please Restart Ziti to Update");
+ this.CloseEdit();
+ }
+ logger.Info("Got response from update config task : {0}", r);
+ }
+ catch (DataStructures.ServiceException se)
+ {
+ this.OnShowBlurb?.Invoke("Error: " + se.Message);
+ logger.Error(se, "service exception in update check: {0}", se.Message);
+ }
+ catch (Exception ex)
+ {
+ this.OnShowBlurb?.Invoke("Error: " + ex.Message);
+ logger.Error(ex, "unexpected error in update check: {0}", ex.Message);
+ }
+ }
+
+ ///
+ /// Save the frequency information to the properties and queue for update.
+ ///
+ async private void UpdateFrequency()
+ {
+ logger.Info("updating frequency...");
+ DataClient client = (DataClient)Application.Current.Properties["ServiceClient"];
+ try
+ {
+ var newFrequencyVar = Int32.Parse(Frequency.Text);
+
+ var r = await client.NotificationFrequencyPayloadAsync(newFrequencyVar);
+ if (r.Code != 0)
+ {
+ this.OnShowBlurb?.Invoke("Error: " + r.Error);
+ logger.Debug("ERROR: {0} : {1}", r.Message, r.Error);
+ }
+ else
+ {
+ this.OnShowBlurb?.Invoke("Frequency Saved");
+ this.CloseFrequency();
+ }
+ logger.Info("Got response from update frequency task : {0}", r);
+ }
+ catch (DataStructures.ServiceException se)
+ {
+ this.OnShowBlurb?.Invoke("Error: " + se.Message);
+ logger.Error(se, "service exception in update frequency check: {0}", se.Message);
+ }
+ catch (Exception ex)
+ {
+ this.OnShowBlurb?.Invoke("Error: " + ex.Message);
+ logger.Error(ex, "unexpected error in update frequency check: {0}", ex.Message);
+ }
+ }
+
+
+ ///
+ /// Show the Edit Modal and blur the background
+ ///
+ private void ShowEdit_Click(object sender, MouseButtonEventArgs e)
+ {
+ ConfigIpNew.Text = ConfigIp.Value;
+ ConfigePageSizeNew.Text = ConfigPageSize.Value;
+ CheckRange();
+ for (int i = 0; i < ConfigMaskNew.Items.Count; i++)
+ {
+ ComboBoxItem item = (ComboBoxItem)ConfigMaskNew.Items.GetItemAt(i);
+ if (item.Content.ToString().IndexOf(ConfigSubnet.Value) > 0)
+ {
+ ConfigMaskNew.SelectedIndex = i;
+ break;
+ }
+ }
+ AddDnsNew.IsChecked = false;
+ if (Application.Current.Properties.Contains("dnsenabled"))
+ {
+ AddDnsNew.IsChecked = (bool)Application.Current.Properties["dnsenabled"];
+ }
+ EditArea.Opacity = 0;
+ EditArea.Visibility = Visibility.Visible;
+ EditArea.Margin = new Thickness(0, 0, 0, 0);
+ EditArea.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(1, TimeSpan.FromSeconds(.3)));
+ EditArea.BeginAnimation(Grid.MarginProperty, new ThicknessAnimation(new Thickness(30, 30, 30, 30), TimeSpan.FromSeconds(.3)));
+ ShowModal();
+ }
+
+ ///
+ /// Show the Frequency Modal and blur the background
+ ///
+ private void ShowFrequency()
+ {
+ Frequency.Text = "";
+ FrequencyArea.Opacity = 0;
+ FrequencyArea.Visibility = Visibility.Visible;
+ FrequencyArea.Margin = new Thickness(0, 0, 0, 0);
+ FrequencyArea.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(1, TimeSpan.FromSeconds(.3)));
+ FrequencyArea.BeginAnimation(Grid.MarginProperty, new ThicknessAnimation(new Thickness(30, 30, 30, 30), TimeSpan.FromSeconds(.3)));
+ ShowModal();
+ }
+
+ ///
+ /// Hide the Edit Config
+ ///
+ private void CloseFrequency()
+ {
+ DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3));
+ ThicknessAnimation animateThick = new ThicknessAnimation(new Thickness(0, 0, 0, 0), TimeSpan.FromSeconds(.3));
+ animation.Completed += CloseFrequencyComplete;
+ FrequencyArea.BeginAnimation(Grid.OpacityProperty, animation);
+ FrequencyArea.BeginAnimation(Grid.MarginProperty, animateThick);
+ HideModal();
+ }
+
+ ///
+ /// Close the config window
+ ///
+ /// The close button
+ /// The event arguments
+ private void CloseFrequencyComplete(object sender, EventArgs e)
+ {
+ FrequencyArea.Visibility = Visibility.Collapsed;
+ }
+
+ ///
+ /// Hide the Edit Config
+ ///
+ private void CloseEdit()
+ {
+ DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3));
+ ThicknessAnimation animateThick = new ThicknessAnimation(new Thickness(0, 0, 0, 0), TimeSpan.FromSeconds(.3));
+ animation.Completed += CloseComplete;
+ EditArea.BeginAnimation(Grid.OpacityProperty, animation);
+ EditArea.BeginAnimation(Grid.MarginProperty, animateThick);
+ HideModal();
+ }
+
+ ///
+ /// Show the modal, aniimating opacity
+ ///
+ private void ShowModal()
+ {
+ ModalBg.Visibility = Visibility.Visible;
+ ModalBg.Opacity = 0;
+ DoubleAnimation animation = new DoubleAnimation(.8, TimeSpan.FromSeconds(.3));
+ ModalBg.BeginAnimation(Grid.OpacityProperty, animation);
+ }
+
+ ///
+ /// Close the config window
+ ///
+ /// The close button
+ /// The event arguments
+ private void CloseComplete(object sender, EventArgs e)
+ {
+ EditArea.Visibility = Visibility.Collapsed;
+ }
+
+ ///
+ /// Hide the modal animating the opacity
+ ///
+ private void HideModal()
+ {
+ DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(.3));
+ animation.Completed += ModalHideComplete;
+ ModalBg.BeginAnimation(Grid.OpacityProperty, animation);
+ }
+
+ ///
+ /// When the animation completes, set the visibility to avoid UI object conflicts
+ ///
+ /// The animation
+ /// The event
+ private void ModalHideComplete(object sender, EventArgs e)
+ {
+ ModalBg.Visibility = Visibility.Collapsed;
+ }
+
+ ///
+ /// Close the config editor without saving
+ ///
+ /// The image button
+ /// The click event
+ private void CloseEditConfig(object sender, MouseButtonEventArgs e)
+ {
+ CloseEdit();
+ }
+
+ private void SaveConfig_Click(object sender, MouseButtonEventArgs e)
+ {
+ this.UpdateConfig();
+ }
+
+ private void SaveFrequencyButton_OnClick(object sender, MouseButtonEventArgs e)
+ {
+ UpdateFrequency();
+ }
+
+ private void CloseFrequencyArea(object sender, MouseButtonEventArgs e)
+ {
+ CloseFrequency();
+ }
+
+ private void EditFreqButton_OnClick(object sender, MouseButtonEventArgs e)
+ {
+ ShowFrequency();
+ }
+
+ private void Frequency_KeyUp(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Return)
+ {
+ UpdateFrequency();
+ }
+ }
+
+ private void ConfigePageSizeNew_KeyDown(object sender, KeyEventArgs e)
+ {
+ }
+
+ private void ConfigePageSizeNew_LostFocus(object sender, RoutedEventArgs e)
+ {
+ CheckRange();
+ }
+
+ private void CheckRange()
+ {
+ int defaultVal = 250;
+ string setVal = ConfigePageSizeNew.Text;
+ int value = defaultVal;
+ if (Int32.TryParse(ConfigePageSizeNew.Text, out value))
+ {
+ }
+ if (value < 10 || value > 500) value = defaultVal;
+ ConfigePageSizeNew.Text = value.ToString();
+ }
+
+ private void ResetUrlButton_Click(object sender, RoutedEventArgs e)
+ {
+ UpdateUrl.Text = GithubAPI.ProdUrl;
+ }
+
+ private async void SetUpdateUrlButton_Click(object sender, MouseButtonEventArgs e)
+ {
+ try
+ {
+ var monitorClient = (MonitorClient)Application.Current.Properties["MonitorClient"];
+
+ SvcResponse r = await monitorClient.SetAutomaticUpgradeURLAsync(UpdateUrl.Text);
+ if (r == null)
+ {
+ logger.Error("Failed to set automatic upgrade url! SvcResponse was null?!?!?");
+ MainWindow.ShowError("Could not set url!", "Is the monitor service running?");
+ }
+ else if (r.Code != 0)
+ {
+ logger.Error(r?.Error);
+ MainWindow.ShowError("Could not set url", r?.Error);
+ }
+ else
+ {
+ this.OnShowBlurb?.Invoke("Config Saved.");
+ }
+ }
+ catch (MonitorServiceException)
+ {
+ MainWindow.ShowError("Could Not Set URL", "The monitor service is offline");
+ }
+ catch (Exception ex)
+ {
+ logger.Error("unexpected error when setting automatic upgrade enabled", ex);
+ }
+ }
+
+ private void UpdateUrl_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ logger.Info("url: {}", state.AutomaticUpdateURL);
+ }
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ logger.Info("sender name: {}", sender);
+
+ }
+ }
}
\ No newline at end of file
diff --git a/ZitiDesktopEdge.Client/DataStructures/DataStructures.cs b/ZitiDesktopEdge.Client/DataStructures/DataStructures.cs
index 02ec3a58c..d4fed04a6 100644
--- a/ZitiDesktopEdge.Client/DataStructures/DataStructures.cs
+++ b/ZitiDesktopEdge.Client/DataStructures/DataStructures.cs
@@ -1,20 +1,20 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-using System;
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+using System;
using System.Linq;
using System.Collections.Generic;
@@ -22,8 +22,10 @@ limitations under the License.
/// These classes represent the data structures that are passed back and forth
/// between the service and the client.
///
-namespace ZitiDesktopEdge.DataStructures {
- public enum LogLevelEnum {
+namespace ZitiDesktopEdge.DataStructures
+{
+ public enum LogLevelEnum
+ {
FATAL = 0,
ERROR = 1,
WARN = 2,
@@ -118,112 +120,143 @@ public IdentityToggleFunction(string identifier, bool theBool)
public IdentityTogglePayload Data { get; set; }
}
- public class EnableMFAFunction : ServiceFunction {
- public EnableMFAFunction(string identifier) {
+ public class EnableMFAFunction : ServiceFunction
+ {
+ public EnableMFAFunction(string identifier)
+ {
this.Command = "EnableMFA";
- this.Data = new EnableMFAFunctionPayload() {
+ this.Data = new EnableMFAFunctionPayload()
+ {
Identifier = identifier
};
}
public EnableMFAFunctionPayload Data { get; set; }
}
- public class EnableMFAFunctionPayload {
+ public class EnableMFAFunctionPayload
+ {
public string Identifier { get; set; }
}
- public class VerifyMFAFunction : ServiceFunction {
- public VerifyMFAFunction(string identifier, string code) {
+ public class VerifyMFAFunction : ServiceFunction
+ {
+ public VerifyMFAFunction(string identifier, string code)
+ {
this.Command = "VerifyMFA";
- this.Data = new VerifyMFAFunctionPayload() {
+ this.Data = new VerifyMFAFunctionPayload()
+ {
Identifier = identifier,
Code = code
};
}
public VerifyMFAFunctionPayload Data { get; set; }
}
- public class VerifyMFAFunctionPayload {
+ public class VerifyMFAFunctionPayload
+ {
public string Identifier { get; set; }
public string Code { get; set; }
}
- public class RemoveMFAFunction : ServiceFunction {
- public RemoveMFAFunction(string identifier, string code) {
+ public class RemoveMFAFunction : ServiceFunction
+ {
+ public RemoveMFAFunction(string identifier, string code)
+ {
this.Command = "RemoveMFA";
- this.Data = new RemoveMFAFunctionPayload() {
+ this.Data = new RemoveMFAFunctionPayload()
+ {
Identifier = identifier,
Code = code
};
}
public RemoveMFAFunctionPayload Data { get; set; }
}
- public class RemoveMFAFunctionPayload {
+ public class RemoveMFAFunctionPayload
+ {
public string Identifier { get; set; }
public string Code { get; set; }
}
- public class AuthMFAFunction : ServiceFunction {
- public AuthMFAFunction(string identifier, string code) {
+ public class AuthMFAFunction : ServiceFunction
+ {
+ public AuthMFAFunction(string identifier, string code)
+ {
this.Command = "SubmitMFA";
- this.Data = new AuthMFAFunctionPayload() {
+ this.Data = new AuthMFAFunctionPayload()
+ {
Identifier = identifier,
Code = code
};
}
public AuthMFAFunctionPayload Data { get; set; }
}
- public class AuthMFAFunctionPayload {
+ public class AuthMFAFunctionPayload
+ {
public string Identifier { get; set; }
public string Code { get; set; }
}
- public class GetMFACodesFunction : ServiceFunction {
- public GetMFACodesFunction(string identifier, string code) {
+ public class GetMFACodesFunction : ServiceFunction
+ {
+ public GetMFACodesFunction(string identifier, string code)
+ {
this.Command = "GetMFACodes";
- this.Data = new GetMFACodesFunctionPayload() {
+ this.Data = new GetMFACodesFunctionPayload()
+ {
Identifier = identifier,
Code = code,
};
}
public GetMFACodesFunctionPayload Data { get; set; }
}
- public class GetMFACodesFunctionPayload {
+ public class GetMFACodesFunctionPayload
+ {
public string Identifier { get; set; }
public string Code { get; set; }
}
- public class GenerateMFACodesFunction : ServiceFunction {
- public GenerateMFACodesFunction(string identifier, string code) {
+ public class GenerateMFACodesFunction : ServiceFunction
+ {
+ public GenerateMFACodesFunction(string identifier, string code)
+ {
this.Command = "GenerateMFACodes";
- this.Data = new GenerateMFACodesFunctionPayload() {
+ this.Data = new GenerateMFACodesFunctionPayload()
+ {
Identifier = identifier,
Code = code,
};
}
public GenerateMFACodesFunctionPayload Data { get; set; }
}
- public class GenerateMFACodesFunctionPayload {
+ public class GenerateMFACodesFunctionPayload
+ {
public string Identifier { get; set; }
public string Code { get; set; }
}
- public class SetLogLevelFunction : ServiceFunction {
- public SetLogLevelFunction(string level) {
+ public class SetLogLevelFunction : ServiceFunction
+ {
+ public SetLogLevelFunction(string level)
+ {
this.Command = "SetLogLevel";
- this.Data = new SetLogLevelPayload() {
+ this.Data = new SetLogLevelPayload()
+ {
Level = level
};
}
public SetLogLevelPayload Data { get; set; }
}
- public class ZitiDumpPayloadFunction {
+ public class ZitiDumpPayloadFunction
+ {
public string DumpPath { get; set; }
}
- public class ZitiDumpFunction : ServiceFunction {
- public ZitiDumpFunction(string dumpPath) {
+ public class ZitiDumpFunction : ServiceFunction
+ {
+ public ZitiDumpFunction(string dumpPath)
+ {
this.Command = "ZitiDump";
- this.Data = new ZitiDumpPayloadFunction() {
+ this.Data = new ZitiDumpPayloadFunction()
+ {
DumpPath = dumpPath
};
}
@@ -235,13 +268,13 @@ public class IdentifierPayload
public string Identifier { get; set; }
}
- public class EnrollIdentifierPayload
+ public class EnrollIdentifierPayload
{
public string JwtFileName { get; set; }
public string JwtContent { get; set; }
- }
+ }
- public class EnrollIdentifierFunction : ServiceFunction
+ public class EnrollIdentifierFunction : ServiceFunction
{
public EnrollIdentifierPayload Data { get; set; }
}
@@ -266,7 +299,8 @@ public class Metrics
public long Down { get; set; }
}
- public class Identity {
+ public class Identity
+ {
public string Name { get; set; }
public string FingerPrint { get; set; }
public string Identifier { get; set; }
@@ -284,7 +318,8 @@ public class Identity {
}
- public class Service {
+ public class Service
+ {
public string Name { get; set; }
public string[] Protocols { get; set; }
public Address[] Addresses { get; set; }
@@ -293,41 +328,54 @@ public class Service {
public string AssignedIP { get; set; }
public PostureCheck[] PostureChecks { get; set; }
public bool IsAccessible { get; set; }
- public int Timeout { get; set; }
- public int TimeoutRemaining { get; set; }
- }
+ public int Timeout { get; set; }
+ public int TimeoutRemaining { get; set; }
+ }
- public class Address {
+ public class Address
+ {
public bool IsHost { get; set; }
public string Hostname { get; set; }
public string IP { get; set; }
public int Prefix { get; set; }
- public override string ToString() {
- if (IsHost) {
+ public override string ToString()
+ {
+ if (IsHost)
+ {
return Hostname;
- } else if (Prefix == 0) {
+ }
+ else if (Prefix == 0)
+ {
return IP;
- } else {
+ }
+ else
+ {
return IP + "/" + Prefix;
}
}
}
- public class PortRange {
+ public class PortRange
+ {
public int High { get; set; }
public int Low { get; set; }
- public override string ToString() {
- if (Low == High) {
+ public override string ToString()
+ {
+ if (Low == High)
+ {
return Low.ToString();
- } else {
+ }
+ else
+ {
return Low + "-" + High;
}
}
}
- public class PostureCheck {
+ public class PostureCheck
+ {
public bool IsPassing { get; set; }
public string QueryType { get; set; }
public string Id { get; set; }
@@ -361,7 +409,8 @@ public override string ToString()
}
}
- public class Notification {
+ public class Notification
+ {
public string IdentityName { get; set; }
public string Identifier { get; set; }
public string Fingerprint { get; set; }
@@ -394,10 +443,12 @@ public class TunnelStatus
public void Dump(System.IO.TextWriter writer)
{
- try {
+ try
+ {
writer.WriteLine($" LogLevel : {LogLevel}");
writer.WriteLine($" EvaluatedLogLevel: {EvaluateLogLevel()}");
- foreach (Identity id in Identities) {
+ foreach (Identity id in Identities)
+ {
writer.WriteLine($" Identifier: {id.Identifier}");
writer.WriteLine($" Name : {id.Name}");
writer.WriteLine($" Active : {id.Active}");
@@ -407,22 +458,24 @@ public void Dump(System.IO.TextWriter writer)
{
foreach (Service s in id?.Services)
{
- //xxfix writer.WriteLine($" Name: {s.Name} Protocols: {string.Join(",", s.Protocols)} Addresses: {string.Join(",", s.Addresses)} Ports: {string.Join(",", s.Ports)}");
+ //xxfix writer.WriteLine($" Name: {s.Name} Protocols: {string.Join(",", s.Protocols)} Addresses: {string.Join(",", s.Addresses)} Ports: {string.Join(",", s.Ports)}");
}
}
writer.WriteLine("=============================================");
}
- } catch (Exception e) {
- if (writer!=null) writer.WriteLine(e.ToString());
- }
-
+ }
+ catch (Exception e)
+ {
+ if (writer != null) writer.WriteLine(e.ToString());
+ }
+
}
public LogLevelEnum EvaluateLogLevel()
{
try
{
- LogLevelEnum l = (LogLevelEnum) Enum.Parse(typeof(LogLevelEnum), LogLevel.ToUpper());
+ LogLevelEnum l = (LogLevelEnum)Enum.Parse(typeof(LogLevelEnum), LogLevel.ToUpper());
return l;
}
catch
@@ -464,17 +517,20 @@ public class MetricsEvent : StatusEvent
public List Identities { get; set; }
}
- public class NotificationEvent : StatusEvent {
+ public class NotificationEvent : StatusEvent
+ {
public List Notification { get; set; }
}
- public class ServiceEvent : ActionEvent {
+ public class ServiceEvent : ActionEvent
+ {
public string Identifier { get; set; }
public Service Service { get; set; }
}
- public class BulkServiceEvent : ActionEvent {
+ public class BulkServiceEvent : ActionEvent
+ {
public string Identifier { get; set; }
public List AddedServices { get; set; }
public List RemovedServices { get; set; }
@@ -484,57 +540,66 @@ public class IdentityEvent : ActionEvent
{
public Identity Id { get; set; }
}
-
+
public class LogLevelEvent : ActionEvent
{
public string LogLevel { get; set; }
}
- public class MonitorServiceStatusEvent : SvcResponse {
+ public class MonitorServiceStatusEvent : SvcResponse
+ {
public string Status { get; set; }
public string ReleaseStream { get; set; }
public string AutomaticUpgradeDisabled { get; set; }
public string AutomaticUpgradeURL { get; set; }
- public bool IsStopped() {
+ public bool IsStopped()
+ {
return "Stopped" == this.Status;
}
public string Type { get; set; }
}
- public class StatusCheck : MonitorServiceStatusEvent {
+ public class StatusCheck : MonitorServiceStatusEvent
+ {
public bool UpdateAvailable { get; set; }
}
- public class InstallationNotificationEvent : MonitorServiceStatusEvent {
+ public class InstallationNotificationEvent : MonitorServiceStatusEvent
+ {
public string ZDEVersion { get; set; }
public DateTime InstallTime { get; set; }
public DateTime PublishTime { get; set; }
public TimeSpan NotificationDuration { get; set; }
}
- public class UrlUpdateEvent : MonitorServiceStatusEvent {
+ public class UrlUpdateEvent : MonitorServiceStatusEvent
+ {
public string URL { get; set; }
}
- public class MfaEvent : ActionEvent {
+ public class MfaEvent : ActionEvent
+ {
public string Identifier { get; set; }
public bool Successful { get; set; }
public string ProvisioningUrl { get; set; }
public List RecoveryCodes { get; set; }
}
- public class ControllerEvent : ActionEvent {
+ public class ControllerEvent : ActionEvent
+ {
public string Identifier { get; set; }
}
- public class MfaRecoveryCodes {
+ public class MfaRecoveryCodes
+ {
public string[] RecoveryCodes { get; set; }
public string Identifier { get; set; }
}
- public class MfaRecoveryCodesResponse : SvcResponse {
+ public class MfaRecoveryCodesResponse : SvcResponse
+ {
public MfaRecoveryCodes Data { get; set; }
}
@@ -562,20 +627,24 @@ public ConfigUpdateFunction(string tunIPv4, int tunPrefixLength, bool addDns, in
public ConfigPayload Data { get; set; }
}
- public class NotificationFrequencyPayload {
+ public class NotificationFrequencyPayload
+ {
public int NotificationFrequency { get; set; }
}
- public class NotificationFrequencyFunction : ServiceFunction {
- public NotificationFrequencyFunction(int notificationFrequency) {
+ public class NotificationFrequencyFunction : ServiceFunction
+ {
+ public NotificationFrequencyFunction(int notificationFrequency)
+ {
this.Command = "UpdateFrequency";
- this.Data = new NotificationFrequencyPayload() {
+ this.Data = new NotificationFrequencyPayload()
+ {
NotificationFrequency = notificationFrequency
};
}
-
+
public NotificationFrequencyPayload Data { get; set; }
- }
+ }
}
diff --git a/ZitiDesktopEdge.Client/Properties/AssemblyInfo.cs b/ZitiDesktopEdge.Client/Properties/AssemblyInfo.cs
index 958e1ef5f..90e18f2bf 100644
--- a/ZitiDesktopEdge.Client/Properties/AssemblyInfo.cs
+++ b/ZitiDesktopEdge.Client/Properties/AssemblyInfo.cs
@@ -1,20 +1,20 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-using System.Reflection;
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
diff --git a/ZitiDesktopEdge.Client/Server/EventRegistry.cs b/ZitiDesktopEdge.Client/Server/EventRegistry.cs
index 816306bce..c04ea2cc9 100644
--- a/ZitiDesktopEdge.Client/Server/EventRegistry.cs
+++ b/ZitiDesktopEdge.Client/Server/EventRegistry.cs
@@ -1,30 +1,33 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-using Newtonsoft.Json;
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+using Newtonsoft.Json;
using System;
using System.Threading;
-namespace ZitiDesktopEdge.Server {
- public class EventRegistry {
+namespace ZitiDesktopEdge.Server
+{
+ public class EventRegistry
+ {
protected static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 1);
public static event EventHandler MyEvent;
- public static void SendEventToConsumers(object objToSend) {
+ public static void SendEventToConsumers(object objToSend)
+ {
MyEvent?.Invoke(JsonConvert.SerializeObject(objToSend), null);
}
}
diff --git a/ZitiDesktopEdge.Client/Server/IPCServer.cs b/ZitiDesktopEdge.Client/Server/IPCServer.cs
index bb275daa3..979f27c53 100644
--- a/ZitiDesktopEdge.Client/Server/IPCServer.cs
+++ b/ZitiDesktopEdge.Client/Server/IPCServer.cs
@@ -1,20 +1,20 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-using System;
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+using System;
using System.Threading.Tasks;
using System.IO;
using System.IO.Pipes;
@@ -26,8 +26,10 @@ limitations under the License.
using ZitiDesktopEdge.DataStructures;
-namespace ZitiDesktopEdge.Server {
- public class IPCServer {
+namespace ZitiDesktopEdge.Server
+{
+ public class IPCServer
+ {
public const string PipeName = @"OpenZiti\ziti-monitor\ipc";
public const string EventPipeName = @"OpenZiti\ziti-monitor\events";
@@ -62,12 +64,14 @@ public class IPCServer {
public SetAutomaticUpdateDisabledDelegate SetAutomaticUpdateDisabled { get; set; }
public SetAutomaticUpdateURLDelegate SetAutomaticUpdateURL { get; set; }
- public IPCServer() {
+ public IPCServer()
+ {
ipcPipeName = PipeName;
eventPipeName = EventPipeName;
}
- async public Task startIpcServerAsync(OnClientAsync onClient) {
+ async public Task startIpcServerAsync(OnClientAsync onClient)
+ {
int idx = 0;
// Allow AuthenticatedUserSid read and write access to the pipe.
@@ -75,8 +79,10 @@ async public Task startIpcServerAsync(OnClientAsync onClient) {
var id = new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null);
pipeSecurity.SetAccessRule(new PipeAccessRule(id, PipeAccessRights.CreateNewInstance | PipeAccessRights.ReadWrite, AccessControlType.Allow));
- while (true) {
- try {
+ while (true)
+ {
+ try
+ {
var ipcPipeServer = new NamedPipeServerStream(
ipcPipeName,
PipeDirection.InOut,
@@ -88,24 +94,31 @@ async public Task startIpcServerAsync(OnClientAsync onClient) {
pipeSecurity);
await ipcPipeServer.WaitForConnectionAsync();
-
+
Logger.Debug("Total ipc clients now at: {0}", ++idx);
- _ = Task.Run(async () => {
- try {
+ _ = Task.Run(async () =>
+ {
+ try
+ {
await handleIpcClientAsync(ipcPipeServer, onClient);
- } catch(Exception icpe) {
+ }
+ catch (Exception icpe)
+ {
Logger.Error(icpe, "Unexpected error in handleIpcClientAsync");
}
idx--;
Logger.Debug("Total ipc clients now at: {0}", idx);
});
- } catch (Exception pe) {
+ }
+ catch (Exception pe)
+ {
Logger.Error(pe, "Unexpected error when connecting a client pipe.");
}
}
}
- async public Task startEventsServerAsync(OnClientAsync onClient) {
+ async public Task startEventsServerAsync(OnClientAsync onClient)
+ {
int idx = 0;
// Allow AuthenticatedUserSid read and write access to the pipe.
@@ -113,8 +126,10 @@ async public Task startEventsServerAsync(OnClientAsync onClient) {
var id = new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null);
pipeSecurity.SetAccessRule(new PipeAccessRule(id, PipeAccessRights.CreateNewInstance | PipeAccessRights.ReadWrite, AccessControlType.Allow));
- while (true) {
- try {
+ while (true)
+ {
+ try
+ {
var eventPipeServer = new NamedPipeServerStream(
eventPipeName,
PipeDirection.InOut,
@@ -127,55 +142,77 @@ async public Task startEventsServerAsync(OnClientAsync onClient) {
await eventPipeServer.WaitForConnectionAsync();
Logger.Debug("Total event clients now at: {0}", ++idx);
- _ = Task.Run(async () => {
- try {
+ _ = Task.Run(async () =>
+ {
+ try
+ {
await handleEventClientAsync(eventPipeServer, onClient);
- } catch (Exception icpe) {
- if (icpe.Message.StartsWith("Service ziti was not found on computer")) {
+ }
+ catch (Exception icpe)
+ {
+ if (icpe.Message.StartsWith("Service ziti was not found on computer"))
+ {
//ignore this for now...
- } else {
+ }
+ else
+ {
Logger.Error(icpe, "Unexpected error in handleEventClientAsync");
}
}
idx--;
Logger.Debug("Total event clients now at: {0}", idx);
});
- } catch (Exception pe) {
+ }
+ catch (Exception pe)
+ {
Logger.Error(pe, "Unexpected error when connecting a client pipe.");
}
}
}
- async public Task handleIpcClientAsync(NamedPipeServerStream ss, OnClientAsync onClient) {
- using (ss) {
- try {
+ async public Task handleIpcClientAsync(NamedPipeServerStream ss, OnClientAsync onClient)
+ {
+ using (ss)
+ {
+ try
+ {
StreamReader reader = new StreamReader(ss);
StreamWriter writer = new StreamWriter(ss);
string line = await reader.ReadLineAsync();
- while (line != null) {
+ while (line != null)
+ {
await processMessageAsync(line, writer);
line = await reader.ReadLineAsync();
}
Logger.Debug("handleIpcClientAsync is complete");
- } catch (Exception e) {
+ }
+ catch (Exception e)
+ {
Logger.Error(e, "Unexpected error when reading from or writing to a client pipe.");
}
}
}
- async public Task handleEventClientAsync(NamedPipeServerStream ss, OnClientAsync onClient) {
- try {
- using (ss) {
+ async public Task handleEventClientAsync(NamedPipeServerStream ss, OnClientAsync onClient)
+ {
+ try
+ {
+ using (ss)
+ {
StreamWriter writer = new StreamWriter(ss);
- EventHandler eh = async (object sender, EventArgs e) => {
- try {
+ EventHandler eh = async (object sender, EventArgs e) =>
+ {
+ try
+ {
await writer.WriteLineAsync(sender.ToString());
await writer.FlushAsync();
- } catch (Exception ex) {
+ }
+ catch (Exception ex)
+ {
Logger.Error("problem with event handler in handleEventClientAsync: {}", ex.Message);
}
};
@@ -186,7 +223,8 @@ async public Task handleEventClientAsync(NamedPipeServerStream ss, OnClientAsync
StreamReader reader = new StreamReader(ss);
string line = await reader.ReadLineAsync();
- while (line != null) {
+ while (line != null)
+ {
await processMessageAsync(line, writer);
line = await reader.ReadLineAsync();
}
@@ -194,25 +232,32 @@ async public Task handleEventClientAsync(NamedPipeServerStream ss, OnClientAsync
Logger.Debug("handleEventClientAsync is complete");
EventRegistry.MyEvent -= eh;
}
- } catch (Exception e) {
+ }
+ catch (Exception e)
+ {
Logger.Error(e, "Unexpected error when reading from or writing to a client pipe.");
}
}
- async public Task processMessageAsync(string json, StreamWriter writer) {
+ async public Task processMessageAsync(string json, StreamWriter writer)
+ {
Logger.Debug("message received: {0}", json);
var r = new SvcResponse();
var rr = new MonitorServiceStatusEvent();
- try {
+ try
+ {
ActionEvent ae = serializer.Deserialize(new JsonTextReader(new StringReader(json)));
Logger.Debug("Op: {0}", ae.Op);
- switch (ae.Op.ToLower()) {
+ switch (ae.Op.ToLower())
+ {
case "stop":
- if (ae.Action == "Force") {
+ if (ae.Action == "Force")
+ {
// attempt to forcefully find the process and terminate it...
Logger.Warn("User has requested a FORCEFUL termination of the service. It must be stuck. Current status: {0}", ServiceActions.ServiceStatus());
var procs = System.Diagnostics.Process.GetProcessesByName("ziti-edge-tunnel");
- if (procs == null || procs.Length == 0) {
+ if (procs == null || procs.Length == 0)
+ {
Logger.Error("Process not found! Cannot terminate!");
rr.Code = -20;
rr.Error = "Process not found! Cannot terminate!";
@@ -220,14 +265,17 @@ async public Task processMessageAsync(string json, StreamWriter writer) {
break;
}
- foreach(var p in procs) {
+ foreach (var p in procs)
+ {
Logger.Warn("Forcefully terminating process: {0}", p.Id);
p.Kill();
}
rr.Message = "Service has been terminated";
rr.Status = ServiceActions.ServiceStatus();
r = rr;
- } else {
+ }
+ else
+ {
r.Message = ServiceActions.StopService();
}
break;
@@ -239,10 +287,13 @@ async public Task processMessageAsync(string json, StreamWriter writer) {
r = rr;
break;
case "capturelogs":
- try {
+ try
+ {
string results = CaptureLogs();
r.Message = results;
- } catch (Exception ex) {
+ }
+ catch (Exception ex)
+ {
string err = string.Format("UNKNOWN ERROR : {0}", ex.Message);
Logger.Error(ex, err);
r.Code = -5;
@@ -275,7 +326,9 @@ async public Task processMessageAsync(string json, StreamWriter writer) {
Logger.Error(r.Message);
break;
}
- } catch (Exception e) {
+ }
+ catch (Exception e)
+ {
Logger.Error(e, "Unexpected error in processMessage!");
r.Message = "FAILURE: " + e.Message;
r.Code = -2;
@@ -287,7 +340,8 @@ async public Task processMessageAsync(string json, StreamWriter writer) {
}
}
- public enum ErrorCodes {
+ public enum ErrorCodes
+ {
NO_ERROR = 0,
COULD_NOT_SET_URL,
URL_INVALID,
diff --git a/ZitiDesktopEdge.Client/Server/ServiceActions.cs b/ZitiDesktopEdge.Client/Server/ServiceActions.cs
index 08cbd7a89..ce147f54f 100644
--- a/ZitiDesktopEdge.Client/Server/ServiceActions.cs
+++ b/ZitiDesktopEdge.Client/Server/ServiceActions.cs
@@ -1,42 +1,47 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
*/
using System;
using System.Diagnostics;
-using System.Linq;
+using System.Linq;
using System.Management;
using System.ServiceProcess;
using NLog;
-namespace ZitiDesktopEdge.Server {
- public static class ServiceActions {
+namespace ZitiDesktopEdge.Server
+{
+ public static class ServiceActions
+ {
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private static int serviceWaitTime = 60; //one minute
private static ServiceController sc = new ServiceController("ziti");
- public static string ServiceStatus() {
+ public static string ServiceStatus()
+ {
var status = sc.Status;
Logger.Debug("service status asked for. current value: {0}", sc.Status);
- if (sc.Status == ServiceControllerStatus.StopPending) {
+ if (sc.Status == ServiceControllerStatus.StopPending)
+ {
//ServiceControllerStatus is reporting 'stop pending' when the service crashes or is terminated by a user
//this is INCORRECT as the service is dead - it is not pending. Test for the process by name and if there's
//still a process - cool. if NOT - send the 'stopped' message...
var procs = System.Diagnostics.Process.GetProcessesByName("ziti-edge-tunnel");
- if (procs != null && procs.Length == 1) {
+ if (procs != null && procs.Length == 1)
+ {
// if there's more than one ziti-edge-tunnel that'd be bad too but we can't account for that here
Logger.Warn("ServiceControllerStatus is StopPending but there is NO ziti-edge-tunnel process! report service is stopped");
return ServiceControllerStatus.Stopped.ToString();
@@ -45,7 +50,8 @@ public static string ServiceStatus() {
return status.ToString();
}
- public static string StartService() {
+ public static string StartService()
+ {
Logger.Info($"request to start ziti service received... waiting up to {serviceWaitTime}s for service start...");
sc.Start();
sc.WaitForStatus(ServiceControllerStatus.Running, new System.TimeSpan(0, 0, serviceWaitTime));
@@ -53,28 +59,39 @@ public static string StartService() {
return ServiceStatus();
}
- public static string StopService() {
- try {
+ public static string StopService()
+ {
+ try
+ {
Logger.Info($"request to stop ziti service received... waiting up to {serviceWaitTime}s for service stop...");
sc.Stop();
sc.WaitForStatus(ServiceControllerStatus.Stopped, new System.TimeSpan(0, 0, serviceWaitTime));
Logger.Info("request to stop ziti service received... complete...");
return ServiceStatus();
- } catch (Exception e) {
+ }
+ catch (Exception e)
+ {
Logger.Error("failed to stop service using ServiceController. Attempting to find and kill the ziti process directly");
var zetProcesses = Process.GetProcesses().Where(p => p.ProcessName == "ziti-edge-tunnel");
- foreach (var process in zetProcesses) {
- try {
+ foreach (var process in zetProcesses)
+ {
+ try
+ {
Logger.Warn($"attempting to forcefully terminate process: {process.Id}");
process.Kill();
- if (process.WaitForExit(30 * 1000)) { // wait for 30s
+ if (process.WaitForExit(30 * 1000))
+ { // wait for 30s
Logger.Warn($"terminated process forcefully: {process.Id}");
- } else {
+ }
+ else
+ {
Logger.Error($"waited 30s, could not terminate process: {process.Id}");
}
- } catch (Exception ex) {
+ }
+ catch (Exception ex)
+ {
Logger.Error($"failed to forcefully terminate process: {process.Id}!!! Error Msg: {ex.Message}");
}
}
@@ -88,7 +105,8 @@ public static string StopService() {
}
}
- static void RemoveNrptRules() {
+ static void RemoveNrptRules()
+ {
Process nrptRuleProcess = new Process();
ProcessStartInfo nrptRuleStartInfo = new ProcessStartInfo();
nrptRuleStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
@@ -98,23 +116,31 @@ static void RemoveNrptRules() {
Logger.Info("Running: {0}", nrptRuleStartInfo.Arguments);
nrptRuleProcess.StartInfo = nrptRuleStartInfo;
nrptRuleProcess.Start();
- if (nrptRuleProcess.WaitForExit(60 * 1000)) { // wait for 60s
+ if (nrptRuleProcess.WaitForExit(60 * 1000))
+ { // wait for 60s
Logger.Debug("NRPT rules have been removed");
- } else {
+ }
+ else
+ {
Logger.Error($"waited 60s, could not remove NRPT rules?!");
}
}
- static void RemoveZitiTunInterfaces() {
+ static void RemoveZitiTunInterfaces()
+ {
string query = "SELECT * FROM Win32_NetworkAdapter WHERE Name LIKE 'ziti%'";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection results = searcher.Get();
- foreach (ManagementObject obj in results) {
- try {
+ foreach (ManagementObject obj in results)
+ {
+ try
+ {
obj.InvokeMethod("Disable", null);
Console.WriteLine("Disabled interface: " + obj["Name"]);
- } catch (Exception e) {
+ }
+ catch (Exception e)
+ {
Console.WriteLine("Error disabling interface: " + obj["Name"] + " - " + e.Message);
}
}
diff --git a/ZitiDesktopEdge.Client/ServiceClient/AbstractClient.cs b/ZitiDesktopEdge.Client/ServiceClient/AbstractClient.cs
index 01725a4f7..57411fbd4 100644
--- a/ZitiDesktopEdge.Client/ServiceClient/AbstractClient.cs
+++ b/ZitiDesktopEdge.Client/ServiceClient/AbstractClient.cs
@@ -1,20 +1,20 @@
-/*
- Copyright NetFoundry Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-using System;
+/*
+ Copyright NetFoundry Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
@@ -31,8 +31,10 @@ limitations under the License.
using ZitiDesktopEdge.DataStructures;
using System.Reflection;
-namespace ZitiDesktopEdge.ServiceClient {
- public abstract class AbstractClient {
+namespace ZitiDesktopEdge.ServiceClient
+{
+ public abstract class AbstractClient
+ {
public event EventHandler