If values in Boot.scala (Scala Lift)
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
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