mirror of
https://gitlab.com/fabinfra/fabaccess/fabaccess-api.git
synced 2025-04-20 10:26:29 +02:00
Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
f3f53dafb6 | |||
c5a59880ad | |||
120db0a68a | |||
ce49e3d07c | |||
|
ec8352c6ae | ||
|
cde4677575 |
@ -1,54 +0,0 @@
|
|||||||
<!--
|
|
||||||
Danke das du dir die Zeit nimmst und FabAccess besser machen willst.
|
|
||||||
|
|
||||||
Feel free to submit features requests in english too, simply use the "Feature Request — EN" template
|
|
||||||
instead!
|
|
||||||
|
|
||||||
Die Punkte in der Vorlage sind nur Anhaltspunkte, du kannst deine Issue auch gerne anders aufbauen.
|
|
||||||
Und mach dir auch keine Gedanken wenn du nicht alles im Detail ausfüllen kannst, eine wenig
|
|
||||||
detaillierte Idee ist immernoch besser als gar nicht von der Idee zu hören!
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Zusammenfassung
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Wenn du magst, schreib ein paar Sätze was du gerne im API hinzugefügt oder geändert sehen würdest.
|
|
||||||
-->
|
|
||||||
|
|
||||||
## Problembeschreibung
|
|
||||||
<!--
|
|
||||||
Hast du ein spezielles Problem was du lösen möchtest? Wenn ja, schilder uns das doch bitte.
|
|
||||||
Falls nicht, kannst du diese Sektion gerne weglassen.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Existierende (provisorische) Lösungen
|
|
||||||
<!--
|
|
||||||
Hast du dein Problem auf einem Umweg oder behilfsmäßig gelöst bekommen?
|
|
||||||
Falls ja, gibts noch Bereiche die nicht funktionieren? Ist diese Umgehungslösung sehr instabil bzw.
|
|
||||||
geht bei updates kaputt oder ist sie einfach nur sehr umständlich und etwas was von FA selber
|
|
||||||
unterstützt werden sollte?
|
|
||||||
|
|
||||||
Dieser Punkt wird nicht dazu dienen das wir den Request einfach ablehnen, sondern damit wir das
|
|
||||||
Problem besser verstehen und beim Entwickeln der Lösung genauer wissen auf welche Punkte wir achten
|
|
||||||
müssen.
|
|
||||||
-->
|
|
||||||
|
|
||||||
## Lösungsvorschalg
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Hast du dir schon Gedanken gemacht wie die Lösung aussehen sollte oder schon angefangen an einer
|
|
||||||
Implementation zu schreiben? Schreib das gerne auf, vorhandene Ansätze sind ein super Start!
|
|
||||||
|
|
||||||
Falls nicht mach dir keinen Kopf, das ist absolut keine Vorraussetzung.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- Gitlab kann quick actions, die Zeile hier fügt zwei passende labels hinzu -->
|
|
||||||
/label ~"Feature Request" ~"Cap'n Proto API"
|
|
||||||
<!-- Note: Bitte füg das "Backwards-Incompatible Change" label nicht selber an außer du weißt mit
|
|
||||||
Gewissheit das deine Änderung das API bricht und ein großes Versionsupdate braucht -->
|
|
||||||
|
|
||||||
<!-- Pingt die richtigen Menschen für diese Art von Issue -->
|
|
||||||
/cc @fabinfra/fabaccess/api-developers
|
|
||||||
|
|
||||||
<!-- vim: textwidth=100
|
|
||||||
-->
|
|
@ -1,51 +0,0 @@
|
|||||||
<!--
|
|
||||||
Thank you for suggesting an idea to make FabAccess better.
|
|
||||||
|
|
||||||
Du kannst Feature Request auch in Englisch verfassen, dafür gibts dann das Template
|
|
||||||
"Feature Request — EN"
|
|
||||||
|
|
||||||
You don't have to stick to the below template, it's just a suggestion from us. Also don't worry if
|
|
||||||
you can't provide much detail, a short idea is still better than not hearing the idea at all!
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Summary
|
|
||||||
|
|
||||||
<!--
|
|
||||||
If you want, give a short summary about what you'd like to see added / changed in the API
|
|
||||||
-->
|
|
||||||
|
|
||||||
## Problem description
|
|
||||||
<!--
|
|
||||||
Do you have a specific problem that you'd like to solve? If so, describe it to us please.
|
|
||||||
If not, feel free to remove this section entirely.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Current solution / Alternatives
|
|
||||||
<!--
|
|
||||||
Do you have a (partial) workaround for the problem or solved the problem a different way?
|
|
||||||
If so, are there parts that still don't work? Is your workaround extremely brittle/breaks on updates
|
|
||||||
or is simply very annoying and something that should be provided by FA already?
|
|
||||||
|
|
||||||
This section is not for us to disregard the request entirely, it simply allows us to potentially
|
|
||||||
better understand the problem and know the what parts should be designed carefully
|
|
||||||
-->
|
|
||||||
|
|
||||||
## Solution idea
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Do you have a solution in mind already? Maybe you've even started writing an implementation? If so,
|
|
||||||
please tell us about it here, existing solutions are a great point to start off with.
|
|
||||||
|
|
||||||
If you don't have any concrete idea or code to show for, don't worry, it is really not required.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- Gitlab supports quick actions, this will automatically assign a few labels to your Issue -->
|
|
||||||
/label ~"Feature Request" ~"Cap'n Proto API"
|
|
||||||
<!-- Note: please don't attach the "Backwards-Incompatible Change" label unless you already know for
|
|
||||||
a fact that your change *will* break the API and require a major release -->
|
|
||||||
|
|
||||||
<!-- Pings the correct group for this kind of issue -->
|
|
||||||
/cc @fabinfra/fabaccess/api-developers
|
|
||||||
|
|
||||||
<!-- vim: textwidth=100
|
|
||||||
-->
|
|
@ -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)
|
@ -43,4 +43,7 @@ struct Session {
|
|||||||
machineSystem @0 : MachineSystem;
|
machineSystem @0 : MachineSystem;
|
||||||
userSystem @1 : UserSystem;
|
userSystem @1 : UserSystem;
|
||||||
permissionSystem @2 : PermissionSystem;
|
permissionSystem @2 : PermissionSystem;
|
||||||
|
|
||||||
|
vendor @3 :AnyPointer;
|
||||||
|
# Vendor-specific APIs outside the normal API stability
|
||||||
}
|
}
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
# Use Markdown Architectural Decision Records (MADR)
|
|
||||||
|
|
||||||
## Context and Problem Statement
|
|
||||||
|
|
||||||
We want to record architectural decisions made in this project.
|
|
||||||
Which format and structure should these records follow?
|
|
||||||
|
|
||||||
## Considered Options
|
|
||||||
|
|
||||||
* [Markdown Architectural Decisions Record (MADR)](https://adr.github.io/madr/)
|
|
||||||
* Gitlab issues
|
|
||||||
* Formless – No conventions for file format and structure
|
|
||||||
|
|
||||||
## Decision Outcome
|
|
||||||
|
|
||||||
Chosen option: "Markdown Architectural Decisions Record (MADR)", because
|
|
||||||
|
|
||||||
* Markdown is an easy to write textual format requiring no tooling to be easily human readable
|
|
||||||
* Markdown is widely supported and is auto-rendered by all git hosting platforms considered
|
|
||||||
* Can be easily stored alongside the actual code and documentation since plain-text files play well with git
|
|
||||||
* Is not bound to a single hosting platform like Gitlab issues would be
|
|
||||||
* Gives a very sensible default template and format for us to use
|
|
@ -1,92 +0,0 @@
|
|||||||
# Require the use of transport encryption
|
|
||||||
|
|
||||||
* Status: accepted <!-- optional -->
|
|
||||||
* Deciders: @dequbed, @TheJoKlLa, @kjkriegel <!-- optional -->
|
|
||||||
|
|
||||||
## Context and Problem Statement
|
|
||||||
|
|
||||||
Implementers of the API should use some level of transport encryption for any
|
|
||||||
non-local communication because it's not the 2000's anymore and our crypto is
|
|
||||||
actually good, cheap and secure.
|
|
||||||
|
|
||||||
## Decision Drivers <!-- optional -->
|
|
||||||
|
|
||||||
* The software stack in question has a decent amount of security relevance, even when only used in a LAN context.
|
|
||||||
* Since most users of the API connect via WLAN and most of those are using PSK, eavesdropping is trivial
|
|
||||||
|
|
||||||
## Considered Options
|
|
||||||
|
|
||||||
* [TLS]
|
|
||||||
* [DTLS]
|
|
||||||
* [Noise protocol][noise]
|
|
||||||
|
|
||||||
## Decision Outcome
|
|
||||||
|
|
||||||
Chosen option: "TLS", because TLS overall is the easiest to implement for the
|
|
||||||
remaining stack as it currently stands and most sysadmins have a good
|
|
||||||
understanding of the PKI of TLS.
|
|
||||||
|
|
||||||
### Positive Consequences <!-- optional -->
|
|
||||||
|
|
||||||
* Reliable transport encryption is ensured
|
|
||||||
* PKI structure of TLS can easily solve the inherent trust establishment problem in a federated setting
|
|
||||||
|
|
||||||
### Negative Consequences <!-- optional -->
|
|
||||||
|
|
||||||
* Generating a trusted X.509 certificate is required for federated application incurring either monetary cost or additional setup work
|
|
||||||
* Encryption overhead is a relevant factor in ultra-low-powered devices in cases with a for that use-case badly configured server (i.e. not offering ChaCha20 and other computationally cheap algorithms)
|
|
||||||
|
|
||||||
## Pros and Cons of the Options <!-- optional -->
|
|
||||||
|
|
||||||
### TLS
|
|
||||||
|
|
||||||
Use the known and proven TLS protocol <!-- optional -->
|
|
||||||
|
|
||||||
* Good, because TLS support is ubiquitous on all platforms
|
|
||||||
* Good, because TLS allows to negotiate cipher algorithms allowing different devices to chose the cipher best suited for them
|
|
||||||
* Good, because TLS offers extensions, e.g. [ALPN] that make protocol versioning easier
|
|
||||||
* Bad, because TLS is not well suited for [SCTP] which the protocol in future wants to switch to
|
|
||||||
* Bad, because TLS is inherently very complex and has suffered from many attack vectors, best known e.g. [Heartbleed] and [Logjam] that require extra caution when configuring TLS
|
|
||||||
* Bad, because TLS' cipher negotiation (especially below version 1.3) is susceptible to downgrade attacks, especially in the case of a `STARTTLS`-style usage.
|
|
||||||
|
|
||||||
### DTLS
|
|
||||||
|
|
||||||
Use the [Datagram Transport Layer Security][DTLS] which is an IETF protocol similar to TLS but specifically designed for message-orientated protocols where message losses and reoderings have to be tolerated.
|
|
||||||
|
|
||||||
* Good, because it shares most of the advantages of TLS but also [more ergonomically works with SCTP][sctp-dtls]
|
|
||||||
* Bad, because DTLS is significantly less well supported than TLS
|
|
||||||
* Bad, because DTLS has no equivalent for TLSv1.3 which adds significant improvents over TLSv1.2 in terms of security
|
|
||||||
|
|
||||||
### Noise protocol framework
|
|
||||||
|
|
||||||
Use encryption based on Noise, a framework with support for mutual and optional authentication, identity hiding, forward secrecy, zero round-trip encryption, and other advanced features. <!-- optional -->
|
|
||||||
|
|
||||||
* Good, because it has no design for cipher negotiation making downgrade attacks impossible
|
|
||||||
* Good, because the lightweight nature of noise and the ciphers chosen means it has very limited impact compared to TLS or DTLS
|
|
||||||
* Good, because noise lends itself very well to a system where encryption keys are shared via side-channel, e.g. by scanning a QR code also containing the address to connect to.
|
|
||||||
* Bad, because platform support is very limited compared to TLS/DTLS, although the most important ones i.e. [Rust][noise-rust] (bffhd), [C#](noise-csharp) (Borepin), Python([1][noise-python1], [2][noise-python2]) (pyfabaccess) are covered.
|
|
||||||
* Bad, because noise requires more implementation work than TLS in terms of numbers of lines of code and in decisions to make.
|
|
||||||
|
|
||||||
## Links <!-- optional -->
|
|
||||||
|
|
||||||
* [Transport Layer Security (TLS)][TLS]
|
|
||||||
* [Datagram Transport Layer Security (DTLS)][DTLS]
|
|
||||||
* [Noise Protocol Framework][noise]
|
|
||||||
* [TLS Application-Layer Protocol Negotiation Extension (ALPN)][ALPN]
|
|
||||||
* [Stream Control Transmission Protocol (SCTP)][SCTP]
|
|
||||||
* [Heartbleed]
|
|
||||||
* [LogJam]
|
|
||||||
* [Datagram Transport Layer Security for Stream Control Transmission Protocol][sctp-dtls]
|
|
||||||
|
|
||||||
[TLS]: https://en.wikipedia.org/wiki/Transport_Layer_Security
|
|
||||||
[DTLS]: https://en.wikipedia.org/wiki/Datagram_Transport_Layer_Security
|
|
||||||
[noise]: http://www.noiseprotocol.org/
|
|
||||||
[ALPN]: https://datatracker.ietf.org/doc/html/rfc7301
|
|
||||||
[SCTP]: https://en.wikipedia.org/wiki/Stream_Control_Transmission_Protocol
|
|
||||||
[Heartbleed]: https://heartbleed.com/
|
|
||||||
[LogJam]: https://weakdh.org/logjam.html
|
|
||||||
[sctp-dtls]: https://datatracker.ietf.org/doc/html/rfc6083
|
|
||||||
[noise-rust]: https://github.com/mcginty/snow
|
|
||||||
[noise-csharp]: https://github.com/Metalnem/noise
|
|
||||||
[noise-python1]: https://github.com/plizonczyk/noiseprotocol
|
|
||||||
[noise-python2]: https://github.com/tgalal/dissononce
|
|
@ -1,14 +0,0 @@
|
|||||||
# Architectural Decision Log
|
|
||||||
|
|
||||||
This log lists the architectural decisions for [project name].
|
|
||||||
|
|
||||||
<!-- adrlog -- Regenerate the content by using "adr-log -i". You can install it via "npm install -g adr-log" -->
|
|
||||||
|
|
||||||
* [ADR-0000](0000-use-markdown-architectural-decision-records.md) - Use Markdown Architectural Decision Records (MADR)
|
|
||||||
* [ADR-0001](0001-require-strong-transport-encryption.md) - Require the use of transport encryption
|
|
||||||
|
|
||||||
<!-- adrlogstop -->
|
|
||||||
|
|
||||||
For new ADRs, please use [template.md](template.md) as basis.
|
|
||||||
More information on MADR is available at <https://adr.github.io/madr/>.
|
|
||||||
General information about architectural decision records is available at <https://adr.github.io/>.
|
|
@ -1,72 +0,0 @@
|
|||||||
# [short title of solved problem and solution]
|
|
||||||
|
|
||||||
* Status: [proposed | rejected | accepted | deprecated | … | superseded by [ADR-0005](0005-example.md)] <!-- optional -->
|
|
||||||
* Deciders: [list everyone involved in the decision] <!-- optional -->
|
|
||||||
* Date: [YYYY-MM-DD when the decision was last updated] <!-- optional -->
|
|
||||||
|
|
||||||
Technical Story: [description | ticket/issue URL] <!-- optional -->
|
|
||||||
|
|
||||||
## Context and Problem Statement
|
|
||||||
|
|
||||||
[Describe the context and problem statement, e.g., in free form using two to three sentences. You may want to articulate the problem in form of a question.]
|
|
||||||
|
|
||||||
## Decision Drivers <!-- optional -->
|
|
||||||
|
|
||||||
* [driver 1, e.g., a force, facing concern, …]
|
|
||||||
* [driver 2, e.g., a force, facing concern, …]
|
|
||||||
* … <!-- numbers of drivers can vary -->
|
|
||||||
|
|
||||||
## Considered Options
|
|
||||||
|
|
||||||
* [option 1]
|
|
||||||
* [option 2]
|
|
||||||
* [option 3]
|
|
||||||
* … <!-- numbers of options can vary -->
|
|
||||||
|
|
||||||
## Decision Outcome
|
|
||||||
|
|
||||||
Chosen option: "[option 1]", because [justification. e.g., only option, which meets k.o. criterion decision driver | which resolves force force | … | comes out best (see below)].
|
|
||||||
|
|
||||||
### Positive Consequences <!-- optional -->
|
|
||||||
|
|
||||||
* [e.g., improvement of quality attribute satisfaction, follow-up decisions required, …]
|
|
||||||
* …
|
|
||||||
|
|
||||||
### Negative Consequences <!-- optional -->
|
|
||||||
|
|
||||||
* [e.g., compromising quality attribute, follow-up decisions required, …]
|
|
||||||
* …
|
|
||||||
|
|
||||||
## Pros and Cons of the Options <!-- optional -->
|
|
||||||
|
|
||||||
### [option 1]
|
|
||||||
|
|
||||||
[example | description | pointer to more information | …] <!-- optional -->
|
|
||||||
|
|
||||||
* Good, because [argument a]
|
|
||||||
* Good, because [argument b]
|
|
||||||
* Bad, because [argument c]
|
|
||||||
* … <!-- numbers of pros and cons can vary -->
|
|
||||||
|
|
||||||
### [option 2]
|
|
||||||
|
|
||||||
[example | description | pointer to more information | …] <!-- optional -->
|
|
||||||
|
|
||||||
* Good, because [argument a]
|
|
||||||
* Good, because [argument b]
|
|
||||||
* Bad, because [argument c]
|
|
||||||
* … <!-- numbers of pros and cons can vary -->
|
|
||||||
|
|
||||||
### [option 3]
|
|
||||||
|
|
||||||
[example | description | pointer to more information | …] <!-- optional -->
|
|
||||||
|
|
||||||
* Good, because [argument a]
|
|
||||||
* Good, because [argument b]
|
|
||||||
* Bad, because [argument c]
|
|
||||||
* … <!-- numbers of pros and cons can vary -->
|
|
||||||
|
|
||||||
## Links <!-- optional -->
|
|
||||||
|
|
||||||
* [Link type] [Link to ADR] <!-- example: Refined by [ADR-0005](0005-example.md) -->
|
|
||||||
* … <!-- numbers of links can vary -->
|
|
@ -65,6 +65,11 @@ struct Machine {
|
|||||||
releasefortakeover @2 ();
|
releasefortakeover @2 ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prodable @16 :Prodable;
|
||||||
|
interface Prodable $CSharp.name("ProdInterface") {
|
||||||
|
prodWithData @0 (data :Data);
|
||||||
|
}
|
||||||
|
|
||||||
takeover @9 :Takeover;
|
takeover @9 :Takeover;
|
||||||
interface Takeover $CSharp.name("TakeoverInterface") {
|
interface Takeover $CSharp.name("TakeoverInterface") {
|
||||||
accept @0 ();
|
accept @0 ();
|
||||||
|
49
user.capnp
49
user.capnp
@ -44,53 +44,8 @@ struct User
|
|||||||
|
|
||||||
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user