From 8035f8b1bd09e29dba8625d220cca156ac7f920e Mon Sep 17 00:00:00 2001 From: Kai Jan Kriegel Date: Thu, 12 Nov 2020 10:08:14 +0100 Subject: [PATCH] implemented Machines interface --- FabAccessAPI/Machines.cs | 176 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 FabAccessAPI/Machines.cs diff --git a/FabAccessAPI/Machines.cs b/FabAccessAPI/Machines.cs new file mode 100644 index 0000000..d5d2247 --- /dev/null +++ b/FabAccessAPI/Machines.cs @@ -0,0 +1,176 @@ +using FabAccessAPI.Schema; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace FabAccessAPI { + /// + /// Wraps a capability for accessing the Machines subsystem of BFFH + /// + class Machines { + private IMachines _machinesCap; + + /// + /// Constructs the Wrapper Class from a given capability. + /// + /// The capability that should be wrapped. + public Machines(IMachines machinesCap) { + _machinesCap = machinesCap; + } + + /// + /// List of all machines that BFFH knows about the user has been granted at least read access on + /// + /// ReadOnlyList of available Machines + public async Task> ListMachines() { + return (await _machinesCap.ListMachines().ConfigureAwait(false)).Select(x => new Machine(x)) as IReadOnlyList; + } + + /// + /// Access a particular machine by known UUID. 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 + /// + /// UUID of the Machine + /// The Machine we requested + public async Task GetMachine(UUID uuid) { + var mach = (await _machinesCap.GetMachine(uuid).ConfigureAwait(false)).Item1; + if (mach == null) { + //TODO: Throw a more specific exception! + throw new Exception(); + } + return new Machine(mach); + } + } + + /// + /// 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. + /// + class Machine { + private Schema.Machine _machine; + + /// + /// Constructs the Wrapper Class from a given capability + /// + /// The capability that should be wrapped. + public Machine(Schema.Machine machine) { + _machine = machine; + } + + // read operations + + /// + /// Get the MInfo Struct for the Machine. + /// This contains everything BFFH knows about the Machine. + /// + /// + /// The MInfo Struct describing the Machine + public async Task GetMInfo() { + var readCap = _machine.Read; + if (readCap == null) { + throw new UnauthorizedException(); + } + + return (await _machine.Read.Info().ConfigureAwait(false)).Item1; + } + + //write operations + + /// + /// 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 + /// + /// + /// Capability to give back the machine + public Task Use() { + var writeCap = _machine.Write; + if (writeCap == null) { + throw new UnauthorizedException(); + } + + return writeCap.Use(); + } + + + // public void GiveBack(Schema.Machine.WriteInterface.IGiveBack cap) { + // cap.Ret(); + // } + + //manage operations + + /// + /// 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. + /// + 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); + } + } + + /// + /// 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. + /// + 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 + + /// + /// Forcefully set a machine state. + /// + /// The desired machine state. + public async void ForceSetState(State state) { + var adminCap = _machine.Admin; + if (adminCap == null) { + throw new UnauthorizedException(); + } + + await adminCap.ForceSetState(state).ConfigureAwait(false); + } + + /// + /// Set the given user as current responsible + /// + /// The user + public async void ForceSetUser(String user) { + var adminCap = _machine.Admin; + if (adminCap == null) { + throw new UnauthorizedException(); + } + + await adminCap.ForceSetUser(user).ConfigureAwait(false); + } + } +}