Question

I'd like to validate a Play 2 Scala password update form using data about the current user. Imagine a form that collects current password, new password, and new password again. On validation of this form should be whether the value for "current password" actually matches the current users actual password. In the validation, I'll need access to the current user - which requires access to the current request. Obviously request is not in scope when I define the form:

val updatePasswordForm = Form(mapping(
"currPassword" -> password,
"newPassword" -> password,
"newPasswordAgain" -> password)(PasswordUpdate.apply)(PasswordUpdate.unapply)
verifying ("passwordsMustMatch", update => update.newPassword == update.newPasswordAgain)
verifying ("incorrectCurrentPassword", pws => authenticate(GAH NEED CURRENT USERS EMAIL, update.currPassword)))

I completely appreciate that having Request access in form validation would introduce a unwanted dependency for Forms. I'm just curious if people have a clever way around this. My only approach so far is something like this:

def updatePassword = Action { implicit req =>
  validateCurrentPasswordMatches(updatePasswordForm).bindFromRequest.fold(
  ....

I'd love a way to package this Request-dependent validation right inside the shared Form declaration.

Was it helpful?

Solution

You can obtain your update password form using a function with an implicitly defined Request parameter like so:

def updatePasswordForm(implicit request: Request[_]) = Form(
    // define form here
).verifying(...)

The request parameter is implicitly passed on from the bindFromRequest function.

The authenticate function now has access to the (again implicitly defined) request parameter. You need to re-define it as

def authenticate( /* old parameters */ )(implicit request: Request[_]): Boolean = {
    // implementation with access to the Request
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top