diff options
Diffstat (limited to 'src/access/token.rs')
| -rw-r--r-- | src/access/token.rs | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/src/access/token.rs b/src/access/token.rs index d33a3fe..e7aff42 100644 --- a/src/access/token.rs +++ b/src/access/token.rs @@ -89,13 +89,16 @@ pub(crate) enum Refused { Disabled, #[error("revoked: issued before its user's tokens were")] Revoked, + #[error("its session was ended (logged out of)")] + Ended, } /// The claims of `token` if this node takes it: well formed, for `swarm`, signed by a /// 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`). +/// (`registry::User::tokens_not_before`), of a session not ended +/// (`registry::session_ended`). pub(crate) fn verify( doc: &impl ReadDoc, token: &str, @@ -150,6 +153,9 @@ pub(crate) fn verify( if claims.iat < user.tokens_not_before { return Err(Refused::Revoked); } + if registry::session_ended(doc, &claims.user, &claims.session) { + return Err(Refused::Ended); + } } Ok(claims) } @@ -290,6 +296,19 @@ mod tests { store::write_path(tx, ®istry::logouts_path("alice"), &json!(1_001)).unwrap() }); assert_eq!(verify(&doc, &token, "s", 1_500), Err(Refused::Revoked)); + // One session ended: its tokens refused, another's taken. + let session = claims_of(&token).session; + change(&mut doc, |tx| { + store::write_path(tx, ®istry::logouts_path("alice"), &json!(0)).unwrap(); + store::write_path( + tx, + ®istry::session_path("alice", &session), + &json!(10_000), + ) + .unwrap() + }); + assert_eq!(verify(&doc, &token, "s", 1_500), Err(Refused::Ended)); + assert!(verify(&doc, &issue(&key, &claims(&key)), "s", 1_500).is_ok()); alice["disabled"] = json!(true); change(&mut doc, |tx| { store::write_path(tx, ®istry::logouts_path("alice"), &json!(0)).unwrap(); |
