From 3ea15af41ad35067c93f4c3535f0c9950233bc15 Mon Sep 17 00:00:00 2001 From: Rahul Rudragoudar Date: Mon, 29 Mar 2021 15:26:59 +0530 Subject: [PATCH 1/9] Add attributes enum Signed-off-by: Rahul Rudragoudar --- src/main/scala/lc/core/captchaFields.scala | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/scala/lc/core/captchaFields.scala b/src/main/scala/lc/core/captchaFields.scala index 5418ee9..34c7b8a 100644 --- a/src/main/scala/lc/core/captchaFields.scala +++ b/src/main/scala/lc/core/captchaFields.scala @@ -10,6 +10,15 @@ object ParametersEnum extends Enumeration { val ALLOWEDLEVELS: Value = Value("allowedLevels") val ALLOWEDMEDIA: Value = Value("allowedMedia") val ALLOWEDINPUTTYPE: Value = Value("allowedInputType") + + val NAME: Value = Value("name") + val RANDOM_SEED: Value = Value("randomSeed") + val PORT: Value = Value("port") + val CAPTCHA_EXPIRY_TIME_LIMIT: Value = Value("captchaExpiryTimeLimit") + val THROTTLE: Value = Value("throttle") + val THREAD_DELAY: Value = Value("threadDelay") + val CONFIG: Value = Value("config") + } object ResultEnum extends Enumeration { From 30f152f7ec86f77042315f6b14b917b5500db366 Mon Sep 17 00:00:00 2001 From: Rahul Rudragoudar Date: Mon, 29 Mar 2021 15:28:28 +0530 Subject: [PATCH 2/9] Minor update Signed-off-by: Rahul Rudragoudar --- src/main/scala/lc/core/captchaFields.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/scala/lc/core/captchaFields.scala b/src/main/scala/lc/core/captchaFields.scala index 34c7b8a..82eb89f 100644 --- a/src/main/scala/lc/core/captchaFields.scala +++ b/src/main/scala/lc/core/captchaFields.scala @@ -11,6 +11,11 @@ object ParametersEnum extends Enumeration { val ALLOWEDMEDIA: Value = Value("allowedMedia") val ALLOWEDINPUTTYPE: Value = Value("allowedInputType") +} + +object AttributesEnum extends Enumeration { + type Attribute = Value + val NAME: Value = Value("name") val RANDOM_SEED: Value = Value("randomSeed") val PORT: Value = Value("port") @@ -18,7 +23,6 @@ object ParametersEnum extends Enumeration { val THROTTLE: Value = Value("throttle") val THREAD_DELAY: Value = Value("threadDelay") val CONFIG: Value = Value("config") - } object ResultEnum extends Enumeration { From fe8bf54196d758ea01fcf561bf87ce511090a22a Mon Sep 17 00:00:00 2001 From: Rahul Rudragoudar Date: Mon, 29 Mar 2021 15:29:21 +0530 Subject: [PATCH 3/9] Config fallback support Signed-off-by: Rahul Rudragoudar --- src/main/scala/lc/core/config.scala | 73 +++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 9 deletions(-) diff --git a/src/main/scala/lc/core/config.scala b/src/main/scala/lc/core/config.scala index 2bf02be..0538e25 100644 --- a/src/main/scala/lc/core/config.scala +++ b/src/main/scala/lc/core/config.scala @@ -2,23 +2,37 @@ package lc.core import scala.io.Source.fromFile import org.json4s.{DefaultFormats, JValue, JObject, JField, JString} -import org.json4s.jackson.JsonMethods.parse +import org.json4s.jackson.JsonMethods.{parse, render, pretty} +import org.json4s.JsonDSL._ +import java.io.{FileNotFoundException, File, PrintWriter} object Config { implicit val formats: DefaultFormats.type = DefaultFormats - private val configFile = fromFile("config.json") + private val configFilePath = "data/config.json" private val configString = - try configFile.mkString - finally configFile.close + try { + val configFile = fromFile(configFilePath) + val configFileContent = configFile.mkString + configFile.close + configFileContent + } catch { + case _: FileNotFoundException => + val configFileContent = getDefaultConfig() + val configFile = new PrintWriter(new File(configFilePath)) + configFile.write(configFileContent) + configFile.close + configFileContent + } + private val configJson = parse(configString) - val port: Int = (configJson \ "port").extract[Int] - val throttle: Int = (configJson \ "throttle").extract[Int] - val seed: Int = (configJson \ "randomSeed").extract[Int] - val captchaExpiryTimeLimit: Int = (configJson \ "captchaExpiryTimeLimit").extract[Int] - val threadDelay: Int = (configJson \ "threadDelay").extract[Int] + val port: Int = (configJson \ AttributesEnum.PORT.toString).extract[Int] + val throttle: Int = (configJson \ AttributesEnum.THROTTLE.toString).extract[Int] + val seed: Int = (configJson \ AttributesEnum.RANDOM_SEED.toString).extract[Int] + val captchaExpiryTimeLimit: Int = (configJson \ AttributesEnum.CAPTCHA_EXPIRY_TIME_LIMIT.toString).extract[Int] + val threadDelay: Int = (configJson \ AttributesEnum.THREAD_DELAY.toString).extract[Int] private val captchaConfigJson = (configJson \ "captchas") val captchaConfigTransform: JValue = captchaConfigJson transformField { @@ -45,4 +59,45 @@ object Config { valueSet } + private def getDefaultConfig(): String = { + val defaultConfigMap = + (AttributesEnum.RANDOM_SEED.toString -> 20) ~ + (AttributesEnum.PORT.toString -> 8888) ~ + (AttributesEnum.CAPTCHA_EXPIRY_TIME_LIMIT.toString -> 5) ~ + (AttributesEnum.THROTTLE.toString -> 10) ~ + (AttributesEnum.THREAD_DELAY.toString -> 2) ~ + ("captchas" -> List( + ( + (AttributesEnum.NAME.toString -> "FilterChallenge") ~ + (ParametersEnum.ALLOWEDLEVELS.toString -> List("medium", "hard")) ~ + (ParametersEnum.ALLOWEDMEDIA.toString -> List("image/png")) ~ + (ParametersEnum.ALLOWEDINPUTTYPE.toString -> List("text")) ~ + (AttributesEnum.CONFIG.toString -> JObject()) + ), + ( + (AttributesEnum.NAME.toString -> "GifCaptcha") ~ + (ParametersEnum.ALLOWEDLEVELS.toString -> List("hard")) ~ + (ParametersEnum.ALLOWEDMEDIA.toString -> List("image/gif")) ~ + (ParametersEnum.ALLOWEDINPUTTYPE.toString -> List("text")) ~ + (AttributesEnum.CONFIG.toString -> JObject()) + ), + ( + (AttributesEnum.NAME.toString -> "ShadowTextCaptcha") ~ + (ParametersEnum.ALLOWEDLEVELS.toString -> List("easy")) ~ + (ParametersEnum.ALLOWEDMEDIA.toString -> List("image/png")) ~ + (ParametersEnum.ALLOWEDINPUTTYPE.toString -> List("text")) ~ + (AttributesEnum.CONFIG.toString -> JObject()) + ), + ( + (AttributesEnum.NAME.toString -> "RainDropsCaptcha") ~ + (ParametersEnum.ALLOWEDLEVELS.toString -> List("easy", "medium")) ~ + (ParametersEnum.ALLOWEDMEDIA.toString -> List("image/gif")) ~ + (ParametersEnum.ALLOWEDINPUTTYPE.toString -> List("text")) ~ + (AttributesEnum.CONFIG.toString -> JObject()) + ) + )) + + pretty(render(defaultConfigMap)) + } + } From e7a046c6ffd91ef4dbda6c33af7a6b08954e4dc7 Mon Sep 17 00:00:00 2001 From: Rahul Rudragoudar Date: Mon, 29 Mar 2021 15:30:12 +0530 Subject: [PATCH 4/9] Move config file to data dir Signed-off-by: Rahul Rudragoudar --- config.json | 37 ------------------------------------- data/config.json | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 37 deletions(-) delete mode 100644 config.json create mode 100644 data/config.json diff --git a/config.json b/config.json deleted file mode 100644 index 727b973..0000000 --- a/config.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "randomSeed": 20, - "port": 8888, - "captchaExpiryTimeLimit": 5, - "threadDelay": 2, - "throttle": 10, - "captchas":[ - { - "name": "FilterChallenge", - "allowedLevels":["medium", "hard"], - "allowedMedia":["image/png"], - "allowedInputType":["text"], - "config":{} - }, - { - "name": "GifCaptcha", - "allowedLevels":["hard"], - "allowedMedia":["image/gif"], - "allowedInputType":["text"], - "config":{} - }, - { - "name": "ShadowTextCaptcha", - "allowedLevels":["easy"], - "allowedMedia":["image/png"], - "allowedInputType":["text"], - "config": {} - }, - { - "name": "RainDropsCaptcha", - "allowedLevels":["easy","medium"], - "allowedMedia":["image/gif"], - "allowedInputType":["text"], - "config":{} - } - ] -} \ No newline at end of file diff --git a/data/config.json b/data/config.json new file mode 100644 index 0000000..41d3c90 --- /dev/null +++ b/data/config.json @@ -0,0 +1,32 @@ +{ + "randomSeed" : 20, + "port" : 8888, + "captchaExpiryTimeLimit" : 5, + "throttle" : 10, + "threadDelay" : 2, + "captchas" : [ { + "name" : "FilterChallenge", + "allowedLevels" : [ "medium", "hard" ], + "allowedMedia" : [ "image/png" ], + "allowedInputType" : [ "text" ], + "config" : { } + }, { + "name" : "GifCaptcha", + "allowedLevels" : [ "hard" ], + "allowedMedia" : [ "image/gif" ], + "allowedInputType" : [ "text" ], + "config" : { } + }, { + "name" : "ShadowTextCaptcha", + "allowedLevels" : [ "easy" ], + "allowedMedia" : [ "image/png" ], + "allowedInputType" : [ "text" ], + "config" : { } + }, { + "name" : "RainDropsCaptcha", + "allowedLevels" : [ "easy", "medium" ], + "allowedMedia" : [ "image/gif" ], + "allowedInputType" : [ "text" ], + "config" : { } + } ] +} \ No newline at end of file From 18d38990e54056871394028963eeba37ab4f33ae Mon Sep 17 00:00:00 2001 From: Rahul Rudragoudar Date: Mon, 29 Mar 2021 15:30:48 +0530 Subject: [PATCH 5/9] Add assembly plugin Signed-off-by: Rahul Rudragoudar --- project/plugins.sbt | 1 + 1 file changed, 1 insertion(+) diff --git a/project/plugins.sbt b/project/plugins.sbt index a5d94ca..9f4cd3e 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,3 +1,4 @@ addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.25") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.0") addSbtPlugin("com.lightbend.sbt" % "sbt-java-formatter" % "0.6.0") +addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.15.0") From 8c8bda8d59fd0438656a11d62b6ea2c624a828ef Mon Sep 17 00:00:00 2001 From: Rahul Rudragoudar Date: Mon, 29 Mar 2021 15:31:27 +0530 Subject: [PATCH 6/9] Add compile config options Signed-off-by: Rahul Rudragoudar --- build.sbt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.sbt b/build.sbt index 4691280..797904c 100644 --- a/build.sbt +++ b/build.sbt @@ -22,5 +22,8 @@ scalacOptions ++= List( ) javacOptions += "-g:none" compileOrder := CompileOrder.JavaThenScala +mainClass in assembly := Some("lc.LCFramework") +mainClass in (Compile, run) := Some("lc.LCFramework") +assemblyJarName in assembly := "LibreCaptcha.jar" fork in run := true From 0b3cddc09d9b4cbd78233036d19489c8e63fb1c1 Mon Sep 17 00:00:00 2001 From: Rahul Rudragoudar Date: Mon, 29 Mar 2021 15:32:06 +0530 Subject: [PATCH 7/9] Add docker support Signed-off-by: Rahul Rudragoudar --- Dockerfile | 37 +++++++++++++++++++++++++++++++++++++ docker-compose.yml | 11 +++++++++++ 2 files changed, 48 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a17b6ef --- /dev/null +++ b/Dockerfile @@ -0,0 +1,37 @@ +FROM alpine:latest AS base-builder +ARG SBT_VERSION=1.3.13 +RUN apk add --no-cache bash +ENV JAVA_HOME="/usr/lib/jvm/default-jvm/" +RUN apk add openjdk11-jre +ENV PATH=$PATH:${JAVA_HOME}/bin +RUN \ + wget -O sbt-$SBT_VERSION.tgz https://github.com/sbt/sbt/releases/download/v$SBT_VERSION/sbt-$SBT_VERSION.tgz && \ + tar -xzvf sbt-$SBT_VERSION.tgz && \ + rm sbt-$SBT_VERSION.tgz + +ENV PATH=$PATH:/sbt/bin/ + + +FROM base-builder AS builder +WORKDIR /build +COPY lib/ lib/ +COPY project/plugins.sbt project/ +COPY build.sbt . +COPY src/ src/ +RUN sbt assembly + + +FROM alpine:latest AS base-core +ENV JAVA_HOME="/usr/lib/jvm/default-jvm/" +RUN apk add openjdk11-jre +ENV PATH=$PATH:${JAVA_HOME}/bin + + +FROM base-core +WORKDIR /lc-core +COPY --from=builder /build/target/scala-2.13/LibreCaptcha.jar . +RUN mkdir data/ + +EXPOSE 8888 + +CMD [ "java", "-jar", "LibreCaptcha.jar" ] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..315720b --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,11 @@ +version: "3.8" + +services: + lc-core: + container_name: "libre-captcha" + build: ./ + image: librecapthca/lc-core:latest + volumes: + - "./docker-data:/lc-core/data" + ports: + - "8888:8888" From 8c5a6a26e8c5a4bac5d07bea1b61f25a87d35cff Mon Sep 17 00:00:00 2001 From: hrj Date: Wed, 31 Mar 2021 13:39:53 +0530 Subject: [PATCH 8/9] use alpine jdk16 image; install font libraries --- Dockerfile | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index a17b6ef..349dcbd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,7 @@ -FROM alpine:latest AS base-builder +FROM adoptopenjdk/openjdk16:alpine AS base-builder ARG SBT_VERSION=1.3.13 RUN apk add --no-cache bash ENV JAVA_HOME="/usr/lib/jvm/default-jvm/" -RUN apk add openjdk11-jre ENV PATH=$PATH:${JAVA_HOME}/bin RUN \ wget -O sbt-$SBT_VERSION.tgz https://github.com/sbt/sbt/releases/download/v$SBT_VERSION/sbt-$SBT_VERSION.tgz && \ @@ -12,18 +11,20 @@ RUN \ ENV PATH=$PATH:/sbt/bin/ -FROM base-builder AS builder +FROM base-builder AS sbt-builder WORKDIR /build COPY lib/ lib/ COPY project/plugins.sbt project/ COPY build.sbt . +RUN sbt assembly + +FROM sbt-builder as builder COPY src/ src/ RUN sbt assembly - -FROM alpine:latest AS base-core +FROM adoptopenjdk/openjdk16:alpine AS base-core ENV JAVA_HOME="/usr/lib/jvm/default-jvm/" -RUN apk add openjdk11-jre +RUN apk add --update ttf-dejavu ENV PATH=$PATH:${JAVA_HOME}/bin @@ -34,4 +35,4 @@ RUN mkdir data/ EXPOSE 8888 -CMD [ "java", "-jar", "LibreCaptcha.jar" ] \ No newline at end of file +CMD [ "java", "-jar", "LibreCaptcha.jar" ] From f99c1bda5fc88f916582fc4a494652ee0a8f059d Mon Sep 17 00:00:00 2001 From: Rahul Rudragoudar Date: Wed, 31 Mar 2021 18:39:05 +0530 Subject: [PATCH 9/9] Swap alpine with alpine-jre for base runner image Signed-off-by: Rahul Rudragoudar --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 349dcbd..24ea0ee 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,7 +22,7 @@ FROM sbt-builder as builder COPY src/ src/ RUN sbt assembly -FROM adoptopenjdk/openjdk16:alpine AS base-core +FROM adoptopenjdk/openjdk16:alpine-jre AS base-core ENV JAVA_HOME="/usr/lib/jvm/default-jvm/" RUN apk add --update ttf-dejavu ENV PATH=$PATH:${JAVA_HOME}/bin