Implement Client
This commit is contained in:
@@ -5,9 +5,12 @@
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="0.10.3" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="0.10.3" />
|
||||
<PackageReference Include="Avalonia.Diagnostics" Version="0.10.3" />
|
||||
<PackageReference Include="Avalonia" Version="0.10.6" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="0.10.6" />
|
||||
<PackageReference Include="Avalonia.Diagnostics" Version="0.10.6" />
|
||||
<PackageReference Include="Grpc.Net.Client" Version="2.37.0" />
|
||||
<PackageReference Include="MessageBox.Avalonia" Version="1.3.1" />
|
||||
<PackageReference Include="XamlNameReferenceGenerator" Version="1.2.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Akari.Prototype.Shared\Akari.Prototype.Shared.csproj" />
|
||||
|
||||
@@ -4,6 +4,76 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Akari.Prototype.Client.MainWindow"
|
||||
Title="Akari.Prototype.Client">
|
||||
Welcome to Avalonia!
|
||||
Title="Akari.Prototype.Client"
|
||||
Width="600"
|
||||
Height="350"
|
||||
ExtendClientAreaToDecorationsHint="True"
|
||||
TransparencyLevelHint="AcrylicBlur"
|
||||
ExtendClientAreaTitleBarHeightHint="-1"
|
||||
Background="{x:Null}">
|
||||
<Panel>
|
||||
<ExperimentalAcrylicBorder IsHitTestVisible="False">
|
||||
<ExperimentalAcrylicBorder.Material>
|
||||
<ExperimentalAcrylicMaterial BackgroundSource="Digger" TintColor="#F8F8F0" TintOpacity="1" MaterialOpacity="0.6" />
|
||||
</ExperimentalAcrylicBorder.Material>
|
||||
</ExperimentalAcrylicBorder>
|
||||
<RelativePanel VerticalAlignment="Center" Margin="20">
|
||||
<TextBlock x:Name="TxtName"
|
||||
Margin="5, 15"
|
||||
Text="Application Name:" />
|
||||
<TextBox x:Name="BoxName"
|
||||
RelativePanel.RightOf="TxtName"
|
||||
RelativePanel.AlignRightWithPanel="True"
|
||||
RelativePanel.AlignVerticalCenterWith="TxtName" />
|
||||
|
||||
<TextBlock x:Name="TxtToken"
|
||||
RelativePanel.Below="TxtName"
|
||||
RelativePanel.AlignRightWith="TxtName"
|
||||
Margin="5, 15"
|
||||
Text="Token:" />
|
||||
<TextBox x:Name="BoxToken"
|
||||
RelativePanel.RightOf="TxtToken"
|
||||
RelativePanel.AlignRightWithPanel="True"
|
||||
RelativePanel.AlignLeftWith="BoxName"
|
||||
RelativePanel.AlignVerticalCenterWith="TxtToken" />
|
||||
|
||||
<TextBlock x:Name="TxtMode"
|
||||
RelativePanel.Below="TxtToken"
|
||||
RelativePanel.AlignRightWith="TxtToken"
|
||||
Margin="5, 15"
|
||||
Text="Mode:" />
|
||||
<ComboBox x:Name="CbxMode"
|
||||
RelativePanel.RightOf="TxtMode"
|
||||
RelativePanel.AlignVerticalCenterWith="TxtMode"
|
||||
MinWidth="100"
|
||||
SelectedIndex="0">
|
||||
<ComboBoxItem>Encrypt</ComboBoxItem>
|
||||
<ComboBoxItem>Decrypt</ComboBoxItem>
|
||||
</ComboBox>
|
||||
|
||||
<Button x:Name="BtnPickFile"
|
||||
RelativePanel.RightOf="CbxMode"
|
||||
RelativePanel.AlignVerticalCenterWith="TxtMode"
|
||||
Margin="15, 0, 5, 0"
|
||||
Content="Pick File"
|
||||
Click="OnPickFile" />
|
||||
<TextBlock x:Name="TxtFile"
|
||||
RelativePanel.RightOf="BtnPickFile"
|
||||
RelativePanel.AlignRightWithPanel="True"
|
||||
RelativePanel.AlignVerticalCenterWith="BtnPickFile"
|
||||
MaxWidth="250"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
Text="N/A" />
|
||||
|
||||
<Button x:Name="BtnSubmit"
|
||||
RelativePanel.Below="TxtMode"
|
||||
RelativePanel.AlignLeftWith="BoxToken"
|
||||
RelativePanel.AlignRightWith="BoxToken"
|
||||
HorizontalContentAlignment="Center"
|
||||
HorizontalAlignment="Stretch"
|
||||
Margin="0, 5"
|
||||
Content="Submit"
|
||||
Click="OnSubmit" />
|
||||
</RelativePanel>
|
||||
</Panel>
|
||||
</Window>
|
||||
|
||||
@@ -1,22 +1,134 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Akari.Prototype.Shared.Protos;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Google.Protobuf;
|
||||
using Grpc.Net.Client;
|
||||
using MessageBox.Avalonia;
|
||||
|
||||
namespace Akari.Prototype.Client
|
||||
{
|
||||
public partial class MainWindow : Window
|
||||
public partial class MainWindow : Window, IDisposable
|
||||
{
|
||||
public const string Hostname = "https://localhost:5001";
|
||||
|
||||
private readonly GrpcChannel _channel;
|
||||
|
||||
private string? _file = null;
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
#if DEBUG
|
||||
this.AttachDevTools();
|
||||
#endif
|
||||
|
||||
_channel = GrpcChannel.ForAddress(Hostname);
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
private async void OnPickFile(object sender, RoutedEventArgs e)
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
var mode = GetMode();
|
||||
|
||||
var dialog = new OpenFileDialog()
|
||||
{
|
||||
AllowMultiple = false,
|
||||
Title = $"Pick a file to {mode}"
|
||||
};
|
||||
|
||||
if (await dialog.ShowAsync(this) is string[] { Length: 1 } res)
|
||||
{
|
||||
_file = res[0];
|
||||
TxtFile.Text = Path.GetFileName(_file);
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnSubmit(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_file is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(BoxName.Text))
|
||||
{
|
||||
await MessageBoxManager.GetMessageBoxStandardWindow("Error", $"Invalid application name", icon: MessageBox.Avalonia.Enums.Icon.Error).Show();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(BoxToken.Text))
|
||||
{
|
||||
await MessageBoxManager.GetMessageBoxStandardWindow("Error", $"Invalid token", icon: MessageBox.Avalonia.Enums.Icon.Error).Show();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var client = new AkariApi.AkariApiClient(_channel);
|
||||
|
||||
// Decrypt
|
||||
if (GetMode() == Mode.Decrypt)
|
||||
{
|
||||
var response = await client.DecryptAsync(new DecryptRequest()
|
||||
{
|
||||
Application = BoxName.Text,
|
||||
Token = BoxToken.Text,
|
||||
Encrypted = ByteString.CopyFrom(File.ReadAllBytes(_file))
|
||||
});
|
||||
|
||||
if (response.ResponseCase == DecryptResponse.ResponseOneofCase.ErrorMessage)
|
||||
{
|
||||
await MessageBoxManager.GetMessageBoxStandardWindow("Error", $"Error during decryption, server response: {response.ErrorMessage}", icon: MessageBox.Avalonia.Enums.Icon.Error).Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
string outPath = Path.ChangeExtension(_file, null);
|
||||
|
||||
File.WriteAllBytes(outPath, response.Plain.ToByteArray());
|
||||
|
||||
await MessageBoxManager.GetMessageBoxStandardWindow("Success", $"Saved decrypted file to {outPath}\n").Show();
|
||||
|
||||
}
|
||||
}
|
||||
// Encrypt
|
||||
else
|
||||
{
|
||||
var response = await client.EncryptAsync(new EncryptRequest()
|
||||
{
|
||||
Application = BoxName.Text,
|
||||
Token = BoxToken.Text,
|
||||
Plain = ByteString.CopyFrom(File.ReadAllBytes(_file))
|
||||
});
|
||||
|
||||
if (response.ResponseCase == EncryptResponse.ResponseOneofCase.ErrorMessage)
|
||||
{
|
||||
await MessageBoxManager.GetMessageBoxStandardWindow("Error", $"Error during encryption, server response: {response.ErrorMessage}", icon: MessageBox.Avalonia.Enums.Icon.Error).Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
string outPath = $"{_file}.enc";
|
||||
|
||||
File.WriteAllBytes(outPath, response.Encrypted.ToByteArray());
|
||||
|
||||
await MessageBoxManager.GetMessageBoxStandardWindow("Success", $"Saved encrypted file to {outPath}").Show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Mode GetMode()
|
||||
{
|
||||
if (CbxMode.SelectedItem is ComboBoxItem { Content: string mode })
|
||||
{
|
||||
return Enum.Parse<Mode>(mode);
|
||||
}
|
||||
|
||||
throw new Exception("Invalid mode in CbxMode");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_channel.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
14
Akari.Prototype.Client/Mode.cs
Normal file
14
Akari.Prototype.Client/Mode.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Akari.Prototype.Client
|
||||
{
|
||||
enum Mode
|
||||
{
|
||||
Encrypt,
|
||||
Decrypt
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user