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
-~----------~----~----~----~------~----~------~--~---

Reply via email to