ecret-rotation.play-v27_2.13.0.39.source-code.RotatingSecretComponents.scala Maven / Gradle / Ivy
There is a newer version: 8.0.0-PREVIEW.fix-forgotten-CSRFTokenSigner.2024-04-03T1117.eca69ca4
Show newest versionpackage com.gu.play.secretrotation
import java.time.Clock
import java.time.Clock.systemUTC
import play.api.http._
import play.api.mvc._
import play.api.mvc.request.{DefaultRequestFactory, RequestFactory}
import play.api.{BuiltInComponentsFromContext, Configuration}
trait RotatingSecretComponents extends BuiltInComponentsFromContext {
val secretStateSupplier: SnapshotProvider
override def configuration: Configuration = {
val nonRotatingSecretOnlyUsedToSatisfyConfigChecks = secretStateSupplier.snapshot().secrets.active
super.configuration ++ Configuration("play.http.secret.key" -> nonRotatingSecretOnlyUsedToSatisfyConfigChecks)
}
override lazy val requestFactory: RequestFactory =
RotatingSecretComponents.requestFactoryFor(secretStateSupplier, httpConfiguration)
}
object RotatingSecretComponents {
def requestFactoryFor(snapshotProvider: SnapshotProvider, hc: HttpConfiguration): RequestFactory =
new DefaultRequestFactory(
new DefaultCookieHeaderEncoding(hc.cookies),
new RotatingKeySessionCookieBaker(hc.session, snapshotProvider),
new RotatingKeyFlashCookieBaker(hc.flash, snapshotProvider)
)
trait RotatingSecretCookieCodec extends CookieDataCodec {
val snapshotProvider: SnapshotProvider
val jwtConfiguration: JWTConfiguration
implicit val c: Clock = systemUTC()
private def jwtCodecFor(secret: String) = DefaultJWTCookieDataCodec(SecretConfiguration(secret), jwtConfiguration)
override def encode(data: Map[String, String]): String =
jwtCodecFor(snapshotProvider.snapshot().secrets.active).encode(data)
override def decode(data: String): Map[String, String] = {
snapshotProvider.snapshot().decode[Map[String, String]](jwtCodecFor(_).decode(data), _.nonEmpty).getOrElse(Map.empty)
}
}
class RotatingKeySessionCookieBaker(
val config: SessionConfiguration,
val snapshotProvider: SnapshotProvider) extends SessionCookieBaker with RotatingSecretCookieCodec {
override val jwtConfiguration: JWTConfiguration = config.jwt
}
class RotatingKeyFlashCookieBaker(
val config: FlashConfiguration,
val snapshotProvider: SnapshotProvider) extends FlashCookieBaker with RotatingSecretCookieCodec {
override val jwtConfiguration: JWTConfiguration = config.jwt
}
}