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

Initial commit for the framework #3

Merged
merged 2 commits into from
Jun 14, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 2 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ lazy val root = (project in file(".")).
libraryDependencies += "com.sksamuel.scrimage" %% "scrimage-filters" % "2.1.8"

)

fork in run := true
Binary file added lib/h2-1.4.197.jar
Binary file not shown.
24 changes: 0 additions & 24 deletions src/main/scala/BlurCaptcha.scala

This file was deleted.

68 changes: 0 additions & 68 deletions src/main/scala/LabelCaptcha.scala

This file was deleted.

43 changes: 0 additions & 43 deletions src/main/scala/Main.scala

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,36 +1,34 @@
package lc

import com.sksamuel.scrimage._
import com.sksamuel.scrimage.filter._
import java.awt.image.BufferedImage
import java.awt.{Graphics2D,Color,Font}
import java.awt.Font
import java.awt.Color

class FilterCaptcha extends CaptchaProvider {
val tokenAnswer = scala.collection.mutable.Map[String, String]()
def getChallenge(): Challenge = {
class FilterChallenge extends ChallengeProvider {
val id = "filter"
def returnChallenge(): (Image, String) = {
val filterTypes = List(new FilterType1, new FilterType2)
val r = new scala.util.Random
val alphabet = "abcdefghijklmnopqrstuvwxyz"
val n = 8
val answer = Stream.continually(r.nextInt(alphabet.size)).map(alphabet).take(n).mkString
val token = scala.util.Random.nextInt(10000).toString
synchronized {
tokenAnswer += token -> answer
}
val secret = Stream.continually(r.nextInt(alphabet.size)).map(alphabet).take(n).mkString
val canvas = new BufferedImage(225, 50, BufferedImage.TYPE_INT_RGB)
val g = canvas.createGraphics()
g.setColor(Color.WHITE)
g.fillRect(0, 0, canvas.getWidth, canvas.getHeight)
g.setColor(Color.BLACK)
g.setFont(new Font("Serif", Font.PLAIN, 30))
g.drawString(answer, 5, 30)
g.drawString(secret, 5, 30)
g.dispose()
var image = new Image(canvas, ImageMetadata.empty)
val s = scala.util.Random.nextInt(2)
image = filterTypes(s).applyFilter(image)
val challenge = new Challenge(token, image)
challenge
(image, secret)
}
def checkAnswer(token: String, input: String): Boolean = {
tokenAnswer(token) == input
def checkAnswer(secret: String, answer: String): Boolean = {
secret == answer
}
}

Expand Down Expand Up @@ -61,3 +59,4 @@ class FilterType2 extends FilterType {
image
}
}

79 changes: 79 additions & 0 deletions src/main/scala/lc/Main.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package lc

import com.sksamuel.scrimage._
import java.sql._
import java.io._

trait ChallengeProvider {
val id: String
def returnChallenge(): (Image, String)
def checkAnswer(secret: String, answer: String): Boolean
//TODO: def configure(): Unit
}

class Captcha {
val con: Connection = DriverManager.getConnection("jdbc:h2:./captcha", "sa", "")
val stmt: Statement = con.createStatement();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this stmt for? Doesn't seem to be used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm using it to execute the CREATE TABLE statement.

stmt.execute("CREATE TABLE IF NOT EXISTS challenge(token varchar, id varchar, secret varchar, image blob)");

def getCaptcha(): Boolean = {
val provider = new FilterChallenge
val (token, image) = this.getChallenge(provider)
val stmt: Statement = con.createStatement();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same with this stmt. Doesn't seem to be used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this wasn't being used. I've removed it in the most recent commit.

image.output(new File("Captcha.png"))
println(s"Token: ${token}")
println("Enter your answer: ")
val answer = scala.io.StdIn.readLine()
this.getAnswer(token, answer, provider)
}

def getChallenge(provider: ChallengeProvider): (String, Image) = {
val (image, secret) = provider.returnChallenge()
val token = scala.util.Random.nextInt(10000).toString
var pstmt: PreparedStatement = null
pstmt = con.prepareStatement("INSERT INTO challenge(token, id, secret) VALUES (?, ?, ?)")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Convert pstmt to val by declaring and initialising in the same line.

var is mutable state, is 💣, avoid

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using prepareStatement is a good optimisation over exectuteQuery. But for it to be effective you should prepare it only once. In other words, move declaration of pstmt to the class level.

pstmt.setString(1, token)
pstmt.setString(2, provider.id)
pstmt.setString(3, secret)
//TODO: insert image into database
pstmt.executeUpdate()
(token, image)
}

def getAnswer(token: String, answer: String, provider: ChallengeProvider): Boolean = {
val stmt: Statement = con.createStatement();
val rs: ResultSet = stmt.executeQuery("SELECT secret FROM challenge WHERE token = "+token);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could convert it to a prepared statement, as an optimisation.

rs.next()
val secret = rs.getString("secret")
provider.checkAnswer(secret, answer)
}

def display(): Unit = {
val stmt: Statement = con.createStatement();
val rs: ResultSet = stmt.executeQuery("SELECT * FROM challenge");

println("token\t\tid\t\tsecret\t\timage");
while(rs.next()) {
val token = rs.getString("token");
val id = rs.getString("id");
val secret = rs.getString("secret");
val image = rs.getString("image");
println(s"${token}\t\t${id}\t\t${secret}\t\t${image}")
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check indentation of the code in this function.

}

def closeConnection(): Unit = {
con.close()
}
}

object LCFramework{
def main(args: scala.Array[String]) {
val captcha = new Captcha
val result = captcha.getCaptcha()
println(result)
captcha.display()
captcha.closeConnection()
}
}