Doran L. Barton wrote:

Not long ago, Fernan Aguero proclaimed...
Certainly not what you were asking (subclassing
store::dbic), but  ...


sub login : Local {
my ( $self, $c ) = @_; my $username = $c->req->params->{username} || ""; my $password = $c->req->params->{password} || "";
   my $model = $c->model('Users');

   if ( $username && $password ) {

     # attempt to login
     if ( $c->login( $username, $password ) ) {

       # now we check site_id
       $ok = $model->search(
         { username => $username,
           password => $password,
           site_id  => $site_id } )->count();
$c->logout unless $ok > 0;

     }

This is an interesting strategy. The only thing I question is the
$c->login() call because the username field is not unique (there could be
more than one 'johndoe' in the table).

After I posted my original question, I started wondering about
concatenating the username and site_id together. I have a feeling this
won't fly well inside DBIx::Class, but in theory if I declare the user
field to be "username || '#' || site_id" and call the login() using
$username . '#' . $c->stash->{'site_id'}, the resulting SELECT in sql would
find the unique row. Of course, that all falls apart in the ORM, most
likely.
We had a similar requirement, and came to a slightly different solution than proposed by Fernan. Instead of authenticating on username/password, we authenticated based on user_id/password where user_id is the primary key and guaranteed to be unique.

In the login subroutine, we pulled the user object based on the username param and the site_id, and then called $c->login with the user object's id and the password param. In code-speak:

In our setup:

__PACKAGE__->config->{ authentication }{ dbic } = {
   user_class    => 'MyModel::users'
   user_field     => 'id',        # guaranteed to be unique
   password_field => 'password',
};

Our login function:

sub login : Local {
   my ( $self, $c ) = @_;

   my $username = $c->req->params->{ username } || '';
   my $password = $c->req->params->{ password } || '';
   my $site_id  = $c->req->params->{ site_id };

   if ( $username && $password ) {
       my $user_obj = $c->model( 'MyModel::users' )->search(
           {
               username => $username,
               site_id  => $site_id,
           }
       )->first;

       if ( $user_obj && $c->login( $user_obj->id, $password ) ) {
# user's logged in... }
   }
}

This process takes an extra query since the authentication class does it's own query as well, but it solves the problem. I hope that helps.

Ashvin

_______________________________________________
List: Catalyst@lists.rawmode.org
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/
Dev site: http://dev.catalyst.perl.org/

Reply via email to