mirror of
https://github.com/librecaptcha/lc-core.git
synced 2025-01-13 06:53:19 -05:00
synchronise access to database statements
This commit is contained in:
parent
0b1e902326
commit
62b3a098bd
@ -5,12 +5,15 @@ import java.io.ByteArrayInputStream
|
|||||||
import java.util.concurrent._
|
import java.util.concurrent._
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import java.sql.{Blob, ResultSet}
|
import java.sql.{Blob, ResultSet}
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
|
||||||
case class Size(height: Int, width: Int)
|
case class Size(height: Int, width: Int)
|
||||||
case class Parameters(level: String, media: String, input_type: String, size: Option[Size])
|
case class Parameters(level: String, media: String, input_type: String, size: Option[Size])
|
||||||
case class Id(id: String)
|
case class Id(id: String)
|
||||||
case class Answer(answer: String, id: String)
|
case class Answer(answer: String, id: String)
|
||||||
|
|
||||||
|
case class ProviderSecret(provider: String, secret: String)
|
||||||
|
|
||||||
class Captcha(throttle: Int) extends DBConn {
|
class Captcha(throttle: Int) extends DBConn {
|
||||||
|
|
||||||
val stmt = getConn()
|
val stmt = getConn()
|
||||||
@ -55,20 +58,25 @@ class Captcha(throttle: Int) extends DBConn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val uniqueIntCount = new AtomicInteger()
|
||||||
|
|
||||||
def generateChallenge(param: Parameters): String = {
|
def generateChallenge(param: Parameters): String = {
|
||||||
//TODO: eval params to choose a provider
|
//TODO: eval params to choose a provider
|
||||||
val providerMap = getProvider()
|
val providerMap = getProvider()
|
||||||
val provider = providers(providerMap)
|
val provider = providers(providerMap)
|
||||||
val challenge = provider.returnChallenge()
|
val challenge = provider.returnChallenge()
|
||||||
val blob = new ByteArrayInputStream(challenge.content)
|
val blob = new ByteArrayInputStream(challenge.content)
|
||||||
val token = scala.util.Random.nextInt(10000).toString
|
// val token = scala.util.Random.nextInt(100000).toString
|
||||||
insertPstmt.setString(1, token)
|
val token = uniqueIntCount.incrementAndGet().toString
|
||||||
insertPstmt.setString(2, provider.getId)
|
insertPstmt.synchronized {
|
||||||
insertPstmt.setString(3, challenge.secret)
|
insertPstmt.setString(1, token)
|
||||||
insertPstmt.setString(4, providerMap)
|
insertPstmt.setString(2, provider.getId)
|
||||||
insertPstmt.setString(5, challenge.contentType)
|
insertPstmt.setString(3, challenge.secret)
|
||||||
insertPstmt.setBlob(6, blob)
|
insertPstmt.setString(4, providerMap)
|
||||||
insertPstmt.executeUpdate()
|
insertPstmt.setString(5, challenge.contentType)
|
||||||
|
insertPstmt.setBlob(6, blob)
|
||||||
|
insertPstmt.executeUpdate()
|
||||||
|
}
|
||||||
token
|
token
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,34 +99,42 @@ class Captcha(throttle: Int) extends DBConn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def getChallenge(param: Parameters): Id = {
|
def getChallenge(param: Parameters): Id = {
|
||||||
val rs = stmt.executeQuery("SELECT token FROM challenge WHERE solved=FALSE ORDER BY RAND() LIMIT 1")
|
val idOpt = stmt.synchronized {
|
||||||
val id = if(rs.next()){
|
val rs = stmt.executeQuery("SELECT token FROM challenge WHERE solved=FALSE ORDER BY RAND() LIMIT 1")
|
||||||
rs.getString("token")
|
if(rs.next()) {
|
||||||
} else {
|
Some(rs.getString("token"))
|
||||||
generateChallenge(param)
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
val id = idOpt.getOrElse(generateChallenge(param))
|
||||||
val uuid = getUUID(id)
|
val uuid = getUUID(id)
|
||||||
Id(uuid)
|
Id(uuid)
|
||||||
}
|
}
|
||||||
|
|
||||||
def getUUID(id: String): String = {
|
def getUUID(id: String): String = {
|
||||||
val uuid = UUID.randomUUID().toString
|
val uuid = UUID.randomUUID().toString
|
||||||
mapPstmt.setString(1,uuid)
|
mapPstmt.synchronized {
|
||||||
mapPstmt.setString(2,id)
|
mapPstmt.setString(1,uuid)
|
||||||
mapPstmt.executeUpdate()
|
mapPstmt.setString(2,id)
|
||||||
|
mapPstmt.executeUpdate()
|
||||||
|
}
|
||||||
uuid
|
uuid
|
||||||
}
|
}
|
||||||
|
|
||||||
def checkAnswer(answer: Answer): Boolean = {
|
def checkAnswer(answer: Answer): Boolean = {
|
||||||
selectPstmt.setString(1, answer.id)
|
val psOpt:Option[ProviderSecret] = selectPstmt.synchronized {
|
||||||
val rs: ResultSet = selectPstmt.executeQuery()
|
selectPstmt.setString(1, answer.id)
|
||||||
if (rs.first()) {
|
val rs: ResultSet = selectPstmt.executeQuery()
|
||||||
val secret = rs.getString("secret")
|
if (rs.first()) {
|
||||||
val provider = rs.getString("provider")
|
val secret = rs.getString("secret")
|
||||||
providers(provider).checkAnswer(secret, answer.answer)
|
val provider = rs.getString("provider")
|
||||||
} else {
|
Some(ProviderSecret(provider, secret))
|
||||||
false
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
psOpt.map(ps => providers(ps.provider).checkAnswer(ps.secret, answer.answer)).getOrElse(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
def getHash(email: String): Int = {
|
def getHash(email: String): Int = {
|
||||||
|
Loading…
Reference in New Issue
Block a user