changes update plus some stub docs
[catagits/Catalyst-Plugin-Authentication.git] / lib / Catalyst / Plugin / Authentication / Realm.pm
CommitLineData
646ea5b1 1package Catalyst::Plugin::Authentication::Realm;
2
3use strict;
4use warnings;
1489b476 5
646ea5b1 6use base qw/Class::Accessor::Fast/;
7
8BEGIN {
9 __PACKAGE__->mk_accessors(qw/store credential name config/);
10};
11
12sub new {
13 my ($class, $realmname, $config, $app) = @_;
14
15 my $self = { config => $config };
16 bless $self, $class;
17
18 $self->name($realmname);
19
20 $app->log->debug("Setting up auth realm $realmname") if $app->debug;
21 if (!exists($config->{'store'}{'class'})) {
22 Carp::croak "Couldn't setup the authentication realm named '$realmname', no class defined";
23 }
24
25 $config->{store}{class} ||= '+Catalyst::Plugin::Authentication::Store::Null';
26
27 # use the
28 my $storeclass = $config->{'store'}{'class'};
29
30 ## follow catalyst class naming - a + prefix means a fully qualified class, otherwise it's
31 ## taken to mean C::P::A::Store::(specifiedclass)
32 if ($storeclass !~ /^\+(.*)$/ ) {
33 $storeclass = "Catalyst::Plugin::Authentication::Store::${storeclass}";
34 } else {
35 $storeclass = $1;
36 }
37
38
39 # a little niceness - since most systems seem to use the password credential class,
40 # if no credential class is specified we use password.
41 $config->{credential}{class} ||= '+Catalyst::Plugin::Authentication::Credential::Password';
42
43 my $credentialclass = $config->{'credential'}{'class'};
44
45 ## follow catalyst class naming - a + prefix means a fully qualified class, otherwise it's
46 ## taken to mean C::P::A::Credential::(specifiedclass)
47 if ($credentialclass !~ /^\+(.*)$/ ) {
48 $credentialclass = "Catalyst::Plugin::Authentication::Credential::${credentialclass}";
49 } else {
50 $credentialclass = $1;
51 }
52
53 # if we made it here - we have what we need to load the classes;
54 Catalyst::Utils::ensure_class_loaded( $credentialclass );
55 Catalyst::Utils::ensure_class_loaded( $storeclass );
56
57 # BACKWARDS COMPATIBILITY - if the store class does not define find_user, we define it in terms
58 # of get_user and add it to the class. this is because the auth routines use find_user,
59 # and rely on it being present. (this avoids per-call checks)
60 if (!$storeclass->can('find_user')) {
61 no strict 'refs';
62 *{"${storeclass}::find_user"} = sub {
63 my ($self, $info) = @_;
64 my @rest = @{$info->{rest}} if exists($info->{rest});
65 $self->get_user($info->{id}, @rest);
66 };
67 }
68
69 ## a little cruft to stay compatible with some poorly written stores / credentials
70 ## we'll remove this soon.
71 if ($storeclass->can('new')) {
72 $self->store($storeclass->new($config->{'store'}, $app, $self));
73 } else {
74 $app->log->error("THIS IS DEPRECATED: $storeclass has no new() method - Attempting to use uninstantiated");
75 $self->store($storeclass);
76 }
77 if ($credentialclass->can('new')) {
78 $self->credential($credentialclass->new($config->{'credential'}, $app, $self));
79 } else {
80 $app->log->error("THIS IS DEPRECATED: $credentialclass has no new() method - Attempting to use uninstantiated");
81 $self->credential($credentialclass);
82 }
83
84 return $self;
85}
86
87sub find_user {
88 my ( $self, $authinfo, $c ) = @_;
89
90 my $res = $self->store->find_user($authinfo, $c);
91
4bd1f581 92 if (!$res) {
93 if ($self->config->{'auto_create'} && $self->store->can('auto_create') ) {
94 $res = $self->store->auto_create($authinfo, $c);
95 }
96 } elsif ($self->config->{'auto_update'} && $self->store->can('auto_update')) {
52a3537a 97 $res = $self->store->auto_update($authinfo, $c, $res);
4bd1f581 98 }
646ea5b1 99
100 return $res;
101}
102
103sub authenticate {
104 my ($self, $c, $authinfo) = @_;
105
106 my $user = $self->credential->authenticate($c, $self, $authinfo);
107 if (ref($user)) {
108 $c->set_authenticated($user, $self->name);
109 return $user;
110 } else {
111 return undef;
112 }
113}
114
115sub save_user_in_session {
116 my ( $self, $c, $user ) = @_;
117
118 $c->session->{__user_realm} = $self->name;
119
120 # we want to ask the store for a user prepared for the session.
121 # but older modules split this functionality between the user and the
122 # store. We try the store first. If not, we use the old method.
123 if ($self->store->can('for_session')) {
124 $c->session->{__user} = $self->store->for_session($c, $user);
125 } else {
126 $c->session->{__user} = $user->for_session;
127 }
128}
129
130sub from_session {
131 my ($self, $c, $frozen_user) = @_;
132
133 return $self->store->from_session($c, $frozen_user);
134}
135
136
137__PACKAGE__;
138
52a3537a 139__END__
1489b476 140
141=pod
142
143=head1 NAME
144
145Catalyst::Plugin::Authentication::Realm - Base class for realm objects.
146
147=head1 DESCRIPTION
148
149=head1 METHODS
150
151=over 4
152
153=item new
154
155=item find_user
156
157=item authenticate
158
159=item save_user_in_session
160
161=item from_session
162
163=back
164
165=cut
166
167