Merge pull request #368 from openziti/release-next

Release next
This commit is contained in:
mary-dcouto
2021-04-22 17:17:40 +05:30
committed by GitHub
42 changed files with 2163 additions and 856 deletions
+412 -10
View File
@@ -1,7 +1,8 @@
<Application x:Class="ZitiDesktopEdge.App"
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ZitiDesktopEdge"
xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2" x:Class="ZitiDesktopEdge.App"
ShutdownMode="OnExplicitShutdown"
StartupUri="MainWindow.xaml">
<Application.Resources>
@@ -18,7 +19,7 @@
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid x:Name="grid">
<Border x:Name="border" CornerRadius="12" BorderThickness="0"></Border>
<Border x:Name="border" CornerRadius="12" BorderThickness="0"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
@@ -33,7 +34,7 @@
</Setter>
</Style>
<Style TargetType="FrameworkElement" x:Key="VisibleAnimation">
<Style TargetType="{x:Type FrameworkElement}" x:Key="VisibleAnimation">
<Setter Property="Visibility" Value="Collapsed"/>
<Setter Property="Opacity" Value="0"/>
<Style.Triggers>
@@ -49,13 +50,13 @@
</Style.Triggers>
</Style>
<Style x:Key="MyButton" TargetType="Button">
<Style x:Key="MyButton" TargetType="{x:Type Button}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border" BorderThickness="0" BorderBrush="Black" Background="{TemplateBinding Background}">
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderThickness="0" BorderBrush="Black" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
@@ -92,7 +93,8 @@
<Style x:Key="{x:Type ScrollBar}" TargetType="{x:Type ScrollBar}">
<Setter Property="Stylus.IsFlicksEnabled" Value="true" />
<Setter Property="Foreground" Value="#d4d9e2" />
<Setter Property="Background" Value="#000F0F23" /> <!-- invalid on purpose -->
<Setter Property="Background" Value="#000F0F23" />
<!-- invalid on purpose -->
<Setter Property="Width" Value="3" />
<Setter Property="Opacity" Value="0.6"/>
<Setter Property="Template">
@@ -149,14 +151,14 @@
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ComboBoxTextBoxStyle" TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Border CornerRadius="5,0,0,5"
BorderThickness="1"
<Border CornerRadius="7"
BorderThickness="4"
Background="{TemplateBinding Background}"
BorderBrush="Black">
<ScrollViewer x:Name="PART_ContentHost"/>
@@ -167,5 +169,405 @@
</Setter>
</Style>
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle StrokeDashArray="1 2" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" Margin="2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<LinearGradientBrush x:Key="ComboBox.Static.Background" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFFFFFFF" Offset="0.0"/>
<GradientStop Color="#FFFFFFFF" Offset="1.0"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ComboBox.Static.Border" Color="#FFACACAC"/>
<SolidColorBrush x:Key="ComboBox.Static.Editable.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="ComboBox.Static.Editable.Border" Color="#FFABADB3"/>
<SolidColorBrush x:Key="ComboBox.Static.Editable.Button.Background" Color="Transparent"/>
<SolidColorBrush x:Key="ComboBox.Static.Editable.Button.Border" Color="Transparent"/>
<SolidColorBrush x:Key="ComboBox.MouseOver.Glyph" Color="#FF000000"/>
<LinearGradientBrush x:Key="ComboBox.MouseOver.Background" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFECF4FC" Offset="0.0"/>
<GradientStop Color="#FFDCECFC" Offset="1.0"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ComboBox.MouseOver.Border" Color="#FF7EB4EA"/>
<SolidColorBrush x:Key="ComboBox.MouseOver.Editable.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="ComboBox.MouseOver.Editable.Border" Color="#FF7EB4EA"/>
<LinearGradientBrush x:Key="ComboBox.MouseOver.Editable.Button.Background" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFEBF4FC" Offset="0.0"/>
<GradientStop Color="#FFDCECFC" Offset="1.0"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ComboBox.MouseOver.Editable.Button.Border" Color="#FF7EB4EA"/>
<SolidColorBrush x:Key="ComboBox.Pressed.Glyph" Color="#FF000000"/>
<LinearGradientBrush x:Key="ComboBox.Pressed.Background" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFDAECFC" Offset="0.0"/>
<GradientStop Color="#FFC4E0FC" Offset="1.0"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ComboBox.Pressed.Border" Color="#FF569DE5"/>
<SolidColorBrush x:Key="ComboBox.Pressed.Editable.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="ComboBox.Pressed.Editable.Border" Color="#FF569DE5"/>
<LinearGradientBrush x:Key="ComboBox.Pressed.Editable.Button.Background" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFDAEBFC" Offset="0.0"/>
<GradientStop Color="#FFC4E0FC" Offset="1.0"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ComboBox.Pressed.Editable.Button.Border" Color="#FF569DE5"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Glyph" Color="#FFBFBFBF"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Background" Color="#FFF0F0F0"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Border" Color="#FFD9D9D9"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Editable.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Editable.Border" Color="#FFBFBFBF"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Editable.Button.Background" Color="Transparent"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Editable.Button.Border" Color="Transparent"/>
<SolidColorBrush x:Key="ComboBox.Static.Glyph" Color="#FF606060"/>
<Style x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Focusable" Value="false"/>
<Setter Property="ClickMode" Value="Press"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border x:Name="templateRoot" SnapsToDevicePixels="true" Background="{StaticResource ComboBox.Static.Background}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="7" BorderBrush="{StaticResource ComboBox.Static.Border}">
<Border x:Name="splitBorder" Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" SnapsToDevicePixels="true" Margin="0" HorizontalAlignment="Right" BorderThickness="1" BorderBrush="Transparent">
<Path x:Name="arrow" VerticalAlignment="Center" Margin="0" HorizontalAlignment="Center" Fill="{StaticResource ComboBox.Static.Glyph}" Data="F1 M 0,0 L 2.667,2.66665 L 5.3334,0 L 5.3334,-1.78168 L 2.6667,0.88501 L0,-1.78168 L0,0 Z"/>
</Border>
</Border>
<ControlTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="false"/>
<Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Self}}" Value="false"/>
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="true"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Static.Editable.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Static.Editable.Border}"/>
<Setter Property="Background" TargetName="splitBorder" Value="{StaticResource ComboBox.Static.Editable.Button.Background}"/>
<Setter Property="BorderBrush" TargetName="splitBorder" Value="{StaticResource ComboBox.Static.Editable.Button.Border}"/>
</MultiDataTrigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Fill" TargetName="arrow" Value="{StaticResource ComboBox.MouseOver.Glyph}"/>
</Trigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="true"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="false"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.MouseOver.Border}"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="true"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.MouseOver.Editable.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.MouseOver.Editable.Border}"/>
<Setter Property="Background" TargetName="splitBorder" Value="{StaticResource ComboBox.MouseOver.Editable.Button.Background}"/>
<Setter Property="BorderBrush" TargetName="splitBorder" Value="{StaticResource ComboBox.MouseOver.Editable.Button.Border}"/>
</MultiDataTrigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Fill" TargetName="arrow" Value="{StaticResource ComboBox.Pressed.Glyph}"/>
</Trigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Self}}" Value="true"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="false"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Pressed.Border}"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Self}}" Value="true"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Pressed.Editable.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Pressed.Editable.Border}"/>
<Setter Property="Background" TargetName="splitBorder" Value="{StaticResource ComboBox.Pressed.Editable.Button.Background}"/>
<Setter Property="BorderBrush" TargetName="splitBorder" Value="{StaticResource ComboBox.Pressed.Editable.Button.Border}"/>
</MultiDataTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Fill" TargetName="arrow" Value="{StaticResource ComboBox.Disabled.Glyph}"/>
</Trigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="false"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Disabled.Border}"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Disabled.Editable.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Disabled.Editable.Border}"/>
<Setter Property="Background" TargetName="splitBorder" Value="{StaticResource ComboBox.Disabled.Editable.Button.Background}"/>
<Setter Property="BorderBrush" TargetName="splitBorder" Value="{StaticResource ComboBox.Disabled.Editable.Button.Border}"/>
</MultiDataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="ComboBoxTemplate" TargetType="{x:Type ComboBox}">
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0"/>
</Grid.ColumnDefinitions>
<Popup x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Themes:SystemDropShadowChrome x:Name="shadow" Color="Transparent" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}">
<Border x:Name="dropDownBorder" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
<ScrollViewer x:Name="DropDownScrollViewer">
<Grid x:Name="grid" RenderOptions.ClearTypeHint="Enabled">
<Canvas x:Name="canvas" HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect" Fill="{Binding Background, ElementName=dropDownBorder}" Height="{Binding ActualHeight, ElementName=dropDownBorder}" Width="{Binding ActualWidth, ElementName=dropDownBorder}"/>
</Canvas>
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Grid>
</ScrollViewer>
</Border>
</Themes:SystemDropShadowChrome>
</Popup>
<ToggleButton x:Name="toggleButton" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ComboBoxToggleButton}"/>
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" Content="{TemplateBinding SelectionBoxItem}" ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" IsHitTestVisible="false" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasDropShadow" SourceName="PART_Popup" Value="true">
<Setter Property="Margin" TargetName="shadow" Value="0,0,5,5"/>
<Setter Property="Color" TargetName="shadow" Value="#71000000"/>
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter Property="Height" TargetName="dropDownBorder" Value="95"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true"/>
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</MultiTrigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer" Value="false">
<Setter Property="Canvas.Top" TargetName="opaqueRect" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer}"/>
<Setter Property="Canvas.Left" TargetName="opaqueRect" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<SolidColorBrush x:Key="TextBox.Static.Background" Color="#FFFFFFFF"/>
<Style x:Key="ComboBoxEditableTextBox" TargetType="{x:Type TextBox}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="MinWidth" Value="0"/>
<Setter Property="MinHeight" Value="0"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<ScrollViewer x:Name="PART_ContentHost" Background="Transparent" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="ComboBoxEditableTemplate" TargetType="{x:Type ComboBox}">
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0"/>
</Grid.ColumnDefinitions>
<Popup x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Themes:SystemDropShadowChrome x:Name="shadow" Color="Transparent" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}">
<Border x:Name="dropDownBorder" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
<ScrollViewer x:Name="DropDownScrollViewer">
<Grid x:Name="grid" RenderOptions.ClearTypeHint="Enabled">
<Canvas x:Name="canvas" HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect" Fill="{Binding Background, ElementName=dropDownBorder}" Height="{Binding ActualHeight, ElementName=dropDownBorder}" Width="{Binding ActualWidth, ElementName=dropDownBorder}"/>
</Canvas>
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Grid>
</ScrollViewer>
</Border>
</Themes:SystemDropShadowChrome>
</Popup>
<ToggleButton x:Name="toggleButton" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ComboBoxToggleButton}"/>
<Border x:Name="border" Background="{StaticResource TextBox.Static.Background}" Margin="{TemplateBinding BorderThickness}">
<TextBox x:Name="PART_EditableTextBox" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" Margin="{TemplateBinding Padding}" Style="{StaticResource ComboBoxEditableTextBox}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="true">
<Setter Property="Foreground" Value="Black"/>
</Trigger>
<Trigger Property="HasDropShadow" SourceName="PART_Popup" Value="true">
<Setter Property="Margin" TargetName="shadow" Value="0,0,5,5"/>
<Setter Property="Color" TargetName="shadow" Value="#71000000"/>
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter Property="Height" TargetName="dropDownBorder" Value="95"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true"/>
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</MultiTrigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer" Value="false">
<Setter Property="Canvas.Top" TargetName="opaqueRect" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer}"/>
<Setter Property="Canvas.Left" TargetName="opaqueRect" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="ComboStyle" TargetType="{x:Type ComboBox}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource ComboBox.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource ComboBox.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="Padding" Value="6,3,5,3"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template" Value="{StaticResource ComboBoxTemplate}"/>
<Style.Triggers>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Padding" Value="2"/>
<Setter Property="Template" Value="{StaticResource ComboBoxEditableTemplate}"/>
</Trigger>
</Style.Triggers>
</Style>
<LinearGradientBrush x:Key="ComboBox.Static.Background2" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFF0F0F0" Offset="0.0"/>
<GradientStop Color="#FFE5E5E5" Offset="1.0"/>
</LinearGradientBrush>
<Style x:Key="ComboBoxToggleButton2" TargetType="{x:Type ToggleButton}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Focusable" Value="false"/>
<Setter Property="ClickMode" Value="Press"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border x:Name="templateRoot" CornerRadius="7" BorderThickness="0" Background="Gray" SnapsToDevicePixels="true">
<Border x:Name="splitBorder" BorderBrush="Transparent" BorderThickness="1" HorizontalAlignment="Right" Margin="0" SnapsToDevicePixels="true" Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}">
<Path x:Name="arrow" Data="F1 M 0,0 L 2.667,2.66665 L 5.3334,0 L 5.3334,-1.78168 L 2.6667,0.88501 L0,-1.78168 L0,0 Z" Fill="{StaticResource ComboBox.Static.Glyph}" HorizontalAlignment="Center" Margin="0" VerticalAlignment="Center"/>
</Border>
</Border>
<ControlTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="false"/>
<Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Self}}" Value="false"/>
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="true"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Static.Editable.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Static.Editable.Border}"/>
<Setter Property="Background" TargetName="splitBorder" Value="{StaticResource ComboBox.Static.Editable.Button.Background}"/>
<Setter Property="BorderBrush" TargetName="splitBorder" Value="{StaticResource ComboBox.Static.Editable.Button.Border}"/>
</MultiDataTrigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Fill" TargetName="arrow" Value="{StaticResource ComboBox.MouseOver.Glyph}"/>
</Trigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="true"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="false"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.MouseOver.Border}"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="true"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.MouseOver.Editable.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.MouseOver.Editable.Border}"/>
<Setter Property="Background" TargetName="splitBorder" Value="{StaticResource ComboBox.MouseOver.Editable.Button.Background}"/>
<Setter Property="BorderBrush" TargetName="splitBorder" Value="{StaticResource ComboBox.MouseOver.Editable.Button.Border}"/>
</MultiDataTrigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Fill" TargetName="arrow" Value="{StaticResource ComboBox.Pressed.Glyph}"/>
</Trigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Self}}" Value="true"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="false"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Pressed.Border}"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Self}}" Value="true"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Pressed.Editable.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Pressed.Editable.Border}"/>
<Setter Property="Background" TargetName="splitBorder" Value="{StaticResource ComboBox.Pressed.Editable.Button.Background}"/>
<Setter Property="BorderBrush" TargetName="splitBorder" Value="{StaticResource ComboBox.Pressed.Editable.Button.Border}"/>
</MultiDataTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Fill" TargetName="arrow" Value="{StaticResource ComboBox.Disabled.Glyph}"/>
</Trigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="false"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Disabled.Border}"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Disabled.Editable.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Disabled.Editable.Border}"/>
<Setter Property="Background" TargetName="splitBorder" Value="{StaticResource ComboBox.Disabled.Editable.Button.Background}"/>
<Setter Property="BorderBrush" TargetName="splitBorder" Value="{StaticResource ComboBox.Disabled.Editable.Button.Border}"/>
</MultiDataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="FilterComboStyle" TargetType="{x:Type ComboBox}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource ComboBox.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource ComboBox.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="Padding" Value="6,3,5,3"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template" Value="{StaticResource ComboBoxTemplate}"/>
<Style.Triggers>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Padding" Value="2"/>
<Setter Property="Template" Value="{StaticResource ComboBoxEditableTemplate}"/>
</Trigger>
</Style.Triggers>
</Style>
</Application.Resources>
</Application>
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

