aboutsummaryrefslogtreecommitdiffstats
path: root/src/access/token.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/access/token.rs')
-rw-r--r--src/access/token.rs18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/access/token.rs b/src/access/token.rs
index 3af8672..d33a3fe 100644
--- a/src/access/token.rs
+++ b/src/access/token.rs
@@ -75,6 +75,8 @@ pub(crate) enum Refused {
OtherSwarm,
#[error("issued by a node that isn't a member here (not yet, or no longer)")]
UnknownIssuer,
+ #[error("issued by a node the swarm banned")]
+ BannedIssuer,
#[error("its signature doesn't hold")]
BadSignature,
#[error("expired")]
@@ -90,7 +92,7 @@ pub(crate) enum Refused {
}
/// The claims of `token` if this node takes it: well formed, for `swarm`, signed by a
-/// node that is a member in `doc`, not expired at `now` (Unix ms), nor issued later
+/// node that is a member in `doc` and not banned, not expired at `now` (Unix ms), nor issued later
/// than a clock off by `SKEW_MS` would; and in a swarm with a registry, for a
/// registered user that is enabled, issued after its tokens were last revoked
/// (`registry::User::tokens_not_before`).
@@ -126,6 +128,9 @@ pub(crate) fn verify(
if !member {
return Err(Refused::UnknownIssuer);
}
+ if super::bans::banned(doc, &claims.issuer) {
+ return Err(Refused::BannedIssuer);
+ }
let mut signed = LABEL.to_vec();
signed.extend_from_slice(&payload);
if !identity::verify(&key, &signed, &signature) {
@@ -236,6 +241,17 @@ mod tests {
verify(&doc, &forged, "s", 1_500),
Err(Refused::BadSignature)
);
+ // By a member banned since.
+ let token = issue(&key, &claims(&key));
+ let ban = crate::access::bans::path(&key.id());
+ let mut banned = doc.fork();
+ change(&mut banned, |tx| {
+ store::write_path(tx, &ban, &json!({"reason": "lost"})).unwrap()
+ });
+ assert_eq!(
+ verify(&banned, &token, "s", 1_500),
+ Err(Refused::BannedIssuer)
+ );
// Changed claims, the signature kept.
let token = issue(&key, &claims(&key));
let (_, signature) = token.rsplit_once('.').unwrap();