diff --git a/auth.capnp b/auth.capnp index c26168d..42e593f 100644 --- a/auth.capnp +++ b/auth.capnp @@ -6,6 +6,11 @@ $CSharp.namespace("FabAccessAPI.Schema"); using import "utils.capnp".L10NString; using import "main.capnp".Session; +struct Mechanism { + name @0 :Text; + additionalInfo @1 :AnyPointer; +} + struct Response { enum Reason { aborted @0; diff --git a/cache.capnp b/cache.capnp new file mode 100644 index 0000000..b249046 --- /dev/null +++ b/cache.capnp @@ -0,0 +1,17 @@ +@0xf6520578f143b471; + +using import "utils.capnp".UUID; + +struct Cache(Value) { + id @0 :UUID; + key @1 :Data; + value @2 :Cacheable(Value); +} + +interface Cacheable(Value) { + get @0 () -> (key :Data, value :Value); + # Access the cached value. This returns both the value and the associated + # key. A consumer MUST use the Key returned here instead of the one stored + # in `Cache`, as it might have changed between being sent the `Cache` + # struct and calling `get`. +} diff --git a/claim.capnp b/claim.capnp index a642993..a218d27 100644 --- a/claim.capnp +++ b/claim.capnp @@ -27,14 +27,16 @@ interface Lockable { # Restore a previously saved SturdyRef pointing to a Lock lock @1 () -> ( lock :Lock ); - # Take exclusive access to a resource, disowning all other claims on this resource. + # Take exclusive access to a resource, disowning all other claims on this + # resource. # - # On resources that do not allow concurrent claims to exist this method behaves similar to - # `claim`, however it will also succeed if a resource is already claimed, disowning the previous - # claim. On resources that do allow concurrent claims this method will disown all current claims on a - # resource and prevent new claims from being granted until the returned Lock capability is - # dropped. A call to `lock` on a resource that is already locked will succeed, invalidating the former - # lock. + # On resources that do not allow concurrent claims to exist this method + # behaves similar to `claim`, however it will also succeed if a resource is + # already claimed, disowning the previous claim. On resources that do + # allow concurrent claims this method will disown all current claims on a + # resource and prevent new claims from being granted until the returned + # Lock capability is dropped. A call to `lock` on a resource that is + # already locked will succeed, invalidating the former lock. } interface Claim extends (Notifiable) { diff --git a/main.capnp b/main.capnp index 82f4588..9ed96e8 100644 --- a/main.capnp +++ b/main.capnp @@ -4,15 +4,18 @@ using CSharp = import "programming_language/csharp.capnp"; $CSharp.namespace("FabAccessAPI.Schema"); using import "auth.capnp".Authentication; +using import "auth.capnp".Mechanism; using import "resources.capnp".Resources; using import "users.capnp".Users; using import "user.capnp".User; using import "permissions.capnp".Permissions; +const currentVersion :Version = (major = 1, minor = 0); + struct Version { - major @0 :Int32 = 0; - minor @1 :Int32 = 4; + major @0 :Int32; + minor @1 :Int32; } interface Bootstrap @@ -24,7 +27,7 @@ interface Bootstrap # debugging output so should be informative over machine-readable. # Example: ("bffhd", "0.3.1-f397e1e [rustc 1.57.0 (f1edd0429 2021-11-29)]") - mechanisms @2 () -> ( mechs :List(Text) ); + mechanisms @2 () -> ( mechs :List(Mechanism) ); # Get a list of Mechanisms this server allows in this context. createSession @3 ( mechanism :Text ) -> ( authentication :Authentication ); diff --git a/notify.capnp b/notify.capnp index 46b78ed..34a114f 100644 --- a/notify.capnp +++ b/notify.capnp @@ -6,13 +6,10 @@ $CSharp.namespace("FabAccessAPI.Schema"); using import "resource.capnp".Resource; using import "utils.capnp".OID; using import "utils.capnp".Map; +using import "state.capnp".Update; interface Notifiable { - traits @0 () -> Map(OID, AnyPointer); -} - -interface Notify(State, Update) { - state @0 () -> ( state :State ); + state @0 () -> ( state :Map(OID, AnyPointer) ); # Returns the current state of a resource. subscribe @1 ( subscriber :Subscriber(Update) ) -> ( subscription :Subscription ); @@ -21,7 +18,7 @@ interface Notify(State, Update) { } interface Subscriber(Update) { - update @0 ( update :Update ) -> (); + update @0 ( update :Update ) -> UpdateResult; # Called by a server when a new state was produced for this resource. This method MAY not be # called when a resource was updated but did not change its state. A server will only ever have # one running update call per client session, so a client can limit the rate of updates by not @@ -30,4 +27,8 @@ interface Subscriber(Update) { # resource. } -interface Subscription { } +struct UpdateResult { } # Empty struct to make `update` apply backpressure. + +interface Subscription { + cancel @0 (); # Cancel this subscription, making the server not send anymore updates. +} diff --git a/resource.capnp b/resource.capnp index d21116c..50036e5 100644 --- a/resource.capnp +++ b/resource.capnp @@ -13,12 +13,16 @@ using import "utils.capnp".OID; using import "utils.capnp".L10NString; using import "utils.capnp".Map; +using import "cache.capnp".Cache; + struct Resource { # 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". - description @0 :Describable; + description @0 :Cache(Description); + # Return information about this resource. This information is usually + # static and thus put behind a Cache. notify @1 :Notifiable; # NULL if the user does not have permission to read this resource, or if this resource is not @@ -37,12 +41,6 @@ struct Resource { # does not support claiming or locking. } -interface Describable { - description @0 () -> Description; - # Return information about this resource. This information is usually static and does not - # change between calls. -} - struct Description { identifier @0 :Text; # The unique identifier for this resource @@ -65,11 +63,28 @@ struct Description { # A category this resource belongs to. If a resource was not assigned a category this is empty, # see the definition of [`Category`](struct::Category) for details. - metadata @5 :Map(Text, Text); + metadata @5 :Map(Text, Metadata); # Metadata associated with this resource. This can be things like links to wikis or similar. # Common keys are pre-defined as constants in this file. } +struct Metadata { + # Metadata associated with a specific resource description. + + union { + inline :group { + mediaType @0 :Text; # Media type of the value sent (as per https://www.iana.org/assignments/media-types/media-types.xhtml ) + value @1 :Data; # The value as BLOB + } + + remoteInline @2 :Text; + # URL pointing to the value. A client should fetch it and show it inline + + remoteUrl @3 :Text; + # An URL that *is* the value. A client should display this as a clickable link. + } +} + struct Category { # A category this resource belongs to.