I have the following code:
def authenticateByUsername(username: String, password:String): Boolean = { val user = users.findOne(MongoDBObject(USERNAME -> username)) if(user.isDefined){ val pw = user.get.getAs(PASSWORD) if(pw.isDefined) BCrypt.checkpw(pw.get, password) else false }else false }
Is there a more idiomatic way of doing this? It's an if-else nightmare, which just doesn't seem right in Scala.
You're correct that there's a better way, and in general using get
(or, to a slightly lesser degree, isDefined
) on an Option
is a red flag. In this case you can use a for
-comprehension:
def authenticateByUsername(username: String, password: String): Boolean = {
val result: Option[Boolean] = for {
user <- users.findOne(MongoDBObject(USERNAME -> username))
pass <- user.getAs(PASSWORD)
} yield BCrypt.checkpw(pass, password)
result getOrElse false
}
Or, a little more concisely:
def authenticateByUsername(username: String, password: String): Boolean =
users.findOne(MongoDBObject(USERNAME -> username)).flatMap(
_.getAs(PASSWORD)
).map(
BCrypt.checkpw(_, password)
).getOrElse(false)
The latter is essentially just a desugared version of the for
-comprehension.