Skip to content

Commit 14d60ea

Browse files
committed
Progress in implementation
1 parent d88f54d commit 14d60ea

4 files changed

Lines changed: 111 additions & 7 deletions

File tree

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System;
2+
using System.Globalization;
3+
using Avalonia.Data.Converters;
4+
using OpenSSHALib.Enums;
5+
using OpenSSHALib.Models;
6+
7+
namespace OpenSSHA_GUI.Converters;
8+
9+
public class SingleSshKeyTypeConverter : IValueConverter
10+
{
11+
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
12+
{
13+
return Enum.GetName(typeof(KeyType), (KeyType)value);
14+
}
15+
16+
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
17+
{
18+
return Enum.Parse<KeyType>((string)value);
19+
}
20+
}

OpenSSHA-GUI/ViewModels/UploadToServerViewModel.cs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
using System.Collections.ObjectModel;
1+
using System;
2+
using System.Collections.ObjectModel;
23
using System.Linq;
34
using System.Reactive;
5+
using Avalonia.Media;
6+
using OpenSSHALib.Lib;
47
using OpenSSHALib.Models;
58
using ReactiveUI;
69
using ReactiveUI.Validation.Abstractions;
@@ -19,11 +22,50 @@ public UploadToServerViewModel(ObservableCollection<SshPublicKey> keys)
1922
{
2023
return this;
2124
});
25+
TestConnection = ReactiveCommand.CreateFromTask<Unit, Unit>(async e =>
26+
{
27+
if (ServerCommunicator.TestConnection(Hostname, User, Password, out var message))
28+
{
29+
StatusButtonBackground = Brushes.LimeGreen;
30+
StatusButtonText = "Status: success";
31+
StatusButtonToolTip = $"Connection successfully established for ssh://{User}@{Hostname}";
32+
}
33+
else
34+
{
35+
StatusButtonBackground = Brushes.IndianRed;
36+
StatusButtonText = "Status: failed";
37+
StatusButtonToolTip = message;
38+
}
39+
return e;
40+
});
2241
}
2342

2443
public string Hostname { get; set; } = "";
2544
public string User { get; set; } = "";
2645
public string Password { get; set; } = "";
46+
47+
public ReactiveCommand<Unit, Unit> TestConnection { get; }
48+
49+
private string _statusButtonToolTip = "Status not yet tested";
50+
public string StatusButtonToolTip
51+
{
52+
get => _statusButtonToolTip;
53+
set => this.RaiseAndSetIfChanged(ref _statusButtonToolTip, value);
54+
}
55+
56+
private string _statusButtonText = "Status: Unknown";
57+
public string StatusButtonText
58+
{
59+
get => _statusButtonText;
60+
set => this.RaiseAndSetIfChanged(ref _statusButtonText, value);
61+
}
62+
63+
private IBrush _statusButtonBackground = Brushes.Gray;
64+
public IBrush StatusButtonBackground
65+
{
66+
get => _statusButtonBackground;
67+
set => this.RaiseAndSetIfChanged(ref _statusButtonBackground, value);
68+
}
2769

2870
public SshPublicKey SelectedPublicKey { get; }
2971
public ObservableCollection<SshPublicKey> Keys { get; }

