Make Solution Buildable

This commit is contained in:
TheJoKlLa 2021-09-11 13:53:40 +02:00
parent 8d96a87534
commit 1d9782f7ba
16 changed files with 310 additions and 566 deletions

View File

@ -19,6 +19,11 @@
<Target Name="MATPrerequisite" BeforeTargets="PrepareForBuild" Condition="!Exists('$(MSBuildExtensionsPath)\Microsoft\Multilingual App Toolkit\Microsoft.Multilingual.ResxResources.targets')" Label="MultilingualAppToolkit"> <Target Name="MATPrerequisite" BeforeTargets="PrepareForBuild" Condition="!Exists('$(MSBuildExtensionsPath)\Microsoft\Multilingual App Toolkit\Microsoft.Multilingual.ResxResources.targets')" Label="MultilingualAppToolkit">
<Warning Text="$(MSBuildProjectFile) is Multilingual build enabled, but the Multilingual App Toolkit is unavailable during the build. If building with Visual Studio, please check to ensure that toolkit is properly installed." /> <Warning Text="$(MSBuildProjectFile) is Multilingual build enabled, but the Multilingual App Toolkit is unavailable during the build. If building with Visual Studio, please check to ensure that toolkit is properly installed." />
</Target> </Target>
<ItemGroup>
<Compile Remove="Behaviour\**" />
<EmbeddedResource Remove="Behaviour\**" />
<None Remove="Behaviour\**" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Plugin.Multilingual" Version="1.0.2" /> <PackageReference Include="Plugin.Multilingual" Version="1.0.2" />
@ -120,9 +125,6 @@
<Generator>MSBuild:UpdateDesignTimeXaml</Generator> <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Behaviour\" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\FabAccessAPI\FabAccessAPI.csproj" /> <ProjectReference Include="..\..\FabAccessAPI\FabAccessAPI.csproj" />
</ItemGroup> </ItemGroup>

View File

