api lib v0.1

This commit is contained in:
Kai Jan Kriegel
2020-12-19 21:04:17 +01:00
parent 944af106a1
commit 7cd285bb85
13 changed files with 171 additions and 134 deletions

View File

@ -97,12 +97,16 @@ namespace FabAccessAPI {
}
class UnauthorizedException : Exception{}
public class UnauthorizedException : Exception{}
/// <summary>
/// THIS IS VERY INCOMPLETE!
/// </summary>
class Auth {
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;
@ -112,43 +116,7 @@ namespace FabAccessAPI {
return _authCap.Mechanisms();
}
public bool Handshake(Stream stream) {
var host = "localhost";
var asm = typeof(Api).Assembly;
var program = $"{asm.FullName}-{asm.GetName().Version}";
var version = (0u, 1u);
var message = new Greeting() {
Host = host,
Major = version.Item1,
Minor = version.Item2,
Program = program
};
var msg = MessageBuilder.Create();
var root = msg.BuildRoot<Schema.Greeting.WRITER>();
message.serialize(root);
var pump = new FramePump(stream);
pump.Send(msg.Frame);
var frame = Framing.ReadSegments(stream);
var deserializer = DeserializerState.CreateRoot(frame);
var reader = new Greeting.READER(deserializer);
var serverInfo = reader;
Console.WriteLine($"Server: {serverInfo.Host}");
Console.WriteLine($"Version: {serverInfo.Program}");
Console.WriteLine($"API-Version: {serverInfo.Major}.{serverInfo.Minor}");
//TODO: Check if we are actually compatible. This will probably need some internal lookup or well defined versioning semantics
return true;
}
public async Task<bool> Authenticate(string mech, Dictionary<string, object> properties) {
//TODO: Perform Handshake to verify that we are compatible with server
var m = SaslFactory.Create(mech);
foreach (KeyValuePair<string, object> entry in properties) {

View File

@ -5,13 +5,19 @@ using System.Collections.Generic;
using System.Threading.Tasks;
namespace FabAccessAPI {
class Connection {
public class Connection {
#region private variables
private TcpRpcClient? _rpcClient = null;
private IBootstrap? _bootstrapCap = null;
private AuthUser? _authUser = null;
private Auth? _auth = null;
private Machines? _machines = null;
#endregion
#region Log
private static readonly log4net.ILog _Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
#endregion
/// <summary>
///
/// </summary>
@ -19,6 +25,7 @@ namespace FabAccessAPI {
public Connection(TcpRpcClient rpcClient) {
_rpcClient = rpcClient;
_bootstrapCap = _rpcClient.GetMain<IBootstrap>();
_Log.Debug($"Done bootstraping API connection.");
}
/// <summary>
@ -28,11 +35,12 @@ namespace FabAccessAPI {
/// <param name="mech">The desired authentication mechanism</param>
/// <param name="kvs">Key-Value data specific to the mechanism</param>
/// <returns></returns>
async Task Auth(string mech, Dictionary<string, object> kvs) {
_auth = new Auth(await _bootstrapCap.Auth());
public async Task Auth(string mech, Dictionary<string, object> kvs) {
// _bootstrapCap = await _bootstrapCap.Unwrap();
var authCap = await _bootstrapCap.Auth();
_auth = new Auth(authCap);
var mechs = await _auth.GetMechanisms().ConfigureAwait(false);
Console.WriteLine("The Server supports the following auth mechs:");
Console.Write(mechs);
_Log.Debug($"The Server supports the following auth mechs: {mechs}");
// TODO: Check that the requested auth mech is actually available.
@ -43,7 +51,7 @@ namespace FabAccessAPI {
/// Get a wrapped capability to interact with machines
/// </summary>
/// <returns>A wrapped capability to interact with machines</returns>
async Task<Machines> AccessMachines() {
public async Task<Machines> AccessMachines() {
_machines ??= new Machines((await _bootstrapCap.Machines().ConfigureAwait(false)));
return _machines;
}

View File

@ -1,11 +0,0 @@
using System;
using S22.Sasl;
namespace FabAccessAPI
{
public class Api
{
}
}

View File

@ -2,13 +2,15 @@
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<LangVersion>9</LangVersion>
<LangVersion>8</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Capnp.Net.Runtime" Version="1.3.118" />
<PackageReference Include="CapnpC.CSharp.MsBuild.Generation" Version="1.3.118" />
<PackageReference Include="log4net" Version="2.0.12" />
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="5.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using Capnp.Rpc;
namespace FabAccessAPI {
class InjectableTcpRpcClient : TcpRpcClient {
public InjectableTcpRpcClient() {
throw new NotImplementedException();
}
}
}

View File

@ -8,7 +8,12 @@ namespace FabAccessAPI {
/// <summary>
/// Wraps a capability for accessing the Machines subsystem of BFFH
/// </summary>
class Machines {
public class Machines {
#region Log
private static readonly log4net.ILog _Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
#endregion
private IMachines _machinesCap;
/// <summary>
@ -23,19 +28,19 @@ namespace FabAccessAPI {
/// 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() {
public async Task<IReadOnlyList<Machine>?> ListMachines() {
return (await _machinesCap.ListMachines().ConfigureAwait(false)).Select(x => new Machine(x)) as IReadOnlyList<Machine>;
}
/// <summary>
/// Access a particular machine by known UUID. This may fail for two reasons:
/// 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="uuid">UUID of the Machine</param>
/// <param name="name">Name of the Machine</param>
/// <returns>The Machine we requested</returns>
public async Task<Machine> GetMachine(UUID uuid) {
var mach = (await _machinesCap.GetMachine(uuid).ConfigureAwait(false)).Item1;
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 Exception();
@ -54,7 +59,7 @@ namespace FabAccessAPI {
///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>
class Machine {
public class Machine {
private Schema.Machine _machine;
/// <summary>
@ -101,6 +106,26 @@ namespace FabAccessAPI {
return writeCap.Use();
}
/// <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();

View File

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