+4 -3
View File
@@ -202,7 +202,7 @@
</StackPanel>
</Grid>
<ScrollViewer Name="IdListScroller" MinHeight="60" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto" CanContentScroll="True" ClipToBounds="True" PanningMode="VerticalOnly" PanningRatio=".1">
<ScrollViewer Name="IdListScroller" MinHeight="60" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto" FocusVisualStyle="{x:Null}" CanContentScroll="True" ClipToBounds="True" PanningMode="VerticalOnly" PanningRatio=".1">
<StackPanel Name="IdList" Orientation="Vertical" IsItemsHost="False" LayoutUpdated="IdList_LayoutUpdated" FocusVisualStyle="{x:Null}"></StackPanel>
</ScrollViewer>
<Grid HorizontalAlignment="Stretch" Margin="0,20,0,10" Width="Auto">
@@ -217,7 +217,7 @@
<!-- Menu UI -->
<local:MainMenu x:Name="MainMenu" Visibility="Collapsed"></local:MainMenu>
<!-- ID Detail UI -->
<local:IdentityDetails x:Name="IdentityMenu" Visibility="Collapsed" OnMFAToggled="MFAToggled" Authenticate="ShowAuthenticate" Recovery="ShowRecovery"></local:IdentityDetails>
<local:IdentityDetails x:Name="IdentityMenu" Visibility="Collapsed" OnMFAToggled="MFAToggled" Authenticate="ShowAuthenticate" Recovery="ShowRecovery" OnLoading="DoLoading"></local:IdentityDetails>
<!-- Modal Background -->
<Rectangle x:Name="ModalBg" Margin="10,10,10,10" Fill="Black" RadiusY="10" RadiusX="10" Opacity="0" Visibility="Collapsed"></Rectangle>
@@ -247,7 +247,8 @@
<RowDefinition Height="60"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Image Source="/Assets/Images/WarningRed.png" Grid.Column="0" Width="30" Grid.Row="1" Height="30" Margin="0,0,0,0"></Image>
<Image x:Name="RedBlurb" Source="/Assets/Images/WarningRed.png" Grid.Column="0" Width="30" Grid.Row="1" Height="30" Margin="0,0,0,0"></Image>
<Image x:Name="InfoBlurb" Visibility="Collapsed" Source="/Assets/Images/Warning.png" Grid.Column="0" Width="30" Grid.Row="1" Height="30" Margin="0,0,0,0"></Image>
<Label x:Name="Blurb" Content="An Update is available!" MouseUp="BlurbAction" Grid.Column="1" Padding="0,0,0,0" Grid.Row="1" Margin="0,0,0,0" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" Foreground="#000000" FontSize="12" Cursor="Hand" HorizontalAlignment="Center" VerticalAlignment="Center"></Label>
<Image Source="/Assets/Images/closeBlack.png" Grid.Column="2" Width="10" Height="10" Grid.Row="1" Margin="0,0,0,0" Cursor="Hand" MouseUp="DoHideBlurb"></Image>
</Grid>
+32 -2
View File
@@ -156,6 +156,11 @@ namespace ZitiDesktopEdge {
this.ShowMFA(identity, 1);
}
/// <summary>
/// Show MFA for the identity and set the type of screen to show
/// </summary>
/// <param name="identity">The Identity that is currently active</param>
/// <param name="type">The type of screen to show - 1 Setup, 2 Authenticate, 3 Remove MFA, 4 Regenerate Codes</param>
private void ShowMFA(ZitiIdentity identity, int type) {
MFASetup.Opacity = 0;
MFASetup.Visibility = Visibility.Visible;
@@ -342,10 +347,18 @@ namespace ZitiDesktopEdge {
this.IdentityMenu.MainWindow = this;
SetNotifyIcon("white");
this.PreviewKeyDown += KeyPressed;
MFASetup.OnLoad += MFASetup_OnLoad;
IdentityMenu.OnMessage += IdentityMenu_OnMessage;
}
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);
@@ -503,6 +516,7 @@ namespace ZitiDesktopEdge {
Application.Current.Properties.Add("Identities", new List<ZitiIdentity>());
MainMenu.OnAttachmentChange += AttachmentChanged;
MainMenu.OnLogLevelChanged += LogLevelChanged;
MainMenu.OnShowBlurb += MainMenu_OnShowBlurb;
IdentityMenu.OnError += IdentityMenu_OnError;
try {
@@ -524,7 +538,11 @@ namespace ZitiDesktopEdge {
Placement();
}
private void ServiceClient_OnBulkServiceEvent(object sender, BulkServiceEvent e) {
private void MainMenu_OnShowBlurb(string message) {
_ = ShowBlurbAsync(message, "", "info");
}
private void ServiceClient_OnBulkServiceEvent(object sender, BulkServiceEvent e) {
var found = identities.Find(id => id.Fingerprint == e.Fingerprint);
if (found == null) {
logger.Warn($"{e.Action} service event for {e.Fingerprint} but the provided identity fingerprint was not found!");
@@ -1287,7 +1305,14 @@ namespace ZitiDesktopEdge {
/// </summary>
/// <param name="message">The message to show</param>
/// <param name="url">The url or action name to execute</param>
public async Task ShowBlurbAsync(string message, string url) {
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;
@@ -1377,6 +1402,11 @@ namespace ZitiDesktopEdge {
someCommand = value;
}
}
private void DoLoading(bool isComplete) {
if (isComplete) HideLoad();
else ShowLoad("Loading", "Please Wait.");
}
}
public class ActionCommand : ICommand {
+22
View File
@@ -0,0 +1,22 @@
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; }
}
}
+235 -127
View File
@@ -1,133 +1,241 @@
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZitiDesktopEdge.DataStructures;
namespace ZitiDesktopEdge.Models {
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using ZitiDesktopEdge.DataStructures;
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; }
private bool failingPostureCheck;
public bool HasFailingPostureCheck() {
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; }
private bool failingPostureCheck;
public bool HasFailingPostureCheck() {
return failingPostureCheck;
}
public bool IsAccessable { 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 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;
}
public bool IsAccessable { 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 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.OwnsIntercept = svc.OwnsIntercept;
if (this.PostureChecks != null) {
this.failingPostureCheck = this.PostureChecks.Any(p => !p.IsPassing);
}
this.IsAccessable = svc.IsAccessable;
//commented out for now logger.Warn("SERVICE: " + this.Name + " HAS FAILING POSTURE CHECK: " + failingPostureCheck);
}
private ServiceMatrix builtMatrix = null;
public ServiceMatrix Matrix {
get {
if (builtMatrix == null) {
builtMatrix = new ServiceMatrix();
List<ServiceMatrixElement> matrix = new List<ServiceMatrixElement>(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;
matrix.Add(m);
}
}
}
builtMatrix.Elements = matrix;
}
return builtMatrix;
}
}
public override string ToString() {
string protos = "<none>";
if (Protocols?.Length > 0) {
if (Protocols.Length > 1) {
protos = "[" + string.Join(",", Protocols.Select(p => p.ToString())) + "]";
} else {
protos = Protocols[0];
}
}
string addys = "<none>";
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 = "<none>";
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;
}
}
public class ServiceMatrix {
public List<ServiceMatrixElement> Elements { get; internal set; }
}
public class ServiceMatrixElement {
public ServiceMatrixElement() {
Proto = "<none>";
Address = "<none>";
Ports = "<none>";
}
public string Proto { get; set; }
public string Address { get; set; }
public string Ports { get; set; }
public override string ToString() {
return Proto + " " + Address + " " + Ports;
}
}
}
}
this.IsAccessable = svc.IsAccessable;
//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<MessageCount> messages = new List<MessageCount>();
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<MessageCount> AppendMessage(List<MessageCount> 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 Visibility WarningVisibility {
get {
return (HasWarning) ? Visibility.Visible : Visibility.Collapsed;
}
set { }
}
public bool HasWarning {
get {
if (!this.OwnsIntercept) return true;
else {
if (this.IsAccessable) {
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 = "";
for (int i = 0; i < this.Protocols.Length; i++) {
toReturn += ((i > 0) ? "," : "") + this.Protocols[i];
}
return toReturn;
}
set { }
}
public string PortString {
get {
string toReturn = "";
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 = "";
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<ServiceMatrixElement> matrix = new List<ServiceMatrixElement>(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;
matrix.Add(m);
}
}
}
builtMatrix.Elements = matrix;
}
return builtMatrix;
}
}
public override string ToString() {
string protos = "<none>";
if (Protocols?.Length > 0) {
if (Protocols.Length > 1) {
protos = "[" + string.Join(",", Protocols.Select(p => p.ToString())) + "]";
} else {
protos = Protocols[0];
}
}
string addys = "<none>";
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 = "<none>";
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;
}
}
public class ServiceMatrix {
public List<ServiceMatrixElement> Elements { get; internal set; }
}
public class ServiceMatrixElement {
public ServiceMatrixElement() {
Proto = "<none>";
Address = "<none>";
Ports = "<none>";
}
public string Proto { get; set; }
public string Address { get; set; }
public string Ports { get; set; }
public override string ToString() {
return Proto + " " + Address + " " + Ports;
}
}
}
+3 -3
View File
@@ -50,6 +50,6 @@ using System.Windows;
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.9.3.0")]
[assembly: AssemblyVersion("1.9.3.0")]
[assembly: AssemblyFileVersion("1.9.3.0")]
// [assembly: AssemblyVersion("1.9.4.0")]
[assembly: AssemblyVersion("1.9.4.0")]
[assembly: AssemblyFileVersion("1.9.4.0")]
@@ -20,6 +20,11 @@
<SolidColorBrush x:Name="ButtonBgColor" Color="#0069FF"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle x:Name="ButtonBgDarken" Margin="40,0,40,0" Opacity="0.0" RadiusX="7" Grid.Row="8" RadiusY="7" ClipToBounds="True" Height="30" VerticalAlignment="Bottom" MouseUp="DoClick" Cursor="Hand" MouseEnter="Hover" MouseLeave="Leave" MouseDown="Down">
<Rectangle.Fill>
<SolidColorBrush Color="#000000"/>
</Rectangle.Fill>
</Rectangle>
<Label x:Name="ButtonLabel" HorizontalAlignment="Center" IsHitTestVisible="False" Foreground="#FFFFFF" Grid.Row="8"></Label>
</Grid>
</UserControl>
@@ -23,6 +23,15 @@ namespace ZitiDesktopEdge {
public delegate void ClickAction();
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 {
@@ -44,8 +53,8 @@ namespace ZitiDesktopEdge {
/// <param name="sender">The button object</param>
/// <param name="e">The mouse event</param>
private void Hover(object sender, MouseEventArgs e) {
ButtonBg.Opacity = 0.8;
ButtonBg.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(1.0, TimeSpan.FromSeconds(.3)));
ButtonBgDarken.Opacity = 0.0;
ButtonBgDarken.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(0.2, TimeSpan.FromSeconds(.3)));
}
/// <summary>
@@ -54,9 +63,8 @@ namespace ZitiDesktopEdge {
/// <param name="sender">The button object</param>
/// <param name="e">The mouse event</param>
private void Leave(object sender, MouseEventArgs e) {
ButtonBgColor.Color = Color.FromRgb(0, 104, 249);
ButtonBg.BeginAnimation(Grid.OpacityProperty, null);
ButtonBg.Opacity = 0.8;
ButtonBgDarken.Opacity = 0.2;
ButtonBgDarken.BeginAnimation(Grid.OpacityProperty, new DoubleAnimation(0.0, TimeSpan.FromSeconds(.3)));
}
/// <summary>
@@ -65,7 +73,7 @@ namespace ZitiDesktopEdge {
/// <param name="sender"></param>
/// <param name="e"></param>
private void Down(object sender, MouseButtonEventArgs e) {
ButtonBgColor.Color = Color.FromRgb(126, 180, 255);
// ButtonBgColor.Color = Color.FromRgb(126, 180, 255);
}
/// <summary>
@@ -0,0 +1,36 @@
<UserControl x:Class="ZitiDesktopEdge.Filter"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ZitiDesktopEdge"
mc:Ignorable="d"
d:DesignHeight="36"
Height="36"
HorizontalAlignment="Stretch"
d:DesignWidth="350" >
<Grid Margin="0,0,0,0">
<Rectangle Margin="0,0,0,0" Fill="#070826" Opacity="0.1" RadiusY="0" RadiusX="0"></Rectangle>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Label Content="Filter" Foreground="Black" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="12" FontWeight="Bold" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans"></Label>
<TextBox x:Name="FilterFor" Text="any text" Width="80" Height="26" Padding="6,0,6,0" Grid.Row="0" VerticalContentAlignment="Center" BorderThickness="0" Cursor="Hand" Foreground="#070826" FontSize="12" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" GotFocus="FocusFilter" LostFocus="FocusLostFilter" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" Keyboard.KeyUp="FilterChanged" Keyboard.KeyDown="FilterPressed">
<TextBox.Resources>
<Style TargetType="{x:Type Border}">
<Setter Property="CornerRadius" Value="7"/>
</Style>
</TextBox.Resources>
</TextBox>
<Label Content=" and sort by " Foreground="Black" FontSize="12" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans"></Label>
<ComboBox Name="SortByField" SelectionChanged="SortByChanged" Width="80" VerticalContentAlignment="Center" Cursor="Hand" Height="26" VerticalAlignment="Center" TextBlock.TextAlignment="Center" HorizontalAlignment="Stretch" BorderThickness="0" Foreground="#070826" FontFamily="/ZitiDesktopEdge;component/Assets/Fonts/#Open Sans" FontSize="12" Style="{DynamicResource FilterComboStyle}">
<ComboBoxItem IsSelected="True">Name</ComboBoxItem>
<ComboBoxItem>Address</ComboBoxItem>
<ComboBoxItem>Protocol</ComboBoxItem>
<ComboBoxItem>Port</ComboBoxItem>
</ComboBox>
<ComboBox Name="SortWayField" Margin="5,0,0,0" Width="60" VerticalContentAlignment="Center" SelectionChanged="SortWayChanged" Cursor="Hand" Height="26" VerticalAlignment="Center" TextBlock.TextAlignment="Center" HorizontalAlignment="Stretch" BorderThickness="0" Foreground="#070826" FontFamily="/ZitiDesktopEdge;component/Assets/Fonts/#Open Sans" FontSize="12" Style="{DynamicResource FilterComboStyle}">
<ComboBoxItem IsSelected="True">Asc</ComboBoxItem>
<ComboBoxItem>Desc</ComboBoxItem>
</ComboBox>
</StackPanel>
</Grid>
</UserControl>
@@ -0,0 +1,106 @@
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 {
/// <summary>
/// Interaction logic for Filter.xaml
/// </summary>
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);
});
}
}
}
@@ -107,8 +107,6 @@ namespace ZitiDesktopEdge {
private void OpenDetails(object sender, MouseButtonEventArgs e) {
IdentityDetails deets = ((MainWindow)Application.Current.MainWindow).IdentityMenu;
deets.SelectedIdentity = this;
deets.ServiceTitle.Clear();
deets.IdDetailToggle.Enabled = this.Identity.IsEnabled;
deets.Identity = this.Identity;
}
@@ -15,6 +15,5 @@
<TextBox Name="MainLabel" Background="White" Height="30" FontWeight="Bold" IsReadOnly="True" HorizontalAlignment="Stretch" BorderThickness="0" ClipToBounds="True" Padding="0,6,3,0" Grid.Column="0" VerticalAlignment="Center" FontSize="12" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" Foreground="Black"></TextBox>
<TextBox Name="MainEdit" Background="White" IsReadOnly="True" HorizontalAlignment="Stretch" Height="30" Grid.Column="1" BorderThickness="0" TextAlignment="Right" Padding="0,6,3,0" FontSize="12" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" ></TextBox>
</Grid>
<Rectangle HorizontalAlignment="Stretch" Height="1" Fill="#7d8faf" Opacity="0.2"></Rectangle>
</StackPanel>
</UserControl>
@@ -21,7 +21,7 @@
<TextBox Name="MainEdit" Background="White" HorizontalAlignment="Stretch" Height="30" Grid.Column="1" BorderThickness="1" TextAlignment="Left" Margin="30,0,0,0" Padding="5,3,3,5" FontSize="12" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" VerticalContentAlignment="Center" SpellCheck.IsEnabled="True" MaxLength="100" KeyUp="MainEdit_KeyUp">
<TextBox.Resources>
<Style TargetType="{x:Type Border}">
<Setter Property="CornerRadius" Value="10"/>
<Setter Property="CornerRadius" Value="7"/>
</Style>
</TextBox.Resources>
</TextBox>
@@ -64,7 +64,6 @@ namespace ZitiDesktopEdge {
private void ShowIdentity(object sender, MouseButtonEventArgs e) {
IdentityDetails deets = ((MainWindow)Application.Current.MainWindow).IdentityMenu;
deets.SelectedIdentityMenu = this;
deets.IdDetailToggle.Enabled = this.Identity.IsEnabled;
deets.Identity = this.Identity;
}
}
@@ -9,7 +9,8 @@
<StackPanel Orientation="Vertical" Height="33">
<Grid Height="32">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="220"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition x:Name="WarningColumn" Width="0"/>
<ColumnDefinition x:Name="DetailColumn" Width="30"/>
</Grid.ColumnDefinitions>
@@ -17,8 +18,12 @@
<TextBox Name="MainLabel" Padding="0,0,12,0" Height="15" IsReadOnly="True" BorderThickness="0" FontWeight="Bold" Background="Transparent" ClipToBounds="True" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" FontSize="11" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" Foreground="White"></TextBox>
<TextBox Name="MainEdit" IsReadOnly="True" Height="14" Padding="0,0,12,0" TextAlignment="Left" BorderThickness="0" Background="Transparent" ClipToBounds="True" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Stretch" FontSize="10" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" Foreground="LightGray"></TextBox>
</StackPanel>
<Image x:Name="DetailIcon" Source="/Assets/Images/detail.png" Grid.Column="2" Width="20" Height="20" Cursor="Hand" MouseUp="DetailIcon_MouseUp"/>
<Image x:Name="WarnIcon" Visibility="Collapsed" Source="/Assets/Images/Warning.png" Grid.Column="1" Width="20" Height="20" Cursor="Hand" MouseUp="WarnIcon_MouseUp"/>
<StackPanel Orientation="Vertical" Height="30" Grid.Column="1">
<TextBox Name="Protocols" Padding="0,0,12,0" Height="15" IsReadOnly="True" BorderThickness="0" FontWeight="Bold" Background="Transparent" ClipToBounds="True" VerticalAlignment="Bottom" HorizontalAlignment="Right" FontSize="11" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" Foreground="White" Opacity="0.9"></TextBox>
<TextBox Name="Ports" IsReadOnly="True" Height="14" Padding="0,0,12,0" TextAlignment="Right" BorderThickness="0" Background="Transparent" ClipToBounds="True" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Stretch" FontSize="10" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" Foreground="LightGray"></TextBox>
</StackPanel>
<Image x:Name="DetailIcon" Source="/Assets/Images/detail.png" Grid.Column="3" Width="20" Height="20" Cursor="Hand" MouseUp="DetailIcon_MouseUp"/>
<Image x:Name="WarnIcon" Visibility="Collapsed" Source="/Assets/Images/Warning.png" Grid.Column="2" Width="20" Height="20" Cursor="Hand" MouseUp="WarnIcon_MouseUp"/>
</Grid>
</StackPanel>
</UserControl>
@@ -36,10 +36,41 @@ namespace ZitiDesktopEdge {
}
set {
this._info = value;
MainEdit.ToolTip = this._info.ToString();
MainEdit.Text = this._info.ToString();
string addresses = "";
if (_info.Addresses!=null) {
for (int i = 0; i < this._info.Addresses?.Length; i++) {
addresses += ((i > 0) ? "," : "") + this._info.Addresses[i].Hostname;
}
}
MainEdit.ToolTip = addresses;
MainEdit.Text = addresses;
MainLabel.ToolTip = this._info.Name;
MainLabel.Text = this._info.Name;
string ports = "";
if (_info.Ports != null) {
for (int i = 0; i < this._info.Ports.Length; i++) {
ports += ((i > 0) ? "," : "") + this._info.Ports[i].ToString();
}
}
Ports.ToolTip = ports;
Ports.Text = ports;
string protocols = "";
if (_info.Protocols != null) {
for (int i = 0; i < this._info.Protocols.Length; i++) {
protocols += ((i > 0) ? "," : "") + this._info.Protocols[i];
}
}
Protocols.ToolTip = protocols;
Protocols.Text = protocols;
WarningColumn.Width = new GridLength(0);
if (this._info.Warning.Length > 0) {
WarnIcon.ToolTip = this._info.Warning;
+65 -83
View File
@@ -6,7 +6,7 @@
xmlns:local="clr-namespace:ZitiDesktopEdge"
mc:Ignorable="d"
x:Name="IdentityArea"
d:DesignHeight="500" d:DesignWidth="350">
d:DesignHeight="500" d:DesignWidth="350" IsVisibleChanged="VisibilityChanged">
<Grid>
<!-- Border Arrow pointing to TaskBar -->
<Canvas>
@@ -16,109 +16,91 @@
</Rectangle.LayoutTransform>
</Rectangle>
</Canvas>
<!-- Background Color for Pop Overs -->
<Rectangle x:Name="MainCanvas" Margin="10,10,10,10" Fill="White" RadiusY="10" RadiusX="10"></Rectangle>
<Grid Margin="20,20,20,-20" MaxWidth="350">
<Grid Margin="0,30,0,-20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Vertical" HorizontalAlignment="Stretch" Margin="10,10,10,10">
<StackPanel Grid.Column="0" Orientation="Vertical" HorizontalAlignment="Stretch" Margin="0,0,0,30">
<!-- Header Controls -->
<Grid Margin="0,0,0,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="60"/>
</Grid.ColumnDefinitions>
<local:Toggler x:Name="IdDetailToggle" Grid.Column="0" HorizontalAlignment="Left" OnToggled="IdToggle"></local:Toggler>
<Image x:Name="IsConnected" Grid.Column="0" Visibility="Visible" Source="/Assets/Images/online.png" Height="25" HorizontalAlignment="Right" Cursor="Hand" MouseUp="DoDisconnect" />
<Image x:Name="IsDisconnected" Grid.Column="0" Visibility="Collapsed" Source="/Assets/Images/offline.png" Height="25" HorizontalAlignment="Right" Cursor="Hand" MouseUp="DoConnect" />
<TextBlock x:Name="IdDetailName" MouseDown="Window_MouseDown" MaxWidth="220" Grid.Column="1" TextTrimming="CharacterEllipsis" HorizontalAlignment="Center" FontSize="14" FontWeight="Bold" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" Foreground="#0F0F23" VerticalAlignment="Center" TextWrapping="NoWrap" />
<Image Grid.Column="2" Cursor="Hand" Source="/Assets/Images/x.png" Width="20" Height="20" Margin="0,0,0,0" HorizontalAlignment="Right" MouseUp="HideMenu"></Image>
<Image Grid.Column="2" Cursor="Hand" Source="/Assets/Images/x.png" Width="20" Height="20" Margin="0,0,0,0" HorizontalAlignment="Left" MouseUp="HideMenu"></Image>
</Grid>
<Rectangle HorizontalAlignment="Stretch" Height="1" Fill="#7d8faf" Opacity="0.2"></Rectangle>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition x:Name="ServiceRow" Height="140"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="40"></RowDefinition>
<RowDefinition x:Name="IdImage" Height="0"></RowDefinition>
</Grid.RowDefinitions>
<!-- Identity Details Area -->
<local:MenuEditItem x:Name="IdentityName" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Stretch" Label="Name" IsLocked="True"></local:MenuEditItem>
<local:MenuEditToggle x:Name="IdentityMFA" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Stretch" Label="Multi Factor Auth" Recovery="MFARecovery" Authenticate="MFAAuthenticate" Toggle="ToggleMFA"></local:MenuEditToggle>
<local:MenuEditItem x:Name="IdentityNetwork" Grid.Column="0" Grid.Row="2" HorizontalAlignment="Stretch" Label="Network" IsLocked="True"></local:MenuEditItem>
<local:MenuEditItem x:Name="IdentityStatus" Grid.Column="0" Grid.Row="3" HorizontalAlignment="Stretch" Label="Status" IsLocked="True"></local:MenuEditItem>
<local:MenuEditItem x:Name="IdentityEnrollment" Grid.Column="0" Grid.Row="4" HorizontalAlignment="Stretch" Label="Enrollment Status" IsLocked="True"></local:MenuEditItem>
<local:MenuEditSearch x:Name="ServiceTitle" Grid.Column="0" Grid.Row="5" HorizontalAlignment="Stretch" Filter="DoFilter"></local:MenuEditSearch>
<TextBox Name="NoAuthServices" Height="30" FontWeight="Bold" TextAlignment="Center" Text="You must authenticate to access services" IsReadOnly="True" HorizontalAlignment="Stretch" BorderThickness="0" ClipToBounds="True" Grid.Column="0" Grid.Row="5" VerticalAlignment="Center" Padding="0,6,3,0" FontSize="12" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" Foreground="Black"></TextBox>
<Rectangle Margin="40,0,40,10" Fill="#070826" Height="1" RadiusY="10" RadiusX="10" Opacity="0.1"></Rectangle>
<local:MenuEditItem x:Name="IdName" Label="Name" IsLocked="True" />
<Rectangle Margin="40,0,40,10" Fill="#070826" Height="1" RadiusY="10" RadiusX="10" Opacity="0.1"></Rectangle>
<local:MenuEditItem x:Name="IdServer" Label="Network" IsLocked="True" />
<Rectangle Margin="40,0,40,10" Fill="#070826" Height="1" RadiusY="10" RadiusX="10" Opacity="0.1"></Rectangle>
<local:MenuEditToggle x:Name="IdentityMFA" HorizontalAlignment="Stretch" Label="Multi Factor Auth" Margin="0,10,0,0" Recovery="MFARecovery" Authenticate="MFAAuthenticate" Toggle="ToggleMFA"></local:MenuEditToggle>
<!-- Service List Area (Higher Contrast to differentiate) -->
<Grid Name="MainDetailScroll" Grid.Column="0" MaxHeight="160" Grid.Row="6" Margin="-8,0,-8,0">
<Rectangle Margin="10,10,10,10" Fill="#070826" RadiusY="10" RadiusX="10"></Rectangle>
<ScrollViewer VerticalScrollBarVisibility="Visible" CanContentScroll="True" Margin="16,16,8,16">
<StackPanel Name="ServiceList" Orientation="Vertical"></StackPanel>
</ScrollViewer>
</Grid>
<Rectangle x:Name="AuthMessageBg" Margin="40,0,40,0" Opacity="0.8" RadiusX="7" Grid.Row="6" RadiusY="7" ClipToBounds="True" Height="30" VerticalAlignment="Bottom" Cursor="Hand" MouseUp="AuthFromMessage">
<local:Filter x:Name="FilterServices" OnFilter="DoFilter" VerticalAlignment="Top" Margin="10,16,10,0" />
<TextBox Name="NoAuthServices" Height="30" FontWeight="Bold" TextAlignment="Center" Text="You must authenticate to access services" IsReadOnly="True" HorizontalAlignment="Stretch" BorderThickness="0" ClipToBounds="True" Grid.Column="0" Grid.Row="5" VerticalAlignment="Center" Padding="0,6,3,0" FontSize="12" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" Foreground="Black"></TextBox>
<Grid Name="MainDetailScroll" MaxHeight="160" Margin="10,0,10,-10">
<Rectangle Margin="10,10,10,10" Fill="#070826" RadiusY="10" RadiusX="10"></Rectangle>
<ListView x:Name="ServiceList" VirtualizingPanel.IsVirtualizing="True" ScrollViewer.IsDeferredScrollingEnabled="True" ScrollViewer.ScrollChanged="Scrolled" Focusable="False" IsManipulationEnabled="False" BorderThickness="0" Background="Transparent" Margin="20,20,10,20" Style="{DynamicResource ServiceListStyle}">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="32">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="220"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition x:Name="WarningColumn" Width="20"/>
<ColumnDefinition x:Name="DetailColumn" Width="20"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Vertical" Height="30" Grid.Column="0">
<TextBlock Name="MainLabel" Text="{Binding Name}" Padding="0,0,12,0" Height="15" FontWeight="Bold" Background="Transparent" ClipToBounds="True" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" FontSize="11" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" Foreground="White"></TextBlock>
<TextBlock Name="MainEdit" Text="{Binding AddressString}" Height="14" Padding="0,0,12,0" Background="Transparent" ClipToBounds="True" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Stretch" FontSize="10" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" Foreground="LightGray"></TextBlock>
</StackPanel>
<StackPanel Orientation="Vertical" Height="30" Grid.Column="1">
<TextBlock Name="Protocols" Text="{Binding ProtocolString}" Padding="0,0,12,0" Height="15" FontWeight="Bold" Background="Transparent" ClipToBounds="True" VerticalAlignment="Bottom" HorizontalAlignment="Center" FontSize="11" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" Foreground="White" Opacity="0.9"></TextBlock>
<TextBlock Name="Ports" Text="{Binding PortString}" Height="14" Padding="0,0,12,0" HorizontalAlignment="Center" Background="Transparent" ClipToBounds="True" Grid.Column="0" VerticalAlignment="Top" FontSize="10" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" Foreground="LightGray"></TextBlock>
</StackPanel>
<Image x:Name="WarnIcon" Visibility="{Binding WarningVisibility}" ToolTip="{Binding WarningMessage}" Source="/Assets/Images/Warning.png" Grid.Column="2" Width="20" Height="20" Cursor="Hand" MouseUp="WarnClicked"/>
<Image x:Name="DetailIcon" Source="/Assets/Images/detail.png" Grid.Column="3" Width="20" Height="20" Cursor="Hand" MouseUp="DetailsClicked"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
<Label x:Name="ServiceCount" HorizontalAlignment="Center" Content="0 Services" Margin="0,0,0,0" Foreground="Gray" FontWeight="Bold" FontSize="12" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans"></Label>
<Grid>
<Rectangle x:Name="AuthMessageBg" Margin="40,0,40,0" Opacity="0.8" RadiusX="7" RadiusY="7" ClipToBounds="True" Height="30" VerticalAlignment="Bottom" Cursor="Hand" MouseUp="AuthFromMessage">
<Rectangle.Fill>
<SolidColorBrush x:Name="AuthBgColor" Color="#0069FF"/>
</Rectangle.Fill>
</Rectangle>
<Label x:Name="AuthMessageLabel" HorizontalAlignment="Center" Content="Authenticate" IsHitTestVisible="False" Foreground="#FFFFFF" Grid.Row="6"></Label>
<!-- Sorting and Paging -->
<Grid x:Name="PageSortArea" Grid.Column="0" Grid.Row="7">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="40"></ColumnDefinition>
<ColumnDefinition Width="90"></ColumnDefinition>
<ColumnDefinition Width="70"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"></RowDefinition>
</Grid.RowDefinitions>
<Label Content="Page" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Right" VerticalAlignment="Center"></Label>
<ComboBox Name="Pages" Grid.Column="1" Grid.Row="0" SelectionChanged="Pages_SelectionChanged" Width="60" Height="28" VerticalAlignment="Top" HorizontalAlignment="Left" BorderThickness="0" Background="#FFD4CECE" Foreground="#FF292626" FontFamily="/ZitiDesktopEdge;component/Assets/Fonts/#Open Sans" FontSize="14"></ComboBox>
<Label Content="Sort" Grid.Column="2" Grid.Row="0" HorizontalAlignment="Right" VerticalAlignment="Center"></Label>
<ComboBox Name="SortByField" Grid.Column="3" Grid.Row="0" SelectionChanged="SortByField_SelectionChanged" Height="28" VerticalAlignment="Top" HorizontalAlignment="Stretch" BorderThickness="0" Background="#FFD4CECE" Foreground="#FF292626" FontFamily="/ZitiDesktopEdge;component/Assets/Fonts/#Open Sans" FontSize="14">
<ComboBoxItem IsSelected="True">Name</ComboBoxItem>
<ComboBoxItem>Address</ComboBoxItem>
<ComboBoxItem>Protocol</ComboBoxItem>
<ComboBoxItem>Port</ComboBoxItem>
</ComboBox>
<ComboBox Name="SortWayField" Grid.Column="4" Grid.Row="0" Margin="5,0,0,0" SelectionChanged="SortWayField_SelectionChanged" Height="28" VerticalAlignment="Top" HorizontalAlignment="Stretch" BorderThickness="0" Foreground="#FF292626" FontFamily="/ZitiDesktopEdge;component/Assets/Fonts/#Open Sans" FontSize="14">
<ComboBox.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.WindowBrushKey}" Color="Yellow" />
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red" />
</ComboBox.Resources>
<ComboBoxItem IsSelected="True">Asc</ComboBoxItem>
<ComboBoxItem>Desc</ComboBoxItem>
</ComboBox>
</Grid>
<!-- Forget Identity Button -->
<Label Name="ForgetIdentityButton" Grid.Column="0" Grid.Row="8" Padding="0,10,0,10" Margin="0,0,0,0" Content="Forget This Identity" Cursor="Hand" Foreground="#F4044D" HorizontalAlignment="Center" Mouse.MouseUp="ForgetIdentity"></Label>
<Label x:Name="AuthMessageLabel" HorizontalAlignment="Center" Content="Authenticate" IsHitTestVisible="False" Foreground="#FFFFFF"></Label>
</Grid>
</StackPanel>
<local:StyledButton x:Name="ForgetIdentityButton" MinWidth="310" BgColor="#F4044D" Label="Forget This Identity" Margin="0,0,0,40" OnClick="ForgetIdentity" HorizontalAlignment="Center" VerticalAlignment="Bottom" />
</Grid>
<Rectangle x:Name="ModalBg" Margin="10,10,10,10" Fill="Black" RadiusY="10" RadiusX="10" Opacity="0" Visibility="Collapsed"></Rectangle>
<!-- Expended Detail Modal for Details pop up on service list -->
<Grid x:Name="DetailsArea" Visibility="Collapsed" Height="400" Margin="0,0,0,0">
<Grid.ColumnDefinitions>
@@ -149,7 +131,7 @@
<Label Content="Protocols" Padding="10,0,0,0" FontWeight="Bold" FontSize="12" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" Foreground="Black"></Label>
<TextBox x:Name="DetailProtocols" MaxWidth="300" Background="Transparent" IsReadOnly="True" HorizontalAlignment="Stretch" Height="20" BorderThickness="0" TextAlignment="Left" Padding="0,0,0,0" FontSize="12" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" ></TextBox>
</StackPanel>
<Image Source="/Assets/Images/closeBlack.png" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="0,40,40,0" Width="10" Height="10" Cursor="Hand" MouseUp="CloseDetails"></Image>
</Grid>
+157 -96
View File
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
@@ -10,6 +11,8 @@ using System.Windows.Media.Animation;
using NLog;
using System.Web;
using System.Windows.Media;
using System.Windows.Data;
namespace ZitiDesktopEdge {
/// <summary>
@@ -35,10 +38,21 @@ namespace ZitiDesktopEdge {
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 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;
public ObservableCollection<ZitiService> _services = new ObservableCollection<ZitiService>();
public ObservableCollection<ZitiService> ZitiServices { get { return _services; } }
internal MainWindow MainWindow { get; set; }
@@ -55,13 +69,15 @@ namespace ZitiDesktopEdge {
return _identity;
}
set {
_loaded = false;
FilterServices.Clear();
scrolledTo = 0;
_identity = value;
this.IdDetailToggle.Enabled = _identity.IsEnabled;
ServiceCount.Content = _identity.Services.Count + " service"+((_identity.Services.Count>1)?"s":"");
Page = 1;
SortBy = "Name";
SortWay = "Asc";
SortByField.SelectedIndex = 0;
SortWayField.SelectedIndex = 0;
filter = "";
UpdateView();
IdentityArea.Opacity = 1.0;
IdentityArea.Visibility = Visibility.Visible;
@@ -97,16 +113,31 @@ namespace ZitiDesktopEdge {
}
public void UpdateView() {
if (_scroller==null) {
_scroller = GetScrollViewer(ServiceList) as ScrollViewer;
}
if (_scroller != null) {
_scroller.InvalidateScrollInfo();
_scroller.ScrollToVerticalOffset(0);
_scroller.InvalidateScrollInfo();
}
scrolledTo = 0;
IdDetailName.Text = _identity.Name;
IdDetailName.ToolTip = _identity.Name;
IdDetailToggle.Enabled = _identity.IsEnabled;
IdentityName.Value = _identity.Name;
IdentityNetwork.Value = _identity.ControllerUrl;
IdentityEnrollment.Value = _identity.EnrollmentStatus;
IdentityStatus.Value = _identity.IsEnabled ? "active" : "disabled";
IdentityMFA.IsOn = _identity.IsMFAEnabled;
IdentityMFA.ToggleField.IsEnabled = true;
IdentityMFA.ToggleField.Opacity = 1;
IsConnected.Visibility = Visibility.Collapsed;
IsDisconnected.Visibility = Visibility.Collapsed;
IsConnected.ToolTip = "Enabled - Click To Disable";
IsDisconnected.ToolTip = "Disabled - Click to Enable";
IdServer.Value = _identity.ControllerUrl;
IdName.Value = _identity.Name;
if (_identity.IsEnabled) {
IsConnected.Visibility = Visibility.Visible;
} else {
IsDisconnected.Visibility = Visibility.Visible;
}
if (_identity.IsMFAEnabled) {
if (_identity.MFAInfo.IsAuthenticated) {
IdentityMFA.ToggleField.IsEnabled = true;
@@ -125,13 +156,16 @@ namespace ZitiDesktopEdge {
IdentityMFA.AuthOff.Visibility = Visibility.Collapsed;
IdentityMFA.RecoveryButton.Visibility = Visibility.Collapsed;
}
ServiceList.Children.Clear();
PageSortArea.Visibility = Visibility.Collapsed;
//ServiceList.Children.Clear();
totalServices = _identity.Services.Count;
if (_identity.Services.Count>0) {
PageSortArea.Visibility = Visibility.Visible;
int index = 0;
int total = 0;
ZitiService[] services = new ZitiService[0];
_services = null;
_services = new ObservableCollection<ZitiService>();
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();
@@ -140,86 +174,49 @@ namespace ZitiDesktopEdge {
int startIndex = (Page - 1) * PerPage;
for (int i= startIndex; i<services.Length; i++) {
ZitiService zitiSvc = services[i];
total++;
if (index<100) {
total++;
if (index<PerPage) {
if (zitiSvc.Name.ToLower().IndexOf(filter.ToLower()) >= 0 || zitiSvc.ToString().ToLower().IndexOf(filter.ToLower()) >= 0) {
Logger.Trace("painting: " + zitiSvc.Name);
ServiceInfo info = new ServiceInfo();
info.Info = zitiSvc;
info.OnMessage += Info_OnMessage;
info.OnDetails += ShowDetails;
ServiceList.Children.Add(info);
_services.Add(zitiSvc);
index++;
}
}
}
ServiceList.ItemsSource = ZitiServices;
if (Page==1) {
Pages.Items.Clear();
int totalPages = (total / PerPage) + 1;
for (int i = 1; i <= totalPages; i++) {
ComboBoxItem item = new ComboBoxItem();
if (i == Page) item.IsSelected = true;
item.Content = i.ToString();
Pages.Items.Add(item);
}
}
TotalPages = (total / PerPage) + 1;
double newHeight = MainHeight - 330;
ServiceRow.Height = new GridLength((double)newHeight);
double newHeight = MainHeight - 330;
MainDetailScroll.MaxHeight = newHeight;
MainDetailScroll.Height = newHeight;
MainDetailScroll.Visibility = Visibility.Visible;
ServiceTitle.Label = _identity.Services.Count + " Services";
ServiceTitle.MainEdit.Visibility = Visibility.Visible;
ServiceTitle.Visibility = Visibility.Visible;
AuthMessageBg.Visibility = Visibility.Collapsed;
AuthMessageLabel.Visibility = Visibility.Collapsed;
NoAuthServices.Visibility = Visibility.Collapsed;
} else {
ServiceRow.Height = new GridLength((double)0.0);
MainDetailScroll.Visibility = Visibility.Collapsed;
ServiceTitle.Label = "No Services";
ServiceTitle.MainEdit.Text = "";
ServiceTitle.MainEdit.Visibility = Visibility.Collapsed;
if (this._identity.IsMFAEnabled&&!this._identity.MFAInfo.IsAuthenticated) {
ServiceTitle.Visibility = Visibility.Collapsed;
AuthMessageBg.Visibility = Visibility.Visible;
AuthMessageLabel.Visibility = Visibility.Visible;
ServiceRow.Height = new GridLength((double)30);
NoAuthServices.Visibility = Visibility.Visible;
} else {
ServiceTitle.Visibility = Visibility.Visible;
AuthMessageBg.Visibility = Visibility.Collapsed;
AuthMessageLabel.Visibility = Visibility.Collapsed;
NoAuthServices.Visibility = Visibility.Collapsed;
}
}
ConfirmView.Visibility = Visibility.Collapsed;
_loaded = true;
}
private void ShowDetails(ZitiService info) {
DetailName.Text = info.Name;
DetailProtocols.Text = info.ProtocolString;
DetailAddress.Text = info.AddressString;
DetailPorts.Text = info.PortString;
DetailUrl.Text = info.ToString();
string protocols = "";
string addresses = "";
string ports = "";
for (int i = 0; i < info.Protocols.Length; i++) {
protocols += ((i > 0) ? "," : "") + info.Protocols[i];
}
for (int i = 0; i < info.Addresses.Length; i++) {
addresses += ((i>0)?",":"")+info.Addresses[i];
}
for (int i = 0; i < info.Ports.Length; i++) {
ports += ((i > 0) ? "," : "") + info.Ports[i];
}
DetailProtocols.Text = protocols;
DetailAddress.Text = addresses;
DetailPorts.Text = ports;
DetailsArea.Visibility = Visibility.Visible;
DetailsArea.Opacity = 0;
DetailsArea.Margin = new Thickness(0, 0, 0, 0);
@@ -257,15 +254,6 @@ namespace ZitiDesktopEdge {
OnMessage?.Invoke(message);
}
async private void IdToggle(bool on) {
DataClient client = (DataClient)Application.Current.Properties["ServiceClient"];
await client.IdentityOnOffAsync(_identity.Fingerprint, on);
if (SelectedIdentity!=null) SelectedIdentity.ToggleSwitch.Enabled = on;
if (SelectedIdentityMenu != null) SelectedIdentityMenu.ToggleSwitch.Enabled = on;
_identity.IsEnabled = on;
IdentityStatus.Value = _identity.IsEnabled ? "active" : "disabled";
}
public IdentityDetails() {
InitializeComponent();
}
@@ -277,7 +265,7 @@ namespace ZitiDesktopEdge {
MainDetailScroll.Height = height;
}
private void ForgetIdentity(object sender, MouseButtonEventArgs e) {
private void ForgetIdentity() {
if (this.Visibility==Visibility.Visible&&ConfirmView.Visibility==Visibility.Collapsed) {
ConfirmView.Visibility = Visibility.Visible;
}
@@ -313,12 +301,6 @@ namespace ZitiDesktopEdge {
}
}
private void DoFilter(string filter) {
this.filter = filter;
if (this._identity!=null) UpdateView();
}
private void ToggleMFA(bool isOn) {
this.OnMFAToggled?.Invoke(isOn);
}
@@ -364,33 +346,112 @@ namespace ZitiDesktopEdge {
this.Authenticate.Invoke(this.Identity);
}
private void Pages_SelectionChanged(object sender, SelectionChangedEventArgs e) {
ComboBoxItem selected = (ComboBoxItem)Pages.SelectedValue;
if (selected!=null) {
int value = Int32.Parse(selected.Content.ToString());
if (value!=Page) {
Page = value;
UpdateView();
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) {
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 SortByField_SelectionChanged(object sender, SelectionChangedEventArgs e) {
ComboBoxItem selected = (ComboBoxItem)SortByField.SelectedValue;
if (selected != null && selected.Content!=null) {
if (selected.Content.ToString()!=SortBy) {
SortBy = selected.Content.ToString();
UpdateView();
}
}
private void DoFilter(FilterData filterData) {
filter = filterData.SearchFor;
SortBy = filterData.SortBy;
SortWay = filterData.SortHow;
UpdateView();
}
private void SortWayField_SelectionChanged(object sender, SelectionChangedEventArgs e) {
ComboBoxItem selected = (ComboBoxItem)SortWayField.SelectedValue;
if (selected != null && selected.Content != null) {
if (selected.Content.ToString() != SortWay) {
SortWay = selected.Content.ToString();
UpdateView();
async private void DoConnect(object sender, MouseButtonEventArgs e) {
this.OnLoading?.Invoke(false);
DataClient client = (DataClient)Application.Current.Properties["ServiceClient"];
await client.IdentityOnOffAsync(_identity.Fingerprint, 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.Fingerprint, 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;
}
}
}
+74
View File
@@ -7,6 +7,7 @@
mc:Ignorable="d"
x:Name="MainMenuArea"
d:DesignHeight="400" d:DesignWidth="400" Margin="1,1,1,1">
<Grid>
<Canvas>
<Rectangle Name="Arrow" HorizontalAlignment="Center" Height="20" Fill="White" VerticalAlignment="Bottom" Width="20" Canvas.Bottom="-10" Canvas.Left="185">
@@ -93,6 +94,7 @@
<local:MenuEditItem x:Name="ConfigSubnet" HorizontalAlignment="Stretch" Width="Auto" Label="Subnet Mask:"></local:MenuEditItem>
<local:MenuEditItem x:Name="ConfigMtu" HorizontalAlignment="Stretch" Width="Auto" Label="MTU:"></local:MenuEditItem>
<local:MenuEditItem x:Name="ConfigDns" HorizontalAlignment="Stretch" Width="Auto" Label="DNS Servers:"></local:MenuEditItem>
<local:StyledButton x:Name="EditButton" OnClick="ShowEdit" Label="Edit Values" Grid.Row="8" Margin="0,20,0,0"></local:StyledButton>
</StackPanel>
<ScrollViewer Name="IdListScrollView" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto" CanContentScroll="True" ClipToBounds="True" Visibility="Collapsed">
<StackPanel Name="IdListView" Orientation="Vertical" IsItemsHost="False"></StackPanel>
@@ -109,5 +111,77 @@
<Label Name="MainItemsButton" Margin="0,10,0,0" Foreground="#F4044D" FontWeight="SemiBold" Content="Quit Ziti Desktop Edge" Cursor="Hand" MouseUp="CloseApp" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" HorizontalAlignment="Center"></Label>
</StackPanel>
</Grid>
<!-- Modal for Menu Items: Next revision make one global modal -->
<Rectangle x:Name="ModalBg" Margin="10,10,10,10" Fill="Black" RadiusY="10" RadiusX="10" Opacity="0" Visibility="Collapsed"></Rectangle>
<!-- Modal For modifying the config data -->
<Grid x:Name="EditArea" Visibility="Collapsed" Height="300" Margin="0,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Border Margin="10,10,10,10" BorderBrush="Black" BorderThickness="8" CornerRadius="10">
<Border.Effect>
<DropShadowEffect BlurRadius="20" Direction="1" RenderingBias="Quality" ShadowDepth="1" Opacity="1"/>
</Border.Effect>
</Border>
<Rectangle Margin="10,10,10,10" RadiusX="10" RadiusY="10" ClipToBounds="True">
<Rectangle.Fill>
<SolidColorBrush Color="#FFFFFF" Opacity="0.97"/>
</Rectangle.Fill>
</Rectangle>
<StackPanel x:Name="DetailPanel" Grid.Column="0" Orientation="Vertical" Margin="20,20,20,20" VerticalAlignment="Center" FocusVisualStyle="{x:Null}">
<Label Content="IP Address" Padding="10,0,0,0" FontWeight="Bold" FontSize="14" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" Foreground="Black"></Label>
<TextBox x:Name="ConfigIpNew" Padding="10" Margin="10,10,10,10" Height="40" BorderThickness="1" TextAlignment="Left" FontSize="14" Foreground="Black" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans">
<TextBox.Resources>
<Style TargetType="{x:Type Border}">
<Setter Property="CornerRadius" Value="7"/>
</Style>
</TextBox.Resources>
</TextBox>
<Label Content="Subnet Mask" Padding="10,0,0,0" FontWeight="Bold" FontSize="14" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" Foreground="Black"></Label>
<ComboBox x:Name="ConfigMaskNew" Padding="10" Margin="10,10,10,10" FontSize="14" Height="40" FontFamily="pack://application:,,,/Assets/Fonts/#Open Sans" Foreground="Black" BorderBrush="#FFACACAC" Style="{DynamicResource ComboStyle}">
<ComboBoxItem Content="/1 - 128.0.0.0" Tag="1" IsSelected="True"/>
<ComboBoxItem Content="/2 - 192.0.0.0" Tag="2"/>
<ComboBoxItem Content="/3 - 224.0.0.0" Tag="3"/>
<ComboBoxItem Content="/4 - 240.0.0.0" Tag="4"/>
<ComboBoxItem Content="/5 - 248.0.0.0" Tag="5"/>
<ComboBoxItem Content="/6 - 252.0.0.0" Tag="6"/>
<ComboBoxItem Content="/7 - 254.0.0.0" Tag="7"/>
<ComboBoxItem Content="/8 - 255.0.0.0" Tag="8"/>
<ComboBoxItem Content="/9 - 255.128.0.0" Tag="9"/>
<ComboBoxItem Content="/10 - 255.192.0.0" Tag="10"/>
<ComboBoxItem Content="/11 - 255.224.0.0" Tag="11"/>
<ComboBoxItem Content="/12 - 255.240.0.0" Tag="12"/>
<ComboBoxItem Content="/13 - 255.248.0.0" Tag="13"/>
<ComboBoxItem Content="/14 - 255.252.0.0" Tag="14"/>
<ComboBoxItem Content="/15 - 255.254.0.0" Tag="15"/>
<ComboBoxItem Content="/16 - 255.255.0.0" Tag="16"/>
<ComboBoxItem Content="/17 - 255.255.128.0" Tag="17"/>
<ComboBoxItem Content="/18 - 255.255.192.0" Tag="18"/>
<ComboBoxItem Content="/19 - 255.255.224.0" Tag="19"/>
<ComboBoxItem Content="/20 - 255.255.240.0" Tag="20"/>
<ComboBoxItem Content="/21 - 255.255.248.0" Tag="21"/>
<ComboBoxItem Content="/22 - 255.255.252.0" Tag="22"/>
<ComboBoxItem Content="/23 - 255.255.254.0" Tag="23"/>
<ComboBoxItem Content="/24 - 255.255.255.0" Tag="24"/>
<ComboBoxItem Content="/25 - 255.255.255.128" Tag="25"/>
<ComboBoxItem Content="/26 - 255.255.255.192" Tag="26"/>
<ComboBoxItem Content="/27 - 255.255.255.224" Tag="27"/>
<ComboBoxItem Content="/28 - 255.255.255.240" Tag="28"/>
<ComboBoxItem Content="/29 - 255.255.255.248" Tag="29"/>
<ComboBoxItem Content="/30 - 255.255.255.252" Tag="30"/>
<ComboBoxItem Content="/31 - 255.255.255.254" Tag="31"/>
<ComboBoxItem Content="/32 - 255.255.255.255" Tag="32"/>
</ComboBox>
<CheckBox x:Name="AddDnsNew" Content="Add DNS" IsChecked="True" Margin="10"/>
<local:StyledButton x:Name="SaveConfigButton" OnClick="SaveConfig" Label="Save" Grid.Row="8"></local:StyledButton>
</StackPanel>
<Image Source="/Assets/Images/closeBlack.png" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="0,40,40,0" Width="10" Height="10" Cursor="Hand" MouseUp="CloseEditConfig"></Image>
</Grid>
</Grid>
</UserControl>
File diff suppressed because it is too large Load Diff
+13
View File
@@ -143,11 +143,15 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="Models\FilterData.cs" />
<Compile Include="Models\MessageCount.cs" />
<Compile Include="Models\MFA.cs" />
<Compile Include="Views\Controls\StyledButton.xaml.cs">
<DependentUpon>StyledButton.xaml</DependentUpon>
</Compile>
<Compile Include="Views\ItemRenderers\Filter.xaml.cs">
<DependentUpon>Filter.xaml</DependentUpon>
</Compile>
<Compile Include="Views\ItemRenderers\MenuEditSearch.xaml.cs">
<DependentUpon>MenuEditSearch.xaml</DependentUpon>
</Compile>
@@ -197,6 +201,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ItemRenderers\Filter.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ItemRenderers\MenuEditSearch.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@@ -447,5 +455,10 @@
<ItemGroup>
<Resource Include="Assets\Images\recovery.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Assets\Images\disconnected.png" />
<Resource Include="Assets\Images\name.png" />
<Resource Include="Assets\Images\statusconnected.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
+2 -2
View File
@@ -23,10 +23,10 @@
<ROW Property="CTRLS" Value="2"/>
<ROW Property="Manufacturer" Value="NetFoundry, Inc."/>
<ROW Property="MsiLogging" MultiBuildValue="AnyCPU_Release:vp"/>
<ROW Property="ProductCode" Value="1033:{758AA10B-B1A9-45FB-97AB-20759FAB902D} " Type="16"/>
<ROW Property="ProductCode" Value="1033:{426F09F2-D144-425D-BB84-593EAA8A6CE2} " Type="16"/>
<ROW Property="ProductLanguage" Value="1033"/>
<ROW Property="ProductName" Value="Ziti Desktop Edge"/>
<ROW Property="ProductVersion" Value="1.9.3" Type="32"/>
<ROW Property="ProductVersion" Value="1.9.4" Type="32"/>
<ROW Property="REBOOT" MultiBuildValue="AnyCPU_Release:Suppress"/>
<ROW Property="SecureCustomProperties" Value="OLDPRODUCTS;AI_NEWERPRODUCTFOUND;AI_SETUPEXEPATH;SETUPEXEDIR"/>
<ROW Property="UpgradeCode" Value="{CB7E173A-663D-4A23-BB22-D1E8D885C2F3}"/>
@@ -459,4 +459,27 @@ namespace ZitiDesktopEdge.DataStructures {
public class MfaRecoveryCodesResponse : SvcResponse {
public string[] Payload { get; set; }
}
public class ConfigPayload
{
public string TunIPv4 { get; set; }
public int TunIPv4Mask { get; set; }
public bool AddDns { get; set; }
}
public class ConfigUpdateFunction : ServiceFunction
{
public ConfigUpdateFunction(string tunIPv4, int tunIPv4Mask, bool addDns)
{
this.Function = "UpdateTunIpv4";
this.Payload = new ConfigPayload()
{
TunIPv4 = tunIPv4,
TunIPv4Mask = tunIPv4Mask,
AddDns = addDns
};
}
public ConfigPayload Payload { get; set; }
}
}
@@ -390,6 +390,30 @@ namespace ZitiDesktopEdge.ServiceClient {
return;
}
async public Task<SvcResponse> UpdateConfigAsync(string tunIPv4, int tunIPv4Mask, bool addDns) {
SvcResponse resp = null;
try {
ConfigUpdateFunction configPayload = new ConfigUpdateFunction(tunIPv4, tunIPv4Mask, addDns);
await sendAsync(configPayload);
resp = await readAsync<SvcResponse>(ipcReader);
Logger.Debug("config update payload is sent to the ziti tunnel");
} catch (Exception ex) {
//almost certainly a problem with the pipe - recreate the pipe...
//setupPipe();
//throw;
Logger.Error(ex, "Unexpected error");
CommunicationError(ex);
throw ex;
}
if (resp?.Code != 0) {
Logger.Warn("failed to update the config. {0} {1}", resp.Message, resp.Error);
throw new ServiceException("Failed to update the config", resp.Code, "Un expected error.");
}
return resp;
}
async public Task<ZitiTunnelStatus> debugAsync() {
try {
await sendAsync(new ServiceFunction() { Function = "Debug" });
+3 -3
View File
@@ -30,6 +30,6 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.9.3.0")]
[assembly: AssemblyVersion("1.9.3.0")]
[assembly: AssemblyFileVersion("1.9.3.0")]
// [assembly: AssemblyVersion("1.9.4.0")]
[assembly: AssemblyVersion("1.9.4.0")]
[assembly: AssemblyFileVersion("1.9.4.0")]
+5 -5
View File
@@ -214,7 +214,7 @@ namespace ZitiUpdateService {
}
return zipName;
} catch (Exception ex) {
Logger.Error(ex, "Unexpected error {0}", ex.Message);
Logger.Error(ex, "Unexpected error in generating system files {0}", ex.Message);
return null;
}
}
@@ -233,7 +233,7 @@ namespace ZitiUpdateService {
process.Start();
process.WaitForExit();
} catch (Exception ex) {
Logger.Error(ex, "Unexpected error {0}", ex.Message);
Logger.Error(ex, "Unexpected error in outputIpconfigInfo {0}", ex.Message);
}
}
@@ -251,7 +251,7 @@ namespace ZitiUpdateService {
process.Start();
process.WaitForExit();
} catch (Exception ex) {
Logger.Error(ex, "Unexpected error {0}", ex.Message);
Logger.Error(ex, "Unexpected error in outputSystemInfo {0}", ex.Message);
}
}
@@ -269,7 +269,7 @@ namespace ZitiUpdateService {
process.Start();
process.WaitForExit();
} catch (Exception ex) {
Logger.Error(ex, "Unexpected error {0}", ex.Message);
Logger.Error(ex, "Unexpected error in outputDnsCache {0}", ex.Message);
}
}
@@ -283,7 +283,7 @@ namespace ZitiUpdateService {
string responseBody = resp.Content.ReadAsStringAsync().Result;
File.WriteAllText(extIpFile, responseBody);
} catch (Exception ex) {
Logger.Error(ex, "Unexpected error {0}", ex.Message);
Logger.Error(ex, "Unexpected error in outputExternalIP {0}", ex.Message);
}
}
+6 -7
View File
@@ -1,16 +1,14 @@
# Release 1.9.3
# Release 1.9.4
## What's New
* Page Service List
* Sort Service on Identity Details Page
* Consistent UX for MFA Screens
* none
## Other changes:
* Service to UI interaction is now with one bulk update of services instead of one event per service update
* Added a configuration option to control if DNS is applied to the TUN. Some users are having issues with NRPT-only working. For now we'll add a boolean that allows the user to control if DNS should be added to the TUN
* none
## Bugs fixed:
* none
* [#362](https://github.com/openziti/desktop-edge-win/issues/362) Update tun ip, mask and addDns flag
* [#364](https://github.com/openziti/desktop-edge-win/issues/364) Add the test nrpt policy function in the startup method
## Dependency Updates
* none
@@ -24,6 +22,7 @@
## Other changes:
* Service to UI interaction is now with one bulk update of services instead of one event per service update
* Added a configuration option to control if DNS is applied to the TUN. Some users are having issues with NRPT-only working. For now we'll add a boolean that allows the user to control if DNS should be added to the TUN
## Bugs fixed:
* none
+50
View File
@@ -238,3 +238,53 @@ ForEach ($ns in $toRemove){
log.Errorf("ERROR removing nrpt rules: %v", err)
}
}
func IsNrptPoliciesEffective(dnsserver string) bool {
script := fmt.Sprintf(`Add-DnsClientNrptRule -Namespace ".ziti.test" -NameServers "%s" -Comment "Added by ziti-tunnel" -DisplayName "ziti-tunnel:.ziti.test"
Get-DnsClientNrptPolicy -Effective | Select-Object Namespace -Unique | Where-Object Namespace -Eq ".ziti.test"`, dnsserver)
log.Debugf("checking the nrpt policies with: %s", script)
cmd := exec.Command("powershell", "-Command", script)
cmd.Stderr = os.Stdout
output := new(bytes.Buffer)
cmd.Stdout = output
err := cmd.Run()
if err != nil {
log.Errorf("ERROR adding the test nrpt rules: %v", err)
return false
}
policyFound := false
for {
l, err := output.ReadString('\n')
policyOut := strings.Trim(l, "\r\n")
if err != nil {
break
}
if strings.Compare(policyOut, ".ziti.test") == 0 {
policyFound = true
log.Debug("The nrpt policies are effective in this client")
break
}
}
removeSingleNrtpRule(".ziti.test")
return policyFound
}
func removeSingleNrtpRule(nrptRule string) {
script := fmt.Sprintf(`Get-DnsClientNrptRule | where Namespace -eq "%s" | Remove-DnsClientNrptRule -Force -ErrorAction SilentlyContinue`, nrptRule)
log.Debugf("Removing the nrpt rule with: %s", script)
cmd := exec.Command("powershell", "-Command", script)
cmd.Stderr = os.Stdout
output := new(bytes.Buffer)
cmd.Stdout = output
err := cmd.Run()
if err != nil {
log.Errorf("ERROR removing the nrpt rules: %v", err)
}
}
+4
View File
@@ -42,6 +42,10 @@ var NOTIFY_IDENTITY_UI = dto.CommandMsg{
Function: "NotifyIdentityUI",
}
var UPDATE_TUN_IPV4 = dto.CommandMsg{
Function: "UpdateTunIpv4",
}
var monitorIpcPipe = `\\.\pipe\OpenZiti\ziti-monitor\ipc`
var templateIdentity = `{{printf "%40s" "Name"}} | {{printf "%41s" "FingerPrint"}} | {{printf "%6s" "Active"}} | {{printf "%30s" "Config"}} | {{"Status"}}
+5 -5
View File
@@ -57,11 +57,11 @@ func convertToServiceCli(svc dto.Service) dto.ServiceCli {
}
return dto.ServiceCli{
Name: svc.Name,
Id: svc.Id,
Protocols: strings.Join(svc.Protocols, ","),
Ports: cliPorts,
Addresses: cliAddresses,
Name: svc.Name,
Id: svc.Id,
Protocols: strings.Join(svc.Protocols, ","),
Ports: cliPorts,
Addresses: cliAddresses,
}
}
+57 -2
View File
@@ -1,9 +1,27 @@
package cli
import (
"strings"
/*
* 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.
*
*/
import (
"github.com/openziti/desktop-edge-win/service/ziti-tunnel/dto"
"net"
"strconv"
"strings"
)
//GetIdentities is to fetch identities through cmdline
@@ -53,3 +71,40 @@ func SetLogLevel(args []string, flags map[string]bool) {
func GetFeedback(args []string, flags map[string]bool) {
GetDataFromMonitorIpcPipe(&dto.FEEDBACK_REQUEST, args, flags)
}
func UpdateConfigIPSubnet(args []string, flags map[string]interface{}) {
CIDRstring := flags["CIDR"]
AddDns := flags["AddDns"]
log.Info("Updating the config file")
updateTunIpv4Payload := make(map[string]interface{})
if CIDRstring != "" {
ip, ipnet, err := net.ParseCIDR(CIDRstring.(string))
if err != nil {
log.Error("Incorrect cidr %s", CIDRstring.(string))
}
ipMask, _ := ipnet.Mask.Size()
updateTunIpv4Payload["TunIPv4"] = ip
updateTunIpv4Payload["TunIPv4Mask"] = ipMask
}
if AddDns != "" {
addDnsBool, err := strconv.ParseBool(AddDns.(string))
if err != nil {
log.Errorf("Incorrect addDns %v", err)
return
}
updateTunIpv4Payload["AddDns"] = addDnsBool
}
UPDATE_TUN_IPV4.Payload = updateTunIpv4Payload
log.Debugf("updateTunIpv4 Payload %v", UPDATE_TUN_IPV4)
status := GetDataFromIpcPipe(&UPDATE_TUN_IPV4, nil, GetResponseObjectFromRTS, args, nil)
if !status {
log.Infof("Config can be updated only if the tunnel is started")
}
}
+41
View File
@@ -0,0 +1,41 @@
package cmd
/*
* 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.
*
*/
import (
"github.com/spf13/cobra"
)
// configCmd represents the config command
var configCmd = &cobra.Command{
Use: "config",
Short: "A brief description of your command",
Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
Run: func(cmd *cobra.Command, args []string) {
checkHelp()
},
}
func init() {
rootCmd.AddCommand(configCmd)
}
+50
View File
@@ -0,0 +1,50 @@
package cmd
/*
* 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.
*
*/
import (
"github.com/openziti/desktop-edge-win/service/ziti-tunnel/cli"
"github.com/spf13/cobra"
)
var CIDR string
var AddDns string
// updateCmd represents the update command
var updateCmd = &cobra.Command{
Use: "update",
Short: "Updates data into the ziti-tunnel",
Long: `update command should be used as a sub command to the main command
It helps to update the data into the ziti-tunnel.
eg: ziti-tunnel config update --CIDR 100.64.0.1/10 --AddDns=true`,
Run: func(cmd *cobra.Command, args []string) {
flags := map[string]interface{}{}
flags["CIDR"] = CIDR
flags["AddDns"] = AddDns
cli.UpdateConfigIPSubnet(args, flags)
},
}
func init() {
configCmd.AddCommand(updateCmd)
updateCmd.Flags().StringVar(&CIDR, "CIDR", "", "Updates the cidr property in the config file")
updateCmd.Flags().StringVar(&AddDns, "AddDns", "", "Updates the Add Dns property in the config file")
}
+5 -5
View File
@@ -27,11 +27,11 @@ type IdentityCli struct {
}
type ServiceCli struct {
Name string
Id string
Protocols string
Ports string
Addresses string
Name string
Id string
Protocols string
Ports string
Addresses string
}
type IdentityOnOffPayload struct {
+3 -1
View File
@@ -111,6 +111,8 @@ func main() {
commandline.Execute()
case "feedback":
commandline.Execute()
case "config":
commandline.Execute()
default:
usage(fmt.Sprintf("invalid command %s", cmd))
}
@@ -126,7 +128,7 @@ func usage(errmsg string) {
"%s\n\n"+
"usage: %s <command>\n"+
" where <command> is one of\n"+
" install, remove, debug, start, stop, pause, continue, list, identity, loglevel, feedback or version.\n",
" install, remove, debug, start, stop, pause, continue, list, identity, loglevel, feedback, config or version.\n",
errmsg, os.Args[0])
os.Exit(2)
}
+27
View File
@@ -41,6 +41,7 @@ import (
"net"
"os"
"os/signal"
"strconv"
"strings"
"sync"
"time"
@@ -498,6 +499,21 @@ func serveIpc(conn net.Conn) {
//save the state
rts.SaveState()
case "UpdateTunIpv4":
var tunIPv4 string
var tunIPv4Mask int
var addDns string
if cmd.Payload["TunIPv4"] != nil {
tunIPv4 = cmd.Payload["TunIPv4"].(string)
}
if cmd.Payload["TunIPv4Mask"] != nil {
var tunIpv4Mask = cmd.Payload["TunIPv4Mask"].(float64)
tunIPv4Mask = int(tunIpv4Mask)
}
if cmd.Payload["AddDns"] != nil {
addDns = strconv.FormatBool(cmd.Payload["AddDns"].(bool))
}
updateTunIpv4(enc, tunIPv4, tunIPv4Mask, addDns)
case "NotifyLogLevelUIAndUpdateService":
sendLogLevelAndNotify(enc, cmd.Payload["Level"].(string))
case "NotifyIdentityUI":
@@ -622,6 +638,17 @@ func setLogLevel(out *json.Encoder, level string) {
respond(out, dto.Response{Message: "log level set", Code: SUCCESS, Error: "", Payload: nil})
}
func updateTunIpv4(out *json.Encoder, ip string, ipMask int, addDns string) {
err := UpdateRuntimeStateIpv4(ip, ipMask, addDns)
if err != nil {
respondWithError(out, "Could not set Tun ip and mask", UNKNOWN_ERROR, err)
return
}
respond(out, dto.Response{Message: "TunIPv4 and mask is set, Manual Restart is required", Code: SUCCESS, Error: "", Payload: ""})
}
func serveLogs(conn net.Conn) {
log.Debug("accepted a logs connection, writing logs to pipe")
w := bufio.NewWriter(conn)
+48 -10
View File
@@ -20,24 +20,26 @@ package service
import (
"bufio"
"encoding/json"
"errors"
"fmt"
"github.com/openziti/desktop-edge-win/service/cziti"
"github.com/openziti/desktop-edge-win/service/windns"
"github.com/openziti/desktop-edge-win/service/ziti-tunnel/config"
"github.com/openziti/desktop-edge-win/service/ziti-tunnel/constants"
"github.com/openziti/desktop-edge-win/service/ziti-tunnel/dto"
idcfg "github.com/openziti/sdk-golang/ziti/config"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
"golang.zx2c4.com/wireguard/tun"
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
"io"
"io/ioutil"
"net"
"os"
"path"
"strconv"
"strings"
"time"
"github.com/openziti/desktop-edge-win/service/cziti"
"github.com/openziti/desktop-edge-win/service/ziti-tunnel/config"
"github.com/openziti/desktop-edge-win/service/ziti-tunnel/constants"
"github.com/openziti/desktop-edge-win/service/ziti-tunnel/dto"
idcfg "github.com/openziti/sdk-golang/ziti/config"
"golang.org/x/sys/windows/registry"
"golang.zx2c4.com/wireguard/tun"
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
)
type RuntimeState struct {
@@ -221,7 +223,14 @@ func (t *RuntimeState) CreateTun(ipv4 string, ipv4mask int, applyDns bool) (net.
}
log.Info("routing applied")
if applyDns {
zitiPoliciesEffective := windns.IsNrptPoliciesEffective(ipv4)
if applyDns || !zitiPoliciesEffective {
if applyDns {
log.Infof("DNS is applied to the TUN interface, because apply Dns flag in the config file is %t ", applyDns)
}
if !applyDns && !zitiPoliciesEffective {
log.Infof("DNS is applied to the TUN interface, because Ziti policies test result in this client is %t", zitiPoliciesEffective)
}
//for windows 10+, could 'domains' be able to replace NRPT? dunno - didn't test it
luid.SetDNS(windows.AF_INET, []net.IP{ip}, nil)
}
@@ -401,6 +410,35 @@ func (t *RuntimeState) UpdateIpv4(ipv4 string) {
rts.SaveState()
}
func UpdateRuntimeStateIpv4(ip string, ipv4Mask int, addDns string) error {
log.Infof("updating configuration ip: %s, mask: %d, dns: %t", ip, ipv4Mask, addDns)
if ipv4Mask < constants.Ipv4MaxMask || ipv4Mask > constants.Ipv4MinMask {
return errors.New(fmt.Sprintf("ipv4Mask should be between %d and %d", constants.Ipv4MaxMask, constants.Ipv4MinMask))
}
if addDns != "" {
addDnsBool, err := strconv.ParseBool(addDns)
if err != nil {
return errors.New(fmt.Sprintf("Incorrect addDns %v", err))
}
rts.state.AddDns = addDnsBool
}
// if ip is not empty, then we set both ip and mask
if ip != "" {
rts.state.TunIpv4 = ip
rts.state.TunIpv4Mask = ipv4Mask
}
rts.SaveState()
return nil
}
// uses the registry to determine if IPv6 is enabled or disabled on this machine. If it is disabled an IPv6 DNS entry
// will end up causing a fatal error on startup of the service. For this registry key and values see the MS documentation
// at https://docs.microsoft.com/en-us/troubleshoot/windows-server/networking/configure-ipv6-in-windows
+4 -4
View File
@@ -20,9 +20,9 @@
package main
const (
Version = "1.9.3"
Revision = "a02a50cf6437"
Branch = "main"
Version = "1.9.4"
Revision = "2db5f6a8362d"
Branch = "release-next"
BuildUser = ""
BuildDate = "2021-04-12 17:35:14"
BuildDate = "2021-04-21 18:46:25"
)
+1 -1
View File
@@ -1 +1 @@
1.9.3
1.9.4