X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FPlugin%2FAuthentication%2FCredential%2FPassword.pm;h=624143b7bd911a788dabd31cac6349bef53d5e3c;hb=646ea5b1aa19c86dda9cc98a62b656e7005c553f;hp=0a161fc8df20d81f11e639b6ca792f3945f2ab11;hpb=89505ffb6e0211be9d995df31f7b7de3913e3922;p=catagits%2FCatalyst-Plugin-Authentication.git diff --git a/lib/Catalyst/Plugin/Authentication/Credential/Password.pm b/lib/Catalyst/Plugin/Authentication/Credential/Password.pm index 0a161fc..624143b 100644 --- a/lib/Catalyst/Plugin/Authentication/Credential/Password.pm +++ b/lib/Catalyst/Plugin/Authentication/Credential/Password.pm @@ -1,6 +1,5 @@ -#!/usr/bin/perl - package Catalyst::Plugin::Authentication::Credential::Password; +use base qw/Class::Accessor::Fast/; use strict; use warnings; @@ -9,26 +8,40 @@ use Scalar::Util (); 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); - if ($user_obj) { + ## 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; } @@ -41,27 +54,29 @@ sub authenticate { 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; @@ -75,7 +90,7 @@ sub check_password { ## 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. @@ -239,6 +254,10 @@ The password module is capable of working with several different password encryption/hashing algorithms. The one the module uses is determined by the credential configuration. +Those who have used L 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 @@ -266,6 +285,12 @@ from the user object. The supported options are: =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. @@ -312,12 +337,13 @@ Any post-salt data to be passed to L after processing the password. =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 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 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} )) {