fix(cognito): keep revoked tokens across restarts #5
@@ -3,13 +3,19 @@ package io.github.hectorvent.floci.services.cognito.model;
|
|||||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Information about a revoked token for tracking and validation purposes.
|
* Information about a revoked token for tracking and validation purposes.
|
||||||
* Used to implement AWS Cognito AdminUserGlobalSignOut token revocation behavior.
|
* Used to implement AWS Cognito AdminUserGlobalSignOut token revocation behavior.
|
||||||
|
*
|
||||||
|
* <p>{@code expired} is derived from {@code expiresAt}, so it is not stored. Files written before
|
||||||
|
* that still carry it, and are read with it ignored instead of being discarded as corrupt.
|
||||||
*/
|
*/
|
||||||
@RegisterForReflection
|
@RegisterForReflection
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public class RevokedTokenInfo {
|
public class RevokedTokenInfo {
|
||||||
|
|
||||||
private final String jti;
|
private final String jti;
|
||||||
@@ -62,6 +68,7 @@ public class RevokedTokenInfo {
|
|||||||
/**
|
/**
|
||||||
* Check if this revocation record has expired and can be cleaned up.
|
* Check if this revocation record has expired and can be cleaned up.
|
||||||
*/
|
*/
|
||||||
|
@JsonIgnore
|
||||||
public boolean isExpired() {
|
public boolean isExpired() {
|
||||||
return System.currentTimeMillis() / 1000L > expiresAt;
|
return System.currentTimeMillis() / 1000L > expiresAt;
|
||||||
}
|
}
|
||||||
|
|||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
package io.github.hectorvent.floci.services.cognito;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import io.github.hectorvent.floci.services.cognito.model.RevokedTokenInfo;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
|
||||||
|
/** Revoked tokens must survive a restart, which reads them back with a strict ObjectMapper. */
|
||||||
|
class RevokedTokenInfoPersistenceTest {
|
||||||
|
|
||||||
|
private static final TypeReference<Map<String, RevokedTokenInfo>> TYPE = new TypeReference<>() {
|
||||||
|
};
|
||||||
|
private final ObjectMapper strictMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void roundTripsWithoutTheDerivedExpiredField() throws Exception {
|
||||||
|
RevokedTokenInfo info = new RevokedTokenInfo("jti-1", "refresh", "alice", "us-east-1_pool", 1_000L, 4_102_444_800L);
|
||||||
|
|
||||||
|
String json = strictMapper.writeValueAsString(Map.of("k", info));
|
||||||
|
RevokedTokenInfo read = strictMapper.readValue(json, TYPE).get("k");
|
||||||
|
|
||||||
|
assertFalse(json.contains("\"expired\""), json);
|
||||||
|
assertEquals("jti-1", read.getJti());
|
||||||
|
assertEquals(4_102_444_800L, read.getExpiresAt());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void readsFilesWrittenWithTheExpiredField() throws Exception {
|
||||||
|
String saved = """
|
||||||
|
{"000000000000/revoked:us-east-1_pool:jti-1":{"jti":"jti-1","tokenType":"refresh","username":"alice",
|
||||||
|
"userPoolId":"us-east-1_pool","revokedAt":1792858112669,"expiresAt":1824394112,"expired":false}}
|
||||||
|
""";
|
||||||
|
|
||||||
|
RevokedTokenInfo read = strictMapper.readValue(saved, TYPE).get("000000000000/revoked:us-east-1_pool:jti-1");
|
||||||
|
|
||||||
|
assertEquals("alice", read.getUsername());
|
||||||
|
assertEquals(1824394112L, read.getExpiresAt());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user