Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mandatory SLULA acceptance flag (#150) #152

Merged
merged 1 commit into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions config/config.minimal.hocon
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
{
# Full license text available in LICENSE.md
"license": {
"accept": true
}

"database": {
"host": "postgres"
"dbname": "igludb"
Expand Down
5 changes: 5 additions & 0 deletions config/config.reference.hocon
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
{
# Full license text available in LICENSE.md
"license": {
"accept": true
}

# Http server settings
"repoServer": {
"interface": "0.0.0.0"
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@

"iglu": {

"license": {
"accept": false
"accept": ${?ACCEPT_LIMITED_USE_LICENSE}
}

"repoServer": {
"interface": "0.0.0.0"
"port": 8080
Expand Down
33 changes: 29 additions & 4 deletions src/main/scala/com/snowplowanalytics/iglu/server/Config.scala
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ case class Config(
swagger: Config.Swagger,
superApiKey: Option[UUID],
preTerminationPeriod: FiniteDuration,
preTerminationUnhealthy: Boolean
preTerminationUnhealthy: Boolean,
license: Config.License
)

object Config {
Expand All @@ -61,9 +62,12 @@ object Config {
implicitly[Encoder[String]].contramap(_.toString)

sealed trait ThreadPool extends Product with Serializable

object ThreadPool {
case object Global extends ThreadPool
case object Cached extends ThreadPool
case object Global extends ThreadPool

case object Cached extends ThreadPool

case class Fixed(size: Int) extends ThreadPool

implicit val threadPoolReader: ConfigReader[ThreadPool] =
Expand Down Expand Up @@ -102,12 +106,15 @@ object Config {
}

sealed trait StorageConfig

object StorageConfig {

/** Frequently used HikariCP settings */
sealed trait ConnectionPool extends Product with Serializable

object ConnectionPool {
case class NoPool(threadPool: ThreadPool) extends ConnectionPool

case class Hikari(
connectionTimeout: Option[FiniteDuration],
maxLifetime: Option[FiniteDuration],
Expand Down Expand Up @@ -205,7 +212,7 @@ object Config {
* Configuration options for the Iglu server.
*
* @param interface The server's host.
* @param port The server's port.
* @param port The server's port.
*/
case class Http(
interface: String,
Expand All @@ -227,6 +234,13 @@ object Config {
implicit val hstsConfigCirceEncoder: Encoder[Hsts] =
deriveEncoder[Hsts]

case class License(
accept: Boolean
)

implicit val licenseConfigEncoder: Encoder[License] =
deriveEncoder[License]

implicit val pureWebhookReader: ConfigReader[Webhook] = ConfigReader.fromCursor { cur =>
for {
objCur <- cur.asObjectCursor
Expand Down Expand Up @@ -272,6 +286,17 @@ object Config {
} yield webhooks
}

implicit val pureLicenseReader: ConfigReader[License] = {
val truthy = Set("true", "yes", "on", "1")
ConfigReader.fromCursor { cur =>
for {
objCur <- cur.asObjectCursor
acceptCur <- objCur.atKey("accept")
value <- acceptCur.asString
} yield License(truthy(value.toLowerCase))
}
}

implicit val pureConfigReader: ConfigReader[Config] = deriveReader[Config]

implicit val mainConfigCirceEncoder: Encoder[Config] =
Expand Down
8 changes: 8 additions & 0 deletions src/main/scala/com/snowplowanalytics/iglu/server/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ object Main extends IOApp {
val cli = for {
command <- EitherT.fromEither[IO](Config.serverCommand.parse(args).leftMap(_.toString))
config <- EitherT.fromEither[IO](command.read)
_ <- EitherT.fromEither[IO](checkLicense(config))
result <- command match {
case _: Config.ServerCommand.Run =>
EitherT.liftF[IO, String, ExitCode](Server.run(config))
Expand All @@ -33,4 +34,11 @@ object Main extends IOApp {
case Left(cliError) => IO(System.err.println(cliError)).as(ExitCode.Error)
}
}

def checkLicense(config: Config): Either[String, Unit] =
if (config.license.accept) Right(())
else
Left(
"Please accept the terms of the Snowplow Limited Use License Agreement to proceed. See https://docs.snowplow.io/docs/pipeline-components-and-applications/iglu/iglu-repositories/iglu-server/reference/#license for more information on the license and how to configure this."
)
}
3 changes: 3 additions & 0 deletions src/test/resources/valid-dummy-config.conf
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
# OF THE SOFTWARE, YOU AGREE TO THE TERMS OF SUCH LICENSE AGREEMENT.

# This file (application.conf) contains all necessary configuration options for the Iglu Server.
license {
accept = yes
}

# 'repoServer' contains configuration options for the repoServer -
# interface and port on which the server will be running
Expand Down
17 changes: 12 additions & 5 deletions src/test/scala/com/snowplowanalytics/iglu/server/ConfigSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ class ConfigSpec extends org.specs2.Specification {
Config.Swagger("/custom/prefix"),
None,
42.seconds,
true
true,
Config.License(false)
)
val result = Config.serverCommand.parse(input.split(" ").toList).leftMap(_.toString).flatMap(_.read)
result must beRight(expected)
Expand All @@ -104,7 +105,8 @@ class ConfigSpec extends org.specs2.Specification {
Config.Swagger(""),
None,
1.seconds,
false
false,
Config.License(true)
)
val result = Config.serverCommand.parse(input.split(" ").toList).leftMap(_.toString).flatMap(_.read)
result must beRight(expected)
Expand Down Expand Up @@ -139,7 +141,8 @@ class ConfigSpec extends org.specs2.Specification {
Config.Swagger("/custom/prefix"),
Some(UUID.fromString("a71aa7d9-6cde-40f7-84b1-046d65dedf9e")),
10.seconds,
true
true,
Config.License(true)
)

val expected = json"""{
Expand Down Expand Up @@ -199,7 +202,10 @@ class ConfigSpec extends org.specs2.Specification {
},
"superApiKey": "******",
"preTerminationPeriod": "10 seconds",
"preTerminationUnhealthy": true
"preTerminationUnhealthy": true,
"license": {
"accept": true
}
}"""

input.asJson must beEqualTo(expected)
Expand Down Expand Up @@ -231,7 +237,8 @@ class ConfigSpec extends org.specs2.Specification {
Config.Swagger(""),
None,
1.seconds,
false
false,
Config.License(false)
)
val result = Config.serverCommand.parse(input.split(" ").toList).leftMap(_.toString).flatMap(_.read)
result must beRight(expected)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,18 @@ object ServerSpec {
true
)
def config(hsts: Config.Hsts) =
Config(storageConfig, httpConfig(hsts), false, true, Nil, Config.Swagger(""), None, 10.seconds, false)
Config(
storageConfig,
httpConfig(hsts),
false,
true,
Nil,
Config.Swagger(""),
None,
10.seconds,
false,
Config.License(true)
)

private def runServer(hsts: Config.Hsts) = Server.buildServer(config(hsts), IO.pure(true)).flatMap(_.resource)
private val client = BlazeClientBuilder[IO](global).resource
Expand Down
Loading