diff --git a/src/main/scala/lc/LabelCaptcha.scala b/src/main/scala/lc/LabelCaptcha.scala index b491f43..9757051 100644 --- a/src/main/scala/lc/LabelCaptcha.scala +++ b/src/main/scala/lc/LabelCaptcha.scala @@ -18,17 +18,28 @@ class LabelCaptcha extends ChallengeProvider { 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) - val token = scala.util.Random.nextInt(10000).toString - tokenImagePair += (token -> ip) + var knownImage = ImageIO.read(new File("known/"+knownImageFile)) var 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) + + new Challenge(baos.toByteArray(), "image/png", token) + } + + private def merge(knownImage: BufferedImage, unknownImage: BufferedImage) = { val width = knownImage.getWidth()+unknownImage.getWidth() val height = List(knownImage.getHeight(), unknownImage.getHeight()).max val imageType = knownImage.getType() @@ -39,16 +50,17 @@ class LabelCaptcha extends ChallengeProvider { g.drawImage(knownImage, null, 0, 0) g.drawImage(unknownImage, null, knownImage.getWidth(), 0) g.dispose() - val baos = new ByteArrayOutputStream() - ImageIO.write(finalImage,"png",baos) - new Challenge(baos.toByteArray(), "image/png", token) + finalImage } + def checkAnswer(token: String, input: String): Boolean = synchronized { - val imagePair = tokenImagePair(token) - val expectedAnswer = imagePair.known.split('.')(0) + 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 = tokenImagePair(token).unknown + val unknownFile = unknownImage if((unknownAnswers(unknownFile)).contains(userAnswer(1))) { unknownAnswers(unknownFile)(userAnswer(1)) += 1 total(unknownFile) += 1 @@ -69,6 +81,12 @@ class LabelCaptcha extends ChallengeProvider { 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. + // There are good ideas here: https://stackoverflow.com/questions/1205135/how-to-encrypt-string-in-java + private def encrypt(s: String) = s + private def decrypt(s: String) = s } class ImagePair(val known: String, val unknown: String)