in core/src/main/scala/com/gu/play/secretrotation/DualSecretTransition.scala [63:102]
def snapshot(): SecretsSnapshot = {
val snapshotTime = clock.instant()
val snapshotBestBefore = snapshotTime.plus(permittedSnapshotStaleness)
val phase = phaseSchedule.phaseAt(snapshotTime)
new SecretsSnapshot {
override def secrets: Phase[String] = phase.map(secretsByAge)
override def description: String = phase match {
case Upcoming =>
s"upcoming transition between old and new secrets in ${Duration.between(snapshotTime, overlapInterval.getStart)} at ${overlapInterval.getStart}"
case InProgress =>
s"transition between old and new secrets in progress (during $overlapInterval)"
case Completed =>
s"transition to latest secret completed at ${overlapInterval.getEnd}"
}
/**
* Want to know:
* If decoding was successful, but with a legacy secret (especially if we are towards the end of the overlap period)
*/
override def decode[T](decodingFunc: String => T, conclusiveDecode: T => Boolean): Option[T] = {
if (clock.instant() > snapshotBestBefore)
logger.warn("Don't hold onto snapshots! Get a new snapshot with each user interaction.")
(for {
secret <- secrets.accepted
decodedValue = decodingFunc(secret)
if conclusiveDecode(decodedValue)
} yield {
if (secret != secrets.active) {
val message = s"Accepted decode with non-active key : $description"
if (clock.instant() > warningThreshold) logger.warn(message) else logger.debug(message)
}
decodedValue
}).headOption
}
}
}