This depends on HTTP_REFERER being set. It usually is, but there's no
guarantee. Another way I've found is to set a SessionVar in the
addDispatchBefore (or wherever you're redirecting to the login page).
Here's what I'm doing (suggestions for improvement most welcome):
(Member is the user model. There are booleans for isDeveloper and
isAdministrator, plus an enum for the various types of Member. Then I
call isDeveloper_?, isAdministrator_?, or isMember_?(<list of types>) in
the SiteMap.)
I'll be adding a Role feature soon, where specific methods will have
rights (e.g. view.categories, update.members) associated with them,
Members will have Roles and Roles will have Rights and a simple test on
the method will determine how the method proceeds.
In boot:
// Keeps folks who ain't logged in out of the admin directory
LiftRules.addDispatchBefore {
case RequestState("admin" :: page , "", _)
if !AccessControl.isAuthenticated_? =>
S.error("Please log in to view the page you requested.")
RequestedURL(Full(S.uri))
() => Full(RedirectResponse("/login"))
}
Elsewhere:
object CurrentUserId extends SessionVar[Can[Long]](Empty)
object RequestedURL extends SessionVar[Can[String]](Empty)
object CurrentUser extends RequestVar[Can[Member]](Empty)
object AccessControl {
// Log the user in
def login(): Can[LiftResponse] = {
if (S.post_?) {
try {
val member: Member =
Model.createNamedQuery[Member]("findMemberByEmailAddress",
"emailAddress" -> S.param("emailAddress").openOr("")).findOne
if (member.authenticate(S.param("password").openOr(""))) {
CurrentUser(Full(member))
CurrentUserId(Full(member.id))
}
else
S.error("Unable to log you in. Please check your " +
"email address and password and try again.")
} catch {
case x: NoResultException =>
S.error("Unable to log you in. Please check your " +
"email address and password and try again.")
case _ => S.error("Oooh, that's gotta hurt.")
}
}
val uri = RequestedURL.openOr("/")
RequestedURL(Empty)
Full(RedirectResponse(uri))
}
// Log the user out
def logout(): Can[LiftResponse] = {
CurrentUser(Empty)
CurrentUserId(Empty)
Full(RedirectResponse(S.param("path").openOr("/")))
}
// Is there a logged-in user?
def isAuthenticated_?() =
CurrentUserId.is.map((Long) => true) openOr false
// Is this user a developer?
def isDeveloper_?() : Boolean = {
CurrentUser.is match {
case Empty => CurrentUserId.is match {
case Empty => false
case Full(id) => Model.find(classOf[Member], id) match {
case null => false
case m => CurrentUser(Full(m))
m.isDeveloper
}
}
case Full(m) => m.isDeveloper
}
}
// Is this user an administrator?
def isAdministrator_?() : Boolean = {
isDeveloper_? || (CurrentUser.is match {
case Empty => CurrentUserId.is match {
case Empty => false
case Full(id) => Model.find(classOf[Member], id) match {
case null => false
case m => CurrentUser(Full(m))
m.isAdministrator
}
}
case Full(m) => m.isAdministrator
})
}
// Allow isMember_? with a string
def isMember_?(mtype: String)() : Boolean = isMember_?(List(mtype))()
// Takes a list of member types and determines if this member
// is one of them
def isMember_?(mtypes: List[String])() : Boolean = {
isAdministrator_? || (
CurrentUser.is match {
case Empty => CurrentUserId.is match {
case Empty => false
case Full(id) => Model.find(classOf[Member], id) match {
case null => false
case m => CurrentUser(Full(m))
mtypes.filter(
_.compareToIgnoreCase(m.memberGroup.toString) == 0
).size > 0
}
}
case Full(m) =>
mtypes.filter(
_.compareToIgnoreCase(m.memberGroup.toString) == 0
).size > 0
}
)
}
}
Chas.
David Pollak wrote:
> object Login {
> def login() = {
> val from = S.referer.openOr("/")
>
> User.currentUser match {
> case Full(_) => // do nothing
> case _ =>
> def testPwd(user: User, pwd: String): Can[Boolean] =
> if (user.password.match_?(pwd)) {
> if (user.invalid_?) Failure(user.invalidReason, Empty, Nil)
> else {User.logUserIn(user); Full(true)}
>
> //Full(true)
> } else Failure("Password mis-match", Empty, Nil)
>
> (for (email <- S.param("username") ?~ "No Username";
> pwd <- S.param("password") ?~ "No Password";
> user <- User.find(By(User.email, email)) ?~ "User Not Found";
> success <- testPwd(user, pwd)) yield {
> user
> }) match {
> case Full(user) => S.notice("Welcome: "+user.niceName)
> if (!user.validated) {
> S.notice("Until your registration is confirmed, you cannot
> edit pages in the wiki")
> }
> case Failure(msg, _, _) => S.error(msg)
> case _ => S.error("Not logged In")
> }
> }
>
> Full(RedirectResponse(from))
> }
>
> def logout() = {
> val from = S.referer.openOr("/")
>
> User.logoutCurrentUser
> S.notice("Logged Out")
>
> Full(RedirectResponse(from))
> }
> }
>
>
> On Tue, Oct 21, 2008 at 2:05 PM, Derek Chen-Becker
> <[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>> wrote:
>
> A followup question. If I want to redirect back to the original page
> that prompted the login redirect, how would I get that? I know I can
> get use S.uri to get everything but the query string, but do I need
> to dig deeper into the actual HttpServletRequest to get at
> everything after the host portion?
>
> Thanks,
>
> Derek
>
>
> On Tue, Oct 21, 2008 at 2:21 PM, Derek Chen-Becker
> <[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>> wrote:
>
> OK, that makes sense. Sometimes when you have a hammer
> everything looks like a nail :)
>
>
> On Tue, Oct 21, 2008 at 2:05 PM, David Pollak
> <[EMAIL PROTECTED]
> <mailto:[EMAIL PROTECTED]>> wrote:
>
> SessionVars are not available during URL rewriting. URL
> rewriting takes place before the session is obtained. This
> is deliberate because the URL rewriting takes place before
> the sessionless dispatch is consulted. This happens before
> the session is retrieved/created and the regular flow happens.
>
> Access control on an HTML page level should be done in SiteMap.
>
>
> On Tue, Oct 21, 2008 at 1:00 PM, Derek Chen-Becker
> <[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>> wrote:
>
> I could have sworn this had been covered recently on the
> list but I can't seem to find it. I'd like to have a
> rewrite function that checks to see if someone is logged
> in and in the proper role before allowing them to get to
> the page. I had wanted to do this using
> LiftRules.addRewriteBefore combined with two SessionVars
> that would hold the user name and their roles (if logged
> in). Unfortunately, it looks like SessionVars don't seem
> to be usable inside the rewrite function because the
> LiftSession hasn't been set up yet at that point. I'm I
> missing something obvious, or does anyone have some
> suggestions for doing it in a different/better way?
>
> Thanks,
>
> Derek
>
>
>
>
>
> --
> Lift, the simply functional web framework http://liftweb.net
> Collaborative Task Management http://much4.us
> Follow me: http://twitter.com/dpp
> Git some: http://github.com/dpp
>
>
>
>
>
>
>
>
>
> --
> Lift, the simply functional web framework http://liftweb.net
> Collaborative Task Management http://much4.us
> Follow me: http://twitter.com/dpp
> Git some: http://github.com/dpp
>
> >
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Lift" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/liftweb?hl=en
-~----------~----~----~----~------~----~------~--~---