Best way to create an entry / exit form in Scala using Lift

As more and more people are interested in Scala (like me), and not a question, I would like to discuss one implementation of the Lift-based webapp login / logout fragment .

I just started to learn Scala and Lift, so it may not be the best way to implement such a function, but I would like to share it with other beginners and discuss it with more experienced developers.Please note that I am also not a specialist in web development . Any help for improvements would be greatly appreciated (especially in terms of performance and security); -)

1) First of all, the fragment should be easily connected, for example, with 1 line of code in the default template. I did this using the built-in Elevator function (pay attention to underlining so that it does not appear as the page itself, but is called only from the displayed page, in short, some kind of "private" fragment):

<lift:embed what="_logInForm" />

2) Then, in _logInForm.html, I use the markup below and the conditional display to handle everything:

<div>
    <!-- User is not logged in, show a form to log in using the method loggedOut -->
    <lift:LogInForm.loggedOut>
        <form class="lift:LogInForm.logIn?form=post">
            <label for="textName">Username: </label><input type="text" id="textName" name="name" /> <span class="lift:Msg?id=name;errorClass=error"/><br/>
            <label for="textPassword">Password: </label><input type="password" id="textPassword" name="password" /> <span class="lift:Msg?id=password;errorClass=error"/><br/>
            <input type="submit" value="Log in" />
        </form>
    </lift:LogInForm.loggedOut>

    <!-- User is logged in, show who she is and a way to log out using the method loggedIn -->
    <lift:LogInForm.loggedIn>
        <form class="lift:LogInForm.logOut?form=post">
        Connected as <span class="lift:LogInForm.getName" />.<br />
        <input type="submit" id="btnLogOut" value="Log out" />
        </form>
    </lift:LogInForm.loggedIn>
</div>

3) ... and now the Scala / Lift logic behind this markup:

object LogInForm {
  private object name extends SessionVar("")
  private object password extends RequestVar("")
  private object referer extends RequestVar(S.referer openOr "/")
  var isLoggedIn = false

  def loggedIn(html: NodeSeq) =
    if (isLoggedIn) html else NodeSeq.Empty

  def loggedOut(html: NodeSeq) =
    if (!isLoggedIn) html else NodeSeq.Empty

  def logIn = {
    def processLogIn() {
      Validator.isValidName(name) match {
        case true => {
          Validator.isValidLogin(name, password) match {
            case true => { isLoggedIn = true } // Success: logged in
            case _ => S.error("password", "Invalid username/password!")
          }
        }
        case _ => S.error("name", "Invalid username format!")
      }
    }

    val r = referer.is
    "name=name" #> SHtml.textElem(name) &
      "name=password" #> (
        SHtml.textElem(password) ++
          SHtml.hidden(() => referer.set(r))) &
      "type=submit" #> SHtml.onSubmitUnit(processLogIn)
  }

  def logOut = {
    def processLogOut() { isLoggedIn = false }
    val r = referer.is
    "type=submit" #> SHtml.onSubmitUnit(processLogOut)
  }

  def getName = "*" #> name.is
}

Comments:

  • , , NodeSeq.Empty, , , .
  • : Msg, (/). S.error id.
  • Validator, .. , .
  • referer, / , .
  • .

4) , Boot.scala:

    def sitemap() = SiteMap(
      Menu("Home") / "index",
      Menu("Protected page") / "protectedPageName" >> If(() => LogInForm.isLoggedIn, ""),
      // etc.

:

  • SSL ( , Scala/Lift). - ?
  • . , Scala/Lift?
  • - / Lift, ?
  • , ? ( . )
  • ?

,

.

+5
2
+2

. net.liftweb.proto.ProtoUser. login() loginXhtml.

Lift :

  • ,

    package yourcompany.model
    
    import net.liftweb.mapper._
    import net.liftweb.util._
    import net.liftweb.common._
    
    class User extends MegaProtoUser[User] { 
      // your code, mostly overrides
    
    }
    
    object User extends User with MetaMegaProtoUser[User] {
      override def dbTableName = "users"
      // other database related code
    }
    
  • :

    // do not forget to import your user
    def sitemap() = Sitemap(Menu("Home") / "index" >> User.AddUserMenusAfter)
    
    // now comes the magic
    LiftRules.setSiteMap(User.sitemapMutator(sitemap()))
    

, /user_mgt, . sign_up, login, lost_password. . , ProtoUser, .

, - , . .

+2

All Articles