incubator-esme-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Vassil Dichev <vdic...@apache.org>
Subject Re: Container-based authentication
Date Sun, 10 Jan 2010 08:48:43 GMT
> Played further with the Container-based AuthModule and got a little
> farther. Can't compile the code based on my limited Scala knowledge
> but I hope you see what I'm trying to achieve.

OK, baby steps.

> You'll notice that I left the ModuleName with "upw". I've done this,
> because I'd assume that the api2 could be used to create the users. A
> moduleName with "container" wouldn't make much sense.
>
> I also don't know what do do with "case Req("authentication" ::
> "login" :: Nil, _, PostRequest) =>", because it refers to a specific
> login page which we won't have if had container-based authentication.

Maybe the ifLoggedIn function in the *Mgr.scala would redirect to this
page on first request, which would then redirect back after
initializing the session.

> Maybe someon can give me a tip where my Scala mistakes are....
>
> object ContainerAuthModule extends AuthModule {
>
>  def moduleName: String = "upw"

While this is correct, the return value doesn't change, so you can use
a val instead of def. You can also safely skip the String declaration
and let the compiler infer the type of the result. For more
complicated return values, you could annotate the type for
documentation and a bit of extra assurance.

>  def performInit(): Unit = {
>    LiftRules.dispatch.append {
>      case Req("authentication" :: "login" :: Nil, _, PostRequest) =>
>        val from = S.referer openOr "/"
>
>        (for {
>            java.security.Principal principal = S.Request.getUserPrincipal();
>            if(principal != null) {
>                 String username = principal.getName();
>
>                  user <- UserAuth.find(By(UserAuth.authKey, username),
>                                  By(UserAuth.authType,
> moduleName)).flatMap(_.user.obj) or
>                  User.find(By(User.nickname, username))
>
>                  userAuth <- UserAuth.find(By(UserAuth.user,
> username), By(UserAuth.authType, moduleName))
>            }
>            if true
>          } yield user) match {
>          case Full(user) =>
>            User.logUserIn(user)
>            S.notice(S.?("base_user_msg_welcome", user.niceName))
>
>          case _ =>
>            S.error(S.?("base_user_err_unknown_creds"))
>        }
>
>        S.redirectTo(from)
>    }
>  }

It seems the big problem here is the "for" statement. What seems weird is this:

    if true
  } yield user

For comprehensions are not entirely like the Java for loop and yield
is not like return. It is more like a value to be returned for each of
the elements in the collection. Note that an Option or Box type can
also be viewed as a collection of zero or one elements, and using
these is more idiomatic than using an "if" filter (but this is a huge
topic in itself). This seems to be an informative article about "for"
comprehensions I found:

http://creativekarma.com/ee.php/weblog/comments/the_scala_for_comprehension_from_a_java_perspective/

Perhaps the best way would be to learn by example and show a more
"best practice" code. Let me try this later.

Mime
View raw message