Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

autarch (914)

autarch
  (email not shown publicly)
http://www.vegguide.org/

Journal of autarch (914)

Saturday March 03, 2007
12:24 PM

Catalystic conversion - part 4

[ #32553 ]

So I wanted to adapt my user handling bits to work with Catalyst's Authentication plugins. I decided to go ahead and use the dev version of Catalyst::Plugin::Authentication, since this presumably will be the Catalyst way in the future.

However, there was one hitch in adapting my app's notion of a user to Catalyst's. In my app, there is always a user object, whether or not the end user has actually authenticated. Before an end user authenticates, this object is a VegGuide::User::Guest, and afterwards it's a VegGuide::User. I like this style because it means I can always count on having a user object. I find code like this rather tedious:

if ( $c->user() and $c->user()->get_object()->can_delete_entry() )
{
    ...
}

When I know that $c->user()->get_object() always returns a valid object, the code that ends up written is much clearer in its intent.

if ( $c->user()->get_object()->can_delete_entry() )
{
    ...
}

This wasn't too hard to work around. I have a controller for my root URI-space that includes an auto() method like this:

sub auto : Private
{
    my $self = shift;
    my $c    = shift;
 
    $c->authenticate( {} )
        unless $c->user();
 
    ...
 
    return 1;
}

This is a bit of a hack, but it works. Once a user has hit the site once, their user_id is stored in their session. This means that $c->user() will always return something after the first hit. If the user hasn't really authenticated, then the session will just indicate that they are a guest.

It would be nice if Catalyst::Plugin::Authentication could support this style of usage natively, maybe with a flag like "auto_authenticate" or something.

To make this work, all I need to do is implement appropriate logic in my Store plugin. If we have real credentials to use, we try to load real user, otherwise we return a guest:

sub find_user
{
    my $class = shift;
    my $auth  = shift;
    my $c     = shift;
 
    my $user = VegGuide::User->new(%$auth)
        if %$auth;
 
    $user ||= VegGuide::User::Guest->new();
 
    return VegGuide::Plugin::Authentication::User->new($user);
}

The VegGuide::Plugin::Authentication::User class provides the minimal glue needed to make Catalyst happy. I didn't want my core user data object to subclass Catalyst::Plugin::Authentication::User, which feels unclean to me. Outside of Catalyst, I don't need any of the methods that Catalyst::Plugin::Authentication::User demands, and I want to make sure that any code that isn't webapp-specific is usable without Catalyst in the mix.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.