Browse Source

Fixed coverage

Efren Yevale Varela 2 weeks ago
parent
commit
b22910c790
1 changed files with 41 additions and 14 deletions
  1. 41 14
      src/protocol/token/grants/refresh_token/tests/jwt.rs

+ 41 - 14
src/protocol/token/grants/refresh_token/tests/jwt.rs

@@ -267,10 +267,44 @@ async fn jwt_discard_orphan_deletes_marker_by_key() -> TestResult {
   Ok(())
 }
 
+/// Every live `jwt:` marker key bound to `grant_id`.
+///
+/// A marker is a hash carrying a `grant_id` field, so filtering on that field
+/// scopes the snapshot to this grant. Required because every lib test in one
+/// `cargo test` process shares the same testcontainers Redis and runs
+/// concurrently: a bare `KEYS` diff would attribute other tests' markers to
+/// this failed rotation.
+async fn grant_marker_keys(
+  conn: &mut crate::state::RedisConn,
+  store: &crate::store::Store,
+  grant_id: &str,
+) -> Result<Vec<String>, TestError> {
+  let pattern = format!("{}*", store.jwt_marker_key(""));
+  let keys: Vec<String> = redis::cmd("KEYS").arg(&pattern).query_async(conn).await?;
+  let mut owned = Vec::new();
+  for key in keys {
+    let fields: Vec<String> = redis::cmd("HGETALL").arg(&key).query_async(conn).await?;
+    let mut bound = false;
+    let mut rest = fields.as_slice();
+    while let [field, value, tail @ ..] = rest {
+      if field == "grant_id" && value == grant_id {
+        bound = true;
+        break;
+      }
+      rest = tail;
+    }
+    if bound {
+      owned.push(key);
+    }
+  }
+  owned.sort();
+  Ok(owned)
+}
+
 /// A REUSE rotation for a JWT client leaves no live `jwt:` marker for the
-/// discarded pre-mint: the `jwt:` key set after the failed rotation holds no
-/// key beyond the committed pair's own marker, and the attempt is
-/// `invalid_grant` with no tokens.
+/// discarded pre-mint: the grant-scoped `jwt:` key set after the failed
+/// rotation holds no key beyond the committed pair's own marker, and the
+/// attempt is `invalid_grant` with no tokens.
 #[tokio::test]
 async fn jwt_failed_rotation_leaves_no_marker() -> TestResult {
   let (_container, mut conn, store, _url) = test_redis().await?;
@@ -320,15 +354,12 @@ async fn jwt_failed_rotation_leaves_no_marker() -> TestResult {
       "a rotated jwt access token must stay a JWT".to_owned(),
     ));
   }
-  // Snapshot the `jwt:` key set: the initial mint's marker and the
+  // Snapshot this grant's `jwt:` marker set: the initial mint's marker and the
   // committed pair's marker both legitimately exist (the cascade does not
   // purge markers until Todo 27), so the invariant is that the failed
   // rotation ADDS nothing.
-  let mut before: Vec<String> = redis::cmd("KEYS")
-    .arg("oauth:{state}:jwt:*")
-    .query_async(&mut conn)
-    .await?;
-  before.sort();
+  let grant_id = old.record.grant_id.clone();
+  let before = grant_marker_keys(&mut conn, &store, &grant_id).await?;
   if !before.contains(&committed_marker) {
     return Err(TestError::Unexpected(format!(
       "committed marker must exist before reuse, saw {before:?}"
@@ -361,11 +392,7 @@ async fn jwt_failed_rotation_leaves_no_marker() -> TestResult {
       error.code()
     )));
   }
-  let mut after: Vec<String> = redis::cmd("KEYS")
-    .arg("oauth:{state}:jwt:*")
-    .query_async(&mut conn)
-    .await?;
-  after.sort();
+  let after = grant_marker_keys(&mut conn, &store, &grant_id).await?;
   let added: Vec<&String> = after.iter().filter(|key| !before.contains(key)).collect();
   if !added.is_empty() {
     return Err(TestError::Unexpected(format!(