mirror of
https://gitlab.com/fabinfra/fabaccess/fabaccess-api.git
synced 2025-03-12 14:51:42 +01:00
update
This commit is contained in:
parent
a13478a3f0
commit
21574d8185
22
claim.capnp
Normal file
22
claim.capnp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
@0xf8f8864ba0678056;
|
||||||
|
|
||||||
|
using CSharp = import "programming_language/csharp.capnp";
|
||||||
|
$CSharp.namespace("FabAccessAPI.Schema");
|
||||||
|
|
||||||
|
using import "/capnp/rpc.capnp".SturdyRef;
|
||||||
|
using import "/capnp/persistent.capnp".Persistent;
|
||||||
|
|
||||||
|
using import "state.capnp".State;
|
||||||
|
|
||||||
|
interface Claimable extends (Persistent) {
|
||||||
|
restore @0 ( sturdy :SturdyRef ) -> ( claim :Claim );
|
||||||
|
# Restore a previously saved SturdyRef pointing to a Claim
|
||||||
|
|
||||||
|
claim @1 () -> ( claim :Claim );
|
||||||
|
# returns NULL if the resource is *currently* not claimable.
|
||||||
|
# drop the returned claim capability to unclaim it.
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Claim extends (Persistent) {
|
||||||
|
update @0 ( state :State ) -> ();
|
||||||
|
}
|
8
interest.capnp
Normal file
8
interest.capnp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
@0xa23cfc5ead0ac055;
|
||||||
|
|
||||||
|
using CSharp = import "programming_language/csharp.capnp";
|
||||||
|
$CSharp.namespace("FabAccessAPI.Schema");
|
||||||
|
|
||||||
|
interface Interestable {
|
||||||
|
|
||||||
|
}
|
17
main.capnp
17
main.capnp
@ -7,12 +7,25 @@ using Authentication = import "auth.capnp".Authentication;
|
|||||||
using Resources = import "resources.capnp".Resources;
|
using Resources = import "resources.capnp".Resources;
|
||||||
using Users = import "users.capnp".Users;
|
using Users = import "users.capnp".Users;
|
||||||
|
|
||||||
|
struct Version
|
||||||
|
{
|
||||||
|
major @0 :Int32 = 0;
|
||||||
|
minor @1 :Int32 = 4;
|
||||||
|
}
|
||||||
|
|
||||||
interface Bootstrap
|
interface Bootstrap
|
||||||
{
|
{
|
||||||
mechanisms @0 () -> ( mechs :List(Text) );
|
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.
|
# Get a list of Mechanisms this server allows in this context.
|
||||||
|
|
||||||
createSession @1 ( mechanism :Text, initialData :Data ) -> ( authentication :Authentication );
|
createSession @3 ( mechanism :Text, initialData :Data ) -> ( authentication :Authentication );
|
||||||
# Create a new session with the server that you wish to authenticate using `mechanism`.
|
# 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
|
# 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
|
# want to send. If the mechanism is server-first or you do not wish to send initial data, make
|
||||||
|
16
notify.capnp
Normal file
16
notify.capnp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
@0xc0787ef6e3cb87e1;
|
||||||
|
|
||||||
|
using CSharp = import "programming_language/csharp.capnp";
|
||||||
|
$CSharp.namespace("FabAccessAPI.Schema");
|
||||||
|
|
||||||
|
using State = import "state.capnp".State;
|
||||||
|
|
||||||
|
interface Notifyable {
|
||||||
|
subscribe @0 ( subscriber :Subscriber ) -> ( subscription :Subscription );
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Subscriber {
|
||||||
|
newState @0 ( state :State ) -> ();
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Subscription { }
|
271
resource.capnp
271
resource.capnp
@ -3,261 +3,32 @@
|
|||||||
using CSharp = import "programming_language/csharp.capnp";
|
using CSharp = import "programming_language/csharp.capnp";
|
||||||
$CSharp.namespace("FabAccessAPI.Schema");
|
$CSharp.namespace("FabAccessAPI.Schema");
|
||||||
|
|
||||||
using Persistent = import "/capnp/persistent.capnp".Persistent;
|
using import "/capnp/persistent.capnp".Persistent;
|
||||||
using Value = import "/capnp/schema.capnp".Value;
|
|
||||||
|
|
||||||
using User = import "user.capnp".User;
|
using import "notify.capnp".Notifyable;
|
||||||
using L10NString = import "utils.capnp".L10NString;
|
using import "interest.capnp".Interestable;
|
||||||
using UUID = import "utils.capnp".UUID;
|
using import "claim.capnp".Claimable;
|
||||||
using OID = import "utils.capnp".OID;
|
|
||||||
|
|
||||||
struct Resource {
|
using import "utils.capnp".OID;
|
||||||
# BFFH's smallest unit of a physical or abstract "thing".
|
|
||||||
# A resource can be as simple and physical as a table, as complex as a PCB production line or as
|
|
||||||
# abstract as "people with specific know-how are present".
|
|
||||||
|
|
||||||
uuid @0 :UUID;
|
interface Resource extends (Persistent) {
|
||||||
# An stable, globally unique descriptor for a resource. Two resources with the same UUID are
|
# BFFH's smallest unit of a physical or abstract "thing". A resource can be
|
||||||
# (almost¹) guaranteed to be the same instance, and the UUID of a resource will survive through
|
# as simple and physical as a table, as complex as a PCB production line or
|
||||||
# server restarts, renaming, reconfiguration etc.
|
# as abstract as "people with specific know-how are present".
|
||||||
#
|
|
||||||
# [¹]: UUID are 128-bit integer. A collision is *possible*, just *very* unlikely. If you
|
|
||||||
# generate 1 billion UUID every second for the next 100 years you have a chance for a collision
|
|
||||||
# of about 50%.
|
|
||||||
|
|
||||||
|
type @0 () -> ( types :List(OID) );
|
||||||
|
# The 'type' of Resource. Each OID in the list specifies certain behaviours
|
||||||
|
# that this Resource follows.
|
||||||
|
|
||||||
id @1 :Text;
|
notify @1 () -> ( notify :Notifyable );
|
||||||
# Every resource in BFFH has a human-readable "name" that is locally unique, but not persistent.
|
# NULL if the user does not have permission to read this resource, or if
|
||||||
# That is a resource called "hello" today may be called "bye" tomorrow and a resource called
|
# this resource is not notifiable
|
||||||
# "hi~~" may not be the same resource as the resource called "hi~~" yesterday. This name is
|
|
||||||
# canonical and thus identifying. There is exactly *one* valid representation of this name at
|
|
||||||
# any given point in time. Thus this name can also not be translated.
|
|
||||||
|
|
||||||
name @2 :L10NString;
|
interest @2 () -> ( interest :Interestable );
|
||||||
# A resource may also have a human-meaningful name that is designed to be shown to users. This
|
# NULL if this resource is not interestable or the user does not have
|
||||||
# name does not have to be unique or identifiable or canonical, its main use is to be
|
# permission to set interests for this resource.
|
||||||
# human-meaningful. For example a "name" could be the translations:
|
|
||||||
# - (en, "Prusa SL1 SLA-Printer")
|
|
||||||
# - (de, "Prusa SL1 SLA-Drucker")
|
|
||||||
# - (es, "Impresora 3D de SLA Prusa SL1")
|
|
||||||
|
|
||||||
description @3 :L10NString;
|
claim @3 () -> ( claim :Claimable );
|
||||||
# A resource may have a description attached to tell an user some more information on a resource
|
# NULL if the user does not have permission to write to this resource, or if
|
||||||
# in a free-form format.
|
# this resource is not (ever!) claimable
|
||||||
# Similar to the human-meaningful name this description can be translated.
|
|
||||||
|
|
||||||
grants @4 :ResourceCaps;
|
|
||||||
|
|
||||||
grant :union {
|
|
||||||
# If the current session has already been given a grant this field will contain a reference
|
|
||||||
# to it. Since stronger grants extend weaker grants only one of these needs to be set at any
|
|
||||||
# given point.
|
|
||||||
# This is mostly useful for session resumption.
|
|
||||||
|
|
||||||
none @5 :Void;
|
|
||||||
# No previous grant for this resource exists for the current user
|
|
||||||
|
|
||||||
notify @6 :Notify;
|
|
||||||
interest @7 :Interest;
|
|
||||||
claim @8 :Claim;
|
|
||||||
# The user has a respective grant on the resource
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ResourceCaps {
|
|
||||||
# Capabilities transfered for a resource. Users will have some or all of these set to non-null
|
|
||||||
# depending on their permission level.
|
|
||||||
|
|
||||||
getState @0 () -> State;
|
|
||||||
# Readonly access to the state of a resource.
|
|
||||||
# A resource can have "state". State are values attached to a resource that describe a specific
|
|
||||||
# state that users or administrators want this resource to be in. Usually this state consists of
|
|
||||||
# a number of primitive values encoding for example "turned on" or "turned off".
|
|
||||||
|
|
||||||
setNotify @1 ( callback :Callback ) -> ( notify :Notify );
|
|
||||||
# Notify allows clients to be informed about state changes asyncronously. A client can register
|
|
||||||
# a callback that is called every time state changes happen to the resource in question.
|
|
||||||
# Notify callbacks are ephermal. If the connection to the server is lost any callbacks from that
|
|
||||||
# client for any resource are unregistered.
|
|
||||||
|
|
||||||
claim @2 () -> ClaimResponse;
|
|
||||||
# Request writeable access to the state of a resource.
|
|
||||||
# Resources are semaphores. They allow writeable access for n ∈ ℕ\{0} clients, depending on the
|
|
||||||
# exact resource in question. In some cases n ≔ 1, and the only write access is exclusive.
|
|
||||||
# "Claims" model this by requiring a client to first assert a claim, thus reserving a semaphore
|
|
||||||
# slot or failing if no more are available, and then using this claim to write to a resources
|
|
||||||
# state.
|
|
||||||
|
|
||||||
interest @3 () -> ( interest :Interest );
|
|
||||||
# Register an "Interest" on this resource.
|
|
||||||
# Sometimes clients are not just interested in the state of a resource but rather want a
|
|
||||||
# resource to stay in a specific state. e.g. somebody working in a makerspace wants the space to
|
|
||||||
# stay open, even though they themselves may not have permission to keep the makerspace open.
|
|
||||||
# "Interest" represents this. Specifically right now it tells BFFH that the client wants at
|
|
||||||
# least one `Claim` to remain.
|
|
||||||
|
|
||||||
override @4 () -> ( claim :Claim );
|
|
||||||
# Override forces a claim to a resource, even if it is already exhausted. This is
|
|
||||||
# primarely useful for administrative overrides.
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
precondition @2;
|
|
||||||
# Some precondition was not met
|
|
||||||
|
|
||||||
dependencies @3;
|
|
||||||
# Resource failed to secure dependencies
|
|
||||||
}
|
|
||||||
|
|
||||||
union {
|
|
||||||
failed :group {
|
|
||||||
error @0 :Error;
|
|
||||||
reason @1 :L10NString;
|
|
||||||
}
|
|
||||||
success @2 :Claim;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Map(Key, Value) {
|
|
||||||
# A serialized key-value map represented as a list of (k,v) tuples.
|
|
||||||
|
|
||||||
entries @0 :List(Entry);
|
|
||||||
|
|
||||||
struct Entry {
|
|
||||||
key @0 :Key;
|
|
||||||
val @1 :Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
using State = Map(OID, Value);
|
|
||||||
# Update state provided to a resource via a claim is represented as a Map of human-readable
|
|
||||||
# identifiers to Cap'n Proto Values. These Values can be either primitive types such as Uint8,
|
|
||||||
# Float64 or more complex types such as structs, lists, or enums.
|
|
||||||
# The resulting state of a resource, which is the output of whatever internal logic the resource
|
|
||||||
# implements, is also represented in this form, but the keys and also values may be different.
|
|
||||||
#
|
|
||||||
# Later on very common cases (use, register, return, etc.) can get shortcut functions in the Claim
|
|
||||||
# interface that pre-emptively check permissions and ability (so you get the respective cap iff the
|
|
||||||
# resource supports that update and if you're allowed to do that) but these functions only serve to
|
|
||||||
# make the update more efficient than calling `update` with the string identifier and dynamic typed
|
|
||||||
# value but do the exact same serverside as an `update` call would. This way we can make future
|
|
||||||
# versions of the API more efficient and easier to use while not breaking compatibility with old
|
|
||||||
# clients.
|
|
||||||
#
|
|
||||||
# TODO: This has the potential problem that a newer client can not distinguish between a server
|
|
||||||
# using an old version of the API and a client simply not being allowed to call a specific shortcut
|
|
||||||
# method because in both cases that cap will be a nullptr. Could be solved by making `Claim` a
|
|
||||||
# struct and indicating which shortcut methods it knows of.
|
|
||||||
# Not sure if this is a big problem, we optimize for old clients and up-to-date servers.
|
|
||||||
#
|
|
||||||
# TODO: We should provide a number of sensible implementations for common complex `Value` types such
|
|
||||||
# as "colour", "temperature", etc. and define identifiers for common values.
|
|
||||||
|
|
||||||
|
|
||||||
interface Notify {
|
|
||||||
# If an user has a notify callback registered it can use this capability to remove it again
|
|
||||||
|
|
||||||
remove @0 ();
|
|
||||||
# Remove any notify callbacks from this user for this resource.
|
|
||||||
|
|
||||||
install @1 ( callback :Callback );
|
|
||||||
# Install a notify callback, replacing any existing one. This method is useful when getting this
|
|
||||||
# interface implicitly via Interest or Claim.
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Callback {
|
|
||||||
# This callback interface needs to be implemented on the client
|
|
||||||
|
|
||||||
newState @0 State;
|
|
||||||
# A server will call newState() with the updated output state. However a server will only
|
|
||||||
# allow one in-flight call, so as long as the previous call to newState() hasn't completed
|
|
||||||
# the server will drop intermediary updates as to not overload a client.
|
|
||||||
# Specifically, example timeline:
|
|
||||||
# 1. Update A
|
|
||||||
# 2. Server calls newState(A)
|
|
||||||
# 3. Update B
|
|
||||||
# 4. Update C
|
|
||||||
# 5. Call to newState(A) completes
|
|
||||||
# 6. Server calls newState(C)
|
|
||||||
# So Update B was never sent to the client but the client will eventually always end up with
|
|
||||||
# the latest state.
|
|
||||||
|
|
||||||
# TODO: There should probably be a more efficient approach here too, something along the
|
|
||||||
# lines of server-side filtering.
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Interest extends(Notify) {
|
|
||||||
# "Interest" right now tells BFFH that the client wants at least one `Claim` to remain.
|
|
||||||
# However, more generally an Interest allows hooking into state changes and block or modify
|
|
||||||
# them.
|
|
||||||
|
|
||||||
dropInterest @0 ();
|
|
||||||
# Remove this interest from a resource.
|
|
||||||
|
|
||||||
lock @1 ();
|
|
||||||
# Lock a resource, making all future state changes from any user but the current one fail until
|
|
||||||
# the lock is released.
|
|
||||||
|
|
||||||
unlock @2 ();
|
|
||||||
# Unlock the resource again, allowing other users to change state again.
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Claim extends(Interest) {
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
readInput @0 () -> State;
|
|
||||||
# Get the current *input* state. This is not the output state that `Notify` or Actors get access
|
|
||||||
# to but instead the currently stored input state of a resource.
|
|
||||||
|
|
||||||
update @1 State -> UpdateResult;
|
|
||||||
# Update the State of the claimed resource with the given one
|
|
||||||
|
|
||||||
dropClaim @2 ();
|
|
||||||
# Drop this claim
|
|
||||||
|
|
||||||
struct UpdateResult {
|
|
||||||
enum Error {
|
|
||||||
# Reason why the update failed
|
|
||||||
|
|
||||||
denied @0;
|
|
||||||
# Update was denied beause user is missing an required permission
|
|
||||||
|
|
||||||
precondition @1;
|
|
||||||
# Some other precondition failed, e.g. because a required field is not set
|
|
||||||
|
|
||||||
invalid @2;
|
|
||||||
# The update is invalid, e.g. because an unknown field was set.
|
|
||||||
|
|
||||||
typeError @3;
|
|
||||||
# A field in the update has a known identifier but a bad type for that identifier
|
|
||||||
|
|
||||||
locked @4;
|
|
||||||
# The state is currently locked and can not be modified by anybody but the user that
|
|
||||||
# issued the lock.
|
|
||||||
}
|
|
||||||
|
|
||||||
union {
|
|
||||||
failed :group {
|
|
||||||
error @0 :Error;
|
|
||||||
field @1 :OID;
|
|
||||||
reason @2 :L10NString;
|
|
||||||
}
|
|
||||||
success @3 :Void;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,19 @@
|
|||||||
using CSharp = import "programming_language/csharp.capnp";
|
using CSharp = import "programming_language/csharp.capnp";
|
||||||
$CSharp.namespace("FabAccessAPI.Schema");
|
$CSharp.namespace("FabAccessAPI.Schema");
|
||||||
|
|
||||||
|
using import "/capnp/rpc.capnp".SturdyRef;
|
||||||
|
|
||||||
using Resource = import "resource.capnp".Resource;
|
using Resource = import "resource.capnp".Resource;
|
||||||
|
|
||||||
interface Resources
|
interface Resources {
|
||||||
{
|
restore @0 ( sturdy :SturdyRef ) -> ( resources :Resource );
|
||||||
listAll @0 () -> ( list :List(Resource) );
|
# Restore a previously saved SturdyRef pointing to a Resource
|
||||||
get @1 ( name :Text ) -> Resource;
|
|
||||||
|
list @1 () -> ( resources :List(Resource) );
|
||||||
|
|
||||||
|
getByUrn @2 ( urn :Text ) -> ( resource :Resource );
|
||||||
|
# Returns a NULL capability if the resource doesn't exist or an user
|
||||||
|
# doesn't have disclose permission for that resource.
|
||||||
|
|
||||||
|
getByName @3 ( name :Text ) -> ( resource :Resource );
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
using CSharp = import "programming_language/csharp.capnp";
|
using CSharp = import "programming_language/csharp.capnp";
|
||||||
$CSharp.namespace("FabAccessAPI.Schema");
|
$CSharp.namespace("FabAccessAPI.Schema");
|
||||||
|
|
||||||
struct Role
|
interface Role {
|
||||||
{
|
name @0 () -> ( name :Text );
|
||||||
name @0 :Text;
|
}
|
||||||
}
|
|
||||||
|
8
state.capnp
Normal file
8
state.capnp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
@0x9d6da2edc6588d6e;
|
||||||
|
|
||||||
|
using CSharp = import "programming_language/csharp.capnp";
|
||||||
|
$CSharp.namespace("FabAccessAPI.Schema");
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
|
||||||
|
}
|
25
user.capnp
25
user.capnp
@ -3,42 +3,35 @@
|
|||||||
using CSharp = import "programming_language/csharp.capnp";
|
using CSharp = import "programming_language/csharp.capnp";
|
||||||
$CSharp.namespace("FabAccessAPI.Schema");
|
$CSharp.namespace("FabAccessAPI.Schema");
|
||||||
|
|
||||||
using UUID = import "utils.capnp".UUID;
|
using import "role.capnp".Role;
|
||||||
using Role = import "role.capnp".Role;
|
|
||||||
|
|
||||||
struct User {
|
interface User {
|
||||||
# Intergalactic lifeform that wants to use BFFH
|
# Intergalactic lifeform that wants to use BFFH
|
||||||
|
|
||||||
id @0 :UUID;
|
info @0 () -> ( info :Info );
|
||||||
# The UUID of an user is a globally unique, persistent identifier for this user.
|
|
||||||
|
|
||||||
username @1 :Text;
|
|
||||||
# username. Locally unique so identifying, but not persistent.
|
|
||||||
|
|
||||||
info @2 :Info;
|
|
||||||
interface Info $CSharp.name("InfoInterface") {
|
interface Info $CSharp.name("InfoInterface") {
|
||||||
listRoles @0 () -> ( roles :List(Role) );
|
listRoles @0 () -> ( roles :List(Role) );
|
||||||
# lists explicit roles for this user. A session may have a number of additional, implicit,
|
# lists explicit roles for this user. A session may have a number of additional, implicit,
|
||||||
# roles set by their choice of authentication or other context.
|
# roles set by their choice of authentication or other context.
|
||||||
}
|
}
|
||||||
|
|
||||||
passwd @3 :Passwd;
|
passwd @1 () -> ( passwd :Passwd );
|
||||||
interface Passwd {
|
interface Passwd {
|
||||||
changepw @0 ( old :Text, new :Text );
|
changepw @0 ( old :Text, new :Text );
|
||||||
}
|
}
|
||||||
|
|
||||||
manage @4 :Manage;
|
manage @2 () -> ( manage :Manage );
|
||||||
interface Manage $CSharp.name("ManageInterface") {
|
interface Manage $CSharp.name("ManageInterface") {
|
||||||
addRole @0 Role;
|
addRole @0 ( role :Role );
|
||||||
removeRole @1 Role;
|
removeRole @1 ( role :Role );
|
||||||
}
|
}
|
||||||
|
|
||||||
admin @5 :Admin;
|
admin @3 () -> ( admin :Admin );
|
||||||
interface Admin $CSharp.name("AdminInterface") {
|
interface Admin $CSharp.name("AdminInterface") {
|
||||||
setpw @0 ( new :Text );
|
setpw @0 ( new :Text );
|
||||||
}
|
}
|
||||||
|
|
||||||
cardDESFireEV2 @6 :CardDESFireEV2;
|
cardDESFireEV2 @4 () -> ( carddesfireev2 :CardDESFireEV2 );
|
||||||
interface CardDESFireEV2 $CSharp.name("CardDESFireInterface") {
|
interface CardDESFireEV2 $CSharp.name("CardDESFireInterface") {
|
||||||
# Card authentication using NXP/MiFare DESFire cards.
|
# Card authentication using NXP/MiFare DESFire cards.
|
||||||
# These cards have the ability to restrict access for data on the cards using symmetric
|
# These cards have the ability to restrict access for data on the cards using symmetric
|
||||||
|
@ -5,16 +5,15 @@ $CSharp.namespace("FabAccessAPI.Schema");
|
|||||||
|
|
||||||
using User = import "user.capnp".User;
|
using User = import "user.capnp".User;
|
||||||
|
|
||||||
interface Users
|
interface Users {
|
||||||
{
|
whoami @0 () -> ( user :User );
|
||||||
whoami @0 () -> User;
|
|
||||||
|
|
||||||
manage @1 () -> ( manage :Manage );
|
manage @1 () -> ( manage :Manage );
|
||||||
interface Manage $CSharp.name("ManageInterface") {
|
interface Manage $CSharp.name("ManageInterface") {
|
||||||
list @0 () -> ( users :List(User) );
|
list @0 () -> ( users :List(User) );
|
||||||
|
|
||||||
addUser @1 ( username :Text, password :Text ) -> User;
|
addUser @1 ( username :Text, password :Text ) -> ( user :User );
|
||||||
|
|
||||||
removeUser @2 User;
|
removeUser @2 ( user :User );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
74
utils.capnp
74
utils.capnp
@ -1,35 +1,41 @@
|
|||||||
@0xed0c02f41fea6b5a;
|
@0xed0c02f41fea6b5a;
|
||||||
|
|
||||||
interface L10NString {
|
interface L10NString {
|
||||||
# Any string type that is intended to be displayed to an user that is more than an identifier to
|
# Any string type that is intended to be displayed to an user that is more
|
||||||
# be used as-is must be able to be localized into the users preferred language. This includes
|
# than an identifier to be used as-is must be able to be localized into the
|
||||||
# description, help messages, etc. but of course does not extend to usernames.
|
# users preferred language. This includes description, help messages, etc.
|
||||||
# TODO: Potentially make generic over the localized content (e.g. dates)? Can be done after the
|
# but of course does not extend to usernames.
|
||||||
# fact without braking protocol, so no big issue.
|
# TODO: Potentially make generic over the localized content (e.g. dates)?
|
||||||
|
# Can be done after the fact without braking protocol, so no big issue.
|
||||||
|
|
||||||
get @0 ( lang :Text ) -> ( lang :Text, content :Text );
|
get @0 ( lang :Text ) -> ( lang :Text, content :Text );
|
||||||
# Retrieve the string in the given locale. The input parameter MUST be a RFC5646-formatted
|
# Retrieve the string in the given locale. The input parameter MUST be a
|
||||||
# locale identifier (e.g: "en-US", "de-DE", "az-Arab-IR").
|
# RFC5646-formatted locale identifier (e.g: "en-US", "de-DE", "az-Arab-IR").
|
||||||
#
|
#
|
||||||
# If a server can't find a localized version matching exactly it MUST try to substitute it.
|
# If a server can't find a localized version matching exactly it MUST try to
|
||||||
# Substitution MUST always return more specific matches for general queries.
|
# substitute it. Substitution MUST always return more specific matches for
|
||||||
# e.g. if "it" is requested and the server has "it-CH" available it returns this string.
|
# general queries. e.g. if "it" is requested and the server has "it-CH"
|
||||||
|
# available it returns this string.
|
||||||
#
|
#
|
||||||
# Substitution SHOULD NOT cross language barriers, e.g. returning "en-GB" for a string requested
|
# Substitution SHOULD NOT cross language barriers, e.g. returning "en-GB"
|
||||||
# in "cy-GB". Substitution MUST NOT return a localization in a different language unless server
|
# for a string requested in "cy-GB". Substitution MUST NOT return a
|
||||||
# has a priori knowledge that the user can read and understand said language.
|
# localization in a different language unless server has a priori knowledge
|
||||||
|
# that the user can read and understand said language.
|
||||||
#
|
#
|
||||||
# Substitution SHOULD prefer unspecified subtags over wrong subtags. If "es-AR" is requested and a
|
# Substitution SHOULD prefer unspecified subtags over wrong subtags. If
|
||||||
# server has "es", and "es-VE" available, "es" should be selected.
|
# "es-AR" is requested and a server has "es", and "es-VE" available, "es"
|
||||||
|
# should be selected.
|
||||||
#
|
#
|
||||||
# A server MUST set the output `lang` field to the exact tag that the content it sends was written
|
# A server MUST set the output `lang` field to the exact tag that the
|
||||||
# in and `content` to the localized string.
|
# content it sends was written in and `content` to the localized string.
|
||||||
# E.g. If a string is requested for "sr" and the server has found a string that was configured as
|
# e.g. If a string is requested for "sr" and the server has found a string
|
||||||
# "sr-Cyrl-BA" the server sets lang to "sr-Cyrl-BA".
|
# that was configured as "sr-Cyrl-BA" the server sets lang to "sr-Cyrl-BA".
|
||||||
#
|
#
|
||||||
# If a server can't find a suitable substitute it MUST set the output `content` to a NULL pointer
|
# If a server can't find a suitable substitute it MUST set the output
|
||||||
# and set the output `lang` to the input `lang` it was passed.
|
# `content` to a NULL pointer and set the output `lang` to the input `lang`
|
||||||
# If a server can't parse a given `lang` tag it MUST set the output `lang` to a NULL pointer.
|
# it was passed.
|
||||||
|
# If a server can't parse a given `lang` tag it MUST set the output `lang`
|
||||||
|
# to NULL.
|
||||||
|
|
||||||
available @1 () -> ( langs :List(Text) );
|
available @1 () -> ( langs :List(Text) );
|
||||||
# Returns the list of locales this content is available in.
|
# Returns the list of locales this content is available in.
|
||||||
@ -52,16 +58,14 @@ struct UUID {
|
|||||||
# upper 8 bytes of the uuid, containing the MSB.
|
# upper 8 bytes of the uuid, containing the MSB.
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OID {
|
using OID = Data;
|
||||||
bytes @0 :Data;
|
# An OID is encoded as a sequence of varints. In this encoding the lower 7 bits
|
||||||
# The OID, encoded as a sequence of varints. In this encoding the lower 7 bits of each octet
|
# of each octet contain data bits while the MSB indicates if the *following*
|
||||||
# contain data bits while the MSB indicates if the *following* octet is still part of this edge.
|
# octet is still part of this edge. It is the same encoding UTF-8 uses. To
|
||||||
# It is the same encoding UTF-8 uses. To decode you simply collect octets until you find an
|
# decode you simply collect octets until you find an octet <128 and then concat
|
||||||
# octet <128 and then concat the data bits of all the octets you've accumulated, including the
|
# the data bits of all the octets you've accumulated, including the current one.
|
||||||
# current one. This gives you the value of one node. Continue until you've exhausted the
|
# This gives you the value of one node. Continue until you've exhausted the
|
||||||
# available data.
|
# available data. This is a rather efficient encoding since almost all edges of
|
||||||
# This is a rather efficient encoding since almost all edges of the OID tree are smaller than
|
# the OID tree are smaller than 128 and thus encode into one byte.
|
||||||
# 128 and thus encode into one byte.
|
# X.208 does *not* limit the size of nodes! However, a reasonable size limit is
|
||||||
# X.208 does *not* limit the size of nodes! However, a reasonable size limit is 128 bit per
|
# 128 bit per node, which is the size of the UUID nodes in the `2.25` subtree.
|
||||||
# node, which is the size of the UUID nodes in the `2.25` subtree.
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user