mirror of
https://gitlab.com/fabinfra/fabaccess/fabaccess-api.git
synced 2025-03-12 14:51:42 +01:00
Claims draft
This commit is contained in:
parent
2c01a62085
commit
32309d09f3
@ -8,7 +8,7 @@ using CSharp = import "programming_language/csharp.capnp";
|
||||
$CSharp.namespace("FabAccessAPI.Schema");
|
||||
|
||||
using L10NString = import "utils.capnp".L10NString;
|
||||
using Session = import "connection.capnp".Session;
|
||||
using Session = import "main.capnp".Session;
|
||||
|
||||
struct Response {
|
||||
enum Error {
|
||||
@ -100,7 +100,7 @@ struct Response {
|
||||
}
|
||||
|
||||
interface Authentication {
|
||||
step @0 ( data: Data ) -> ( response: Response );
|
||||
step @0 (data :Data) -> Response;
|
||||
# Respond to a challenge with more data. A client MUST NOT call this after having received an
|
||||
# "successful" response.
|
||||
|
@ -1,98 +0,0 @@
|
||||
@0x8c2f829df1930cd5;
|
||||
|
||||
using Rust = import "programming_language/rust.capnp";
|
||||
$Rust.parentModule("schema");
|
||||
|
||||
using CSharp = import "programming_language/csharp.capnp";
|
||||
$CSharp.namespace("FabAccessAPI.Schema");
|
||||
|
||||
using General = import "general.capnp";
|
||||
using User = import "user.capnp".User;
|
||||
using Space = import "space.capnp".Space;
|
||||
|
||||
struct Machine {
|
||||
enum MachineState {
|
||||
free @0;
|
||||
inUse @1;
|
||||
toCheck @2;
|
||||
blocked @3;
|
||||
disabled @4;
|
||||
reserved @5;
|
||||
}
|
||||
struct MachineInfoExtended {
|
||||
currentUser @0 :User;
|
||||
transferUser @1 :User;
|
||||
}
|
||||
|
||||
struct Reservation {
|
||||
user @0 :User;
|
||||
start @1: UInt64;
|
||||
end @2: UInt64;
|
||||
}
|
||||
|
||||
id @0 :General.UUID;
|
||||
space @1 :Space;
|
||||
name @2 :Text;
|
||||
description @3 :Text;
|
||||
state @4 :MachineState;
|
||||
manager @5:User;
|
||||
|
||||
info @6 :Info;
|
||||
interface Info $CSharp.name("InfoInterface") {
|
||||
getMachineInfoExtended @0 () -> ( machineInfoExtended :MachineInfoExtended, dummy :UInt8 = 0);
|
||||
|
||||
getPropertyList @1 () -> ( propertyList :List(General.KeyValuePair) );
|
||||
|
||||
getReservationList @2 () -> ( reservationList :List(Reservation) );
|
||||
}
|
||||
|
||||
use @7 :Use;
|
||||
interface Use $CSharp.name("UseInterface") {
|
||||
use @0 ();
|
||||
|
||||
reserve @1 ();
|
||||
reserveto @2 (start :UInt64, end :UInt64);
|
||||
}
|
||||
|
||||
inuse @8 :InUse;
|
||||
interface InUse $CSharp.name("InUseInterface") {
|
||||
giveBack @0 ();
|
||||
sendRawData @1 (data :Data);
|
||||
}
|
||||
|
||||
transfer @9 :Transfer;
|
||||
interface Transfer $CSharp.name("TransferInterface") {
|
||||
accept @0 ();
|
||||
reject @1 ();
|
||||
}
|
||||
|
||||
check @10 :Check;
|
||||
interface Check $CSharp.name("CheckInterface") {
|
||||
check @0 ();
|
||||
reject @1 ();
|
||||
}
|
||||
|
||||
manage @11 :Manage;
|
||||
interface Manage $CSharp.name("ManageInterface") {
|
||||
setProperty @0 (property :General.KeyValuePair);
|
||||
removeProperty @1 (property :General.KeyValuePair);
|
||||
|
||||
forceUse @2 ();
|
||||
forceFree @3 ();
|
||||
|
||||
forceTransfer @4 (user :User);
|
||||
|
||||
block @5 ();
|
||||
disabled @6 ();
|
||||
}
|
||||
|
||||
admin @12 :Admin;
|
||||
interface Admin $CSharp.name("AdminInterface") {
|
||||
forceSetState @0 ( state :MachineState );
|
||||
forceSetUser @1 ( user :User );
|
||||
|
||||
getAdminPropertyList @2 () -> (propertyList :List(General.KeyValuePair));
|
||||
setAdminProperty @3 (property :General.KeyValuePair);
|
||||
removeAdminProperty @4 (property :General.KeyValuePair);
|
||||
}
|
||||
}
|
@ -6,17 +6,16 @@ $Rust.parentModule("schema");
|
||||
using CSharp = import "programming_language/csharp.capnp";
|
||||
$CSharp.namespace("FabAccessAPI.Schema");
|
||||
|
||||
using Authentication = import "authenticationsystem.capnp".Authentication;
|
||||
using MachineSystem = import "machinesystem.capnp".MachineSystem;
|
||||
using UserSystem = import "usersystem.capnp".UserSystem;
|
||||
using PermissionSystem = import "permissionsystem.capnp".PermissionSystem;
|
||||
using Authentication = import "auth.capnp".Authentication;
|
||||
using Ressources = import "ressources.capnp".Ressources;
|
||||
using Users = import "users.capnp".Users;
|
||||
|
||||
interface Bootstrap
|
||||
{
|
||||
mechanisms @0 () -> ( mechs: List(Text) );
|
||||
# Get a list of Mechanisms this server allows in this context.
|
||||
|
||||
createSession @1 ( mechanism :Text, initialData :Data ) -> ( authentication :Authentication);
|
||||
createSession @1 ( mechanism :Text, initialData :Data ) -> ( authentication :Authentication );
|
||||
# Create a new session with the server that you wish to authenticate using `mechanism`.
|
||||
# If the mechanism is a client-first mechanism you MAY set `initialData` to contain the data you
|
||||
# want to send. If the mechanism is server-first or you do not wish to send initial data, make
|
||||
@ -24,7 +23,13 @@ interface Bootstrap
|
||||
}
|
||||
|
||||
struct Session {
|
||||
machineSystem @0 : MachineSystem;
|
||||
userSystem @1 : UserSystem;
|
||||
permissionSystem @2 : PermissionSystem;
|
||||
# An API session with the server. The below capabilities are set to NULL if the authenticated
|
||||
# user doesn't have permission to access the system in question.
|
||||
|
||||
ressources @0 : Ressources;
|
||||
# Access to the ressources configured.
|
||||
|
||||
users @1 : Users;
|
||||
# User administration. This includes both modifying other users and self-modification, so this
|
||||
# is allowed for most sessions
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
@0xd0568a21cf11488e;
|
||||
|
||||
using Rust = import "programming_language/rust.capnp";
|
||||
$Rust.parentModule("schema");
|
||||
|
||||
using CSharp = import "programming_language/csharp.capnp";
|
||||
$CSharp.namespace("FabAccessAPI.Schema");
|
||||
|
||||
using Role = import "role.capnp".Role;
|
||||
|
||||
interface PermissionSystem
|
||||
{
|
||||
info @0 () -> ( info : Info );
|
||||
interface Info $CSharp.name("InfoInterface") {
|
||||
getRoleList @0 () -> ( role_list :List(Role) );
|
||||
}
|
||||
|
||||
manage @1 () -> ( manage : Manage );
|
||||
interface Manage $CSharp.name("ManageInterface") {
|
||||
|
||||
}
|
||||
}
|
173
resource.capnp
Normal file
173
resource.capnp
Normal file
@ -0,0 +1,173 @@
|
||||
@0x8c2f829df1930cd5;
|
||||
|
||||
using Rust = import "programming_language/rust.capnp";
|
||||
$Rust.parentModule("schema");
|
||||
|
||||
using CSharp = import "programming_language/csharp.capnp";
|
||||
$CSharp.namespace("FabAccessAPI.Schema");
|
||||
|
||||
using Persistent = import "/capnp/persistent.capnp".Persistent;
|
||||
using Value = import "/capnp/schema.capnp".Value;
|
||||
|
||||
using General = import "general.capnp";
|
||||
using User = import "user.capnp".User;
|
||||
using Space = import "space.capnp".Space;
|
||||
|
||||
struct Node {
|
||||
# A node in the state tree. If it's the root note this struct "contains" the whole tree.
|
||||
|
||||
# TODO: I'm not happy with this representation. While it's about as generic as we can get it's
|
||||
# unhandly because all clients and servers have to always manually check every leaf of the
|
||||
# state tree, relying on convention instead of static type checking. But I'm not sure how else
|
||||
# to represent the state extensibly in a way that lets us evolve the protocol by stabilizing
|
||||
# extensions. One option could be to use OID or UUID as "tag bits" and "stabilize" them by
|
||||
# defining those as `const` values, but that wouldn't give us proper type checking either.
|
||||
|
||||
part @0 :Text;
|
||||
# Name of the node, making up a path to this node (e.g. "set/colour/red")
|
||||
|
||||
union {
|
||||
# Content of a node. A node has either children *or* a value, not both.
|
||||
|
||||
children @1 :List(Node);
|
||||
# Node is not a leaf node ⇒ it has a list of children
|
||||
|
||||
value @2 :Value;
|
||||
# Node is a leaf node ⇒ it contains a (typed) Cap'n Proto value.
|
||||
# The type `Value` comes from the Cap'n Proto schema definition file (usually
|
||||
# /usr/include/capnp/schema.capnp) and can be any basic capnp type, including lists and
|
||||
# structs (as :AnyPointer which a client has to cast)
|
||||
}
|
||||
}
|
||||
|
||||
struct Applied {
|
||||
# Encodes if a specific actor has applied/verified a state change
|
||||
|
||||
name @0 :Text;
|
||||
# Name of the actor
|
||||
|
||||
state @1 :State;
|
||||
# State of the state change in the actor
|
||||
enum State {
|
||||
unapplied @0;
|
||||
applied @1;
|
||||
verified @2;
|
||||
}
|
||||
}
|
||||
|
||||
interface Access {
|
||||
# Allow syncronous read access to a resource's state. You're not given this capability directly
|
||||
# but instead Notify, Interest and Claim all extend it, allowing you to call these methods from
|
||||
# any of those.
|
||||
|
||||
readState @0 Node;
|
||||
readApplied @1 Applied;
|
||||
|
||||
# TODO: There should probably be a more efficient approach for reading state than "read *all*
|
||||
# state".
|
||||
}
|
||||
|
||||
interface Notify extends(Access) {
|
||||
# The Notify interface allows clients to be informed about state changes asyncronously.
|
||||
# It is mainly designed around the `register` function which allows a client to register a
|
||||
# Callback on the client that is called every time state changes happen to the resource in
|
||||
# question.
|
||||
# Notify are ephermal. If the connection to the server is lost all `Notify` are unregistered
|
||||
|
||||
register @0 ( cb: Callback );
|
||||
# Register a given callback to be called on every state update. If this client already has a
|
||||
# callback registered for this resource the old callback is replaced.
|
||||
# The two fields `state` and `applied` indicate interest for `state` and `applied`. If they are
|
||||
# unset the respective method on the callback will not be called.
|
||||
|
||||
unregister @1 ();
|
||||
# Unregister the current callback, if any.
|
||||
|
||||
interface Callback {
|
||||
# This callback interface is implemented on the client
|
||||
|
||||
newState @0 Node;
|
||||
# A server will call newState() with the updated set state tree if `state` was set to `true`
|
||||
# in `register`, however unless the last call to newState() didn't complete yet, as to not
|
||||
# overload a client.
|
||||
|
||||
# TODO: There should probably be a more efficient approach here too, something along the
|
||||
# lines of server-side filtering.
|
||||
|
||||
# TODO: Add newApplied?
|
||||
}
|
||||
}
|
||||
|
||||
interface Interestable {
|
||||
interest @0 () -> ( interest: Interest );
|
||||
}
|
||||
|
||||
interface Interest extends(Access) {
|
||||
register @0 ( cb: Callback );
|
||||
unregister @1 ();
|
||||
|
||||
blocking @2 ();
|
||||
# As an alternative to the `register`/`Callback` system you can also call `blocking` which will
|
||||
# — as the name suggests — block until the last claim was dropped.
|
||||
|
||||
interface Callback {
|
||||
drop @0 ();
|
||||
# The last claim on the resource this Interest is registered on was dropped, invalidating
|
||||
# the Interest.
|
||||
}
|
||||
}
|
||||
|
||||
interface Claimable {
|
||||
# Having this capability set (i.e. not be a `nullptr`) means the user has at least writeable
|
||||
# access to a resource and the resource is claimable (n > 0).
|
||||
|
||||
claim @0 () -> ClaimResponse;
|
||||
# Assert a claim on a resource.
|
||||
}
|
||||
|
||||
interface Lockable {
|
||||
# Having this capability set means the user has managerial access to a resource.
|
||||
|
||||
lock @0 () -> ( lock: Claim );
|
||||
}
|
||||
|
||||
struct ClaimResponse {
|
||||
enum Error {
|
||||
# Error describing why a claim failed.
|
||||
|
||||
exhausted @0;
|
||||
# There are no more free Claim slots
|
||||
|
||||
locked @1;
|
||||
# The resource was locked
|
||||
}
|
||||
|
||||
union {
|
||||
error @0 :Error;
|
||||
success @1 :Claim;
|
||||
}
|
||||
}
|
||||
|
||||
interface Claim extends(Access) {
|
||||
# TODO: extend Persistance. Claims and Interests need to be able to survive a connection loss,
|
||||
# which is exactly what `SturdyRef`/Persistance are designed to provide. The Persistance
|
||||
# interface only provides one method, `save`, returning a `SturdyRef`. A SturdyRef is a generic
|
||||
# and generally speaking opaque type that can be restored to a live capability using some sort
|
||||
# of `Restorer` service.
|
||||
# In this case the `Restorer` service could be `Claimable` / `Interestable` providing a
|
||||
# `restore( ref: SturdyRef )` method.
|
||||
|
||||
update @0 Node;
|
||||
# Update the State of the claimed resource with the given one
|
||||
}
|
||||
|
||||
struct Resource {
|
||||
name @0 :Text;
|
||||
description @1 :Text;
|
||||
typeid @2 :Text;
|
||||
|
||||
notify @3 :Notify;
|
||||
interest @4 :Interest;
|
||||
claimable @5 :Claimable;
|
||||
lockable @6 :Lockable;
|
||||
}
|
@ -9,12 +9,8 @@ $CSharp.namespace("FabAccessAPI.Schema");
|
||||
using General = import "general.capnp";
|
||||
using Machine = import "machine.capnp".Machine;
|
||||
|
||||
interface MachineSystem
|
||||
interface Ressources
|
||||
{
|
||||
info @0 () -> ( info : Info );
|
||||
interface Info $CSharp.name("InfoInterface") {
|
||||
getMachineList @0 () -> ( machine_list :List(Machine) );
|
||||
|
||||
getMachine @1 ( name :Text ) -> ( machine :Machine, dummy :UInt8 = 0 );
|
||||
}
|
||||
listAll @0 () -> ( machine_list :List(Machine) );
|
||||
get @1 ( name :Text ) -> Machine;
|
||||
}
|
24
users.capnp
Normal file
24
users.capnp
Normal file
@ -0,0 +1,24 @@
|
||||
@0x9a05e95f65f2edda;
|
||||
|
||||
using Rust = import "programming_language/rust.capnp";
|
||||
$Rust.parentModule("schema");
|
||||
|
||||
using CSharp = import "programming_language/csharp.capnp";
|
||||
$CSharp.namespace("FabAccessAPI.Schema");
|
||||
|
||||
using General = import "general.capnp";
|
||||
using User = import "user.capnp".User;
|
||||
|
||||
interface Users
|
||||
{
|
||||
whoami @0 () -> User;
|
||||
|
||||
manage @1 () -> ( manage :Manage );
|
||||
interface Manage $CSharp.name("ManageInterface") {
|
||||
list @0 () -> ( users :List(User) );
|
||||
|
||||
addUser @1 ( username: Text, password: Text ) -> User;
|
||||
|
||||
removeUser @2 User;
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
@0x9a05e95f65f2edda;
|
||||
|
||||
using Rust = import "programming_language/rust.capnp";
|
||||
$Rust.parentModule("schema");
|
||||
|
||||
using CSharp = import "programming_language/csharp.capnp";
|
||||
$CSharp.namespace("FabAccessAPI.Schema");
|
||||
|
||||
using General = import "general.capnp";
|
||||
using User = import "user.capnp".User;
|
||||
|
||||
interface UserSystem
|
||||
{
|
||||
info @0 () -> ( info : Info );
|
||||
interface Info $CSharp.name("InfoInterface") {
|
||||
getUserSelf @0 ( ) -> ( user :User, dummy :UInt8 = 0 );
|
||||
}
|
||||
|
||||
manage @1 () -> ( manage : Manage );
|
||||
interface Manage $CSharp.name("ManageInterface") {
|
||||
getUserList @0 () -> ( user_list :List(User) );
|
||||
|
||||
addUser @1 (username :Text, password: Text) -> ( user :User );
|
||||
removeUser @2 (user :User, dummy :UInt8 = 0);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user