mirror of
https://gitlab.com/fabinfra/fabaccess/borepin.git
synced 2025-03-12 23:01:52 +01:00
225 lines
8.5 KiB
C#
225 lines
8.5 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|