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() ) { ... }
$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() ) { ... }
auto()
method like this:sub auto : Private { my $self = shift; my $c = shift;
$c->authenticate( {} ) unless $c->user();
...
return 1; }
$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.Catalyst::Plugin::Authentication
could support this style of usage natively, maybe with a flag like "auto_authenticate" or something.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); }
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.