Question

I feel like I'm monopolizing the stack for Scala/Lift, so I apologize, but the questions keep coming. Here's the latest.

I'm trying to restrict access to anything in the /login/* to those users who have not yet logged in.

Here is how I'm trying to do it:

val entries = Menu(Loc("Home", List("index"), "Home")) ::  //login stuff
    Menu(Loc("loginBase", ("login"::""::Nil)->true, "Login Base", Hidden, anyLoggedIn))::...

Thats the entry in SiteMap. Then I define anyLoggedIn in Boot.scala like so:

val anyLoggedIn  = If(() => !(Student.loggedIn_? || Provider.loggedIn_?), 
            if (sessionLoginType.is map {_ == StudentLogin} openOr false)
            {
                println("student")
                RedirectResponse("studentHome")

            }
            else 
            {
                println("provider")
                RedirectResponse("providerHome")
            }

I want to send providers and students to their "homes" respectively, when they try to access any login page when they are already logged in. For some reason, (maybe its my boolean logic), it never works, and I never make it to the redirects.

Any Ideas?

Thanks

Was it helpful?

Solution

Common mistake with val is to define a variable after the use:

scala> object test {  
     | val f = x      
     | val x = 1      
     | }
defined module test

scala> println(test.f)
0

Which is pretty often mistake when working with Lift's SiteMap conditions (I personally tend to define them in the bottom). To overcome this, define your val as lazy:

scala> object test {  
     | val f = x      
     | lazy val x = 1 
     | }
defined module test

scala> println(test.f)
1

Side note

Your second test in If does not look too Scalaish, it's a mix of functional and procedural styles. There are options on how to write it, please see just one possible variant:

sessionLoginType.is match {
  case Full(StudentLogin) => 
    println("student")
    RedirectResponse("studentHome")
  case Full(ProviderLogin) =>
    println("provider")
    RedirectResponse("providerHome")
}

Another option

You can define a static map from login type to uri, e.g.

val redirectMap = Map(StudentLogin -> "studentHome", ProviderLogin -> "providerHome")

Then you can use it in your If like

sessionLoginType.is.flatMap{ redirectMap.get }.map{ RedirectResponse _ }.open_!

the same can be rewritten using for-comprehensions:

(for {val loginType <- sessionLoginType.is
      val uri <- redirectMap.get(loginType) }
      yield RedirectResponse(uri)
).open_!

But beware, if redirectMap does not contain a key or your sessionLoginType is empty, you are in trouble -- open_! will fail, as it should not be applied to empty boxes. If you know a reasonable default value, better use .openOr defaultRedirect

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top