mirror of
https://gitlab.com/fabinfra/fabaccess/borepin_tmp.git
synced 2025-03-12 14:51:43 +01:00
Added: external libs
This commit is contained in:
parent
a4b95106d7
commit
4b9f7688cd
15
.gitmodules
vendored
Normal file
15
.gitmodules
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
[submodule "external/Shell"]
|
||||||
|
path = external/Shell
|
||||||
|
url = https://github.com/AvaloniaInside/Shell.git
|
||||||
|
[submodule "external/capnproto-dotnetcore_Runtime"]
|
||||||
|
path = external/capnproto-dotnetcore_Runtime
|
||||||
|
url = https://github.com/FabInfra/capnproto-dotnetcore_Runtime.git
|
||||||
|
[submodule "external/S22.Sasl"]
|
||||||
|
path = external/S22.Sasl
|
||||||
|
url = https://github.com/kjkriegel/S22.Sasl.git
|
||||||
|
[submodule "external/nfc"]
|
||||||
|
path = external/nfc
|
||||||
|
url = https://gitlab.com/fabinfra/fabaccess/nfc.git
|
||||||
|
[submodule "api/schema"]
|
||||||
|
path = api/schema
|
||||||
|
url = https://gitlab.com/fabinfra/fabaccess/fabaccess-api.git
|
30
Borepin.sln
30
Borepin.sln
@ -20,6 +20,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||||||
README.md = README.md
|
README.md = README.md
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Capnp.Net.Runtime", "external\capnproto-dotnetcore_Runtime\Capnp.Net.Runtime\Capnp.Net.Runtime.csproj", "{2805B6A8-35FC-4C2E-900A-111223E82985}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "S22.Sasl", "external\S22.Sasl\S22.Sasl.csproj", "{FC22A6DA-322D-4BF2-9288-AAA496B75F36}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AvaloniaInside.Shell", "external\Shell\src\AvaloniaInside.Shell\AvaloniaInside.Shell.csproj", "{0D3D5AE2-9524-4387-9565-EA363E8BF608}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NFC", "external\nfc\NFC\NFC.csproj", "{2B29261E-E23F-46A6-AFBC-1738E7F81471}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FabAccessAPI", "api\FabAccessAPI.csproj", "{26B621D8-E409-4ADE-B53C-8888ADA6817C}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -50,6 +60,26 @@ Global
|
|||||||
{1E07BDF6-DDC7-462E-BD29-77E150717455}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{1E07BDF6-DDC7-462E-BD29-77E150717455}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{1E07BDF6-DDC7-462E-BD29-77E150717455}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{1E07BDF6-DDC7-462E-BD29-77E150717455}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{1E07BDF6-DDC7-462E-BD29-77E150717455}.Release|Any CPU.Build.0 = Release|Any CPU
|
{1E07BDF6-DDC7-462E-BD29-77E150717455}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{2805B6A8-35FC-4C2E-900A-111223E82985}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{2805B6A8-35FC-4C2E-900A-111223E82985}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{2805B6A8-35FC-4C2E-900A-111223E82985}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{2805B6A8-35FC-4C2E-900A-111223E82985}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{FC22A6DA-322D-4BF2-9288-AAA496B75F36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{FC22A6DA-322D-4BF2-9288-AAA496B75F36}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{FC22A6DA-322D-4BF2-9288-AAA496B75F36}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{FC22A6DA-322D-4BF2-9288-AAA496B75F36}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{0D3D5AE2-9524-4387-9565-EA363E8BF608}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{0D3D5AE2-9524-4387-9565-EA363E8BF608}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{0D3D5AE2-9524-4387-9565-EA363E8BF608}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{0D3D5AE2-9524-4387-9565-EA363E8BF608}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{2B29261E-E23F-46A6-AFBC-1738E7F81471}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{2B29261E-E23F-46A6-AFBC-1738E7F81471}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{2B29261E-E23F-46A6-AFBC-1738E7F81471}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{2B29261E-E23F-46A6-AFBC-1738E7F81471}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{26B621D8-E409-4ADE-B53C-8888ADA6817C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{26B621D8-E409-4ADE-B53C-8888ADA6817C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{26B621D8-E409-4ADE-B53C-8888ADA6817C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{26B621D8-E409-4ADE-B53C-8888ADA6817C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net7.0-android</TargetFramework>
|
<TargetFramework>net8.0-android34.0</TargetFramework>
|
||||||
<SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
|
<SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ApplicationId>com.CompanyName.AvaloniaTest</ApplicationId>
|
<ApplicationId>com.CompanyName.AvaloniaTest</ApplicationId>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
|
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
|
||||||
<WasmMainJSPath>AppBundle\main.js</WasmMainJSPath>
|
<WasmMainJSPath>AppBundle\main.js</WasmMainJSPath>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<!--If you are willing to use Windows/MacOS native APIs you will need to create 3 projects.
|
<!--If you are willing to use Windows/MacOS native APIs you will need to create 3 projects.
|
||||||
One for Windows with net7.0-windows TFM, one for MacOS with net7.0-macos and one with net7.0 TFM for Linux.-->
|
One for Windows with net7.0-windows TFM, one for MacOS with net7.0-macos and one with net7.0 TFM for Linux.-->
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net7.0-ios</TargetFramework>
|
<TargetFramework>net8.0-ios16.1</TargetFramework>
|
||||||
<SupportedOSPlatformVersion>10.0</SupportedOSPlatformVersion>
|
<SupportedOSPlatformVersion>10.0</SupportedOSPlatformVersion>
|
||||||
<ProvisioningType>manual</ProvisioningType>
|
<ProvisioningType>manual</ProvisioningType>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@ -12,7 +12,6 @@
|
|||||||
<PackageReference Include="Avalonia.ReactiveUI" Version="11.0.9" />
|
<PackageReference Include="Avalonia.ReactiveUI" Version="11.0.9" />
|
||||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.9" />
|
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.9" />
|
||||||
<PackageReference Include="AvaloniaInside.Shell" Version="1.1.2" />
|
|
||||||
<PackageReference Include="Material.Avalonia" Version="3.3.0" />
|
<PackageReference Include="Material.Avalonia" Version="3.3.0" />
|
||||||
<PackageReference Include="Material.Icons.Avalonia" Version="2.1.0" />
|
<PackageReference Include="Material.Icons.Avalonia" Version="2.1.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
@ -28,4 +27,12 @@
|
|||||||
<Folder Include="Themes\" />
|
<Folder Include="Themes\" />
|
||||||
<Folder Include="Resources\" />
|
<Folder Include="Resources\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\api\FabAccessAPI.csproj" />
|
||||||
|
<ProjectReference Include="..\..\external\capnproto-dotnetcore_Runtime\Capnp.Net.Runtime\Capnp.Net.Runtime.csproj" />
|
||||||
|
<ProjectReference Include="..\..\external\nfc\NFC\NFC.csproj" />
|
||||||
|
<ProjectReference Include="..\..\external\S22.Sasl\S22.Sasl.csproj" />
|
||||||
|
<ProjectReference Include="..\..\external\Shell\src\AvaloniaInside.Shell\AvaloniaInside.Shell.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -59,6 +59,14 @@
|
|||||||
<SideMenuItem.Icon>
|
<SideMenuItem.Icon>
|
||||||
</SideMenuItem.Icon>
|
</SideMenuItem.Icon>
|
||||||
</SideMenuItem>
|
</SideMenuItem>
|
||||||
|
<SideMenuItem Path="/main/settings" Title="Settings">
|
||||||
|
<SideMenuItem.Icon>
|
||||||
|
</SideMenuItem.Icon>
|
||||||
|
</SideMenuItem>
|
||||||
|
<SideMenuItem Path="/main/profile" Title="Profile">
|
||||||
|
<SideMenuItem.Icon>
|
||||||
|
</SideMenuItem.Icon>
|
||||||
|
</SideMenuItem>
|
||||||
|
|
||||||
<ShellView.SideMenuHeader>
|
<ShellView.SideMenuHeader>
|
||||||
<TextBlock Text="FabAccess"
|
<TextBlock Text="FabAccess"
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
ShellView.EnableSafeAreaForBottom="False">
|
ShellView.EnableSafeAreaForBottom="False">
|
||||||
<TabControl.ItemTemplate>
|
<TabControl.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<Grid RowDefinitions="*,*" Width="70">
|
<!--<Grid RowDefinitions="*,*" Width="70">
|
||||||
<i:Icon Value="{Binding Instance.Icon}"
|
<i:Icon Value="{Binding Instance.Icon}"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
Height="24"
|
Height="24"
|
||||||
@ -22,7 +22,7 @@
|
|||||||
Text="{Binding Path=(NavigationBar.Header)}"
|
Text="{Binding Path=(NavigationBar.Header)}"
|
||||||
FontSize="14"
|
FontSize="14"
|
||||||
HorizontalAlignment="Center"></TextBlock>
|
HorizontalAlignment="Center"></TextBlock>
|
||||||
</Grid>
|
</Grid>-->
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</TabControl.ItemTemplate>
|
</TabControl.ItemTemplate>
|
||||||
<TabControl.ContentTemplate>
|
<TabControl.ContentTemplate>
|
||||||
@ -37,6 +37,7 @@
|
|||||||
</Style>
|
</Style>
|
||||||
<Style Selector="TabControl.MainTab /template/ Border > DockPanel > ItemsPresenter">
|
<Style Selector="TabControl.MainTab /template/ Border > DockPanel > ItemsPresenter">
|
||||||
<Setter Property="HorizontalAlignment" Value="Center" />
|
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||||
|
<Setter Property="Height" Value="0" />
|
||||||
</Style>
|
</Style>
|
||||||
</TabControl.Styles>
|
</TabControl.Styles>
|
||||||
</TabControl>
|
</TabControl>
|
||||||
|
@ -93,7 +93,7 @@
|
|||||||
<Setter Property="Background" Value="#40000000" />
|
<Setter Property="Background" Value="#40000000" />
|
||||||
<Setter Property="HorizontalAlignment" Value="Center" />
|
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||||
<Setter Property="CornerRadius" Value="5" />
|
<Setter Property="CornerRadius" Value="5" />
|
||||||
<Setter Property="Padding" Value="8" />
|
<Setter Property="Padding" Value="3" />
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style Selector="TabControl.Center">
|
<Style Selector="TabControl.Center">
|
||||||
|
506
api/API.cs
Normal file
506
api/API.cs
Normal file
@ -0,0 +1,506 @@
|
|||||||
|
using Capnp.Rpc;
|
||||||
|
using FabAccessAPI.Exceptions;
|
||||||
|
using FabAccessAPI.Exceptions.SASL;
|
||||||
|
using FabAccessAPI.Schema;
|
||||||
|
using NLog;
|
||||||
|
using S22.Sasl;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Security;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FabAccessAPI
|
||||||
|
{
|
||||||
|
public class API : IAPI
|
||||||
|
{
|
||||||
|
#region Logger
|
||||||
|
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Private Members
|
||||||
|
/// <summary>
|
||||||
|
/// Internal client to connect to a server with TCP and RPC
|
||||||
|
/// </summary>
|
||||||
|
private TcpRpcClient _TcpRpcClient;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Private ConnectionData
|
||||||
|
/// </summary>
|
||||||
|
private ConnectionData _ConnectionData;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Private ServerData
|
||||||
|
/// </summary>
|
||||||
|
private ServerData _ServerData;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Private Session
|
||||||
|
/// </summary>
|
||||||
|
private Session _Session;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Private Bootstrap
|
||||||
|
/// </summary>
|
||||||
|
private IBootstrap _Bootstrap;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Timer to check connection status
|
||||||
|
/// </summary>
|
||||||
|
private readonly Timer _ConnectionHeatbeat;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Semaphore to connect only once
|
||||||
|
/// </summary>
|
||||||
|
private static SemaphoreSlim _ConnectSemaphore = new SemaphoreSlim(1, 1);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
public API()
|
||||||
|
{
|
||||||
|
_ConnectionHeatbeat = new Timer(Heartbeat, null, 1000, 1000);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Members
|
||||||
|
/// <summary>
|
||||||
|
/// State of the conneciton, can the API-Service connect to a server
|
||||||
|
/// </summary>
|
||||||
|
public bool CanConnect
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _ConnectionData != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// State of the conneciton, is the API-Service connecting to a server
|
||||||
|
/// </summary>
|
||||||
|
public bool IsConnecting
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _TcpRpcClient != null && _ConnectionData != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// State of the conneciton, is the API-Service connected to a server
|
||||||
|
/// </summary>
|
||||||
|
public bool IsConnected
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _TcpRpcClient != null && _TcpRpcClient.State == ConnectionState.Active;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Information about the connection
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="InvalidOperationException"> When API-Service is not connected or trying to connected to a server </exception>
|
||||||
|
public ConnectionData ConnectionData
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if(_ConnectionData == null || !IsConnecting)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return _ConnectionData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
_ConnectionData = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Information about the server
|
||||||
|
/// Is only avalible if the API-Service is connected
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="InvalidOperationException"> When API-Service is not connected </exception>
|
||||||
|
public ServerData ServerData
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_ServerData == null || !IsConnected)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return _ServerData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
_ServerData = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Events
|
||||||
|
/// <summary>
|
||||||
|
/// Event on changes in connection status
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<ConnectionStatusChanged> ConnectionStatusChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unbind all handlers from EventHandler<ConnectionStatusChanged>
|
||||||
|
/// </summary>
|
||||||
|
public void UnbindEventHandler()
|
||||||
|
{
|
||||||
|
if (ConnectionStatusChanged != null)
|
||||||
|
{
|
||||||
|
Log.Trace("Eventhandlers unbinded");
|
||||||
|
foreach (Delegate d in ConnectionStatusChanged.GetInvocationList())
|
||||||
|
{
|
||||||
|
ConnectionStatusChanged -= (EventHandler<ConnectionStatusChanged>)d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Eventhandler for TcpRpcConnectionChanged
|
||||||
|
/// Track connection loss and publish i in ConnectionStatusChanged
|
||||||
|
/// </summary>
|
||||||
|
public void OnTcpRpcConnectionChanged(object sender, ConnectionStateChange args)
|
||||||
|
{
|
||||||
|
if (args.LastState == ConnectionState.Active && args.NewState == ConnectionState.Down)
|
||||||
|
{
|
||||||
|
Log.Trace("TcpRpcClient Event ConnectionLoss");
|
||||||
|
ConnectionStatusChanged?.Invoke(this, FabAccessAPI.ConnectionStatusChanged.ConnectionLoss);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Session
|
||||||
|
/// <summary>
|
||||||
|
/// Get session after connection
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="InvalidOperationException"> When API-Service is not connected </exception>
|
||||||
|
public Session Session
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_Session == null || !IsConnected)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return _Session;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
_Session = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
/// <summary>
|
||||||
|
/// Connect to server with ConnectionData
|
||||||
|
/// If connection lost, the API-Server will try to reconnect
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="connectionData"> Data to establish a connection to a server </param>
|
||||||
|
/// <exception cref="ConnectionException"> When API-Service can not connect to a server </exception>
|
||||||
|
/// <exception cref="AuthenticationException"> When API-Service can connect to a server but can not authenticate </exception>
|
||||||
|
/// <exception cref="InvalidOperationException"> When API-Service is allready connected </exception>
|
||||||
|
public async Task Connect(ConnectionData connectionData, TcpRpcClient tcpRpcClient = null)
|
||||||
|
{
|
||||||
|
await _ConnectSemaphore.WaitAsync();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (IsConnected)
|
||||||
|
{
|
||||||
|
Log.Warn("API already connected");
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tcpRpcClient == null)
|
||||||
|
{
|
||||||
|
tcpRpcClient = new TcpRpcClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _ConnectAsync(tcpRpcClient, connectionData).ConfigureAwait(false);
|
||||||
|
|
||||||
|
_Bootstrap = tcpRpcClient.GetMain<IBootstrap>();
|
||||||
|
ServerData = await _GetServerData(_Bootstrap);
|
||||||
|
|
||||||
|
Session = await _Authenticate(connectionData).ConfigureAwait(false);
|
||||||
|
ConnectionData = connectionData;
|
||||||
|
|
||||||
|
_TcpRpcClient = tcpRpcClient;
|
||||||
|
tcpRpcClient.ConnectionStateChanged += OnTcpRpcConnectionChanged;
|
||||||
|
ConnectionStatusChanged?.Invoke(this, FabAccessAPI.ConnectionStatusChanged.Connected);
|
||||||
|
Log.Info("API connected");
|
||||||
|
}
|
||||||
|
catch (System.Exception ex)
|
||||||
|
{
|
||||||
|
Log.Warn(ex, "API connect failed");
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_ConnectSemaphore.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disconnect from a server
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="InvalidOperationException"> When API-Service is not connected or trying to connect </exception>
|
||||||
|
public Task Disconnect()
|
||||||
|
{
|
||||||
|
if (IsConnected)
|
||||||
|
{
|
||||||
|
_TcpRpcClient.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
_Bootstrap = null;
|
||||||
|
_TcpRpcClient = null;
|
||||||
|
|
||||||
|
Session = null;
|
||||||
|
ConnectionData = null;
|
||||||
|
ServerData = null;
|
||||||
|
|
||||||
|
ConnectionStatusChanged?.Invoke(this, FabAccessAPI.ConnectionStatusChanged.Disconnected);
|
||||||
|
|
||||||
|
Log.Info("API disconnected");
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Try to connect to a server and get ServerData
|
||||||
|
/// The connection is not maintained
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="ConnectionException"> When API-Service can not connect to a server </exception>
|
||||||
|
public async Task<ServerData> TryToConnect(ConnectionData connectionData, TcpRpcClient tcpRpcClient = null)
|
||||||
|
{
|
||||||
|
if (tcpRpcClient == null)
|
||||||
|
{
|
||||||
|
tcpRpcClient = new TcpRpcClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
await _ConnectAsync(tcpRpcClient, connectionData).ConfigureAwait(false);
|
||||||
|
IBootstrap bootstrap = tcpRpcClient.GetMain<IBootstrap>();
|
||||||
|
|
||||||
|
ServerData serverData = await _GetServerData(bootstrap).ConfigureAwait(false);
|
||||||
|
|
||||||
|
tcpRpcClient.Dispose();
|
||||||
|
|
||||||
|
return serverData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Public Wrapper to run HeartbeatAsync
|
||||||
|
/// </summary>
|
||||||
|
public void Heartbeat(object state)
|
||||||
|
{
|
||||||
|
_ = HeartbeatAsync();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Private Methods
|
||||||
|
|
||||||
|
|
||||||
|
private async Task HeartbeatAsync()
|
||||||
|
{
|
||||||
|
if(!IsConnected && CanConnect)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await Connect(ConnectionData).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch(AuthenticationException)
|
||||||
|
{
|
||||||
|
await Disconnect().ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validate Certificate
|
||||||
|
/// TODO: Do some validation
|
||||||
|
/// </summary>
|
||||||
|
private bool _RemoteCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
|
||||||
|
{
|
||||||
|
// TODO Cert Check
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Injects SSL as Midlayer in TCPRPCConnection
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="ConnectionException"></exception>
|
||||||
|
private Stream InjectSSL(Stream tcpstream)
|
||||||
|
{
|
||||||
|
SslStream sslStream = new SslStream(tcpstream, false, new RemoteCertificateValidationCallback(_RemoteCertificateValidationCallback));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
sslStream.ReadTimeout = 5000;
|
||||||
|
sslStream.AuthenticateAsClient("bffhd");
|
||||||
|
sslStream.ReadTimeout = -1;
|
||||||
|
|
||||||
|
return sslStream;
|
||||||
|
}
|
||||||
|
catch (System.Security.Authentication.AuthenticationException exception)
|
||||||
|
{
|
||||||
|
sslStream.Close();
|
||||||
|
Log.Warn(exception);
|
||||||
|
throw new ConnectionException("TLS failed", exception);
|
||||||
|
}
|
||||||
|
catch(IOException exception)
|
||||||
|
{
|
||||||
|
sslStream.Close();
|
||||||
|
Log.Warn(exception);
|
||||||
|
throw new ConnectionException("TLS failed", new Exceptions.TimeoutException("TLS timeout", exception));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Connect async to a server with ConnectionData
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="ConnectionException">Based on RPC Exception</exception>
|
||||||
|
private async Task _ConnectAsync(TcpRpcClient tcprpcClient, ConnectionData connectionData)
|
||||||
|
{
|
||||||
|
tcprpcClient.InjectMidlayer(InjectSSL);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Task timeoutTask = Task.Delay(5000);
|
||||||
|
tcprpcClient.Connect(connectionData.Host.Host, connectionData.Host.Port);
|
||||||
|
await await Task.WhenAny(tcprpcClient.WhenConnected, timeoutTask);
|
||||||
|
|
||||||
|
if (timeoutTask.IsCompleted)
|
||||||
|
{
|
||||||
|
Exceptions.TimeoutException timeoutException = new Exceptions.TimeoutException();
|
||||||
|
Log.Warn(timeoutException);
|
||||||
|
throw new ConnectionException("Connection timeout", timeoutException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (RpcException exception) when (string.Equals(exception.Message, "TcpRpcClient is unable to connect", StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
Log.Warn(exception);
|
||||||
|
throw new ConnectionException("RPC Connecting failed", exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Authenticate connection with ConnectionData
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="connectionData"> Data to establish a connection to a server </param>
|
||||||
|
/// <exception cref="AuthenticationException"></exception>
|
||||||
|
private async Task<Session> _Authenticate(ConnectionData connectionData)
|
||||||
|
{
|
||||||
|
IAuthentication? authentication = await _Bootstrap.CreateSession(SASLMechanism.ToString(connectionData.Mechanism)).ConfigureAwait(false);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await _SASLAuthenticate(authentication, SASLMechanism.ToString(connectionData.Mechanism), connectionData.Properties).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch (System.Exception exception)
|
||||||
|
{
|
||||||
|
Log.Warn(exception, "API authenticating failed");
|
||||||
|
AuthenticationException authenticationException = new AuthenticationException("Authentication failed", exception);
|
||||||
|
|
||||||
|
throw authenticationException;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Authenticate with SASL
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="BadMechanismException"></exception>
|
||||||
|
/// <exception cref="InvalidCredentialsException"></exception>
|
||||||
|
/// <exception cref="AuthenticationFailedException"></exception>
|
||||||
|
private async Task<Session> _SASLAuthenticate(IAuthentication authentication, string mech, Dictionary<string, object> properties)
|
||||||
|
{
|
||||||
|
SaslMechanism? saslMechanism = SaslFactory.Create(mech);
|
||||||
|
foreach (KeyValuePair<string, object> entry in properties)
|
||||||
|
{
|
||||||
|
saslMechanism.Properties.Add(entry.Key, entry.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] data = new byte[0];
|
||||||
|
|
||||||
|
if (saslMechanism.HasInitial)
|
||||||
|
{
|
||||||
|
data = saslMechanism.GetResponse(new byte[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Response? response = await authentication.Step(data);
|
||||||
|
while (!saslMechanism.IsCompleted)
|
||||||
|
{
|
||||||
|
if (response.Failed != null)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (response.Challenge != null)
|
||||||
|
{
|
||||||
|
byte[]? additional = saslMechanism.GetResponse(response.Challenge.ToArray());
|
||||||
|
response = await authentication.Step(additional);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new AuthenticationFailedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.Successful != null)
|
||||||
|
{
|
||||||
|
return response.Successful.Session;
|
||||||
|
}
|
||||||
|
else if (response.Failed != null)
|
||||||
|
{
|
||||||
|
switch (response.Failed.Code)
|
||||||
|
{
|
||||||
|
case Response.Error.badMechanism:
|
||||||
|
throw new BadMechanismException();
|
||||||
|
case Response.Error.invalidCredentials:
|
||||||
|
throw new InvalidCredentialsException();
|
||||||
|
case Response.Error.aborted:
|
||||||
|
case Response.Error.failed:
|
||||||
|
default:
|
||||||
|
throw new AuthenticationFailedException(response.Failed.AdditionalData.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new AuthenticationFailedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get ServerData from server with tcprpcconnection
|
||||||
|
/// </summary>
|
||||||
|
private async Task<ServerData> _GetServerData(IBootstrap bootstrap)
|
||||||
|
{
|
||||||
|
ServerData serverData = new ServerData()
|
||||||
|
{
|
||||||
|
APIVersion = await bootstrap.GetAPIVersion().ConfigureAwait(false),
|
||||||
|
Mechanisms = new List<string>(await bootstrap.Mechanisms().ConfigureAwait(false)),
|
||||||
|
ServerName = (await bootstrap.GetServerRelease().ConfigureAwait(false)).Item1,
|
||||||
|
ServerRelease = (await bootstrap.GetServerRelease().ConfigureAwait(false)).Item2,
|
||||||
|
};
|
||||||
|
|
||||||
|
return serverData;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
45
api/ConnectionData.cs
Normal file
45
api/ConnectionData.cs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace FabAccessAPI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Data to establish a connection to a server
|
||||||
|
/// With Data for Authentication
|
||||||
|
/// </summary>
|
||||||
|
public class ConnectionData
|
||||||
|
{
|
||||||
|
public Uri Host;
|
||||||
|
public string Username;
|
||||||
|
|
||||||
|
public SASLMechanismEnum Mechanism;
|
||||||
|
public Dictionary<string, object> Properties;
|
||||||
|
|
||||||
|
public DateTime LastTime;
|
||||||
|
|
||||||
|
public override bool Equals(object? obj)
|
||||||
|
{
|
||||||
|
if(obj is ConnectionData && obj != null)
|
||||||
|
{
|
||||||
|
ConnectionData? data = obj as ConnectionData;
|
||||||
|
|
||||||
|
return data.Host.Host == Host.Host &&
|
||||||
|
data.Host.Port == Host.Port &&
|
||||||
|
data.Mechanism == Mechanism &&
|
||||||
|
data.Username == Username;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
int hashCode = -1151110446;
|
||||||
|
hashCode = hashCode * -1521134295 + EqualityComparer<Uri>.Default.GetHashCode(Host);
|
||||||
|
hashCode = hashCode * -1521134295 + Mechanism.GetHashCode();
|
||||||
|
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Username);
|
||||||
|
hashCode = hashCode * -1521134295 + EqualityComparer<Dictionary<string, object>>.Default.GetHashCode(Properties);
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
20
api/ConnectionStatusChanged.cs
Normal file
20
api/ConnectionStatusChanged.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
namespace FabAccessAPI
|
||||||
|
{
|
||||||
|
public enum ConnectionStatusChanged
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// API-Service has established connection to server
|
||||||
|
/// </summary>
|
||||||
|
Connected,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// API-Service has closed the connection to a server
|
||||||
|
/// </summary>
|
||||||
|
Disconnected,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Connection was lost and the API-Service will try to reconnect automatically
|
||||||
|
/// </summary>
|
||||||
|
ConnectionLoss
|
||||||
|
}
|
||||||
|
}
|
22
api/Exceptions/APIIncompatibleException.cs
Normal file
22
api/Exceptions/APIIncompatibleException.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace FabAccessAPI.Exceptions
|
||||||
|
{
|
||||||
|
public class APIIncompatibleException : Exception
|
||||||
|
{
|
||||||
|
public APIIncompatibleException()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public APIIncompatibleException(string message) : base(message)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public APIIncompatibleException(string message, Exception inner) : base(message, inner)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
api/Exceptions/AuthenticationException.cs
Normal file
26
api/Exceptions/AuthenticationException.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace FabAccessAPI.Exceptions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Authenticating to a server has failed
|
||||||
|
/// InnerException will provide more information
|
||||||
|
/// </summary>
|
||||||
|
public class AuthenticationException : Exception
|
||||||
|
{
|
||||||
|
public AuthenticationException()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthenticationException(string message) : base(message)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthenticationException(string message, Exception inner) : base(message, inner)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
api/Exceptions/ConnectionException.cs
Normal file
26
api/Exceptions/ConnectionException.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace FabAccessAPI.Exceptions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Connecting to a server has failed
|
||||||
|
/// InnerException will provide more information
|
||||||
|
/// </summary>
|
||||||
|
public class ConnectionException : Exception
|
||||||
|
{
|
||||||
|
public ConnectionException()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnectionException(string message) : base(message)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnectionException(string message, Exception inner) : base(message, inner)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
api/Exceptions/ReconnectingFailedException.cs
Normal file
22
api/Exceptions/ReconnectingFailedException.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace FabAccessAPI.Exceptions
|
||||||
|
{
|
||||||
|
public class ReconnectingFailedException : Exception
|
||||||
|
{
|
||||||
|
public ReconnectingFailedException()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReconnectingFailedException(string message) : base(message)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReconnectingFailedException(string message, Exception inner) : base(message, inner)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
api/Exceptions/SASL/AuthenticationFailedException.cs
Normal file
28
api/Exceptions/SASL/AuthenticationFailedException.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace FabAccessAPI.Exceptions.SASL
|
||||||
|
{
|
||||||
|
public class AuthenticationFailedException : Exception
|
||||||
|
{
|
||||||
|
#region Constructors
|
||||||
|
public AuthenticationFailedException(byte[] additionalData = null)
|
||||||
|
{
|
||||||
|
AdditionalData = additionalData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthenticationFailedException(byte[] additionalData, string message) : base(message)
|
||||||
|
{
|
||||||
|
AdditionalData = additionalData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthenticationFailedException(byte[] additionalData, string message, Exception inner) : base(message, inner)
|
||||||
|
{
|
||||||
|
AdditionalData = additionalData;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Fields
|
||||||
|
public byte[]? AdditionalData { get; }
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
22
api/Exceptions/SASL/BadMechanismException.cs
Normal file
22
api/Exceptions/SASL/BadMechanismException.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace FabAccessAPI.Exceptions.SASL
|
||||||
|
{
|
||||||
|
public class BadMechanismException : Exception
|
||||||
|
{
|
||||||
|
public BadMechanismException()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public BadMechanismException(string message) : base(message)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public BadMechanismException(string message, Exception inner) : base(message, inner)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
api/Exceptions/SASL/InvalidCredentialsException.cs
Normal file
22
api/Exceptions/SASL/InvalidCredentialsException.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace FabAccessAPI.Exceptions.SASL
|
||||||
|
{
|
||||||
|
public class InvalidCredentialsException : Exception
|
||||||
|
{
|
||||||
|
public InvalidCredentialsException()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidCredentialsException(string message) : base(message)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidCredentialsException(string message, Exception inner) : base(message, inner)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
api/Exceptions/TimeoutException.cs
Normal file
25
api/Exceptions/TimeoutException.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace FabAccessAPI.Exceptions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Timeout on Connection
|
||||||
|
/// </summary>
|
||||||
|
public class TimeoutException : Exception
|
||||||
|
{
|
||||||
|
public TimeoutException()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeoutException(string message) : base(message)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeoutException(string message, Exception inner) : base(message, inner)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
api/Exceptions/UnsupportedMechanismException.cs
Normal file
22
api/Exceptions/UnsupportedMechanismException.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace FabAccessAPI.Exceptions
|
||||||
|
{
|
||||||
|
public class UnsupportedMechanismException : Exception
|
||||||
|
{
|
||||||
|
public UnsupportedMechanismException()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnsupportedMechanismException(string message) : base(message)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnsupportedMechanismException(string message, Exception inner) : base(message, inner)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
api/FabAccessAPI.csproj
Normal file
24
api/FabAccessAPI.csproj
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<LangVersion>8</LangVersion>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
|
<NoWarn>1701;1702;CS8625;CS8602;CS8603;CS8601;CS8619;CS8618;CS8620</NoWarn>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="CapnpC.CSharp.MsBuild.Generation" Version="1.3.118" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="6.1.0" />
|
||||||
|
<PackageReference Include="NLog" Version="5.1.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\external\capnproto-dotnetcore_Runtime\Capnp.Net.Runtime\Capnp.Net.Runtime.csproj" />
|
||||||
|
<ProjectReference Include="..\external\S22.Sasl\S22.Sasl.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
84
api/IAPI.cs
Normal file
84
api/IAPI.cs
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Capnp.Rpc;
|
||||||
|
using FabAccessAPI.Exceptions;
|
||||||
|
using FabAccessAPI.Schema;
|
||||||
|
|
||||||
|
namespace FabAccessAPI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Service to connect to a server and maintain the connection
|
||||||
|
/// </summary>
|
||||||
|
public interface IAPI
|
||||||
|
{
|
||||||
|
#region Information about a connection and the server
|
||||||
|
/// <summary>
|
||||||
|
/// State of the conneciton, is the API-Service connecting to a server
|
||||||
|
/// </summary>
|
||||||
|
bool IsConnecting { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// State of the conneciton, is the API-Service connected to a server
|
||||||
|
/// </summary>
|
||||||
|
bool IsConnected { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Information about the connection
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="InvalidOperationException"> When API-Service is not connected or trying to connected to a server </exception>
|
||||||
|
ConnectionData ConnectionData { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Information about the server
|
||||||
|
/// Is only avalible if the API-Service is connected
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="InvalidOperationException"> When API-Service is not connected </exception>
|
||||||
|
ServerData ServerData { get; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods to connect to server
|
||||||
|
/// <summary>
|
||||||
|
/// Connect to server with ConnectionData
|
||||||
|
/// If connection lost, the API-Server will try to reconnect
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="connectionData"> Data to establish a connection to a server </param>
|
||||||
|
/// <exception cref="ConnectionException"> When API-Service can not connect to a server </exception>
|
||||||
|
/// <exception cref="AuthenticationException"> When API-Service can connect to a server but can not authenticate </exception>
|
||||||
|
/// <exception cref="InvalidOperationException"> When API-Service is allready connected </exception>
|
||||||
|
Task Connect(ConnectionData connectionData, TcpRpcClient tcpRpcClient = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disconnect from a server
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="InvalidOperationException"> When API-Service is not connected or trying to connect </exception>
|
||||||
|
Task Disconnect();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Try to connect to a server and get ServerData
|
||||||
|
/// The connection is not maintained
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="ConnectionException"> When API-Service can not connect to a server </exception>
|
||||||
|
Task<ServerData> TryToConnect(ConnectionData connectionData, TcpRpcClient tcpRpcClient = null);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Session
|
||||||
|
/// <summary>
|
||||||
|
/// Get session after connection
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="InvalidOperationException"> When API-Service is not connected </exception>
|
||||||
|
Session Session { get; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Events
|
||||||
|
/// <summary>
|
||||||
|
/// Event on changes in connection status
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<ConnectionStatusChanged> ConnectionStatusChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unbind all handlers from EventHandler<ConnectionStatusChanged>
|
||||||
|
/// </summary>
|
||||||
|
void UnbindEventHandler();
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
24
api/SASLMechanismEnum.cs
Normal file
24
api/SASLMechanismEnum.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace FabAccessAPI
|
||||||
|
{
|
||||||
|
public enum SASLMechanismEnum
|
||||||
|
{
|
||||||
|
PLAIN,
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SASLMechanism
|
||||||
|
{
|
||||||
|
public static string ToString(SASLMechanismEnum mechanism)
|
||||||
|
{
|
||||||
|
switch(mechanism)
|
||||||
|
{
|
||||||
|
case SASLMechanismEnum.PLAIN:
|
||||||
|
return "PLAIN";
|
||||||
|
default:
|
||||||
|
throw new ArgumentException("Mechanism unknown.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
13
api/ServerData.cs
Normal file
13
api/ServerData.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace FabAccessAPI
|
||||||
|
{
|
||||||
|
public class ServerData
|
||||||
|
{
|
||||||
|
public Schema.Version APIVersion;
|
||||||
|
public string ServerName;
|
||||||
|
public string ServerRelease;
|
||||||
|
public List<string> Mechanisms;
|
||||||
|
}
|
||||||
|
}
|
1
api/schema
Submodule
1
api/schema
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit ec8352c6ae97a0c0b75ad8bcdd5b0cb156f753e7
|
1
external/S22.Sasl
vendored
Submodule
1
external/S22.Sasl
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 7316498e9bf9b6380227823f9ae120de09a896ce
|
1
external/Shell
vendored
Submodule
1
external/Shell
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit dffd61592ff1473cce9eba86d9a58a8ef3c9d07a
|
1
external/capnproto-dotnetcore_Runtime
vendored
Submodule
1
external/capnproto-dotnetcore_Runtime
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 1be9ffbf8acbc9770f2d5b67c961fb60e49e5ec5
|
1
external/nfc
vendored
Submodule
1
external/nfc
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit a6479be14e86add7a84b3a1a502608a665ec51f0
|
Loading…
x
Reference in New Issue
Block a user