I am new to play framework(Scala),In my project I need to update new Password for this I need to get user id which is Primary key for that user table. Based on this unique user id value i will update Password.

What I need

need to get user table's user id value and pass this value into Controller's Action

What I tried

controllers/users.scala

 import play.api.mvc._
import play.api.data._
import play.api.data.Forms._
import views._
import models._


  val changepasswordForm = Form(
          mapping(
            "userid" -> ignored(None:Option[Int]),
              "password" -> tuple(
            "main" -> text,
            "confirm" -> text
          ).verifying(
            // Add an additional constraint: both passwords must match
            "Passwords don't match", passwords => passwords._1 == passwords._2
          ) 
          )(models.Changepassword.apply)(models.Changepassword.unapply)
          )

 def changePassword =   Action {
     Ok(html.changePassword(changepasswordForm))
   }



def updatePassword(userid: Int) = Action { implicit request =>
    changepasswordForm.bindFromRequest.fold(
      formWithErrors => BadRequest(html.changePassword(formWithErrors)),
      user => {
        Changepassword.update(userid, user)
    Ok("password Updated")
      }
    )
  }

models/User.scala

case class Changepassword(
     userid: Option[Int] = None,
     password:(String,String)
    )
object Changepassword{

    val simple = {
    get[Option[Int]]("user.USER_ID") ~
    get[String]("user.PASSWORD") map {
      case userid~password => Changepassword(userid, (password,password))
    }
  }
     def update(userid: Int,changepassword:Changepassword) = {
    DB.withConnection { implicit connection =>
      SQL("update  user set PASSWORD = {changepassword} where USER_ID = {userid}").
      on('userid -> userid,
          'changepassword -> changepassword.password._1)
      .executeUpdate()
    }
  }
}

views/changePassword.scala.html

@(userForm: Form[Changepassword])

@import helper._

@implicitFieldConstructor = @{ FieldConstructor(twitterBootstrapInput.f) } 

@main("") {

    <h1>Change Password</h1>

    @form(routes.Users.updatePassword(userForm.userid.get)) {

        <fieldset>


            @inputPassword(userForm("password.main"), '_label -> "New Password", '_help -> "",'placeholder -> "New Password")
             @inputPassword(userForm("password.confirm"), '_label -> "Confirm Password", '_help -> "",'placeholder -> "Repeat Password")

        </fieldset>

        <div class="actions">
            <input type="submit" value="Change password" class="btn primary"> or
            <a href="@routes.Application.index()" class="btn">Cancel</a> 
        </div>

    }

}

If I run activator compile command it shows below exception

D:\Jamal\test>activator compile
[info] Loading project definition from D:\Jamal\test\p
roject
[info] Set current project to scala-crud (in build file:/D:\Jamal\test/)
[info] Compiling 1 Scala source to D:\Jamal\test\targe
t\scala-2.11\classes...
[error] D:\Jamal\test\app\views\changePassword.sc
ala.html:11: value userid is not a member of play.api.data.Form[models.Changepas
sword]
[error]     @form(routes.Users.updatePassword(userForm.userid.get)) {
[error]                                                          ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 13 s, completed Jun 11, 2015 3:52:19 PM

D:\Jamal\test>
1

There are 1 answers

8
Peanut On BEST ANSWER

You can't use the value of the form as a parameter for the route:

@form(routes.Users.updatePassword(userForm.userid.get))

The userid depends on the form and could therefore change. In any case, you would access the userid of the form using userForm("userid") and not userForm.userid (although it might not be what you want/need).

A better approach for your problem would be to pass a second parameter like this:

controllers/users.scala

 def changePassword =   Action {
     val userId = ... get the current id ...
     Ok(html.changePassword(changepasswordForm,userId))
   }

views/changePassword.scala.html

@(userForm: Form[Changepassword], userId:Int)
...
...
  @form(routes.Users.updatePassword(userId)) {
   ...
   ...
  }
...

This way, you ensure the userId is known when the page is displayed and that a "evil" user can't change the passwords of other users by manipulating the userId.