@ -8,9 +8,9 @@ namespace Borepin.Converter
{ {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{ {
switch((FabAccessAPI.Schema.State)value) switch((FabAccessAPI.Schema.Machine.MachineState)value)
{ {
case (FabAccessAPI.Schema.State.free): case (FabAccessAPI.Schema.Machine.MachineState.free):
return (Color)Application.Current.Resources["FirstColor"]; return (Color)Application.Current.Resources["FirstColor"];
default: default:
return (Color)Application.Current.Resources["SixthColor"]; return (Color)Application.Current.Resources["SixthColor"];

View File

@ -8,19 +8,19 @@ namespace Borepin.Converter
{ {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{ {
switch((FabAccessAPI.Schema.State)value) switch((FabAccessAPI.Schema.Machine.MachineState)value)
{ {
case (FabAccessAPI.Schema.State.free): case (FabAccessAPI.Schema.Machine.MachineState.free):
return "Free"; return "Free";
case (FabAccessAPI.Schema.State.inUse): case (FabAccessAPI.Schema.Machine.MachineState.inUse):
return "In Use"; return "In Use";
case (FabAccessAPI.Schema.State.toCheck): case (FabAccessAPI.Schema.Machine.MachineState.toCheck):
return "To Check"; return "To Check";
case (FabAccessAPI.Schema.State.reserved): case (FabAccessAPI.Schema.Machine.MachineState.reserved):
return "Reserved"; return "Reserved";
case (FabAccessAPI.Schema.State.blocked): case (FabAccessAPI.Schema.Machine.MachineState.blocked):
return "Blocked"; return "Blocked";
case (FabAccessAPI.Schema.State.disabled): case (FabAccessAPI.Schema.Machine.MachineState.disabled):
return "Disabled"; return "Disabled";
default: default:
return "Unknown"; return "Unknown";

View File

@ -1,8 +0,0 @@
namespace Borepin.Model
{
public class Machine
{
public FabAccessAPI.Machine Instance { get; set; }
public FabAccessAPI.Schema.Machine.MInfo MInfo { get; set; }
}
}

View File

@ -37,23 +37,22 @@ namespace Borepin.PageModel
IsConnected = true; IsConnected = true;
} }
FabAccessAPI.Machines machineInterface = await _BFFHService.GetMachineInterface(); FabAccessAPI.Schema.IMachineSystem machineInterface = await _BFFHService.GetMachineSystemInterface();
FabAccessAPI.Schema.MachineSystem.IInfoInterface infoInterface = await machineInterface.Info();
List<Machine> list = new List<Machine>(); //IReadOnlyList<FabAccessAPI.Machine> machine_list = await machineInterface.Info();
//foreach (FabAccessAPI.Machine machine in machine_list)
//{
// list.Add(new Machine() { Instance = machine, MInfo = await machine.GetMInfo() });
//}
IReadOnlyList<FabAccessAPI.Machine> machine_list = await machineInterface.ListMachines(); //List<MachineListItemViewModel> viewmodel_list = new List<MachineListItemViewModel>();
foreach (FabAccessAPI.Machine machine in machine_list) //foreach (Machine machine in list)
{ //{
list.Add(new Machine() { Instance = machine, MInfo = await machine.GetMInfo() }); // viewmodel_list.Add(new MachineListItemViewModel(machine));
} //}
List<MachineListItemViewModel> viewmodel_list = new List<MachineListItemViewModel>(); MachineListItemViewModel_List = null;//viewmodel_list;
foreach (Machine machine in list)
{
viewmodel_list.Add(new MachineListItemViewModel(machine));
}
MachineListItemViewModel_List = viewmodel_list;
IsBusy = false; IsBusy = false;
} }
@ -88,7 +87,7 @@ namespace Borepin.PageModel
NavigationParameters parameters = new NavigationParameters NavigationParameters parameters = new NavigationParameters
{ {
{ "instance", viewmodel.Instance } //{ "instance", viewmodel.Instance }
}; };
INavigationResult result = await _NavigationService.NavigateAsync($"MachinePage", parameters); INavigationResult result = await _NavigationService.NavigateAsync($"MachinePage", parameters);

View File

@ -4,7 +4,6 @@ using Prism.Commands;
using Prism.Navigation; using Prism.Navigation;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using static FabAccessAPI.Schema.Machine.WriteInterface;
namespace Borepin.PageModel namespace Borepin.PageModel
{ {
@ -21,16 +20,7 @@ namespace Borepin.PageModel
#region Data #region Data
public override Task LoadData() public override Task LoadData()
{ {
Name = MachineItem.MInfo.Name; //Name = MachineItem.MInfo.Name;
CanUse = MachineItem.MInfo.State == FabAccessAPI.Schema.State.free;
//if (GiveBack == null)
//{
// GiveBack = await MachineItem.Instance.GetGiveBack();
//}
CanGiveBack = GiveBack != null;
IsBusy = false; IsBusy = false;
@ -40,12 +30,12 @@ namespace Borepin.PageModel
#endregion #endregion
#region Properties #region Properties
private Machine _MachineItem; //private Machine _MachineItem;
public Machine MachineItem //public Machine MachineItem
{ //{
get => _MachineItem; // get => _MachineItem;
set => SetProperty(ref _MachineItem, value); // set => SetProperty(ref _MachineItem, value);
} //}
private string _Name; private string _Name;
public string Name public string Name
@ -54,13 +44,6 @@ namespace Borepin.PageModel
set => SetProperty(ref _Name, value); set => SetProperty(ref _Name, value);
} }
private IGiveBack _GiveBack;
public IGiveBack GiveBack
{
get => _GiveBack;
set => SetProperty(ref _GiveBack, value);
}
private bool _CanUse; private bool _CanUse;
public bool CanUse public bool CanUse
{ {
@ -86,12 +69,12 @@ namespace Borepin.PageModel
private async void UseMachineCommandExecuted() private async void UseMachineCommandExecuted()
{ {
GiveBack = await MachineItem.Instance.Use(); //GiveBack = await MachineItem.Instance.Use();
CanGiveBack = GiveBack != null; //CanGiveBack = GiveBack != null;
MachineItem.MInfo = await MachineItem.Instance.GetMInfo(); //MachineItem.MInfo = await MachineItem.Instance.GetMInfo();
CanUse = MachineItem.MInfo.State == FabAccessAPI.Schema.State.free; //CanUse = MachineItem.MInfo.State == FabAccessAPI.Schema.Machine.MachineState.free;
} }
private ICommand _GiveBackMachineCommand; private ICommand _GiveBackMachineCommand;
@ -103,14 +86,14 @@ namespace Borepin.PageModel
private async void GiveBackMachineCommandExecuted() private async void GiveBackMachineCommandExecuted()
{ {
await GiveBack.Ret(); //await GiveBack.Ret();
GiveBack = null; //GiveBack = null;
CanGiveBack = GiveBack != null; //CanGiveBack = GiveBack != null;
MachineItem.MInfo = await MachineItem.Instance.GetMInfo(); //MachineItem.MInfo = await MachineItem.Instance.GetMInfo();
CanUse = MachineItem.MInfo.State == FabAccessAPI.Schema.State.free; //CanUse = MachineItem.MInfo.State == FabAccessAPI.Schema.Machine.MachineState.free;
} }
#endregion #endregion
@ -122,7 +105,7 @@ namespace Borepin.PageModel
public override void OnNavigatedTo(INavigationParameters parameters) public override void OnNavigatedTo(INavigationParameters parameters)
{ {
MachineItem = parameters["instance"] as Machine; //MachineItem = parameters["instance"] as Machine;
IsBusy = true; IsBusy = true;
Task.Run(LoadData); Task.Run(LoadData);

View File

@ -3,8 +3,7 @@ using Borepin.Service.Credentials;
using System.Threading.Tasks; using System.Threading.Tasks;
using Capnp.Rpc; using Capnp.Rpc;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using FabAccessAPI.Schema;
using System;
namespace Borepin.Service.BFFH namespace Borepin.Service.BFFH
{ {
@ -75,9 +74,19 @@ namespace Borepin.Service.BFFH
return await Task.FromResult(true); return await Task.FromResult(true);
} }
public Task<FabAccessAPI.Machines> GetMachineInterface() public Task<IMachineSystem> GetMachineSystemInterface()
{ {
return _Connection.AccessMachines(); return _Connection.AccessMachineSystem();
}
public Task<IUserSystem> GetUserSystemInterface()
{
return _Connection.AccessUserSystem();
}
public Task<IPermissionSystem> GetPermissionSystemInterface()
{
return _Connection.AccessPermissionSystem();
} }
} }
} }

View File

@ -1,4 +1,5 @@
using Borepin.Model; using Borepin.Model;
using FabAccessAPI.Schema;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Borepin.Service.BFFH namespace Borepin.Service.BFFH
@ -46,6 +47,8 @@ namespace Borepin.Service.BFFH
/// <param name="connection">address + username</param> /// <param name="connection">address + username</param>
Task<bool> Authenticate(Connection connection, string password); Task<bool> Authenticate(Connection connection, string password);
Task<FabAccessAPI.Machines> GetMachineInterface(); Task<IMachineSystem> GetMachineSystemInterface();
Task<IUserSystem> GetUserSystemInterface();
Task<IPermissionSystem> GetPermissionSystemInterface();
} }
} }

View File

@ -4,20 +4,20 @@ namespace Borepin.ViewModel
{ {
public class MachineListItemViewModel : BindableBase public class MachineListItemViewModel : BindableBase
{ {
public MachineListItemViewModel(Model.Machine instance) public MachineListItemViewModel()//Model.Machine instance)
{ {
_Instance = instance; //_Instance = null;
Name = instance.MInfo.Name; //Name = instance.MInfo.Name;
State = instance.MInfo.State; //State = instance.MInfo.State;
} }
private Model.Machine _Instance; //private Model.Machine _Instance;
public Model.Machine Instance //public Model.Machine Instance
{ //{
get => _Instance; // get => _Instance;
set => SetProperty(ref _Instance, value); // set => SetProperty(ref _Instance, value);
} //}
private string _Name; private string _Name;
public string Name public string Name
@ -26,8 +26,8 @@ namespace Borepin.ViewModel
set => SetProperty(ref _Name, value); set => SetProperty(ref _Name, value);
} }
private FabAccessAPI.Schema.State _State; private FabAccessAPI.Schema.Machine.MachineState _State;
public FabAccessAPI.Schema.State State public FabAccessAPI.Schema.Machine.MachineState State
{ {
get => _State; get => _State;
set => SetProperty(ref _State, value); set => SetProperty(ref _State, value);

View File

@ -1,163 +1,176 @@
//using FabAccessAPI.Schema; using FabAccessAPI.Schema;
//using S22.Sasl; using S22.Sasl;
//using System.Collections.Generic; using System.Collections.Generic;
//using System.Linq; using System.Linq;
//using System.Threading.Tasks; using System.Threading.Tasks;
//using Exception = System.Exception; using Exception = System.Exception;
//namespace FabAccessAPI namespace FabAccessAPI
//{ {
// / Authentication Identity /// Authentication Identity
// / ///
// / Under the hood a string because the form depends heavily on the method /// Under the hood a string because the form depends heavily on the method
// public struct AuthCId { public struct AuthCId
// public string Id { get; private set; } {
public string Id { get; private set; }
// public AuthCId(string id) : this() { Id = id; } public AuthCId(string id) : this() { Id = id; }
// } }
// / Authorization Identity
// /
// / This identity is internal to FabAccess and completely independent from the authentication
// / method or source
// public struct AuthZId {
// / Main User ID. Generally an user name or similar
// public string Uid;
// / Sub user ID. /// Authorization Identity
// / ///
// / Can change scopes for permissions, e.g. having a +admin account with more permissions than /// This identity is internal to FabAccess and completely independent from the authentication
// / the default account and +dashboard et.al. accounts that have restricted permissions for /// method or source
// / their applications public struct AuthZId
// public string Subuid; {
/// Main User ID. Generally an user name or similar
public string Uid;
// / Realm this account originates. /// Sub user ID.
// / ///
// / The Realm is usually described by a domain name but local policy may dictate an unrelated /// Can change scopes for permissions, e.g. having a +admin account with more permissions than
// / mapping /// the default account and +dashboard et.al. accounts that have restricted permissions for
// public string Realm; /// their applications
// } public string Subuid;
// / Authentication/Authorization user object. /// Realm this account originates.
// / ///
// / This struct contains the user as is passed to the actual authentication/authorization /// The Realm is usually described by a domain name but local policy may dictate an unrelated
// / subsystems /// mapping
// / public string Realm;
// public struct AuthUser { }
// / Contains the Authentication ID used
// /
// / The authentication ID is an identifier for the authentication exchange. This is different
// / than the ID of the user to be authenticated; for example when using x509 the authcid is
// / the dn of the certificate, when using GSSAPI the authcid is of form `<userid>@<REALM>`
// public AuthCId Authcid;
// / Contains the Authorization ID /// Authentication/Authorization user object.
// / ///
// / This is the identifier of the user to *authenticate as*. This in several cases is different /// This struct contains the user as is passed to the actual authentication/authorization
// / to the `authcid`: /// subsystems
// / If somebody wants to authenticate as somebody else, su-style. ///
// / If a person wants to authenticate as a higher-permissions account, e.g. foo may set authzid foo+admin public struct AuthUser
// / to split normal user and "admin" accounts. {
// / If a method requires a specific authcid that is different from the identifier of the user /// Contains the Authentication ID used
// / to authenticate as, e.g. GSSAPI, x509 client certificates, API TOKEN authentication. ///
// public AuthZId Authzid; /// The authentication ID is an identifier for the authentication exchange. This is different
/// than the ID of the user to be authenticated; for example when using x509 the authcid is
/// the dn of the certificate, when using GSSAPI the authcid is of form `<userid>@<REALM>`
public AuthCId Authcid;
// / Contains the authentication method used /// Contains the Authorization ID
// / ///
// / For the most part this is the SASL method /// This is the identifier of the user to *authenticate as*. This in several cases is different
// public string AuthMethod; /// to the `authcid`:
/// If somebody wants to authenticate as somebody else, su-style.
/// If a person wants to authenticate as a higher-permissions account, e.g. foo may set authzid foo+admin
/// to split normal user and "admin" accounts.
/// If a method requires a specific authcid that is different from the identifier of the user
/// to authenticate as, e.g. GSSAPI, x509 client certificates, API TOKEN authentication.
public AuthZId Authzid;
// / Method-specific key-value pairs /// Contains the authentication method used
// / ///
// / Each method can use their own key-value pairs. /// For the most part this is the SASL method
// / E.g. EXTERNAL encodes the actual method used (x509 client certs, UID/GID for unix sockets, public string AuthMethod;
// / ...)
// public Dictionary<string, string> Kvs;
// } /// Method-specific key-value pairs
///
/// Each method can use their own key-value pairs.
/// E.g. EXTERNAL encodes the actual method used (x509 client certs, UID/GID for unix sockets,
/// ...)
public Dictionary<string, string> Kvs;
// Authentication has two parts: Granting the authentication itself and then performing the }
// authentication.
// Granting the authentication checks if
// a) the given authcid fits with the given (authMethod, kvs). In general a failure here indicates
// a programming failure — the authcid come from the same source as that tuple
// b) the given authcid may authenticate as the given authzid. E.g. if a given client certificate
// has been configured for that user, if a GSSAPI user maps to a given user,
// public enum AuthError {
// / Authentication ID is bad/unknown/..
// BadAuthcid,
// / Authorization ID is unknown/..
// BadAuthzid,
// / Authorization ID is not of form user+uid@realm
// MalformedAuthzid,
// / User may not use that authorization id
// NotAllowedAuthzid,
// } // Authentication has two parts: Granting the authentication itself and then performing the
// authentication.
// Granting the authentication checks if
// a) the given authcid fits with the given (authMethod, kvs). In general a failure here indicates
// a programming failure — the authcid come from the same source as that tuple
// b) the given authcid may authenticate as the given authzid. E.g. if a given client certificate
// has been configured for that user, if a GSSAPI user maps to a given user,
public enum AuthError
{
/// Authentication ID is bad/unknown/..
BadAuthcid,
/// Authorization ID is unknown/..
BadAuthzid,
/// Authorization ID is not of form user+uid@realm
MalformedAuthzid,
/// User may not use that authorization id
NotAllowedAuthzid,
// public class UnauthorizedException : Exception{} }
// public class UnsupportedMechanismException : Exception{}
// / <summary> public class UnauthorizedException : Exception { }
// / THIS IS VERY INCOMPLETE! public class UnsupportedMechanismException : Exception { }
// / </summary>
// public class Auth {
// #region Log
// private static readonly log4net.ILog _Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
// #endregion
// private IAuthentication _authCap;
// public Auth(IAuthentication authCap) {
// _authCap = authCap;
// }
// public Task<IReadOnlyList<string>> GetMechanisms() { /// <summary>
// return _authCap.Mechanisms(); /// THIS IS VERY INCOMPLETE!
// } /// </summary>
public class Auth
{
#region Log
private static readonly log4net.ILog _Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
#endregion
// public async Task<bool> Authenticate(string mech, Dictionary<string, object> properties) { private IAuthenticationSystem _authCap;
public Auth(IAuthenticationSystem authCap)
{
_authCap = authCap;
}
// var m = SaslFactory.Create(mech); public Task<IReadOnlyList<string>> GetMechanisms()
// foreach (KeyValuePair<string, object> entry in properties) { {
// m.Properties.Add(entry.Key, entry.Value); return _authCap.Mechanisms();
// } }
// var initialResponse = new Request.initialResponse(); public async Task<bool> Authenticate(string mech, Dictionary<string, object> properties)
// if (m.HasInitial) { {
// initialResponse.Initial = m.GetResponse(new byte[0]);
// }
// var req = new Request { var m = SaslFactory.Create(mech);
// Mechanism = m.Name, foreach (KeyValuePair<string, object> entry in properties)
// InitialResponse = initialResponse {
// }; m.Properties.Add(entry.Key, entry.Value);
}
// var resp = await _authCap.Start(req); var initialResponse = new Request.initialResponse();
// while (!m.IsCompleted) { if (m.HasInitial)
// if (resp.which == Response.WHICH.Challence) { {
// var additional = m.GetResponse(resp.Challence.ToArray()); initialResponse.Initial = m.GetResponse(new byte[0]);
// resp = await _authCap.Step(additional); }
// }
// else {
// break;
// }
// }
// if (resp.which == Response.WHICH.Outcome) { var req = new Request
// if (resp.Outcome.Result == Response.Result.successful) { {
// return true; Mechanism = m.Name,
// } InitialResponse = initialResponse
// else { };
// TODO: Provide meaningful info about auth failure
// return false;
// }
// }
// return false; var resp = await _authCap.Start(req);
// } while (!m.IsCompleted)
{
if (resp.which == Response.WHICH.Challence)
{
var additional = m.GetResponse(resp.Challence.ToArray());
resp = await _authCap.Step(additional);
}
else
{
break;
}
}
if (resp.which == Response.WHICH.Outcome)
{
if (resp.Outcome.Result == Response.Result.successful)
{
return true;
}
else
{
//TODO: Provide meaningful info about auth failure
return false;
}
}
// } return false;
}
//} }
}

View File

@ -1,64 +1,86 @@
//using Capnp.Rpc; using Capnp.Rpc;
//using FabAccessAPI.Schema; using FabAccessAPI.Schema;
//using System; using System;
//using System.Collections.Generic; using System.Collections.Generic;
//using System.Linq; using System.Linq;
//using System.Threading; using System.Threading;
//using System.Threading.Tasks; using System.Threading.Tasks;
//namespace FabAccessAPI { namespace FabAccessAPI
// public class Connection { {
// #region private variables public class Connection
// private readonly TcpRpcClient? _rpcClient = null; {
// private readonly IBootstrap? _bootstrapCap = null; #region private variables
// private Auth? _auth = null; private readonly TcpRpcClient? _rpcClient = null;
// private Machines? _machines = null; private readonly IBootstrap? _bootstrapCap = null;
// #endregion private Auth? _auth = null;
#endregion
// public TcpRpcClient? RpcClient => _rpcClient;
// #region Log
// private static readonly log4net.ILog _Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
// #endregion
// /// <summary>
// ///
// /// </summary>
// /// <param name="rpcClient">Should be an already configured and connected TcpRpcClient</param>
// public Connection(TcpRpcClient rpcClient) {
// _rpcClient = rpcClient;
// _bootstrapCap = _rpcClient.GetMain<IBootstrap>();
// _Log.Debug($"Done bootstraping API connection.");
// }
// /// <summary> public TcpRpcClient? RpcClient => _rpcClient;
// /// Authenticate this connection.
// /// Calling this more then once is UB
// /// </summary>
// /// <param name="mech">The desired authentication mechanism</param>
// /// <param name="kvs">Key-Value data specific to the mechanism</param>
// /// <returns></returns>
// public async Task Auth(string mech, Dictionary<string, object> kvs, CancellationToken cancellationToken_ = default) {
// // _bootstrapCap = await _bootstrapCap.Unwrap();
// var authCap = await _bootstrapCap.Auth(cancellationToken_);
// _auth = new Auth(authCap);
// var mechs = await _auth.GetMechanisms();
// _Log.Debug($"The Server supports the following auth mechs: {string.Join(", ", mechs)}");
// if (!mechs.Contains(mech)) { #region Log
// throw new UnsupportedMechanismException(); private static readonly log4net.ILog _Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
// } #endregion
// await _auth.Authenticate(mech, kvs); /// <summary>
// } ///
/// </summary>
/// <param name="rpcClient">Should be an already configured and connected TcpRpcClient</param>
public Connection(TcpRpcClient rpcClient)
{
_rpcClient = rpcClient;
_bootstrapCap = _rpcClient.GetMain<IBootstrap>();
_Log.Debug($"Done bootstraping API connection.");
}
// /// <summary> /// <summary>
// /// Get a wrapped capability to interact with machines /// Authenticate this connection.
// /// </summary> /// Calling this more then once is UB
// /// <returns>A wrapped capability to interact with machines</returns> /// </summary>
// public async Task<Machines> AccessMachines() { /// <param name="mech">The desired authentication mechanism</param>
// _machines ??= new Machines(await _bootstrapCap.Machines()); /// <param name="kvs">Key-Value data specific to the mechanism</param>
// return _machines; /// <returns></returns>
// } public async Task Auth(string mech, Dictionary<string, object> kvs, CancellationToken cancellationToken_ = default)
// } {
//} // _bootstrapCap = await _bootstrapCap.Unwrap();
var authCap = await _bootstrapCap.AuthenticationSystem(cancellationToken_);
_auth = new Auth(authCap);
var mechs = await _auth.GetMechanisms();
_Log.Debug($"The Server supports the following auth mechs: {string.Join(", ", mechs)}");
if (!mechs.Contains(mech))
{
throw new UnsupportedMechanismException();
}
await _auth.Authenticate(mech, kvs);
}
/// <summary>
/// Get a wrapped capability to interact with machines
/// </summary>
/// <returns>A wrapped capability to interact with machines</returns>
public async Task<IMachineSystem> AccessMachineSystem()
{
return await _bootstrapCap.MachineSystem();
}
/// <summary>
/// Get a wrapped capability to interact with users
/// </summary>
/// <returns>A wrapped capability to interact with users</returns>
public async Task<IUserSystem> AccessUserSystem()
{
return await _bootstrapCap.UserSystem();
}
/// <summary>
/// Get a wrapped capability to interact with permissions
/// </summary>
/// <returns>A wrapped capability to interact with permissions</returns>
public async Task<IPermissionSystem> AccessPermissionSystem()
{
return await _bootstrapCap.PermissionSystem();
}
}
}

View File

@ -14,7 +14,7 @@
<PackageReference Include="Capnp.Net.Runtime" Version="1.3.118" /> <PackageReference Include="Capnp.Net.Runtime" Version="1.3.118" />
<PackageReference Include="CapnpC.CSharp.MsBuild.Generation" Version="1.3.118" /> <PackageReference Include="CapnpC.CSharp.MsBuild.Generation" Version="1.3.118" />
<PackageReference Include="log4net" Version="2.0.12" /> <PackageReference Include="log4net" Version="2.0.12" />
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="5.0.3" /> <PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="5.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,224 +0,0 @@
//using FabAccessAPI.Schema;
//using System;
//using System.Collections.Generic;
//using System.Threading.Tasks;
//namespace FabAccessAPI
//{
// public class MachineException : Exception { }
// /// <summary>
// /// Wraps a capability for accessing the Machines subsystem of BFFH
// /// </summary>
// public class Machines {
// private readonly IMachines _machinesCap;
// /// <summary>
// /// Constructs the Wrapper Class from a given capability.
// /// </summary>
// /// <param name="machinesCap">The capability that should be wrapped.</param>
// public Machines(IMachines machinesCap) {
// _machinesCap = machinesCap;
// }
// /// <summary>
// /// List of all machines that BFFH knows about the user has been granted at least read access on
// /// </summary>
// /// <returns>ReadOnlyList of available Machines</returns>
// public async Task<IReadOnlyList<Machine>?> ListMachines()
// {
// IReadOnlyList<Schema.Machine>? machineList = await _machinesCap.ListMachines().ConfigureAwait(false);
// List<Machine> machineList_new = new List<Machine>();
// foreach(Schema.Machine machine in machineList)
// {
// machineList_new.Add(new Machine(machine));
// }
// return machineList_new;
// }
// /// <summary>
// /// Access a particular machine by known name. This may fail for two reasons:
// /// The user has not been granted access to know the machine exists or the machine does in fact not exist.
// /// In both cases the `machine` result will be a NULL-pointer
// /// </summary>
// /// <param name="name">Name of the Machine</param>
// /// <returns>The Machine we requested</returns>
// public async Task<Machine> GetMachine(string name) {
// var mach = (await _machinesCap.GetMachine(name).ConfigureAwait(false)).Item1;
// if (mach == null) {
// //TODO: Throw a more specific exception!
// throw new MachineException();
// }
// return new Machine(mach);
// }
// }
// /// <summary>
// /// A machine. This represents a machine as BFFH thinks about it which may mean
// ///several machines or just part of a machine in the real world.
// ///By itself this struct is completely useless since it contains only the information
// ///that the machine exists the user is allowed to know about that fact. For all further
// ///information the user has to call the contained capabilities which depending on the
// ///access level may not be set. For example an admin will have every capability here
// ///set but a simple user may only have `read` and `write` set while some users may not
// /// even have `read` set and are unable to even see if the machine is currently in use.
// /// </summary>
// public class Machine {
// private readonly Schema.Machine _machine;
// /// <summary>
// /// Constructs the Wrapper Class from a given capability
// /// </summary>
// /// <param name="machine">The capability that should be wrapped.</param>
// public Machine(Schema.Machine machine) {
// _machine = machine;
// }
// // read operations
// /// <summary>
// /// Get the MInfo Struct for the Machine.
// /// This contains everything BFFH knows about the Machine.
// /// </summary>
// /// <exception cref="UnauthorizedException"></exception>
// /// <returns>The MInfo Struct describing the Machine</returns>
// public async Task<Schema.Machine.MInfo> GetMInfo() {
// var readCap = _machine.Read;
// if (readCap == null) {
// throw new UnauthorizedException();
// }
// return (await _machine.Read.Info().ConfigureAwait(false)).Item1;
// }
// //write operations
// /// <summary>
// /// Try to use a machine. Throws a UnauthorizedException if the user does not have the required
// /// permissions to use this machine.
// ///
// /// Use the Ret() Method of the returned Object to return the machine
// /// </summary>
// /// <exception cref="UnauthorizedException"></exception>
// /// <returns>Capability to give back the machine</returns>
// public Task<Schema.Machine.WriteInterface.IGiveBack> Use() {
// var writeCap = _machine.Write;
// if (writeCap == null) {
// throw new UnauthorizedException();
// }
// return writeCap.Use();
// }
// /// <summary>
// /// Try to get a GiveBack capability for a machine.
// /// </summary>
// /// <returns>Capability to give back the machine or null</returns>
// /// <exception cref="UnauthorizedException"></exception>
// public Task<Schema.Machine.WriteInterface.IGiveBack> GetGiveBack()
// {
// var writeCap = _machine.Write;
// if (writeCap == null)
// {
// throw new UnauthorizedException();
// }
// return writeCap.GetGiveBack();
// }
// /// <summary>
// /// Try to reserve a machine. Throws a UnauthorizedException if the user does not have the required
// /// permissions to use this machine.
// ///
// /// Use the Ret() Method of the returned Object to return the machine
// /// Use the Use() Nethod of the Machine to use your reserved machine.
// /// </summary>
// /// <exception cref="UnauthorizedException"></exception>
// /// <returns>Capability to give back the machine</returns>
// public Task<Schema.Machine.WriteInterface.IGiveBack> Reserve()
// {
// var writeCap = _machine.Write;
// if (writeCap == null)
// {
// throw new UnauthorizedException();
// }
// return writeCap.Reserve();
// }
// // public void GiveBack(Schema.Machine.WriteInterface.IGiveBack cap) {
// // cap.Ret();
// // }
// //manage operations
// /// <summary>
// /// After a machine has been used by an user with low enough permissions it's
// /// in the 'toCheck' state. This call then allows more priviledged users to
// /// "check" the machine and move it to the `free` state.
// ///
// /// Calling this method signifies that the machine was checked and in an acceptable state.
// /// </summary>
// public async void MarkOk() {
// var manageCap = _machine.Manage;
// if (manageCap == null) {
// throw new UnauthorizedException();
// }
// // TODO: Do we really want to check this here?
// if ((await GetMInfo().ConfigureAwait(false)).State == State.toCheck) {
// await _machine.Manage.Ok().ConfigureAwait(false);
// }
// }
// /// <summary>
// /// After a machine has been used by an user with low enough permissions it's
// /// in the 'toCheck' state. This call then allows more priviledged users to
// /// "check" the machine and move it to the `free` state.
// ///
// /// Calling this method signifies that the machine was checked and in an unacceptable state.
// /// It will most likely be marked as `blocked` and the previous user will somehow be informed.
// /// </summary>
// public async void MarkNotOk() {
// var manageCap = _machine.Manage;
// if (manageCap == null) {
// throw new UnauthorizedException();
// }
// // TODO: Do we really want to check this here?
// if ((await GetMInfo().ConfigureAwait(false)).State == State.toCheck) {
// await _machine.Manage.NotOk().ConfigureAwait(false);
// }
// }
// //administrative operations
// /// <summary>
// /// Forcefully set a machine state.
// /// </summary>
// /// <param name="state">The desired machine state.</param>
// public async void ForceSetState(State state) {
// var adminCap = _machine.Admin;
// if (adminCap == null) {
// throw new UnauthorizedException();
// }
// await adminCap.ForceSetState(state).ConfigureAwait(false);
// }
// /// <summary>
// /// Set the given user as current responsible
// /// </summary>
// /// <param name="user">The user</param>
// public async void ForceSetUser(String user) {
// var adminCap = _machine.Admin;
// if (adminCap == null) {
// throw new UnauthorizedException();
// }
// await adminCap.ForceSetUser(user).ConfigureAwait(false);
// }
// }
//}

View File

@ -1,9 +0,0 @@
////This is where the permissions subsystem will live
//namespace FabAccessAPI
//{
// public class Permissions {
// #region Log
// private static readonly log4net.ILog _Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
// #endregion
// }
//}

View File

@ -6,7 +6,6 @@ using Capnp;
using Capnp.Rpc; using Capnp.Rpc;
using log4net.Config; using log4net.Config;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using static FabAccessAPI.Schema.Machine.WriteInterface;
namespace FabAccessAPI_Test { namespace FabAccessAPI_Test {
public class Tests { public class Tests {
@ -51,50 +50,5 @@ namespace FabAccessAPI_Test {
public async Task Authenticate() { public async Task Authenticate() {
await _connection.Auth("PLAIN", new Dictionary<string, object>{{"Username", "Testuser"}, {"Password", "secret"}}); await _connection.Auth("PLAIN", new Dictionary<string, object>{{"Username", "Testuser"}, {"Password", "secret"}});
} }
[Test]
public async Task GetMInfo() {
await _connection.Auth("PLAIN", new Dictionary<string, object>{{"Username", "Testuser"}, {"Password", "secret"}});
Machines machines = await _connection.AccessMachines();
Machine testmachine = await machines.GetMachine("Testmachine");
Assert.NotNull(testmachine);
FabAccessAPI.Schema.Machine.MInfo minfo = await testmachine.GetMInfo();
Assert.NotNull(minfo);
_Log.Info($"Name: {minfo.Name}, Description: {minfo.Description}, State: {minfo.State}");
}
[Test]
public async Task ListMachines()
{
await _connection.Auth("PLAIN", new Dictionary<string, object> { { "Username", "Testuser" }, { "Password", "secret" } });
Machines machines = await _connection.AccessMachines();
IReadOnlyList<Machine> machineList = await machines.ListMachines();
Assert.NotNull(machineList);
Assert.AreNotEqual(0, machineList.Count);
}
[Test]
public async Task UseMachine()
{
await _connection.Auth("PLAIN", new Dictionary<string, object> { { "Username", "Testuser" }, { "Password", "secret" } });
Machines machines = await _connection.AccessMachines();
Machine testmachine = await machines.GetMachine("Testmachine");
Assert.NotNull(testmachine);
await testmachine.Use();
FabAccessAPI.Schema.Machine.MInfo minfo = await testmachine.GetMInfo();
Assert.NotNull(minfo);
Assert.AreEqual(FabAccessAPI.Schema.State.inUse, minfo.State);
//await giveBack.Ret();
//minfo = await testmachine.GetMInfo();
//Assert.NotNull(minfo);
//Assert.AreEqual(FabAccessAPI.Schema.State.free, minfo.State);
}
} }
} }

View File

@ -7,7 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="5.0.3" /> <PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="5.0.4" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" /> <PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />