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

@ -21,10 +21,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NFC", "NFC\NFC.csproj", "{9
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FabAccessAPI", "FabAccessAPI\FabAccessAPI.csproj", "{3251FCE9-FEA3-4662-8BEB-636BE6732D48}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FabAccessAPI_Test", "FabAccessAPI_Test\FabAccessAPI_Test.csproj", "{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "S22.Sasl", "external\SASL\S22.Sasl.csproj", "{7FEC3D5E-C240-41B6-BBFA-895C4F4D45CA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FabAccessAPI_Test", "FabAccessAPI_Test\FabAccessAPI_Test.csproj", "{1C85978A-9FC0-4064-8399-FA2455C5EC2A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -305,30 +305,6 @@ Global
{3251FCE9-FEA3-4662-8BEB-636BE6732D48}.Release|x64.Build.0 = Release|Any CPU
{3251FCE9-FEA3-4662-8BEB-636BE6732D48}.Release|x86.ActiveCfg = Release|Any CPU
{3251FCE9-FEA3-4662-8BEB-636BE6732D48}.Release|x86.Build.0 = Release|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Debug|ARM.ActiveCfg = Debug|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Debug|ARM.Build.0 = Debug|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Debug|iPhone.Build.0 = Debug|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Debug|x64.ActiveCfg = Debug|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Debug|x64.Build.0 = Debug|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Debug|x86.ActiveCfg = Debug|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Debug|x86.Build.0 = Debug|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Release|Any CPU.Build.0 = Release|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Release|ARM.ActiveCfg = Release|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Release|ARM.Build.0 = Release|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Release|iPhone.ActiveCfg = Release|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Release|iPhone.Build.0 = Release|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Release|x64.ActiveCfg = Release|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Release|x64.Build.0 = Release|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Release|x86.ActiveCfg = Release|Any CPU
{6DD3DE28-BB0B-45BA-9072-CF6325E294CB}.Release|x86.Build.0 = Release|Any CPU
{7FEC3D5E-C240-41B6-BBFA-895C4F4D45CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7FEC3D5E-C240-41B6-BBFA-895C4F4D45CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7FEC3D5E-C240-41B6-BBFA-895C4F4D45CA}.Debug|ARM.ActiveCfg = Debug|Any CPU
@ -353,6 +329,30 @@ Global
{7FEC3D5E-C240-41B6-BBFA-895C4F4D45CA}.Release|x64.Build.0 = Release|Any CPU
{7FEC3D5E-C240-41B6-BBFA-895C4F4D45CA}.Release|x86.ActiveCfg = Release|Any CPU
{7FEC3D5E-C240-41B6-BBFA-895C4F4D45CA}.Release|x86.Build.0 = Release|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Debug|ARM.ActiveCfg = Debug|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Debug|ARM.Build.0 = Debug|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Debug|iPhone.Build.0 = Debug|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Debug|x64.ActiveCfg = Debug|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Debug|x64.Build.0 = Debug|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Debug|x86.ActiveCfg = Debug|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Debug|x86.Build.0 = Debug|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Release|Any CPU.Build.0 = Release|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Release|ARM.ActiveCfg = Release|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Release|ARM.Build.0 = Release|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Release|iPhone.ActiveCfg = Release|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Release|iPhone.Build.0 = Release|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Release|x64.ActiveCfg = Release|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Release|x64.Build.0 = Release|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Release|x86.ActiveCfg = Release|Any CPU
{1C85978A-9FC0-4064-8399-FA2455C5EC2A}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

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
}
}

@ -1 +1 @@
Subproject commit 1753ef037e90da110bd169a1cd2ae2e00af561a1
Subproject commit 4adb05341763b96a43440a6a96e0d9959ba71e89

View File

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using NUnit.Framework;
using FabAccessAPI;
using Capnp;
using Capnp.Rpc;
using log4net.Config;
using Microsoft.Extensions.Logging;
namespace FabAccessAPI_Test {
public class Tests {
private static ILoggerFactory _loggerFactory;
[OneTimeSetUp]
public void Setup() {
XmlConfigurator.Configure(new System.IO.FileInfo("log4net.config"));
_loggerFactory = LoggerFactory.Create(builder => {
builder
.AddFilter("Microsoft", LogLevel.Warning)
.AddFilter("System", LogLevel.Warning);
});
_loggerFactory.AddLog4Net();
Logging.LoggerFactory = _loggerFactory;
}
[Test]
public void Connect() {
var rpcClient = new TcpRpcClient();
rpcClient.Connect("::1", 59661);
var con = new Connection(rpcClient);
Assert.AreEqual(ConnectionState.Active, rpcClient.State);
}
[Test]
public async Task Machines() {
var rpcClient = new TcpRpcClient();
rpcClient.Connect("::1", 59661);
var con = new Connection(rpcClient);
var machines = await con.AccessMachines();
var testmachine = await machines.GetMachine("Testmachine");
Assert.NotNull(testmachine);
var minfo = await testmachine.GetMInfo();
Assert.NotNull(minfo);
Console.WriteLine($"Name: {minfo.Name}, Description: {minfo.Description}, State: {minfo.State.ToString()}");
}
}
}

View File

@ -1,19 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="5.0.0" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FabAccessAPI\FabAccessAPI.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FabAccessAPI\FabAccessAPI.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="log4net.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -1,18 +0,0 @@
using NUnit.Framework;
namespace FabAccessAPI_Test
{
public class Tests
{
[SetUp]
public void Setup()
{
}
[Test]
public void Test1()
{
Assert.Pass();
}
}
}

View File

@ -0,0 +1,16 @@
<log4net>
<!-- A1 is set to be a ConsoleAppender -->
<appender name="A1" type="log4net.Appender.ConsoleAppender">
<!-- A1 uses PatternLayout -->
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-4timestamp [%thread] %-5level %logger %ndc - %message%newline" />
</layout>
</appender>
<!-- Set root logger level to DEBUG and its only appender to A1 -->
<root>
<level value="ALL" />
<appender-ref ref="A1" />
</root>
</log4net>