OpenSSHA-GUI/Views/UploadToServerWindow.axaml

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@
33
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
44
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
55
xmlns:viewModels="clr-namespace:OpenSSHA_GUI.ViewModels"
6+
xmlns:models="clr-namespace:OpenSSHALib.Models;assembly=OpenSSHALib"
7+
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
8+
xmlns:converters="clr-namespace:OpenSSHA_GUI.Converters"
69
x:DataType="viewModels:UploadToServerViewModel"
710
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="600"
811
x:Class="OpenSSHA_GUI.Views.UploadToServerWindow"
9-
Width="400"
12+
Width="500"
1013
Height="600"
1114
Title="Upload key to Server">
15+
<Window.Resources>
16+
<converters:SingleSshKeyTypeConverter x:Key="SingleSshKeyTypeConverter" />
17+
</Window.Resources>
1218
<Design.DataContext>
1319
<!-- This only sets the DataContext for the previewer in an IDE,
1420
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
@@ -17,12 +23,37 @@
1723
<Grid ColumnDefinitions="* * *" RowDefinitions="* * * * *">
1824
<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" Content="Upload a Key to a Server" VerticalAlignment="Top" HorizontalAlignment="Center" Margin="0 20"/>
1925
<ListBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" Grid.RowSpan="2" ItemsSource="{Binding Keys}">
26+
<ListBox.ItemTemplate>
27+
<DataTemplate DataType="models:SshPublicKey">
28+
<Grid RowDefinitions="*" ColumnDefinitions="* * * *">
29+
<StackPanel Grid.Column="0" Orientation="Horizontal" HorizontalAlignment="Center">
30+
<avalonia:MaterialIcon Kind="FileKey"/>
31+
<TextBlock Text="{Binding Filename}" VerticalAlignment="Center"/>
32+
</StackPanel>
33+
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Center">
34+
<avalonia:MaterialIcon Kind="Key"/>
35+
<Label Content="{Binding KeyType.BaseType, Converter={StaticResource SingleSshKeyTypeConverter}}"/>
36+
</StackPanel>
37+
<StackPanel Grid.Column="2" Grid.ColumnSpan="2" Orientation="Horizontal">
38+
<avalonia:MaterialIcon Kind="CommentText"/>
39+
<Label Content="{Binding Comment}"/>
40+
</StackPanel>
41+
</Grid>
42+
</DataTemplate>
43+
</ListBox.ItemTemplate>
2044
</ListBox>
2145
<TextBox Grid.Row="3" Grid.Column="0" Text="{Binding Hostname}" Watermark="Hostname" Margin="5 20" Height="25"/>
2246
<TextBox Grid.Row="3" Grid.Column="1" Text="{Binding User}" Watermark="Username" Margin="5 20" Height="25"/>
2347
<TextBox Grid.Row="3" Grid.Column="2" Text="{Binding Password}" Watermark="Password" PasswordChar="*" Margin="5 20" Height="25"/>
24-
<Button Grid.Row="4" Grid.Column="0" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="5" >Test connection</Button>
25-
<Button Grid.Row="4" Grid.Column="2" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="5" IsEnabled="False">Status: Unknown</Button>
48+
<Button Grid.Row="4" Grid.Column="0" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="5" Command="{Binding TestConnection}" >
49+
<Label Content="Test connection"/>
50+
</Button>
51+
<Canvas Grid.Row="4" Grid.Column="2" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="5" Background="{Binding StatusButtonBackground}">
52+
<ToolTip.Tip>
53+
<Label Content="{Binding StatusButtonToolTip}"/>
54+
</ToolTip.Tip>
55+
<Label Content="{Binding StatusButtonText}" />
56+
</Canvas>
2657
<Button Grid.Row="4" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="5" Background="LimeGreen">Upload</Button>
2758
</Grid>
2859
</Window>

OpenSSHALib/Lib/ServerCommunicator.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace OpenSSHALib.Lib;
99

1010
public static class ServerCommunicator
1111
{
12-
public static bool TestConnection(string ipAddressOrHostname, [NotNullWhen(false)]out string? message)
12+
public static bool TestConnection(string ipAddressOrHostname, string user, string userPassword, [NotNullWhen(false)]out string? message)
1313
{
1414
message = null;
1515
if (!NetworkInterface.GetIsNetworkAvailable())
@@ -18,8 +18,19 @@ public static bool TestConnection(string ipAddressOrHostname, [NotNullWhen(false
1818
return false;
1919
}
2020

21-
using var ping = new Ping();
22-
return ping.Send(ipAddressOrHostname).Status == IPStatus.Success;
21+
try
22+
{
23+
using var sshClient = new SshClient(ipAddressOrHostname, user, userPassword);
24+
sshClient.Connect();
25+
var result = sshClient.IsConnected;
26+
sshClient.Disconnect();
27+
return result;
28+
}
29+
catch (Exception e)
30+
{
31+
message = e.Message;
32+
return false;
33+
}
2334
}
2435

2536
public static bool TryOpenSshConnection(string ipAddressOrHostname, string user, string userPassword,[NotNullWhen(true)] out SshClient? connection, [NotNullWhen(false)] out string? message)

0 commit comments

Comments
 (0)