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.