[Catalyst-commits] r6541 - in trunk/Catalyst-Plugin-Authentication:
. lib/Catalyst/Plugin lib/Catalyst/Plugin/Authentication
lib/Catalyst/Plugin/Authentication/Credential
lib/Catalyst/Plugin/Authentication/Store
lib/Catalyst/Plugin/Authentication/Store/Minimal
lib/Catalyst/Plugin/Authentication/User
matthewt at dev.catalyst.perl.org
matthewt at dev.catalyst.perl.org
Tue Jul 17 17:57:33 GMT 2007
Author: matthewt
Date: 2007-07-17 17:57:33 +0100 (Tue, 17 Jul 2007)
New Revision: 6541
Modified:
trunk/Catalyst-Plugin-Authentication/
trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication.pm
trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/Credential/Password.pm
trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/Store/Minimal.pm
trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/Store/Minimal/Backend.pm
trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/User.pm
trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/User/Hash.pm
Log:
r33939 at cain (orig r5489): jayk | 2006-11-10 22:29:07 +0000
Updates to authentication system. Initial import of modifications.
POD documentation NOT complete yet... so this is a RTFS import
Property changes on: trunk/Catalyst-Plugin-Authentication
___________________________________________________________________
Name: svk:merge
+ 4ad37cd2-5fec-0310-835f-b3785c72a374:/branches/Catalyst-Plugin-Authentication:5489
Modified: trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/Credential/Password.pm
===================================================================
--- trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/Credential/Password.pm 2007-07-17 16:40:30 UTC (rev 6540)
+++ trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/Credential/Password.pm 2007-07-17 16:57:33 UTC (rev 6541)
@@ -9,36 +9,105 @@
use Catalyst::Exception ();
use Digest ();
-sub login {
- my ( $c, $user, $password, @rest ) = @_;
+sub new {
+ my ($class, $config, $app) = @_;
+
+ my $self = { %{$config} };
+ $self->{'password_field'} ||= 'password';
+ $self->{'password_type'} ||= 'clear';
+ $self->{'password_hash_type'} ||= 'SHA-1';
+
+ if (!grep /$$self{'password_type'}/, ('clear', 'hashed', 'salted_hash', 'crypted', 'self_check')) {
+ Catalyst::Exception->throw(__PACKAGE__ . " used with unsupported password type: " . $self->{'password_type'});
+ }
- for ( $c->request ) {
- unless (
- defined($user)
- or
- $user = $_->param("login")
- || $_->param("user")
- || $_->param("username")
- ) {
- $c->log->debug(
- "Can't login a user without a user object or user ID param")
- if $c->debug;
- return;
+ bless $self, $class;
+}
+
+sub authenticate {
+ my ( $self, $c, $authstore, $authinfo ) = @_;
+
+ my $user_obj = $authstore->find_user($authinfo, $c);
+ if ($user_obj) {
+ if ($self->check_password($user_obj, $authinfo)) {
+ return $user_obj;
}
+ } else {
+ $c->log->debug("Unable to locate user matching user info provided");
+ return;
+ }
+}
- unless (
- defined($password)
- or
- $password = $_->param("password")
- || $_->param("passwd")
- || $_->param("pass")
- ) {
- $c->log->debug("Can't login a user without a password")
- if $c->debug;
- return;
+sub check_password {
+ my ( $self, $user, $authinfo ) = @_;
+
+ if ($self->{'password_type'} eq 'self_check') {
+ return $user->check_password($authinfo->{$self->{'password_field'}});
+ } else {
+ my $password = $authinfo->{$self->{'password_field'}};
+ my $storedpassword = $user->get($self->{'password_field'});
+
+ if ($self->{password_type} eq 'clear') {
+ return $password eq $storedpassword;
+ } elsif ($self->{'password_type'} eq 'crypted') {
+ return $storedpassword eq crypt( $password, $storedpassword );
+ } elsif ($self->{'password_type'} eq 'salted_hash') {
+ require Crypt::SaltedHash;
+ my $salt_len = $self->{'password_salt_len'} ? $self->{'password_salt_len'} : 0;
+ return Crypt::SaltedHash->validate( $storedpassword, $password,
+ $salt_len );
+ } elsif ($self->{'password_type'} eq 'hashed') {
+
+ my $d = Digest->new( $self->{'password_hash_type'} );
+ $d->add( $self->{'password_pre_salt'} || '' );
+ $d->add($password);
+ $d->add( $self->{'password_post_salt'} || '' );
+
+ my $computed = $d->clone()->digest;
+ my $b64computed = $d->clone()->b64digest;
+ return ( ( $computed eq $storedpassword )
+ || ( unpack( "H*", $computed ) eq $storedpassword )
+ || ( $b64computed eq $storedpassword)
+ || ( $b64computed.'=' eq $storedpassword) );
}
}
+}
+## BACKWARDS COMPATIBILITY - all subs below here are deprecated
+## They are here for compatibility with older modules that use / inherit from C::P::A::Password
+## login()'s existance relies rather heavily on the fact that Credential::Password
+## is being used as a credential. This may not be the case. This is only here
+## for backward compatibility. It will go away in a future version
+## login should not be used in new applications.
+
+sub login {
+ my ( $c, $user, $password, @rest ) = @_;
+
+ unless (
+ defined($user)
+ or
+ $user = $c->request->param("login")
+ || $c->request->param("user")
+ || $c->request->param("username")
+ ) {
+ $c->log->debug(
+ "Can't login a user without a user object or user ID param")
+ if $c->debug;
+ return;
+ }
+
+ unless (
+ defined($password)
+ or
+ $password = $c->request->param("password")
+ || $c->request->param("passwd")
+ || $c->request->param("pass")
+ ) {
+ $c->log->debug("Can't login a user without a password")
+ if $c->debug;
+ return;
+ }
+
unless ( Scalar::Util::blessed($user)
and $user->isa("Catalyst::Plugin::Authentication::User") )
{
@@ -64,11 +133,13 @@
if $c->debug;
return;
}
+
}
+## also deprecated. Here for compatibility with older credentials which do not inherit from C::P::A::Password
sub _check_password {
my ( $c, $user, $password ) = @_;
-
+
if ( $user->supports(qw/password clear/) ) {
return $user->password eq $password;
}
Modified: trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/Store/Minimal/Backend.pm
===================================================================
--- trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/Store/Minimal/Backend.pm 2007-07-17 16:40:30 UTC (rev 6540)
+++ trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/Store/Minimal/Backend.pm 2007-07-17 16:57:33 UTC (rev 6541)
@@ -9,9 +9,9 @@
use Scalar::Util ();
sub new {
- my ( $class, $hash ) = @_;
+ my ( $class, $config, $app) = @_;
- bless { hash => $hash }, $class;
+ bless { hash => $config }, $class;
}
sub from_session {
@@ -19,25 +19,28 @@
return $id if ref $id;
- $self->get_user( $id );
+ $self->find_user( { id => $id } );
}
-sub get_user {
- my ( $self, $id ) = @_;
+## this is not necessarily a good example of what find_user can do, since all we do is
+## look up with the id anyway. find_user can be used to locate a user based on other
+## combinations of data. See C::P::Authentication::Store::DBIx::Class for a better example
+sub find_user {
+ my ( $self, $userinfo, $c ) = @_;
- return unless exists $self->{hash}{$id};
+ my $id = $userinfo->{'id'};
+
+ return unless exists $self->{'hash'}{$id};
- my $user = $self->{hash}{$id};
+ my $user = $self->{'hash'}{$id};
if ( ref $user ) {
if ( Scalar::Util::blessed($user) ) {
- $user->store( $self );
$user->id( $id );
return $user;
}
elsif ( ref $user eq "HASH" ) {
$user->{id} ||= $id;
- $user->{store} ||= $self;
return bless $user, "Catalyst::Plugin::Authentication::User::Hash";
}
else {
@@ -64,6 +67,18 @@
$user->supports(@_);
}
+## Backwards compatibility
+#
+# This is a backwards compatible routine. get_user is specifically for loading a user by it's unique id
+# find_user is capable of doing the same by simply passing { id => $id }
+# no new code should be written using get_user as it is deprecated.
+sub get_user {
+ my ( $self, $id ) = @_;
+ $self->find_user({id => $id});
+}
+
+
+
__PACKAGE__;
__END__
Modified: trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/Store/Minimal.pm
===================================================================
--- trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/Store/Minimal.pm 2007-07-17 16:40:30 UTC (rev 6540)
+++ trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/Store/Minimal.pm 2007-07-17 16:57:33 UTC (rev 6541)
@@ -11,8 +11,8 @@
my $c = shift;
$c->default_auth_store(
- Catalyst::Plugin::Authentication::Store::Minimal::Backend->new(
- $c->config->{authentication}{users}
+ Catalyst::Plugin::Authentication::Store::Minimal::Backend->new(
+ $c->config->{authentication}{users}, $c
)
);
Modified: trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/User/Hash.pm
===================================================================
--- trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/User/Hash.pm 2007-07-17 16:40:30 UTC (rev 6540)
+++ trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/User/Hash.pm 2007-07-17 16:57:33 UTC (rev 6541)
@@ -24,10 +24,11 @@
$self->_accessor( "id", @_ );
}
-sub store {
- my $self = shift;
- $self->_accessor( "store", @_ ) || ref $self;
-}
+## deprecated. Let the base class handle this.
+# sub store {
+# my $self = shift;
+# $self->_accessor( "store", @_ ) || ref $self;
+# }
sub _accessor {
my $self = shift;
Modified: trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/User.pm
===================================================================
--- trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/User.pm 2007-07-17 16:40:30 UTC (rev 6540)
+++ trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/User.pm 2007-07-17 16:57:33 UTC (rev 6541)
@@ -5,10 +5,18 @@
use strict;
use warnings;
-sub id { die "virtual" }
-sub store { die "virtual" }
+## chances are you want to override this.
+sub id { shift->get('id'); }
+## returns the realm the user came from - not a good idea to override this.
+sub auth_realm {
+ my $self = shift;
+ $self->{'realm'};
+}
+
+
+
sub supports {
my ( $self, @spec ) = @_;
@@ -25,6 +33,47 @@
return $cursor;
}
+## REQUIRED.
+## get should return the value of the field specified as it's single argument from the underlying
+## user object. This is here to provide a simple, standard way of accessing individual elements of a user
+## object - ensuring no overlap between C::P::A::User methods and actual fieldnames.
+## this is not the most effecient method, since it uses introspection. If you have an underlying object
+## you most likely want to write this yourself.
+sub get {
+ my ($self, $field) = @_;
+
+ my $object;
+ if ($object = $self->get_object && $object->can($field)) {
+ return $object->$field();
+ } else {
+ return undef;
+ }
+}
+
+## REQUIRED.
+## get_object should return the underlying user object. This is for when more advanced uses of the
+## user is required. Modifications to the existing user, etc. Changes in the object returned
+## by this routine may not be reflected in the C::P::A::User object - if this is required, re-authenticating
+## the user is probably the best route to take.
+## note that it is perfectly acceptable to return $self in cases where there is no underlying object.
+sub get_object {
+ return shift;
+}
+
+## this is an internal routine. I suggest you don't rely on it's presence.
+## sets the realm the user came from.
+sub _set_auth_realm {
+ my ($self, $realmname) = @_;
+ $self->{'realm'} = $realmname;
+}
+
+## Backwards Compatibility
+## you probably want auth_realm, in fact. but this does work for backwards compatibility.
+sub store {
+ my ($self) = @_;
+ return $self->auth_realm->{store};
+}
+
__PACKAGE__;
__END__
Modified: trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication.pm
===================================================================
--- trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication.pm 2007-07-17 16:40:30 UTC (rev 6540)
+++ trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication.pm 2007-07-17 16:57:33 UTC (rev 6541)
@@ -6,7 +6,7 @@
BEGIN {
__PACKAGE__->mk_accessors(qw/_user/);
- __PACKAGE__->mk_classdata($_) for qw/_auth_stores _auth_store_names/;
+ __PACKAGE__->mk_classdata($_) for qw/_auth_realms/;
}
use strict;
@@ -22,19 +22,27 @@
# constant->import(have_want => eval { require Want });
#}
-our $VERSION = "0.09";
+our $VERSION = "0.10";
sub set_authenticated {
- my ( $c, $user ) = @_;
+ my ( $c, $user, $realmname ) = @_;
$c->user($user);
$c->request->{user} = $user; # compatibility kludge
- if ( $c->_should_save_user_in_session($user) ) {
- $c->save_user_in_session($user);
+ if (!$realmname) {
+ $realmname = 'default';
}
-
- $c->NEXT::set_authenticated($user);
+
+ if ( $c->isa("Catalyst::Plugin::Session")
+ and $c->config->{authentication}{use_session}
+ and $user->supports("session") )
+ {
+ $c->save_user_in_session($realmname, $user);
+ }
+ $user->_set_auth_realm($realmname);
+
+ $c->NEXT::set_authenticated($user, $realmname);
}
sub _should_save_user_in_session {
@@ -72,17 +80,28 @@
}
}
+# change this to allow specification of a realm - to verify the user is part of that realm
+# in addition to verifying that they exist.
sub user_exists {
my $c = shift;
return defined($c->_user) || defined($c->_user_in_session);
}
+
sub save_user_in_session {
- my ( $c, $user ) = @_;
+ my ( $c, $realmname, $user ) = @_;
- my $store = $user->store || ref $user;
- $c->session->{__user_store} = $c->get_auth_store_name($store) || $store;
- $c->session->{__user} = $user->for_session;
+ $c->session->{__user_realm} = $realmname;
+
+ # we want to ask the backend for a user prepared for the session.
+ # but older modules split this functionality between the user and the
+ # backend. We try the store first. If not, we use the old method.
+ my $realm = $c->get_auth_realm($realmname);
+ if ($realm->{'store'}->can('for_session')) {
+ $c->session->{__user} = $realm->{'store'}->for_session($c, $user);
+ } else {
+ $c->session->{__user} = $user->for_session;
+ }
}
sub logout {
@@ -90,31 +109,30 @@
$c->user(undef);
- if ( $c->_should_load_user_from_session ) {
- $c->_delete_user_from_session();
+ if (
+ $c->isa("Catalyst::Plugin::Session")
+ and $c->config->{authentication}{use_session}
+ and $c->session_is_valid
+ ) {
+ delete @{ $c->session }{qw/__user __user_realm/};
}
$c->NEXT::logout(@_);
}
-sub _delete_user_from_session {
- my $c = shift;
- delete @{ $c->session }{qw/__user __user_store/};
+sub find_user {
+ my ( $c, $userinfo, $realmname ) = @_;
+
+ $realmname ||= 'default';
+ my $realm = $c->get_auth_realm($realmname);
+ if ( $realm->{'store'} ) {
+ return $realm->{'store'}->find_user($userinfo, $c);
+ } else {
+ $c->log->debug('find_user: unable to locate a store matching the requested realm');
+ }
}
-sub get_user {
- my ( $c, $uid, @rest ) = @_;
- if ( my $store = $c->default_auth_store ) {
- return $store->get_user( $uid, @rest );
- }
- else {
- Catalyst::Exception->throw(
- "The user id $uid was passed to an authentication "
- . "plugin, but no default store was specified" );
- }
-}
-
sub _user_in_session {
my $c = shift;
@@ -132,84 +150,260 @@
}
sub auth_restore_user {
- my ( $c, $frozen_user, $store_name ) = @_;
+ my ( $c, $frozen_user, $realmname ) = @_;
$frozen_user ||= $c->_user_in_session;
return unless defined($frozen_user);
- $store_name ||= $c->_store_in_session;
- return unless $store_name; # FIXME die unless? This is an internal inconsistency
+ $realmname ||= $c->session->{__user_realm};
+ return unless $realmname; # FIXME die unless? This is an internal inconsistency
- my $store = $c->get_auth_store($store_name);
-
- $c->_user( my $user = $store->from_session( $c, $frozen_user ) );
-
+ my $realm = $c->get_auth_realm($realmname);
+ $c->_user( my $user = $realm->{'store'}->from_session( $c, $frozen_user ) );
+
+ # this sets the realm the user originated in.
+ $user->_set_auth_realm($realmname);
return $user;
}
+# we can't actually do our setup in setup because the model has not yet been loaded.
+# So we have to trigger off of setup_finished. :-(
sub setup {
my $c = shift;
- my $cfg = $c->config->{authentication} ||= {};
+ $c->_authentication_initialize();
+ $c->NEXT::setup(@_);
+}
+## the actual initialization routine. whee.
+sub _authentication_initialize {
+ my $c = shift;
+
+ if ($c->_auth_realms) { return };
+
+ my $cfg = $c->config->{'authentication'} || {};
+
%$cfg = (
use_session => 1,
%$cfg,
);
- $c->register_auth_stores(
- default => $cfg->{store},
- %{ $cfg->{stores} || {} },
- );
+ my $realmhash = {};
+ $c->_auth_realms($realmhash);
+
+ ## BACKWARDS COMPATIBILITY - if realm is not defined - then we are probably dealing
+ ## with an old-school config. The only caveat here is that we must add a classname
+ if (exists($cfg->{'realms'})) {
+
+ foreach my $realm (keys %{$cfg->{'realms'}}) {
+ $c->setup_auth_realm($realm, $cfg->{'realms'}{$realm});
+ }
- $c->NEXT::setup(@_);
+ # if we have a 'default-realm' in the config hash and we don't already
+ # have a realm called 'default', we point default at the realm specified
+ if (exists($cfg->{'default_realm'}) && !$c->get_auth_realm('default')) {
+ $c->set_default_auth_realm($cfg->{'default_realm'});
+ }
+ } else {
+ foreach my $storename (keys %{$cfg->{'stores'}}) {
+ my $realmcfg = {
+ store => $cfg->{'stores'}{$storename},
+ };
+ $c->setup_auth_realm($storename, $realmcfg);
+ }
+ }
+
}
-sub get_auth_store {
- my ( $self, $name ) = @_;
- $self->auth_stores->{$name} || ( Class::Inspector->loaded($name) && $name );
+
+# set up realmname.
+sub setup_auth_realm {
+ my ($app, $realmname, $config) = @_;
+
+ $app->log->debug("Setting up $realmname");
+ if (!exists($config->{'store'}{'class'})) {
+ Carp::croak "Couldn't setup the authentication realm named '$realmname', no class defined";
+ }
+
+ # use the
+ my $storeclass = $config->{'store'}{'class'};
+
+ ## follow catalyst class naming - a + prefix means a fully qualified class, otherwise it's
+ ## taken to mean C::P::A::Store::(specifiedclass)::Backend
+ if ($storeclass !~ /^\+(.*)$/ ) {
+ $storeclass = "Catalyst::Plugin::Authentication::Store::${storeclass}::Backend";
+ } else {
+ $storeclass = $1;
+ }
+
+
+ # a little niceness - since most systems seem to use the password credential class,
+ # if no credential class is specified we use password.
+ $config->{credential}{class} ||= "Catalyst::Plugin::Authentication::Credential::Password";
+
+ my $credentialclass = $config->{'credential'}{'class'};
+
+ ## follow catalyst class naming - a + prefix means a fully qualified class, otherwise it's
+ ## taken to mean C::P::A::Credential::(specifiedclass)
+ if ($credentialclass !~ /^\+(.*)$/ ) {
+ $credentialclass = "Catalyst::Plugin::Authentication::Credential::${credentialclass}";
+ } else {
+ $credentialclass = $1;
+ }
+
+ # if we made it here - we have what we need to load the classes;
+ Catalyst::Utils::ensure_class_loaded( $credentialclass );
+ Catalyst::Utils::ensure_class_loaded( $storeclass );
+
+ # BACKWARDS COMPATIBILITY - if the store class does not define find_user, we define it in terms
+ # of get_user and add it to the class. this is because the auth routines use find_user,
+ # and rely on it being present. (this avoids per-call checks)
+ if (!$storeclass->can('find_user')) {
+ no strict 'refs';
+ *{"${storeclass}::find_user"} = sub {
+ my ($self, $info) = @_;
+ my @rest = @{$info->{rest}} if exists($info->{rest});
+ $self->get_user($info->{id}, @rest);
+ };
+ }
+
+ $app->auth_realms->{$realmname}{'store'} = $storeclass->new($config->{'store'}, $app);
+ if ($credentialclass->can('new')) {
+ $app->auth_realms->{$realmname}{'credential'} = $credentialclass->new($config->{'credential'}, $app);
+ } else {
+ # if the credential class is not actually a class - has no 'new' operator, we wrap it,
+ # once again - to allow our code to be simple at runtime and allow non-OO packages to function.
+ my $wrapperclass = 'Catalyst::Plugin::Authentication::Credential::Wrapper';
+ Catalyst::Utils::ensure_class_loaded( $wrapperclass );
+ $app->auth_realms->{$realmname}{'credential'} = $wrapperclass->new($config->{'credential'}, $app);
+ }
}
-sub get_auth_store_name {
- my ( $self, $store ) = @_;
- $self->auth_store_names->{$store};
+sub auth_realms {
+ my $self = shift;
+ return($self->_auth_realms);
}
-sub register_auth_stores {
- my ( $self, %new ) = @_;
+sub get_auth_realm {
+ my ($app, $realmname) = @_;
+ return $app->auth_realms->{$realmname};
+}
- foreach my $name ( keys %new ) {
- my $store = $new{$name} or next;
- $self->auth_stores->{$name} = $store;
- $self->auth_store_names->{$store} = $name;
+sub set_default_auth_realm {
+ my ($app, $realmname) = @_;
+
+ if (exists($app->auth_realms->{$realmname})) {
+ $app->auth_realms->{'default'} = $app->auth_realms->{$realmname};
}
+ return $app->get_auth_realm('default');
}
-sub auth_stores {
- my $self = shift;
- $self->_auth_stores(@_) || $self->_auth_stores( {} );
+sub authenticate {
+ my ($app, $userinfo, $realmname) = @_;
+
+ if (!$realmname) {
+ $realmname = 'default';
+ }
+
+ my $realm = $app->get_auth_realm($realmname);
+
+ if ($realm && exists($realm->{'credential'})) {
+ my $user = $realm->{'credential'}->authenticate($app, $realm->{store}, $userinfo);
+ if ($user) {
+ $app->set_authenticated($user, $realmname);
+ return $user;
+ }
+ } else {
+ $app->log->debug("The realm requested, '$realmname' does not exist," .
+ " or there is no credential associated with it.")
+ }
+ return 0;
}
-sub auth_store_names {
- my $self = shift;
+## BACKWARDS COMPATIBILITY -- Warning: Here be monsters!
+#
+# What follows are backwards compatibility routines - for use with Stores and Credentials
+# that have not been updated to work with C::P::Authentication v0.10.
+# These are here so as to not break people's existing installations, but will go away
+# in a future version.
+#
+# The old style of configuration only supports a single store, as each store module
+# sets itself as the default store upon being loaded. This is the only supported
+# 'compatibility' mode.
+#
- $self->_auth_store_names || do {
- tie my %hash, 'Tie::RefHash';
- $self->_auth_store_names( \%hash );
- }
+sub get_user {
+ my ( $c, $uid, @rest ) = @_;
+
+ return $c->find_user( {'id' => $uid, 'rest'=>\@rest }, 'default' );
}
+##
+## this should only be called when using old-style authentication plugins. IF this gets
+## called in a new-style config - it will OVERWRITE the store of your default realm. Don't do it.
+## also - this is a partial setup - because no credential is instantiated... in other words it ONLY
+## works with old-style auth plugins and C::P::Authentication in compatibility mode. Trying to combine
+## this with a realm-type config will probably crash your app.
sub default_auth_store {
my $self = shift;
if ( my $new = shift ) {
- $self->register_auth_stores( default => $new );
+ $self->auth_realms->{'default'}{'store'} = $new;
+ my $storeclass = ref($new);
+
+ # BACKWARDS COMPATIBILITY - if the store class does not define find_user, we define it in terms
+ # of get_user and add it to the class. this is because the auth routines use find_user,
+ # and rely on it being present. (this avoids per-call checks)
+ if (!$storeclass->can('find_user')) {
+ no strict 'refs';
+ *{"${storeclass}::find_user"} = sub {
+ my ($self, $info) = @_;
+ my @rest = @{$info->{rest}} if exists($info->{rest});
+ $self->get_user($info->{id}, @rest);
+ };
+ }
}
- $self->get_auth_store("default");
+ return $self->get_auth_realm('default')->{'store'};
}
+## BACKWARDS COMPATIBILITY
+## this only ever returns a hash containing 'default' - as that is the only
+## supported mode of calling this.
+sub auth_store_names {
+ my $self = shift;
+
+ my %hash = ( $self->get_auth_realm('default')->{'store'} => 'default' );
+}
+
+sub get_auth_store {
+ my ( $self, $name ) = @_;
+
+ if ($name ne 'default') {
+ Carp::croak "get_auth_store called on non-default realm '$name'. Only default supported in compatibility mode";
+ } else {
+ $self->default_auth_store();
+ }
+}
+
+sub get_auth_store_name {
+ my ( $self, $store ) = @_;
+ return 'default';
+}
+
+# sub auth_stores is only used internally - here for completeness
+sub auth_stores {
+ my $self = shift;
+
+ my %hash = ( 'default' => $self->get_auth_realm('default')->{'store'});
+}
+
+
+
+
+
+
__PACKAGE__;
__END__
@@ -225,14 +419,11 @@
use Catalyst qw/
Authentication
- Authentication::Store::Foo
- Authentication::Credential::Password
/;
# later on ...
- # ->login is provided by the Credential::Password module
- $c->login('myusername', 'mypassword');
- my $age = $c->user->age;
+ $c->authenticate({ username => 'myusername', password => 'mypassword' });
+ my $age = $c->user->get('age');
$c->logout;
=head1 DESCRIPTION
More information about the Catalyst-commits
mailing list