Skip to content

Commit

Permalink
Merge pull request #411 from guardian/support-scala-3-and-play-3
Browse files Browse the repository at this point in the history
Support Scala 3 & Play 3 - drop oldest Play & Scala versions
  • Loading branch information
rtyley authored Nov 8, 2023
2 parents 4bb38f1 + 22528d1 commit 70900eb
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.gu.play.secretrotation.aws.parameterstore
import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagement
import com.amazonaws.services.simplesystemsmanagement.model.GetParametersRequest

import scala.collection.JavaConverters._
import scala.jdk.CollectionConverters._

case class AwsSdkV1(ssmClient: AWSSimpleSystemsManagement) extends MinimalAwsSdkWrapper {
override def fetchValues(parameters: Seq[String]): Iterable[ParameterValue] = ssmClient.getParameters(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.gu.play.secretrotation.aws.parameterstore

import software.amazon.awssdk.services.ssm.SsmClient

import scala.collection.JavaConverters._
import scala.jdk.CollectionConverters._

case class AwsSdkV2(ssmClient: SsmClient) extends MinimalAwsSdkWrapper{
override def fetchValues(parameters: Seq[String]): Iterable[ParameterValue] = ssmClient.getParameters(
Expand Down
37 changes: 21 additions & 16 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import ReleaseTransformations._

lazy val baseSettings = Seq(
scalaVersion := "2.12.18",
scalaVersion := "2.13.11",
organization := "com.gu.play-secret-rotation",
licenses := Seq("Apache-2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0")),
scalacOptions ++= Seq("-deprecation", "-Xlint", "-unchecked"),
scalacOptions ++= Seq("-deprecation", "-unchecked"),
Test / testOptions +=
Tests.Argument(TestFrameworks.ScalaTest,"-u", s"test-results/scala-${scalaVersion.value}")
)

lazy val crossCompileScala213 = crossScalaVersions := Seq(scalaVersion.value, "2.13.11")
lazy val crossCompileScala3 = crossScalaVersions := Seq(scalaVersion.value, "3.3.1")

// Until all dependencies are on scala-java8-compat v1.x, this avoids unnecessary fatal eviction errors
ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-java8-compat" % VersionScheme.Always

lazy val core =
project.settings(crossCompileScala213, baseSettings).settings(
project.settings(crossCompileScala3, baseSettings).settings(
libraryDependencies ++= Seq(
"com.github.blemale" %% "scaffeine" % "5.2.1",
"com.typesafe.scala-logging" %% "scala-logging" % "3.9.5",
Expand All @@ -25,7 +25,7 @@ lazy val core =
)

lazy val `aws-parameterstore-secret-supplier-base` =
project.in(file("aws-parameterstore/secret-supplier")).settings(crossCompileScala213, baseSettings).dependsOn(core)
project.in(file("aws-parameterstore/secret-supplier")).settings(crossCompileScala3, baseSettings).dependsOn(core)

val awsSdkForVersion = Map(
1 -> "com.amazonaws" % "aws-java-sdk-ssm" % "1.12.513",
Expand All @@ -34,47 +34,52 @@ val awsSdkForVersion = Map(

def awsParameterStoreWithSdkVersion(version: Int)=
Project(s"aws-parameterstore-sdk-v$version", file(s"aws-parameterstore/secret-supplier/aws-sdk-v$version"))
.settings(crossCompileScala213, baseSettings)
.settings(crossCompileScala3, baseSettings)
.dependsOn(`aws-parameterstore-secret-supplier-base`)
.settings(libraryDependencies += awsSdkForVersion(version))

lazy val `aws-parameterstore-sdk-v1` = awsParameterStoreWithSdkVersion(1)
lazy val `aws-parameterstore-sdk-v2` = awsParameterStoreWithSdkVersion(2)

lazy val `aws-parameterstore-lambda` = project.in(file("aws-parameterstore/lambda"))
.settings(crossCompileScala213, baseSettings).dependsOn(`secret-generator`).settings(
.settings(crossCompileScala3, baseSettings).dependsOn(`secret-generator`).settings(
libraryDependencies ++= Seq(
"com.amazonaws" % "aws-lambda-java-core" % "1.2.2",
"com.amazonaws" % "aws-lambda-java-events" % "3.11.2",
awsSdkForVersion(1)
)
)

lazy val `secret-generator` = project.settings(crossCompileScala213, baseSettings)
lazy val `secret-generator` = project.settings(crossCompileScala3, baseSettings)

val exactPlayVersions = Map(
"26" -> "2.6.25",
"27" -> "2.7.9",
"28" -> "2.8.20"
"27" -> "com.typesafe.play" %% "play" % "2.7.9",
"28" -> "com.typesafe.play" %% "play" % "2.8.20",
"29" -> "com.typesafe.play" %% "play" % "2.9.0",
"30" -> "org.playframework" %% "play" % "3.0.0"
)

def playVersion(majorMinorVersion: String)= {
Project(s"play-v$majorMinorVersion", file(s"play/play-v$majorMinorVersion"))
.settings(baseSettings)
.dependsOn(core)
.settings(libraryDependencies += "com.typesafe.play" %% "play" % exactPlayVersions(majorMinorVersion))
.settings(libraryDependencies += exactPlayVersions(majorMinorVersion))
}

lazy val `play-v26` = playVersion("26")
lazy val `play-v27` = playVersion("27").settings(crossCompileScala213)
lazy val `play-v28` = playVersion("28").settings(crossCompileScala213)

lazy val `play-v27` = playVersion("27")
lazy val `play-v28` = playVersion("28")
lazy val `play-v29` = playVersion("29").settings(crossCompileScala3)
lazy val `play-v30` = playVersion("30").settings(crossCompileScala3)


lazy val `play-secret-rotation-root` = (project in file("."))
.aggregate(
core,
`play-v26`,
`play-v27`,
`play-v28`,
`play-v29`,
`play-v30`,
`aws-parameterstore-secret-supplier-base`,
`aws-parameterstore-sdk-v1`,
`aws-parameterstore-sdk-v2`,
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/com/gu/play/secretrotation/Phase.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ trait Phase[T] {

final def onlyAcceptsActive = alsoAccepted.isEmpty

final def accepted: Stream[T] = Stream(active) ++ alsoAccepted
final def accepted: LazyList[T] = LazyList(active) ++ alsoAccepted

def map[S](f: T => S): Phase[S] = {
val activeS = f(active)
Expand All @@ -36,6 +36,6 @@ case class PhaseSchedule[T](initialPhase: Phase[T], phaseStarts: (Instant, Phase
val phasesByStart = SortedMap(phaseStarts: _*)

def phaseAt(instant: Instant): Phase[T] =
phasesByStart.until(instant).values.lastOption.getOrElse(initialPhase)
phasesByStart.rangeUntil(instant).values.lastOption.getOrElse(initialPhase)

}
62 changes: 0 additions & 62 deletions play/play-v26/RotatingSecretComponents.scala

This file was deleted.

1 change: 0 additions & 1 deletion play/play-v27/RotatingSecretComponents.scala

This file was deleted.

62 changes: 62 additions & 0 deletions play/play-v27/RotatingSecretComponents.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package 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
}
}
1 change: 1 addition & 0 deletions play/play-v29/RotatingSecretComponents.scala
1 change: 1 addition & 0 deletions play/play-v30/RotatingSecretComponents.scala
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=1.9.3
sbt.version=1.9.7

0 comments on commit 70900eb

Please sign in to comment.