package Catalyst::Plugin::Authentication;
-use base qw/Class::Accessor::Fast/;
+use base qw/Class::Accessor::Fast Class::Data::Inheritable/;
-BEGIN { __PACKAGE__->mk_accessors(qw/user/) }
+BEGIN {
+ __PACKAGE__->mk_accessors(qw/user/);
+ __PACKAGE__->mk_classdata(qw/default_auth_store/);
+}
use strict;
use warnings;
-sub default_auth_store {
- my $c = shift;
- $c->config->{authentication}{store};
-}
-
sub set_authenticated {
my ( $c, $user ) = @_;
my $c = shift;
$c->user(undef);
- delete @{ $c->session }{qw/__user __user_class/};
+
+ if ( $c->isa("Catalyst::Plugin::Session")
+ and $c->config->{authentication}{use_session} )
+ {
+ delete @{ $c->session }{qw/__user __user_class/};
+ }
}
sub get_user {
use_session => 1,
%$cfg,
);
+
+ $c->NEXT::setup(@_);
}
__PACKAGE__;
use Digest ();
sub login {
- my ( $self, $c, $user, $password ) = @_;
+ my ( $c, $user, $password ) = @_;
$user = $c->get_user($user)
unless Scalar::Util::blessed($user)
and $user->isa("Catalyst:::Plugin::Authentication::User");
$d->add( $user->password_pre_salt || '' );
$d->add($password);
$d->add( $user->password_post_salt || '' );
- return $c->digest eq $user->hashed_password;
+ return $d->digest eq $user->hashed_password;
}
else {
Catalyst::Exception->throw(
=back
+=head1 SUPPORTING THIS PLUGIN
+
+=head2 Clear Text Passwords
+
+Predicate:
+
+ $user->supports(qw/password clear/);
+
+Expected methods:
+
+=over 4
+
+=item password
+
+Returns the user's clear text password as a string to be compared with C<eq>.
+
+=back
+
+=head2 Crypted Passwords
+
+Predicate:
+
+ $user->supports(qw/password crypted/);
+
+Expected methods:
+
+=over 4
+
+=item crypted_password
+
+Return's the user's crypted password as a string, with the salt as the first two chars.
+
+=back
+
+=head2 Hashed Passwords
+
+Predicate:
+
+ $user->supports(qw/password hashed/);
+
+Expected methods:
+
+=over 4
+
+=item hashed_passwords
+
+Return's the hash of the user's password as B<binary>.
+
+=item hash_algorithm
+
+Returns a string suitable for feeding into L<Digest/new>.
+
+=item password_pre_salt
+
+=item password_post_salt
+
+Returns a string to be hashed before/after the user's password. Typically only
+a pre-salt is used.
+
+=back
+
=cut
sub setup {
my $c = shift;
- $c->config->{authentication}{store} =
- Catalyst::Plugin::Authentication::Store::Minimal::Backend->new(
- $c->config->{authentication}{users} );
+ $c->default_auth_store(
+ Catalyst::Plugin::Authentication::Store::Minimal::Backend->new(
+ $c->config->{authentication}{users}
+ )
+ );
+ $c->NEXT::setup(@_);
}
__PACKAGE__;
password => {
clear => ["password"],
crypted => ["crypted_password"],
- hashed => ["hashed_password hash_algorithm"],
+ hashed => [qw/hashed_password hash_algorithm/],
},
session => 1,
);
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More 'no_plan';
+
+
+my $m; BEGIN { use_ok($m = "Catalyst::Plugin::Authentication") }
+
+can_ok( $m, $_ ) for qw/user logout/;
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More 'no_plan';
+
+
+my $m; BEGIN { use_ok($m = "Catalyst::Plugin::Authentication::Credential::Password") }
+
+can_ok($m, "login");
+
+
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More 'no_plan';
+
+{
+ package AuthTestApp;
+ use Catalyst qw/
+ Authentication
+ Authentication::Store::Minimal
+ Authentication::Credential::Password
+ /;
+
+ use Test::More;
+ use Test::Exception;
+
+ use Digest::MD5 qw/md5/;
+
+ our $users;
+
+ sub moose : Local {
+ my ( $self, $c ) = @_;
+
+ ok(!$c->user, "no user");
+ ok($c->login( "foo", "s3cr3t" ), "can login with clear");
+ is( $c->user, $users->{foo}, "user object is in proper place");
+ $c->logout;
+
+ ok(!$c->user, "no more user, after logout");
+
+ ok($c->login( "bar", "s3cr3t" ), "can login with crypted");
+ is( $c->user, $users->{bar}, "user object is in proper place");
+ $c->logout;
+
+ ok($c->login("gorch", "s3cr3t"), "can login with hashed");
+ is( $c->user, $users->{gorch}, "user object is in proper place");
+ $c->logout;
+
+ ok(!$c->login( "bar", "bad pass" ), "can't login with bad password");
+ ok(!$c->user, "no user");
+
+ throws_ok { $c->login( "baz", "foo" ) } qr/support.*mechanism/, "can't login without any supported mech";
+ }
+
+ __PACKAGE__->config->{authentication}{users} = $users = {
+ foo => {
+ password => "s3cr3t",
+ },
+ bar => {
+ crypted_password => crypt("s3cr3t", "x8"),
+ },
+ gorch => {
+ hashed_password => md5("s3cr3t"),
+ hash_algorithm => "MD5",
+ },
+ baz => {},
+ };
+
+ __PACKAGE__->setup;
+}
+
+use Catalyst::Test qw/AuthTestApp/;
+
+get("/moose");