Merge pull request #90 from rr83019/BT-captcha

Background Thread - Random Captcha Generation
This commit is contained in:
hrj 2021-04-24 21:52:25 +05:30 committed by GitHub
commit 6196a34aae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 79 additions and 42 deletions

View File

@ -23,6 +23,7 @@ scalacOptions ++= List(
)
javacOptions += "-g:none"
compileOrder := CompileOrder.JavaThenScala
javafmtOnCompile := false
assembly / mainClass := Some("lc.LCFramework")
Compile / run / mainClass := Some("lc.LCFramework")
assembly / assemblyJarName := "LibreCaptcha.jar"

View File

@ -1,9 +1,16 @@
package lc.misc;
import java.awt.*;
import java.util.Random;
public class HelperFunctions {
private static Random random = new Random();
synchronized public static void setSeed(long seed){
random.setSeed(seed);
}
public static void setRenderingHints(Graphics2D g2d) {
g2d.setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
@ -25,13 +32,18 @@ public class HelperFunctions {
public static String randomString(final int n, final String characters) {
final StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < n; i++) {
int index = (int) (characters.length() * Math.random());
int index = randomNumber(characters.length());
stringBuilder.append(characters.charAt(index));
}
return stringBuilder.toString();
}
public static int randomNumber(int min, int max) {
return (int) (Math.random() * ((max - min) + 1)) + min;
synchronized public static int randomNumber(int min, int max) {
return (random.nextInt() * ((max - min) + 1)) + min;
}
synchronized public static int randomNumber(int bound) {
return random.nextInt(bound);
}
}

View File

@ -2,8 +2,9 @@ package lc.background
import lc.database.Statements
import java.util.concurrent.{ScheduledThreadPoolExecutor, TimeUnit}
import lc.core.Captcha
import lc.core.{Captcha, Config}
import lc.core.{Parameters, Size}
import lc.misc.HelperFunctions
class BackgroundTask(throttle: Int, timeLimit: Int) {
@ -22,13 +23,26 @@ class BackgroundTask(throttle: Int, timeLimit: Int) {
if (imageNum.next())
throttleIn = (throttleIn - imageNum.getInt("total"))
while (0 < throttleIn) {
Captcha.generateChallenge(Parameters("medium", "image/png", "text", Option(Size(0, 0))))
Captcha.generateChallenge(getRandomParam())
throttleIn -= 1
}
} catch { case exception: Exception => println(exception) }
}
}
private def getRandomParam(): Parameters = {
val captcha = pickRandom(Config.captchaConfig)
val level = pickRandom(captcha.allowedLevels)
val media = pickRandom(captcha.allowedMedia)
val inputType = pickRandom(captcha.allowedInputType)
Parameters(level, media, inputType, Some(Size(0, 0)))
}
private def pickRandom[T](list: List[T]): T = {
list(HelperFunctions.randomNumber(list.size))
}
def beginThread(delay: Int): Unit = {
val ex = new ScheduledThreadPoolExecutor(1)
ex.scheduleWithFixedDelay(task, 1, delay, TimeUnit.SECONDS)

View File

@ -4,6 +4,7 @@ import lc.captchas._
import lc.captchas.interfaces.ChallengeProvider
import lc.captchas.interfaces.Challenge
import scala.collection.mutable.Map
import lc.misc.HelperFunctions
object CaptchaProviders {
private val providers = Map(
@ -23,15 +24,8 @@ object CaptchaProviders {
}
}
private val seed = Config.seed
private val random = new scala.util.Random(seed)
private val config = Config.captchaConfig
private def getNextRandomInt(max: Int): Int =
random.synchronized {
random.nextInt(max)
}
def getProviderById(id: String): ChallengeProvider = {
return providers(id)
}
@ -58,7 +52,7 @@ object CaptchaProviders {
def getProvider(param: Parameters): Option[ChallengeProvider] = {
val providerConfig = filterProviderByParam(param).toList
if (providerConfig.length > 0) {
val randomIndex = getNextRandomInt(providerConfig.length)
val randomIndex = HelperFunctions.randomNumber(providerConfig.length)
val providerIndex = providerConfig(randomIndex)._1
val selectedProvider = providers(providerIndex)
selectedProvider.configure(providerConfig(randomIndex)._2)

View File

@ -6,6 +6,7 @@ import org.json4s.jackson.JsonMethods.{parse, render, pretty}
import org.json4s.JsonDSL._
import java.io.{FileNotFoundException, File, PrintWriter}
import java.{util => ju}
import lc.misc.HelperFunctions
object Config {
@ -49,6 +50,8 @@ object Config {
val allowedMedia: Set[String] = captchaConfig.flatMap(_.allowedMedia).toSet
val allowedInputType: Set[String] = captchaConfig.flatMap(_.allowedInputType).toSet
HelperFunctions.setSeed(seed)
private def getDefaultConfig(): String = {
val defaultConfigMap =
(AttributesEnum.RANDOM_SEED.toString -> new ju.Random().nextInt()) ~

View File

@ -11,16 +11,22 @@ import scala.io.Source
import org.limium.picoserve.Server.StringResponse
class Server(port: Int) {
val server: picoserve.Server = picoserve.Server.builder()
val server: picoserve.Server = picoserve.Server
.builder()
.port(port)
.backlog(32)
.POST("/v1/captcha", (request) => {
.POST(
"/v1/captcha",
(request) => {
val json = parse(request.getBodyString())
val param = json.extract[Parameters]
val id = Captcha.getChallenge(param)
getResponse(id)
})
.GET("/v1/media", (request) => {
}
)
.GET(
"/v1/media",
(request) => {
val params = request.getQueryParams()
val result = if (params.containsKey("id")) {
val paramId = params.get("id").get(0)
@ -30,18 +36,25 @@ class Server(port: Int) {
Left(Error(ErrorMessageEnum.INVALID_PARAM.toString + "=> id"))
}
getResponse(result)
})
.POST("/v1/answer", (request) => {
}
)
.POST(
"/v1/answer",
(request) => {
val json = parse(request.getBodyString())
val answer = json.extract[Answer]
val result = Captcha.checkAnswer(answer)
getResponse(result)
})
.GET("/demo/index.html", (_) => {
}
)
.GET(
"/demo/index.html",
(_) => {
val resStream = getClass().getResourceAsStream("/index.html")
val str = Source.fromInputStream(resStream).mkString
new StringResponse(200, str)
})
}
)
.build()
private def getResponse(response: Either[Error, ByteConvert]): ByteResponse = {