[java-opensaml] branch main updated: Add additional APIs and tests for putting content in revocation records.
Scott Cantor
cantor.2 at osu.edu
Thu Jul 21 19:03:13 UTC 2022
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository java-opensaml.
View the commit online:
http://git.shibboleth.net/view/?p=java-opensaml.git;a=commit;h=b930c41f78b3a1687cdb5e7c1dd4caa313c7cc24
The following commit(s) were added to refs/heads/main by this push:
new b930c41f7 Add additional APIs and tests for putting content in revocation records.
b930c41f7 is described below
commit b930c41f78b3a1687cdb5e7c1dd4caa313c7cc24
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Thu Jul 21 15:02:17 2022 -0400
Add additional APIs and tests for putting content in revocation records.
---
.../java/org/opensaml/storage/RevocationCache.java | 72 +++++++++++++++++++++-
.../opensaml/storage/impl/RevocationCacheTest.java | 27 +++++---
2 files changed, 88 insertions(+), 11 deletions(-)
diff --git a/opensaml-storage-api/src/main/java/org/opensaml/storage/RevocationCache.java b/opensaml-storage-api/src/main/java/org/opensaml/storage/RevocationCache.java
index 5a0393f61..b4e0c7f7c 100644
--- a/opensaml-storage-api/src/main/java/org/opensaml/storage/RevocationCache.java
+++ b/opensaml-storage-api/src/main/java/org/opensaml/storage/RevocationCache.java
@@ -22,6 +22,7 @@ import java.time.Duration;
import java.time.Instant;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
@@ -156,6 +157,26 @@ public class RevocationCache extends AbstractIdentifiableInitializableComponent
*/
public synchronized boolean revoke(@Nonnull @NotEmpty final String context, @Nonnull @NotEmpty final String s,
@Nonnull final Duration exp) {
+ return revoke(context, s, "y", exp);
+ }
+
+ /**
+ * Returns true if the value is successfully revoked.
+ *
+ * <p>If the key has already been revoked, expiration is updated.</p>
+ *
+ * @param context a context label to subdivide the cache
+ * @param s value to revoke
+ * @param value value to insert into revocation record
+ * @param exp entry expiration
+ *
+ * @return true if value has successfully been listed as revoked in the cache
+ *
+ * @since 4.3.0
+ */
+ public synchronized boolean revoke(@Nonnull @NotEmpty final String context, @Nonnull @NotEmpty final String s,
+ @Nonnull @NotEmpty final String value, @Nonnull final Duration exp) {
+
final String key;
final StorageCapabilities caps = storage.getCapabilities();
@@ -172,11 +193,11 @@ public class RevocationCache extends AbstractIdentifiableInitializableComponent
if (entry == null) {
log.debug("Entry '{}' of context '{}' is not yet on list of revoked entries,"
+ " adding to cache with expiration time {}", key, context, expires);
- storage.create(context, key, "y", Instant.now().plus(exp).toEpochMilli());
+ storage.create(context, key, value, Instant.now().plus(exp).toEpochMilli());
return true;
}
- storage.update(context, key, "y", Instant.now().plus(exp).toEpochMilli());
+ storage.updateExpiration(context, key, Instant.now().plus(exp).toEpochMilli());
log.debug("Entry '{}' of context '{}' was already revoked, updating expiration", key, context);
return true;
} catch (final IOException e) {
@@ -221,4 +242,51 @@ public class RevocationCache extends AbstractIdentifiableInitializableComponent
}
}
+ /**
+ * Attempts to read back a revocation record for a given context and key.
+ *
+ * <p>This alternative approach allows revocation records to include richer data,
+ * rather than simple presence/absence as a signal.</p>
+ *
+ * @param context revocation context
+ * @param s revocation key
+ *
+ * @return the matching record, if found, or null if absent
+ *
+ * @throws IOException raised if an error occurs leading to an indeterminate result
+ *
+ * @since 4.3.0
+ */
+ @Nullable @NotEmpty public synchronized String getRevocationRecord(@Nonnull @NotEmpty final String context,
+ @Nonnull @NotEmpty final String s) throws IOException {
+ final String key;
+ final StorageCapabilities caps = storage.getCapabilities();
+ if (context.length() > caps.getContextSize()) {
+ log.error("context {} too long for StorageService (limit {})", context, caps.getContextSize());
+ throw new IOException("Context exceeded storage service limit.");
+ } else if (s.length() > caps.getKeySize()) {
+ key = DigestUtils.sha1Hex(s);
+ } else {
+ key = s;
+ }
+
+ try {
+ final StorageRecord<?> entry = storage.read(context, key);
+ if (entry == null) {
+ log.debug("Entry '{}' is not revoked", key);
+ return null;
+ }
+
+ log.debug("Entry '{}' is revoked", s);
+ return entry.getValue();
+ } catch (final IOException e) {
+ if (strict) {
+ throw e;
+ }
+
+ log.error("Exception reading from storage service, non-strict so treating as non-revoked", e);
+ return null;
+ }
+ }
+
}
\ No newline at end of file
diff --git a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/RevocationCacheTest.java b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/RevocationCacheTest.java
index b2e27fa76..f245c83a4 100644
--- a/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/RevocationCacheTest.java
+++ b/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/RevocationCacheTest.java
@@ -17,6 +17,7 @@
package org.opensaml.storage.impl;
+import java.io.IOException;
import java.nio.charset.Charset;
import java.time.Duration;
import java.util.Random;
@@ -36,17 +37,17 @@ import org.opensaml.storage.RevocationCache;
* Tests for {@link RevocationCache}
*/
public class RevocationCacheTest {
-
private MemoryStorageService storageService;
private RevocationCache revocationCache;
@BeforeMethod
- protected void setUp() throws Exception {
+ protected void setUp() throws ComponentInitializationException {
storageService = new MemoryStorageService();
storageService.setId("test");
+ storageService.setCleanupInterval(Duration.ZERO);
storageService.initialize();
revocationCache = new RevocationCache();
@@ -58,10 +59,7 @@ public class RevocationCacheTest {
@AfterMethod
protected void tearDown() {
revocationCache.destroy();
- revocationCache = null;
-
storageService.destroy();
- storageService = null;
}
@Test
@@ -93,19 +91,19 @@ public class RevocationCacheTest {
}
@Test (expectedExceptions = ConstraintViolationException.class)
- public void testExpirationSetter() throws ComponentInitializationException {
+ public void testExpirationSetter() {
//Must be positive
revocationCache = new RevocationCache();
revocationCache.setEntryExpiration(Duration.ZERO);
}
@Test
- public void testStorageGetter() throws ComponentInitializationException {
+ public void testStorageGetter() {
Assert.assertEquals(storageService, revocationCache.getStorage());
}
@Test
- public void testRevocationSuccess() throws ComponentInitializationException {
+ public void testRevocationSuccess() {
Assert.assertFalse(revocationCache.isRevoked("context", "item"));
Assert.assertTrue(revocationCache.revoke("context", "item"));
Assert.assertTrue(revocationCache.isRevoked("context", "item"));
@@ -116,6 +114,7 @@ public class RevocationCacheTest {
storageService = new MemoryStorageService();
storageService.setId("test");
storageService.setContextSize(50);
+ storageService.setCleanupInterval(Duration.ZERO);
storageService.initialize();
revocationCache = new RevocationCache();
@@ -134,6 +133,7 @@ public class RevocationCacheTest {
public void testRevocationSuccessLongLongItem() throws ComponentInitializationException {
storageService = new MemoryStorageService();
storageService.setId("test");
+ storageService.setCleanupInterval(Duration.ZERO);
storageService.setKeySize(50);
storageService.initialize();
revocationCache = new RevocationCache();
@@ -149,7 +149,7 @@ public class RevocationCacheTest {
}
@Test
- public void testRevocationExpirationSuccess() throws ComponentInitializationException, InterruptedException {
+ public void testRevocationExpirationSuccess() throws InterruptedException {
//Test expiration of entry (500ms)
Assert.assertFalse(revocationCache.isRevoked("context", "item"));
Assert.assertTrue(revocationCache.revoke("context", "item"));
@@ -162,4 +162,13 @@ public class RevocationCacheTest {
Thread.sleep(300L);
Assert.assertTrue(revocationCache.isRevoked("context", "item"));
}
+
+ @Test
+ public void testRevokedRecordFetch() throws IOException {
+ Assert.assertTrue(revocationCache.revoke("context", "item", "value", Duration.ofHours(1)));
+ Assert.assertNull(revocationCache.getRevocationRecord("context", "item2"));
+ Assert.assertEquals(revocationCache.getRevocationRecord("context", "item"), "value");
+
+ }
+
}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list