-#!/usr/bin/perl
-
package Catalyst::Plugin::Authentication::Credential::Password;
+use base qw/Class::Accessor::Fast/;
use strict;
use warnings;
use Catalyst::Exception ();
use Digest ();
+BEGIN {
+ __PACKAGE__->mk_accessors(qw/_config realm/);
+}
+
sub new {
- my ($class, $config, $app) = @_;
+ my ($class, $config, $app, $realm) = @_;
+
+ my $self = { _config => $config };
+ bless $self, $class;
+
+ $self->realm($realm);
- my $self = { %{$config} };
- $self->{'password_field'} ||= 'password';
- $self->{'password_type'} ||= 'clear';
- $self->{'password_hash_type'} ||= 'SHA-1';
+ $self->_config->{'password_field'} ||= 'password';
+ $self->_config->{'password_type'} ||= 'clear';
+ $self->_config->{'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'});
+ my $passwordtype = $self->_config->{'password_type'};
+ if (!grep /$passwordtype/, ('none', 'clear', 'hashed', 'salted_hash', 'crypted', 'self_check')) {
+ Catalyst::Exception->throw(__PACKAGE__ . " used with unsupported password type: " . $self->_config->{'password_type'});
}
-
- bless $self, $class;
+ return $self;
}
sub authenticate {
- my ( $self, $c, $authstore, $authinfo ) = @_;
+ my ( $self, $c, $realm, $authinfo ) = @_;
- my $user_obj = $authstore->find_user($authinfo, $c);
+ ## because passwords may be in a hashed format, we have to make sure that we remove the
+ ## password_field before we pass it to the user routine, as some auth modules use
+ ## all data passed to them to find a matching user...
+ my $userfindauthinfo = {%{$authinfo}};
+ delete($userfindauthinfo->{$self->_config->{'password_field'}});
+
+ my $user_obj = $realm->find_user($userfindauthinfo, $c);
if (ref($user_obj)) {
if ($self->check_password($user_obj, $authinfo)) {
return $user_obj;
sub check_password {
my ( $self, $user, $authinfo ) = @_;
- if ($self->{'password_type'} eq 'self_check') {
- return $user->check_password($authinfo->{$self->{'password_field'}});
+ if ($self->_config->{'password_type'} eq 'self_check') {
+ return $user->check_password($authinfo->{$self->_config->{'password_field'}});
} else {
- my $password = $authinfo->{$self->{'password_field'}};
- my $storedpassword = $user->get($self->{'password_field'});
+ my $password = $authinfo->{$self->_config->{'password_field'}};
+ my $storedpassword = $user->get($self->_config->{'password_field'});
- if ($self->{password_type} eq 'clear') {
+ if ($self->_config->{'password_type'} eq 'none') {
+ return 1;
+ } elsif ($self->_config->{'password_type'} eq 'clear') {
return $password eq $storedpassword;
- } elsif ($self->{'password_type'} eq 'crypted') {
+ } elsif ($self->_config->{'password_type'} eq 'crypted') {
return $storedpassword eq crypt( $password, $storedpassword );
- } elsif ($self->{'password_type'} eq 'salted_hash') {
+ } elsif ($self->_config->{'password_type'} eq 'salted_hash') {
require Crypt::SaltedHash;
- my $salt_len = $self->{'password_salt_len'} ? $self->{'password_salt_len'} : 0;
+ my $salt_len = $self->_config->{'password_salt_len'} ? $self->_config->{'password_salt_len'} : 0;
return Crypt::SaltedHash->validate( $storedpassword, $password,
$salt_len );
- } elsif ($self->{'password_type'} eq 'hashed') {
+ } elsif ($self->_config->{'password_type'} eq 'hashed') {
- my $d = Digest->new( $self->{'password_hash_type'} );
- $d->add( $self->{'password_pre_salt'} || '' );
+ my $d = Digest->new( $self->_config->{'password_hash_type'} );
+ $d->add( $self->_config->{'password_pre_salt'} || '' );
$d->add($password);
- $d->add( $self->{'password_post_salt'} || '' );
+ $d->add( $self->_config->{'password_post_salt'} || '' );
my $computed = $d->clone()->digest;
my $b64computed = $d->clone()->b64digest;
## 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
+## login()'s existance relies rather heavily on the fact that only 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.
encryption/hashing algorithms. The one the module uses is determined by the
credential configuration.
+Those who have used L<Catalyst::Plugin::Authentication> prior to the 0.10 release
+should note that the password field and type information is no longer part
+of the store configuration and is now part of the Password credential configuration.
+
=over 4
=item class
=over 8
+=item none
+
+No password check is done. An attempt is made to retrieve the user based on
+the information provided in the $c->authenticate() call. If a user is found,
+authentication is considered to be successful.
+
=item clear
The password in user is in clear text and will be compared directly.
=head1 USAGE
-The Password credential module is very simple to use. Once configured as indicated
-above, authenticating using this module is simply a matter of calling $c->authenticate()
-with an authinfo hashref that includes the B<password> element. The password element should
-contain the password supplied by the user to be authenticated, in clear text. The other
-information supplied in the auth hash is ignored by the Password module, and simply passed
-to the auth store to be used to retrieve the user. An example call follows:
+The Password credential module is very simple to use. Once configured as
+indicated above, authenticating using this module is simply a matter of
+calling $c->authenticate() with an authinfo hashref that includes the
+B<password> element. The password element should contain the password supplied
+by the user to be authenticated, in clear text. The other information supplied
+in the auth hash is ignored by the Password module, and simply passed to the
+auth store to be used to retrieve the user. An example call follows:
if ($c->authenticate({ username => $username,
password => $password} )) {