mirror of
https://github.com/librecaptcha/lc-core.git
synced 2025-11-29 05:18:50 -05:00
Linter and Formatter support (#58)
* Add scala linter and formatter Signed-off-by: Rahul Rudragoudar <rr83019@gmail.com> * Add java formatter Signed-off-by: Rahul Rudragoudar <rr83019@gmail.com> * Add linter support Signed-off-by: Rahul Rudragoudar <rr83019@gmail.com> * Increase maxColumn limit Signed-off-by: Rahul Rudragoudar <rr83019@gmail.com> * Reformat and lint Signed-off-by: Rahul Rudragoudar <rr83019@gmail.com> * Minor reformatting Signed-off-by: Rahul Rudragoudar <rr83019@gmail.com> * Add scala formatter on compile option Signed-off-by: Rahul Rudragoudar <rr83019@gmail.com> * Enable scala linter for CI Signed-off-by: Rahul Rudragoudar <rr83019@gmail.com>
This commit is contained in:
committed by
GitHub
parent
6d04cdc3b4
commit
de50d8123e
@@ -8,7 +8,6 @@ import java.awt.Color
|
||||
import lc.captchas.interfaces.ChallengeProvider
|
||||
import lc.captchas.interfaces.Challenge
|
||||
|
||||
|
||||
class FilterChallenge extends ChallengeProvider {
|
||||
def getId = "FilterChallenge"
|
||||
def returnChallenge(): Challenge = {
|
||||
@@ -62,4 +61,3 @@ class FilterType2 extends FilterType {
|
||||
image
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,45 +4,45 @@ import java.io.File
|
||||
import java.io.ByteArrayOutputStream
|
||||
import javax.imageio.ImageIO
|
||||
import scala.collection.mutable.Map
|
||||
import java.nio.file.{Files,Path,StandardCopyOption}
|
||||
import java.nio.file.{Files, StandardCopyOption}
|
||||
import java.awt.image.BufferedImage
|
||||
import java.awt.{Graphics2D,Color}
|
||||
import java.awt.Color
|
||||
import lc.captchas.interfaces.ChallengeProvider
|
||||
import lc.captchas.interfaces.Challenge
|
||||
|
||||
class LabelCaptcha extends ChallengeProvider {
|
||||
private var knownFiles = new File("known").list.toList
|
||||
private var unknownFiles = new File("unknown").list.toList
|
||||
private var unknownAnswers = Map[String, Map[String, Int]]()
|
||||
private var total = Map[String, Int]()
|
||||
private val unknownAnswers = Map[String, Map[String, Int]]()
|
||||
private val total = Map[String, Int]()
|
||||
|
||||
for(file <- unknownFiles) {
|
||||
unknownAnswers += file -> Map[String, Int]()
|
||||
total += file -> 0
|
||||
for (file <- unknownFiles) {
|
||||
unknownAnswers += file -> Map[String, Int]()
|
||||
total += file -> 0
|
||||
}
|
||||
|
||||
def getId = "LabelCaptcha"
|
||||
|
||||
def returnChallenge(): Challenge = synchronized {
|
||||
val r = scala.util.Random.nextInt(knownFiles.length)
|
||||
val s = scala.util.Random.nextInt(unknownFiles.length)
|
||||
val knownImageFile = knownFiles(r)
|
||||
val unknownImageFile = unknownFiles(s)
|
||||
val ip = new ImagePair(knownImageFile, unknownImageFile)
|
||||
def returnChallenge(): Challenge =
|
||||
synchronized {
|
||||
val r = scala.util.Random.nextInt(knownFiles.length)
|
||||
val s = scala.util.Random.nextInt(unknownFiles.length)
|
||||
val knownImageFile = knownFiles(r)
|
||||
val unknownImageFile = unknownFiles(s)
|
||||
|
||||
var knownImage = ImageIO.read(new File("known/"+knownImageFile))
|
||||
var unknownImage = ImageIO.read(new File("unknown/"+unknownImageFile))
|
||||
val mergedImage = merge(knownImage, unknownImage)
|
||||
val knownImage = ImageIO.read(new File("known/" + knownImageFile))
|
||||
val unknownImage = ImageIO.read(new File("unknown/" + unknownImageFile))
|
||||
val mergedImage = merge(knownImage, unknownImage)
|
||||
|
||||
val token = encrypt(knownImageFile + "," + unknownImageFile)
|
||||
val baos = new ByteArrayOutputStream()
|
||||
ImageIO.write(mergedImage,"png",baos)
|
||||
val token = encrypt(knownImageFile + "," + unknownImageFile)
|
||||
val baos = new ByteArrayOutputStream()
|
||||
ImageIO.write(mergedImage, "png", baos)
|
||||
|
||||
new Challenge(baos.toByteArray(), "image/png", token)
|
||||
}
|
||||
new Challenge(baos.toByteArray(), "image/png", token)
|
||||
}
|
||||
|
||||
private def merge(knownImage: BufferedImage, unknownImage: BufferedImage) = {
|
||||
val width = knownImage.getWidth()+unknownImage.getWidth()
|
||||
val width = knownImage.getWidth() + unknownImage.getWidth()
|
||||
val height = List(knownImage.getHeight(), unknownImage.getHeight()).max
|
||||
val imageType = knownImage.getType()
|
||||
val finalImage = new BufferedImage(width, height, imageType)
|
||||
@@ -55,34 +55,39 @@ class LabelCaptcha extends ChallengeProvider {
|
||||
finalImage
|
||||
}
|
||||
|
||||
def checkAnswer(token: String, input: String): Boolean = synchronized {
|
||||
val parts = decrypt(token).split(",")
|
||||
val knownImage = parts(0)
|
||||
val unknownImage = parts(1)
|
||||
val expectedAnswer = knownImage.split('.')(0)
|
||||
val userAnswer = input.split(' ')
|
||||
if(userAnswer(0)==expectedAnswer) {
|
||||
val unknownFile = unknownImage
|
||||
if((unknownAnswers(unknownFile)).contains(userAnswer(1))) {
|
||||
unknownAnswers(unknownFile)(userAnswer(1)) += 1
|
||||
total(unknownFile) += 1
|
||||
} else {
|
||||
unknownAnswers(unknownFile)+=(userAnswer(1)) -> 1
|
||||
total(unknownFile) += 1
|
||||
}
|
||||
if(total(unknownFile)>=3) {
|
||||
if((unknownAnswers(unknownFile)(userAnswer(1))/total(unknownFile))>=0.9) {
|
||||
unknownAnswers -= unknownFile
|
||||
Files.move(new File("unknown/"+unknownFile).toPath, new File("known/"+userAnswer(1)+".png").toPath, StandardCopyOption.REPLACE_EXISTING)
|
||||
knownFiles = new File("known").list.toList
|
||||
unknownFiles = new File("unknown").list.toList
|
||||
def checkAnswer(token: String, input: String): Boolean =
|
||||
synchronized {
|
||||
val parts = decrypt(token).split(",")
|
||||
val knownImage = parts(0)
|
||||
val unknownImage = parts(1)
|
||||
val expectedAnswer = knownImage.split('.')(0)
|
||||
val userAnswer = input.split(' ')
|
||||
if (userAnswer(0) == expectedAnswer) {
|
||||
val unknownFile = unknownImage
|
||||
if ((unknownAnswers(unknownFile)).contains(userAnswer(1))) {
|
||||
unknownAnswers(unknownFile)(userAnswer(1)) += 1
|
||||
total(unknownFile) += 1
|
||||
} else {
|
||||
unknownAnswers(unknownFile) += (userAnswer(1)) -> 1
|
||||
total(unknownFile) += 1
|
||||
}
|
||||
if (total(unknownFile) >= 3) {
|
||||
if ((unknownAnswers(unknownFile)(userAnswer(1)) / total(unknownFile)) >= 0.9) {
|
||||
unknownAnswers -= unknownFile
|
||||
Files.move(
|
||||
new File("unknown/" + unknownFile).toPath,
|
||||
new File("known/" + userAnswer(1) + ".png").toPath,
|
||||
StandardCopyOption.REPLACE_EXISTING
|
||||
)
|
||||
knownFiles = new File("known").list.toList
|
||||
unknownFiles = new File("unknown").list.toList
|
||||
}
|
||||
}
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Encryption is not implemented for the POC, since the API re-maps the tokens anyway.
|
||||
// But we need to encrypt after POC, to avoid leaking file-names.
|
||||
|
||||
@@ -5,9 +5,7 @@ import java.awt.RenderingHints
|
||||
import java.awt.Font
|
||||
import java.awt.font.TextAttribute
|
||||
import java.awt.Color
|
||||
import java.io.ByteArrayOutputStream
|
||||
import javax.imageio.ImageIO
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import javax.imageio.stream.MemoryCacheImageOutputStream;
|
||||
import lc.captchas.interfaces.ChallengeProvider
|
||||
import lc.captchas.interfaces.Challenge
|
||||
@@ -19,8 +17,8 @@ class Drop {
|
||||
var yOffset = 0
|
||||
var color = 0
|
||||
var colorChange = 10
|
||||
def mkColor = {
|
||||
new Color(color, color, math.min(200, color+100))
|
||||
def mkColor: Color = {
|
||||
new Color(color, color, math.min(200, color + 100))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,8 +34,8 @@ class RainDropsCP extends ChallengeProvider {
|
||||
private def extendDrops(drops: Array[Drop], steps: Int, xOffset: Int) = {
|
||||
drops.map(d => {
|
||||
val nd = new Drop()
|
||||
nd.x + xOffset*steps
|
||||
nd.y + d.yOffset*steps
|
||||
nd.x + xOffset * steps
|
||||
nd.y + d.yOffset * steps
|
||||
nd
|
||||
})
|
||||
}
|
||||
@@ -48,20 +46,23 @@ class RainDropsCP extends ChallengeProvider {
|
||||
val width = 450
|
||||
val height = 100
|
||||
val imgType = BufferedImage.TYPE_INT_RGB
|
||||
val xOffset = 2+r.nextInt(3)
|
||||
val xOffset = 2 + r.nextInt(3)
|
||||
val xBias = (height / 10) - 2
|
||||
val dropsOrig = Array.fill[Drop](2000)( new Drop())
|
||||
val dropsOrig = Array.fill[Drop](2000)(new Drop())
|
||||
for (d <- dropsOrig) {
|
||||
d.x = r.nextInt(width) - (xBias/2)*xOffset
|
||||
d.yOffset = 6+r.nextInt(6)
|
||||
d.x = r.nextInt(width) - (xBias / 2) * xOffset
|
||||
d.yOffset = 6 + r.nextInt(6)
|
||||
d.y = r.nextInt(height)
|
||||
d.color = r.nextInt(240)
|
||||
if (d.color > 128) {
|
||||
d.colorChange *= -1
|
||||
}
|
||||
}
|
||||
val drops = dropsOrig ++ extendDrops(dropsOrig, 1, xOffset) ++ extendDrops(dropsOrig, 2, xOffset) ++ extendDrops(dropsOrig, 3, xOffset)
|
||||
|
||||
val drops = dropsOrig ++ extendDrops(dropsOrig, 1, xOffset) ++ extendDrops(dropsOrig, 2, xOffset) ++ extendDrops(
|
||||
dropsOrig,
|
||||
3,
|
||||
xOffset
|
||||
)
|
||||
|
||||
val baseFont = new Font(Font.MONOSPACED, Font.BOLD, 80)
|
||||
val attributes = new java.util.HashMap[TextAttribute, Object]()
|
||||
@@ -72,7 +73,7 @@ class RainDropsCP extends ChallengeProvider {
|
||||
val baos = new ByteArrayOutputStream();
|
||||
val ios = new MemoryCacheImageOutputStream(baos);
|
||||
val writer = new GifSequenceWriter(ios, imgType, 60, true);
|
||||
for(i <- 0 until 60){
|
||||
for (_ <- 0 until 60) {
|
||||
// val yOffset = 5+r.nextInt(5)
|
||||
val canvas = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB)
|
||||
val g = canvas.createGraphics()
|
||||
@@ -85,14 +86,14 @@ class RainDropsCP extends ChallengeProvider {
|
||||
// paint the rain
|
||||
for (d <- drops) {
|
||||
g.setColor(d.mkColor)
|
||||
g.drawLine(d.x, d.y, d.x+xOffset, d.y+d.yOffset)
|
||||
d.x += xOffset/2
|
||||
d.y += d.yOffset/2
|
||||
g.drawLine(d.x, d.y, d.x + xOffset, d.y + d.yOffset)
|
||||
d.x += xOffset / 2
|
||||
d.y += d.yOffset / 2
|
||||
d.color += d.colorChange
|
||||
if (d.x > width || d.y > height) {
|
||||
val ySteps = (height / d.yOffset) + 1
|
||||
d.x -= xOffset*ySteps
|
||||
d.y -= d.yOffset*ySteps
|
||||
val ySteps = (height / d.yOffset) + 1
|
||||
d.x -= xOffset * ySteps
|
||||
d.y -= d.yOffset * ySteps
|
||||
|
||||
}
|
||||
if (d.color > 200 || d.color < 21) {
|
||||
@@ -103,7 +104,7 @@ class RainDropsCP extends ChallengeProvider {
|
||||
// center the text
|
||||
g.setFont(spacedFont)
|
||||
val textWidth = g.getFontMetrics().charsWidth(secret.toCharArray, 0, secret.toCharArray.length)
|
||||
val textX = (width - textWidth)/2
|
||||
val textX = (width - textWidth) / 2
|
||||
|
||||
// paint the top outline
|
||||
g.setColor(textHighlightColor)
|
||||
|
||||
Reference in New Issue
Block a user