mirror of
https://gitlab.com/fabinfra/fabaccess/fabaccess-api.git
synced 2025-04-20 10:26:29 +02:00
Compare commits
54 Commits
Author | SHA1 | Date | |
---|---|---|---|
f3f53dafb6 | |||
c5a59880ad | |||
120db0a68a | |||
ce49e3d07c | |||
|
ec8352c6ae | ||
|
cde4677575 | ||
|
19f20f5154 | ||
|
f1fa024613 | ||
|
54508a7944 | ||
|
5e7b7d9949 | ||
|
544402ea39 | ||
|
6043448645 | ||
|
d2e46cc6d2 | ||
|
1e2f1b40a9 | ||
|
8f1e528ba8 | ||
|
244eb9bd1b | ||
|
d04d930bd3 | ||
|
c00a274a16 | ||
|
93f130873e | ||
|
750ae0c34b | ||
|
f02afb3736 | ||
|
aea03aabe3 | ||
|
aa006507c4 | ||
|
049b183f96 | ||
|
2406e77fb9 | ||
|
f8b317bb15 | ||
|
d006351b6f | ||
|
2977a0f5d9 | ||
|
ea388f998c | ||
|
c9283ebd69 | ||
|
c20703dd5b | ||
|
9c745b79bb | ||
|
557f37b7cf | ||
|
564a69ef35 | ||
|
63e74aacc0 | ||
|
277133dd35 | ||
|
6b0aba90a9 | ||
|
97ca7deba1 | ||
|
76b886140d | ||
|
bda6c0be37 | ||
|
18ed9c2ae6 | ||
|
3ccfcc2b35 | ||
|
ae1c762f3e | ||
|
4925081753 | ||
|
64863ec96c | ||
|
a9ea612073 | ||
|
bb88fb1832 | ||
|
8033653d2c | ||
|
5de7dc2ef3 | ||
|
f1a7e3882d | ||
|
89edea3ead | ||
|
b12a5601c3 | ||
|
f1bd45141e | ||
|
d34c06c48e |
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,2 +1,7 @@
|
|||||||
tags
|
tags
|
||||||
*.cs
|
*.cs
|
||||||
|
|
||||||
|
# MADR
|
||||||
|
/node_modules/
|
||||||
|
/package-lock.json
|
||||||
|
/package.json
|
||||||
|
@ -7,3 +7,10 @@ When returning an Interface it may be required to append a dummy valueto work ar
|
|||||||
- whoami @4 () -> ( you :Api.User );
|
- whoami @4 () -> ( you :Api.User );
|
||||||
+ whoami @4 () -> ( you :Api.User, dummy :UInt8 = 0 );
|
+ whoami @4 () -> ( you :Api.User, dummy :UInt8 = 0 );
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Docs
|
||||||
|
A lot of information (concepts, usage, decisions) about this API can be found at [docs.fab-access.org](https://docs.fab-access.org/books/schnittstellen-und-apis/page/fabaccess-api#bkmrk-fabaccess-api).
|
||||||
|
|
||||||
|
See also:
|
||||||
|
- [pyfabapi (Python Wrapper)](https://gitlab.com/fabinfra/fabaccess/pyfabapi)
|
||||||
|
- [FabAccess-API-cs (C# implementation)](https://gitlab.com/fabinfra/fabaccess/fabaccess-api-cs)
|
@ -1,135 +1,76 @@
|
|||||||
@0xb9cffd29ac983e9f;
|
@0xb9cffd29ac983e9f;
|
||||||
|
|
||||||
|
|
||||||
using Rust = import "programming_language/rust.capnp";
|
using Rust = import "programming_language/rust.capnp";
|
||||||
$Rust.parentModule("schema");
|
$Rust.parentModule("schema");
|
||||||
|
|
||||||
using CSharp = import "programming_language/csharp.capnp";
|
using CSharp = import "programming_language/csharp.capnp";
|
||||||
$CSharp.namespace("FabAccessAPI.Schema");
|
$CSharp.namespace("FabAccessAPI.Schema");
|
||||||
|
|
||||||
using User = import "user.capnp".User;
|
using Session = import "connection.capnp".Session;
|
||||||
|
|
||||||
interface AuthenticationSystem {
|
|
||||||
mechanisms @0 () -> ( mechs :List(Text) );
|
|
||||||
# Get the list of mechanisms supported by the server
|
|
||||||
|
|
||||||
start @1 ( request :Request ) -> ( response :Response );
|
|
||||||
# Initiate an authentication exchange
|
|
||||||
# NOTE: Calling start() after an authentication exchange has already
|
|
||||||
# finished is undefined behaviour. If you want to double-authenticate call
|
|
||||||
# auth() from connection.capnp again to get a fresh capability you can use.
|
|
||||||
# This may however return NULL if you are not allowed to authenticate twice.
|
|
||||||
|
|
||||||
step @2 ( response :Data ) -> ( response :Response );
|
|
||||||
# Respond to a challenge with more data
|
|
||||||
# NOTE: As with start() calling this after having received an outcome is
|
|
||||||
# undefined behaviour.
|
|
||||||
|
|
||||||
abort @3 () -> ();
|
|
||||||
# Abort the current exchange. This may be sent by both client and server
|
|
||||||
# at any point during the exchange. It MUST not be sent by a server
|
|
||||||
# after sending an outcome or by a client after receiving an outcome.
|
|
||||||
# A server receiving an abort after sending an outcome but before
|
|
||||||
# receiving any other message MUST respect the abort.
|
|
||||||
|
|
||||||
whoami @4 () -> ( you :User, dummy :UInt8 = 0 );
|
|
||||||
# Returns NULL if not authenticated and an User object if authenticated.
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Request {
|
|
||||||
mechanism @0 :Text; # The SASL mechanism name.
|
|
||||||
|
|
||||||
initialResponse :union {
|
|
||||||
# A client may send some intial data when requesting an auth exchange.
|
|
||||||
# According to RFC4422 section 4.3a an implementation MUST be able to
|
|
||||||
# distinguish between an empty initial reponse and no initial response.
|
|
||||||
|
|
||||||
none @1 :Void;
|
|
||||||
# No initial reponse is being sent.
|
|
||||||
# The lowest numbered field in an union is the default value in Cap'n
|
|
||||||
# Proto.
|
|
||||||
|
|
||||||
initial @2 :Data;
|
|
||||||
# A response may be any sequence of octets, including zero-length
|
|
||||||
# sequences and zero-valued octets.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Response {
|
struct Response {
|
||||||
enum Result {
|
enum Error {
|
||||||
# Result code of the outcome
|
aborted @0;
|
||||||
successful @0;
|
# This authentication exchange was aborted by either side.
|
||||||
|
|
||||||
badMechanism @1;
|
badMechanism @1;
|
||||||
# The server does not support this mechanism in this context.
|
# The server does not support this mechanism in this context.
|
||||||
|
|
||||||
unwilling @2;
|
invalidCredentials @2;
|
||||||
# Generic "I'm sorry dave, I can't do that" response. MAY be set for any
|
# The exchange was valid, but the provided credentials are invalid. This may mean that the
|
||||||
# reason, all reasons or no reason at all.
|
# authcid is not known to the server or that the password/certificate/key/ticket/etc is not
|
||||||
# A server SHOULD set the `action` and `helpText` fields as appropiate.
|
# correct.
|
||||||
# This code SHOULD only be sent if no other value is more fitting.
|
|
||||||
|
|
||||||
invalidCredentials @3;
|
failed @3;
|
||||||
# The exchange was valid, but the provided credentials are invalid. This
|
# A generic failed result. A server sending this result MUST set the `action` field to
|
||||||
# may mean that the authcid is not known to the server or that the
|
# indicate whether this is a temporary or permanent failure and SHOULD set `description` to
|
||||||
# password/certificate/key/etc. is not correct.
|
# a human-readable error message.
|
||||||
|
|
||||||
unauthorized @4;
|
|
||||||
# The given authcid is not authorized to act as the requested authzid.
|
|
||||||
# This MAY also be returned for the cases `authzid == NULL` or
|
|
||||||
# `authzid == authcid`, for example because login is disabled for that
|
|
||||||
# authcid.
|
|
||||||
|
|
||||||
malformedAuthZid @5;
|
|
||||||
# The provided authzid is malformed in some way.
|
|
||||||
|
|
||||||
failed @6;
|
|
||||||
# A generic failed result. A server sending this result MUST set the
|
|
||||||
# `action` field to indicate whether this is a temporary or permanent
|
|
||||||
# failure and SHOULD set `helpText` to a human-readable error message.
|
|
||||||
}
|
}
|
||||||
enum Action {
|
|
||||||
# In case of a unsuccessful outcome, how should a client proceed?
|
|
||||||
|
|
||||||
unset @0;
|
|
||||||
# Not a unsuccessful outcome, or the server doesn't know either.
|
|
||||||
# Also, the default value
|
|
||||||
|
|
||||||
retry @1;
|
|
||||||
# A client should just try again, potentially after prompting the user
|
|
||||||
# to enter their credentials again.
|
|
||||||
|
|
||||||
wait @2;
|
|
||||||
# The client should wait and try again later. This MAY mean that
|
|
||||||
# whatever failure happened was temporary or the server is applying
|
|
||||||
# rate-limiting to the connection.
|
|
||||||
|
|
||||||
permanent @3;
|
|
||||||
# The issue appears to the server as being permanent. Another try is
|
|
||||||
# very likely to return the exact same result. In most cases the user
|
|
||||||
# should notify the responsible system administrator.
|
|
||||||
}
|
|
||||||
|
|
||||||
union {
|
union {
|
||||||
challence @0 :Data;
|
failed :group {
|
||||||
outcome :group {
|
code @0 :Error;
|
||||||
result @1 :Result; # Result code
|
# Error code indicating the cause of the error
|
||||||
|
|
||||||
action @2 :Action; # Hints for the client how to proceed in case of an error
|
additionalData @1 :Data;
|
||||||
|
# Some mechanisms will send additional data after an error
|
||||||
|
}
|
||||||
|
# Some kind of error happened. This in the first entry in the union because it is the
|
||||||
|
# default set value meaning if a server fails to set any of the values, indicating some
|
||||||
|
# pretty severe server bugs, it is parsed as an "aborted" error.
|
||||||
|
|
||||||
|
challenge @2 :Data;
|
||||||
|
# The data provided so far is not enough to authenticate the user. The data MAY be a
|
||||||
|
# NULL-ptr or a non-NULL list ptr of zero bytes which clients MUST pass to their SASL
|
||||||
|
# implementation as "no data" and "some data of zero length" respectively.
|
||||||
|
|
||||||
helpText @3 :Text; # Human-readable further information in case of an error
|
successful :group {
|
||||||
|
# The exchange was successful and a new session has been created for the authzid that
|
||||||
|
# was established by the SASL exchange.
|
||||||
|
|
||||||
additionalData :union {
|
session @3 :Session;
|
||||||
# Additional data that may be sent by the server to the client after a
|
# The session that was created. It grants access to all capabilities the connecting
|
||||||
# successful authentication exchange.
|
# party has permissions for.
|
||||||
|
|
||||||
none @4 :Void;
|
additionalData @4 :Data;
|
||||||
# No additional data is being sent. This MUST be set on unsuccessful
|
# SASL may send additional data with the successful result. This MAY be a NULL-ptr or a
|
||||||
# outcomes.
|
# non-NULL list ptr of zero bytes which clients MUST pass to their SASL implementation
|
||||||
|
# as "no additional data" and "some additional data of zero length" respectively.
|
||||||
additional @5 :Data;
|
|
||||||
# Additional data may be any sequence of octets, including zero-length
|
|
||||||
# sequences and zero-value octets.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Authentication {
|
||||||
|
step @0 ( data: Data ) -> Response;
|
||||||
|
# Respond to a challenge with more data. A client MUST NOT call this after having received an
|
||||||
|
# "successful" response.
|
||||||
|
|
||||||
|
abort @1 ();
|
||||||
|
# Abort the current exchange. This will invalidate the Authentication making all further calls
|
||||||
|
# to `step` return an error response. A client MUST NOT call this function after
|
||||||
|
# having received an "successful" response.
|
||||||
|
# A server will indicate that they have aborted an authentication exchange by replying with an
|
||||||
|
# "aborted" Error to the next `step` call. A server SHOULD directly terminate the underlying stream
|
||||||
|
# after sending this response. The server MAY after a short grace period terminate the stream
|
||||||
|
# without sending a response if no call to `step` was received by the client.
|
||||||
|
}
|
||||||
|
@ -6,18 +6,44 @@ $Rust.parentModule("schema");
|
|||||||
using CSharp = import "programming_language/csharp.capnp";
|
using CSharp = import "programming_language/csharp.capnp";
|
||||||
$CSharp.namespace("FabAccessAPI.Schema");
|
$CSharp.namespace("FabAccessAPI.Schema");
|
||||||
|
|
||||||
using AuthenticationSystem = import "authenticationsystem.capnp".AuthenticationSystem;
|
using Authentication = import "authenticationsystem.capnp".Authentication;
|
||||||
using MachineSystem = import "machinesystem.capnp".MachineSystem;
|
using MachineSystem = import "machinesystem.capnp".MachineSystem;
|
||||||
using UserSystem = import "usersystem.capnp".UserSystem;
|
using UserSystem = import "usersystem.capnp".UserSystem;
|
||||||
using PermissionSystem = import "permissionsystem.capnp".PermissionSystem;
|
using PermissionSystem = import "permissionsystem.capnp".PermissionSystem;
|
||||||
|
|
||||||
|
const apiVersionMajor :Int32 = 0;
|
||||||
|
const apiVersionMinor :Int32 = 3;
|
||||||
|
const apiVersionPatch :Int32 = 0;
|
||||||
|
|
||||||
|
struct Version
|
||||||
|
{
|
||||||
|
major @0 :Int32;
|
||||||
|
minor @1 :Int32;
|
||||||
|
patch @2 :Int32;
|
||||||
|
}
|
||||||
|
|
||||||
interface Bootstrap
|
interface Bootstrap
|
||||||
{
|
{
|
||||||
authenticationSystem @0 () -> ( authenticationSystem : AuthenticationSystem );
|
getAPIVersion @0 () -> Version;
|
||||||
|
|
||||||
machineSystem @1 () -> ( machineSystem : MachineSystem );
|
getServerRelease @1 () -> ( name :Text, release :Text );
|
||||||
|
# Returns the server implementation name and version/build number
|
||||||
userSystem @2 () -> ( userSystem : UserSystem );
|
# Designed only for human-facing debugging output so should be informative over machine-readable
|
||||||
|
# Example: ( name = "bffhd", release = "0.3.1-f397e1e [rustc 1.57.0 (f1edd0429 2021-11-29)]")
|
||||||
|
|
||||||
permissionSystem @3 () -> ( permissionSystem : PermissionSystem );
|
mechanisms @2 () -> ( mechs: List(Text) );
|
||||||
|
# Get a list of Mechanisms this server allows in this context.
|
||||||
|
|
||||||
|
createSession @3 ( mechanism :Text ) -> ( authentication :Authentication );
|
||||||
|
# Create a new session with the server that you wish to authenticate using `mechanism`.
|
||||||
|
# Using pipelining makes this one-roundtrip capable without explicit initial data support.
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Session {
|
||||||
|
machineSystem @0 : MachineSystem;
|
||||||
|
userSystem @1 : UserSystem;
|
||||||
|
permissionSystem @2 : PermissionSystem;
|
||||||
|
|
||||||
|
vendor @3 :AnyPointer;
|
||||||
|
# Vendor-specific APIs outside the normal API stability
|
||||||
}
|
}
|
||||||
|
@ -25,4 +25,21 @@ struct UUID {
|
|||||||
struct KeyValuePair {
|
struct KeyValuePair {
|
||||||
key @0 :Text;
|
key @0 :Text;
|
||||||
value @1 :Text;
|
value @1 :Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Optional(T) {
|
||||||
|
union {
|
||||||
|
nothing @0 :Void;
|
||||||
|
just @1 :T;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Fallible(T, E) {
|
||||||
|
# Some operations can fail in several expected ways.
|
||||||
|
# In those cases returning an `Optional` doesn't transfer information about the way that the
|
||||||
|
# operation failed. `Fallible` contains this information in the generic `E` type.
|
||||||
|
union {
|
||||||
|
failed @0 :E;
|
||||||
|
successful @1 :T;
|
||||||
|
}
|
||||||
}
|
}
|
@ -7,6 +7,7 @@ using CSharp = import "programming_language/csharp.capnp";
|
|||||||
$CSharp.namespace("FabAccessAPI.Schema");
|
$CSharp.namespace("FabAccessAPI.Schema");
|
||||||
|
|
||||||
using General = import "general.capnp";
|
using General = import "general.capnp";
|
||||||
|
using Optional = General.Optional;
|
||||||
using User = import "user.capnp".User;
|
using User = import "user.capnp".User;
|
||||||
using Space = import "space.capnp".Space;
|
using Space = import "space.capnp".Space;
|
||||||
|
|
||||||
@ -18,10 +19,12 @@ struct Machine {
|
|||||||
blocked @3;
|
blocked @3;
|
||||||
disabled @4;
|
disabled @4;
|
||||||
reserved @5;
|
reserved @5;
|
||||||
|
totakeover @6;
|
||||||
}
|
}
|
||||||
struct MachineInfoExtended {
|
struct MachineInfoExtended {
|
||||||
currentUser @0 :User;
|
currentUser @0 :Optional(User);
|
||||||
transferUser @1 :User;
|
lastUser @1 :Optional(User);
|
||||||
|
instructorUser @2 :Optional(User);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Reservation {
|
struct Reservation {
|
||||||
@ -35,17 +38,16 @@ struct Machine {
|
|||||||
name @2 :Text;
|
name @2 :Text;
|
||||||
description @3 :Text;
|
description @3 :Text;
|
||||||
state @4 :MachineState;
|
state @4 :MachineState;
|
||||||
manager @5:User;
|
manager @5:Optional(User);
|
||||||
wiki @13 :Text;
|
wiki @13 :Text;
|
||||||
urn @14 :Text;
|
urn @14 :Text;
|
||||||
|
category @15 :Text;
|
||||||
|
|
||||||
info @6 :Info;
|
info @6 :Info;
|
||||||
interface Info $CSharp.name("InfoInterface") {
|
interface Info $CSharp.name("InfoInterface") {
|
||||||
getMachineInfoExtended @0 () -> ( machineInfoExtended :MachineInfoExtended, dummy :UInt8 = 0);
|
getPropertyList @0 () -> ( propertyList :List(General.KeyValuePair) );
|
||||||
|
|
||||||
getPropertyList @1 () -> ( propertyList :List(General.KeyValuePair) );
|
getReservationList @1 () -> ( reservationList :List(Reservation) );
|
||||||
|
|
||||||
getReservationList @2 () -> ( reservationList :List(Reservation) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
use @7 :Use;
|
use @7 :Use;
|
||||||
@ -60,10 +62,16 @@ struct Machine {
|
|||||||
interface InUse $CSharp.name("InUseInterface") {
|
interface InUse $CSharp.name("InUseInterface") {
|
||||||
giveBack @0 ();
|
giveBack @0 ();
|
||||||
sendRawData @1 (data :Data);
|
sendRawData @1 (data :Data);
|
||||||
|
releasefortakeover @2 ();
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer @9 :Transfer;
|
prodable @16 :Prodable;
|
||||||
interface Transfer $CSharp.name("TransferInterface") {
|
interface Prodable $CSharp.name("ProdInterface") {
|
||||||
|
prodWithData @0 (data :Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
takeover @9 :Takeover;
|
||||||
|
interface Takeover $CSharp.name("TakeoverInterface") {
|
||||||
accept @0 ();
|
accept @0 ();
|
||||||
reject @1 ();
|
reject @1 ();
|
||||||
}
|
}
|
||||||
@ -76,16 +84,18 @@ struct Machine {
|
|||||||
|
|
||||||
manage @11 :Manage;
|
manage @11 :Manage;
|
||||||
interface Manage $CSharp.name("ManageInterface") {
|
interface Manage $CSharp.name("ManageInterface") {
|
||||||
setProperty @0 (property :General.KeyValuePair);
|
getMachineInfoExtended @0 () -> MachineInfoExtended;
|
||||||
removeProperty @1 (property :General.KeyValuePair);
|
|
||||||
|
setProperty @1 (property :General.KeyValuePair);
|
||||||
|
removeProperty @2 (property :General.KeyValuePair);
|
||||||
|
|
||||||
forceUse @2 ();
|
forceUse @3 ();
|
||||||
forceFree @3 ();
|
forceFree @4 ();
|
||||||
|
|
||||||
forceTransfer @4 (user :User);
|
forceTransfer @5 (user :User);
|
||||||
|
|
||||||
block @5 ();
|
block @6 ();
|
||||||
disabled @6 ();
|
disabled @7 ();
|
||||||
}
|
}
|
||||||
|
|
||||||
admin @12 :Admin;
|
admin @12 :Admin;
|
||||||
|
@ -7,15 +7,16 @@ using CSharp = import "programming_language/csharp.capnp";
|
|||||||
$CSharp.namespace("FabAccessAPI.Schema");
|
$CSharp.namespace("FabAccessAPI.Schema");
|
||||||
|
|
||||||
using General = import "general.capnp";
|
using General = import "general.capnp";
|
||||||
|
using Optional = General.Optional;
|
||||||
using Machine = import "machine.capnp".Machine;
|
using Machine = import "machine.capnp".Machine;
|
||||||
|
|
||||||
interface MachineSystem
|
struct MachineSystem
|
||||||
{
|
{
|
||||||
info @0 () -> ( info : Info );
|
info @0 :Info;
|
||||||
interface Info $CSharp.name("InfoInterface") {
|
interface Info $CSharp.name("InfoInterface") {
|
||||||
getMachineList @0 () -> ( machine_list :List(Machine) );
|
getMachineList @0 () -> ( machine_list :List(Machine) );
|
||||||
|
|
||||||
getMachine @1 ( id :Text ) -> ( machine :Machine, dummy :UInt8 = 0 );
|
getMachine @1 ( id :Text ) -> Optional(Machine);
|
||||||
getMachineURN @2 ( urn :Text ) -> ( machine :Machine, dummy :UInt8 = 0 );
|
getMachineURN @2 ( urn :Text ) -> Optional(Machine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,14 +8,14 @@ $CSharp.namespace("FabAccessAPI.Schema");
|
|||||||
|
|
||||||
using Role = import "role.capnp".Role;
|
using Role = import "role.capnp".Role;
|
||||||
|
|
||||||
interface PermissionSystem
|
struct PermissionSystem
|
||||||
{
|
{
|
||||||
info @0 () -> ( info : Info );
|
info @0 :Info;
|
||||||
interface Info $CSharp.name("InfoInterface") {
|
interface Info $CSharp.name("InfoInterface") {
|
||||||
getRoleList @0 () -> ( role_list :List(Role) );
|
getRoleList @0 () -> ( role_list :List(Role) );
|
||||||
}
|
}
|
||||||
|
|
||||||
manage @1 () -> ( manage : Manage );
|
manage @1 :Manage;
|
||||||
interface Manage $CSharp.name("ManageInterface") {
|
interface Manage $CSharp.name("ManageInterface") {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
62
user.capnp
62
user.capnp
@ -24,8 +24,7 @@ struct User
|
|||||||
|
|
||||||
info @3 :Info;
|
info @3 :Info;
|
||||||
interface Info $CSharp.name("InfoInterface") {
|
interface Info $CSharp.name("InfoInterface") {
|
||||||
getUserInfoExtended @0 () -> ( userInfoExtended :UserInfoExtended );
|
listRoles @0 () -> ( roles :List(Role) );
|
||||||
listRoles @1 () -> ( roles :List(Role) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
manage @4 :Manage;
|
manage @4 :Manage;
|
||||||
@ -35,61 +34,18 @@ struct User
|
|||||||
|
|
||||||
admin @5 :Admin;
|
admin @5 :Admin;
|
||||||
interface Admin $CSharp.name("AdminInterface") {
|
interface Admin $CSharp.name("AdminInterface") {
|
||||||
addRole @0 ( role :Role ) -> ();
|
getUserInfoExtended @0 () -> ( userInfoExtended :UserInfoExtended );
|
||||||
removeRole @1 ( role :Role ) -> ();
|
|
||||||
|
addRole @1 ( role :Role ) -> ();
|
||||||
|
removeRole @2 ( role :Role ) -> ();
|
||||||
|
|
||||||
pwd @2 ( new_pwd :Text ) -> ();
|
pwd @3 ( new_pwd :Text ) -> ();
|
||||||
}
|
}
|
||||||
|
|
||||||
cardDESFireEV2 @6 :CardDESFireEV2;
|
cardDESFireEV2 @6 :CardDESFireEV2;
|
||||||
interface CardDESFireEV2 $CSharp.name("CardDESFireInterface") {
|
interface CardDESFireEV2 $CSharp.name("CardDESFireInterface") {
|
||||||
# Card authentication using NXP/MiFare DESFire cards.
|
# For more details about FabFire specification please see:
|
||||||
# These cards have the ability to restrict access for data on the cards using symmetric
|
# https://docs.fab-access.org/books/fabfire-und-nfc-tags/page/fabfire-funktionsprinzip-grundlagen
|
||||||
# encryption and using a keyed Diffie-Hellman to prevent eavesdropping by any relaying
|
|
||||||
# party.
|
|
||||||
# A card has several "applications", containing up to 32 files. A file can be read or
|
|
||||||
# written. Both kinds of access can be restricted to parties knowing a PSK, on a
|
|
||||||
# file-to-file basis.
|
|
||||||
# The current system uses File 0001 through File 0004:
|
|
||||||
#
|
|
||||||
# File 0001 allows public (i.e. unauthenticated) read access and contains the Strings
|
|
||||||
# "FABACCESS", "DESFIRE", and "1.0" as packed list of UTF-8 encoded zero-terminated strings:
|
|
||||||
# (i.e. "FABACCESS\0DESFIRE\01.0\0")
|
|
||||||
# This file serves as sort of magic identifier allowing a server to verify quickly if it is
|
|
||||||
# able to use this card at all.
|
|
||||||
#
|
|
||||||
# File 0002 too allows public read access and contains:
|
|
||||||
# - An URL-encoded name of the issuing lab as URN in the format "urn:fabaccess:lab:<labname>"
|
|
||||||
# Examples:
|
|
||||||
# - "urn:fabaccess:lab:innovisionlab"
|
|
||||||
# - "urn:fabaccess:lab:Bibliothek%20Neustadt%20Makerspace"
|
|
||||||
# - "urn:fabaccess:lab:Offene%20Werkstatt%20M%C3%A4rz"
|
|
||||||
# - A valid IRI pointing towards the bffd instance running for this lab. This uffd SHOULD be
|
|
||||||
# reachable from the internet. Using private use IP addresses or IRIs that resolve to such
|
|
||||||
# may be necessary for labs behind restrictive firewalls or due to local policy.
|
|
||||||
# The IRI MUST use the "fabaccess" scheme, and SHOULD NOT contain an userinfo, path, query,
|
|
||||||
# or fragment part.
|
|
||||||
# Examples:
|
|
||||||
# - "fabaccess://innovisionlab.de/"
|
|
||||||
# - "fabaccess://192.168.178.65"
|
|
||||||
# - "fabaccess://fabaccess-server.localnet"
|
|
||||||
# - A zero-terminated list of UTF-8 encoded IRIs giving contact options to notify the issuer
|
|
||||||
# or owner in case the card has been lost. Issuers SHOULD set one value on card creation and
|
|
||||||
# MAY allow card owners to change or add values of their choosing.
|
|
||||||
# Examples:
|
|
||||||
# - "mailto:lostcard@innovisionlab.de"
|
|
||||||
# - "https://innovisionlab.de/lostcard"
|
|
||||||
# - "https://werkstatt-märz.de/cardlost.php?action=submitcardlost"
|
|
||||||
#
|
|
||||||
# File 0003 allows public access or access using a key, at the issuers option.
|
|
||||||
# It contains a token that can be used by the home server of the card owner to identify the
|
|
||||||
# card owner. The format of the token MUST NOT be relied on by any party except the home
|
|
||||||
# server.
|
|
||||||
#
|
|
||||||
# File 0004 restricts read access to a single key known to the home server of the card
|
|
||||||
# owner.
|
|
||||||
# It is empty but by being access restricted allows the home server to validate the card as
|
|
||||||
# being genuine and thus finalizing the authentication of the user.
|
|
||||||
|
|
||||||
getTokenList @0 () -> ( token_list :List(Data) );
|
getTokenList @0 () -> ( token_list :List(Data) );
|
||||||
# Get a list of all user Token currently bound to an user. This will generally be the number
|
# Get a list of all user Token currently bound to an user. This will generally be the number
|
||||||
@ -117,4 +73,4 @@ struct User
|
|||||||
# format to be written to the card as-is, but a client MAY add or change some information
|
# format to be written to the card as-is, but a client MAY add or change some information
|
||||||
# contained.
|
# contained.
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,19 +8,44 @@ $CSharp.namespace("FabAccessAPI.Schema");
|
|||||||
|
|
||||||
using General = import "general.capnp";
|
using General = import "general.capnp";
|
||||||
using User = import "user.capnp".User;
|
using User = import "user.capnp".User;
|
||||||
|
using Optional = General.Optional;
|
||||||
|
using Fallible = General.Fallible;
|
||||||
|
|
||||||
interface UserSystem
|
struct UserSystem
|
||||||
{
|
{
|
||||||
info @0 () -> ( info : Info );
|
info @0 :Info;
|
||||||
interface Info $CSharp.name("InfoInterface") {
|
interface Info $CSharp.name("InfoInterface") {
|
||||||
getUserSelf @0 ( ) -> ( user :User, dummy :UInt8 = 0 );
|
getUserSelf @0 ( ) -> User;
|
||||||
}
|
}
|
||||||
|
|
||||||
manage @1 () -> ( manage : Manage );
|
search @2 :Search;
|
||||||
|
interface Search $CSharp.name("SearchInterface") {
|
||||||
|
getUserByName @0 (username: Text) -> Optional(User);
|
||||||
|
}
|
||||||
|
|
||||||
|
manage @1 :Manage;
|
||||||
interface Manage $CSharp.name("ManageInterface") {
|
interface Manage $CSharp.name("ManageInterface") {
|
||||||
getUserList @0 () -> ( user_list :List(User) );
|
getUserList @0 () -> ( user_list :List(User) );
|
||||||
|
|
||||||
addUser @1 (username :Text, password: Text) -> ( user :User );
|
addUser @1 (username :Text, password: Text) -> User;
|
||||||
removeUser @2 (user :User, dummy :UInt8 = 0);
|
# DEPRECATED: use `addUserFallible` instead
|
||||||
|
|
||||||
|
removeUser @2 (user: User);
|
||||||
|
|
||||||
|
struct AddUserError {
|
||||||
|
enum AddUserError $CSharp.name("AddUserErrorEnum") {
|
||||||
|
alreadyExists @0;
|
||||||
|
# An user with that username already exists
|
||||||
|
|
||||||
|
usernameInvalid @1;
|
||||||
|
# The provided username is unusable, e.g. contains invalid characters,
|
||||||
|
# is too long or too short.
|
||||||
|
|
||||||
|
passwordInvalid @2;
|
||||||
|
# The provided password is unusable, e.g. it's of zero length
|
||||||
|
}
|
||||||
|
error @0 :AddUserError;
|
||||||
|
}
|
||||||
|
addUserFallible @3 (username :Text, password: Text) -> Fallible(User, AddUserError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user