use submodule

This commit is contained in:
LastExceed
2025-10-22 17:54:06 +02:00
parent ff94b31ee0
commit d44b8bb1fc
17 changed files with 4 additions and 572 deletions
+3
View File
@@ -0,0 +1,3 @@
[submodule "fabaccess-api"]
path = fabaccess-api
url = https://gitlab.com/fabinfra/fabaccess/fabaccess-api
Submodule
+1
Submodule fabaccess-api added at f3f53dafb6
-7
View File
@@ -1,7 +0,0 @@
tags
*.cs
# MADR
/node_modules/
/package-lock.json
/package.json
-21
View File
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2020 FabInfra / FabAccess
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-16
View File
@@ -1,16 +0,0 @@
# FabAccess API
## Code generation bugs under c#
When returning an Interface it may be required to append a dummy valueto work around a c# code generation bug.
```diff
- whoami @4 () -> ( you :Api.User );
+ 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)
-76
View File
@@ -1,76 +0,0 @@
@0xb9cffd29ac983e9f;
using Rust = import "programming_language/rust.capnp";
$Rust.parentModule("schema");
using CSharp = import "programming_language/csharp.capnp";
$CSharp.namespace("FabAccessAPI.Schema");
using Session = import "connection.capnp".Session;
struct Response {
enum Error {
aborted @0;
# This authentication exchange was aborted by either side.
badMechanism @1;
# The server does not support this mechanism in this context.
invalidCredentials @2;
# The exchange was valid, but the provided credentials are invalid. This may mean that the
# authcid is not known to the server or that the password/certificate/key/ticket/etc is not
# correct.
failed @3;
# 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 `description` to
# a human-readable error message.
}
union {
failed :group {
code @0 :Error;
# Error code indicating the cause of the 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.
successful :group {
# The exchange was successful and a new session has been created for the authzid that
# was established by the SASL exchange.
session @3 :Session;
# The session that was created. It grants access to all capabilities the connecting
# party has permissions for.
additionalData @4 :Data;
# SASL may send additional data with the successful result. This MAY be a NULL-ptr or a
# 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.
}
}
}
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.
}
-49
View File
@@ -1,49 +0,0 @@
@0xbf017710be5a54ff;
using Rust = import "programming_language/rust.capnp";
$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;
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
{
getAPIVersion @0 () -> Version;
getServerRelease @1 () -> ( name :Text, release :Text );
# Returns the server implementation name and version/build number
# 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)]")
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
}
-45
View File
@@ -1,45 +0,0 @@
@0xff5b4a767d98592a;
using Rust = import "programming_language/rust.capnp";
$Rust.parentModule("schema");
using CSharp = import "programming_language/csharp.capnp";
$CSharp.namespace("FabAccessAPI.Schema");
struct UUID {
# UUID type used to identify machines.
# Since the exact value has no meaning the encoding rules are not too relevant, but it is
# paramount that you are consistent when encoding and decoding this type.
#
# Consider using this algorithm for assembling the 128-bit integer:
# (assuming ISO9899:2018 shifting & casting rules)
# uint128_t num = (uuid1 << 64) + uuid0;
# And then respectively this code for deconstructing it:
# uint64_t uuid0 = (uint64_t) num;
# uint64_t uuid1 = (uint64_t) (num >> 64);
uuid0 @0 :UInt64;
uuid1 @1 :UInt64;
}
struct KeyValuePair {
key @0 :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;
}
}
-110
View File
@@ -1,110 +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 Optional = General.Optional;
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;
totakeover @6;
}
struct MachineInfoExtended {
currentUser @0 :Optional(User);
lastUser @1 :Optional(User);
instructorUser @2 :Optional(User);
}
struct Reservation {
user @0 :User;
start @1: UInt64;
end @2: UInt64;
}
id @0 :Text;
space @1 :Space;
name @2 :Text;
description @3 :Text;
state @4 :MachineState;
manager @5:Optional(User);
wiki @13 :Text;
urn @14 :Text;
category @15 :Text;
info @6 :Info;
interface Info $CSharp.name("InfoInterface") {
getPropertyList @0 () -> ( propertyList :List(General.KeyValuePair) );
getReservationList @1 () -> ( 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);
releasefortakeover @2 ();
}
prodable @16 :Prodable;
interface Prodable $CSharp.name("ProdInterface") {
prodWithData @0 (data :Data);
}
takeover @9 :Takeover;
interface Takeover $CSharp.name("TakeoverInterface") {
accept @0 ();
reject @1 ();
}
check @10 :Check;
interface Check $CSharp.name("CheckInterface") {
check @0 ();
reject @1 ();
}
manage @11 :Manage;
interface Manage $CSharp.name("ManageInterface") {
getMachineInfoExtended @0 () -> MachineInfoExtended;
setProperty @1 (property :General.KeyValuePair);
removeProperty @2 (property :General.KeyValuePair);
forceUse @3 ();
forceFree @4 ();
forceTransfer @5 (user :User);
block @6 ();
disabled @7 ();
}
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);
}
}
-22
View File
@@ -1,22 +0,0 @@
@0xe89d197dcef9c49b;
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 Optional = General.Optional;
using Machine = import "machine.capnp".Machine;
struct MachineSystem
{
info @0 :Info;
interface Info $CSharp.name("InfoInterface") {
getMachineList @0 () -> ( machine_list :List(Machine) );
getMachine @1 ( id :Text ) -> Optional(Machine);
getMachineURN @2 ( urn :Text ) -> Optional(Machine);
}
}
-22
View File
@@ -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;
struct PermissionSystem
{
info @0 :Info;
interface Info $CSharp.name("InfoInterface") {
getRoleList @0 () -> ( role_list :List(Role) );
}
manage @1 :Manage;
interface Manage $CSharp.name("ManageInterface") {
}
}
@@ -1,25 +0,0 @@
@0xeb0d831668c6edab;
$namespace("Capnp.Annotations");
enum TypeVisibility @0xeb0d831668c6eda5 {
public @0;
internal @1;
}
annotation namespace @0xeb0d831668c6eda0 (file) : Text;
# C# namespace for code generation
annotation nullableEnable @0xeb0d831668c6eda1 (file) : Bool;
# Whether to generate C# nullable reference types
annotation emitNullableDirective @0xeb0d831668c6eda3 (file) : Bool;
# Whether to surround the generated code with #nullable enable/disable ... #nullable restore
annotation emitDomainClassesAndInterfaces @0xeb0d831668c6eda4 (file) : Bool;
# Whether generate domain classes and interfaces (default is 'true' if annotation is missing)
annotation typeVisibility @0xeb0d831668c6eda6 (file) : TypeVisibility;
# Visibility of generated types
annotation name @0xeb0d831668c6eda2 (field, enumerant, struct, enum, interface, method, param, group, union) : Text;
# C# member name for code generation
@@ -1,24 +0,0 @@
# This file contains annotations that are recognized by the capnpc-rust code generator.
@0x83b3c14c3c8dd083;
annotation name @0xc2fe4c6d100166d0 (field, struct, enum, enumerant, union, group) :Text;
# Rename something in the generated code. The value that you specify in this
# annotation should follow capnp capitalization conventions. So, for example,
# a struct should use CamelCase capitalization like `StructFoo`, even though
# that will get translated to a `struct_foo` module in the generated Rust code.
#
# TODO: support annotating more kinds of things with this.
annotation parentModule @0xabee386cd1450364 (file) :Text;
# A Rust module path indicating where the generated code will be included.
# For example, if this is set to "foo::bar" and the schema file is named
# "baz.capnp", then you could include the generated code like this:
#
# pub mod foo {
# pub mod bar {
# pub mod baz_capnp {
# include!(concat!(env!("OUT_DIR"), "/baz_capnp.rs"));
# }
# }
# }
-12
View File
@@ -1,12 +0,0 @@
@0xb61c6ec239895b01;
using Rust = import "programming_language/rust.capnp";
$Rust.parentModule("schema");
using CSharp = import "programming_language/csharp.capnp";
$CSharp.namespace("FabAccessAPI.Schema");
struct Role
{
name @0 :Text;
}
-16
View File
@@ -1,16 +0,0 @@
@0xbacaff4190ac7d80;
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";
struct Space
{
id @0 :General.UUID;
name @1 :Text;
info @2 :Text;
}
-76
View File
@@ -1,76 +0,0 @@
@0xc7941adf5db6bbf0;
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 Space = import "space.capnp".Space;
using Role = import "role.capnp".Role;
struct User
{
id @0 :General.UUID;
username @1 :Text;
space @2 :Space;
struct UserInfoExtended
{
id @0 :General.UUID;
name @1 :Text;
}
info @3 :Info;
interface Info $CSharp.name("InfoInterface") {
listRoles @0 () -> ( roles :List(Role) );
}
manage @4 :Manage;
interface Manage $CSharp.name("ManageInterface") {
pwd @0 ( old_pwd :Text, new_pwd :Text ) -> ();
}
admin @5 :Admin;
interface Admin $CSharp.name("AdminInterface") {
getUserInfoExtended @0 () -> ( userInfoExtended :UserInfoExtended );
addRole @1 ( role :Role ) -> ();
removeRole @2 ( role :Role ) -> ();
pwd @3 ( new_pwd :Text ) -> ();
}
cardDESFireEV2 @6 :CardDESFireEV2;
interface CardDESFireEV2 $CSharp.name("CardDESFireInterface") {
# For more details about FabFire specification please see:
# https://docs.fab-access.org/books/fabfire-und-nfc-tags/page/fabfire-funktionsprinzip-grundlagen
getTokenList @0 () -> ( token_list :List(Data) );
# Get a list of all user Token currently bound to an user. This will generally be the number
# of cards they use.
bind @1 ( token :Data, auth_key :Data ) -> ();
# Bind a given URL to a given auth key. The server will store both URL and key, so using
# this frequently will force the server to store large amounts of data.
# Trying to bind a new key to an existing URL will fail.
unbind @2 ( token :Data ) -> ();
# Unbind the key associated with the given token. This will fail all future attempts to use
# the card with the associated key.
genCardToken @3 () -> ( token :Data );
# Generate a new Token that can be used to access an user in a pseudonymized fashion.
# This call is extremely cheap to make as the server will not store this Token.
getMetaInfo @4 () -> ( bytes :Data );
# Retrieve the blob for File 0001 from the server. The returned bytes are in the correct
# format to be written to the card as-is.
getSpaceInfo @5 () -> ( bytes :Data );
# Retrieve the blob for File 0002 from the server. The returned bytes are in the correct
# format to be written to the card as-is, but a client MAY add or change some information
# contained.
}
}
-51
View File
@@ -1,51 +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;
using Optional = General.Optional;
using Fallible = General.Fallible;
struct UserSystem
{
info @0 :Info;
interface Info $CSharp.name("InfoInterface") {
getUserSelf @0 ( ) -> User;
}
search @2 :Search;
interface Search $CSharp.name("SearchInterface") {
getUserByName @0 (username: Text) -> Optional(User);
}
manage @1 :Manage;
interface Manage $CSharp.name("ManageInterface") {
getUserList @0 () -> ( user_list :List(User) );
addUser @1 (username :Text, password: Text) -> User;
# 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);
}
}