Refactor + perltidy of Authentication
[catagits/Catalyst-Plugin-Authentication.git] / lib / Catalyst / Plugin / Authentication.pm
1 #!/usr/bin/perl
2
3 package Catalyst::Plugin::Authentication;
4
5 use base qw/Class::Accessor::Fast Class::Data::Inheritable/;
6
7 BEGIN {
8     __PACKAGE__->mk_accessors(qw/user/);
9     __PACKAGE__->mk_classdata($_) for qw/_auth_stores _auth_store_names/;
10 }
11
12 use strict;
13 use warnings;
14
15 use Tie::RefHash;
16 use Class::Inspector;
17
18 our $VERSION = "0.01";
19
20 sub set_authenticated {
21     my ( $c, $user ) = @_;
22
23     $c->user($user);
24
25     if (    $c->isa("Catalyst::Plugin::Session")
26         and $c->config->{authentication}{use_session}
27         and $user->supports("session") )
28     {
29         $c->save_user_in_session($user);
30     }
31 }
32
33 sub save_user_in_session {
34         my ( $c, $user ) = @_;
35
36     my $store = $user->store || ref $user;
37     $c->session->{__user_store} = $c->get_auth_store_name($store) || $store;
38     $c->session->{__user} = $user->for_session;
39 }
40
41 sub logout {
42     my $c = shift;
43
44     $c->user(undef);
45
46     if (    $c->isa("Catalyst::Plugin::Session")
47         and $c->config->{authentication}{use_session} )
48     {
49         delete @{ $c->session }{qw/__user __user_store/};
50     }
51 }
52
53 sub get_user {
54     my ( $c, $uid ) = @_;
55
56     if ( my $store = $c->default_auth_store ) {
57         return $store->get_user($uid);
58     }
59     else {
60         Catalyst::Exception->throw(
61                 "The user id $uid was passed to an authentication "
62               . "plugin, but no default store was specified" );
63     }
64 }
65
66 sub prepare {
67     my $c = shift->NEXT::prepare(@_);
68
69     if (    $c->isa("Catalyst::Plugin::Session")
70         and $c->default_auth_store
71         and !$c->user )
72     {
73         if ( $c->sessionid and my $user_id = $c->session->{__user} ) {
74             my $store = $c->get_auth_store( $c->session->{__user_store} );
75             $c->user( $store->from_session( $c, $user_id ) );
76             $c->request->{user} = $c->user;    # compatibility kludge
77         }
78     }
79
80     return $c;
81 }
82
83 sub setup {
84     my $c = shift;
85
86     my $cfg = $c->config->{authentication} || {};
87
88     %$cfg = (
89         use_session => 1,
90         %$cfg,
91     );
92
93     $c->register_auth_stores(
94         default => $cfg->{store},
95         %{ $cfg->{stores} || {} },
96     );
97
98     $c->NEXT::setup(@_);
99 }
100
101 sub get_auth_store {
102     my ( $self, $name ) = @_;
103     $self->auth_stores->{$name} || ( Class::Inspector->loaded($name) && $name );
104 }
105
106 sub get_auth_store_name {
107     my ( $self, $store ) = @_;
108     $self->auth_store_names->{$store};
109 }
110
111 sub register_auth_stores {
112     my ( $self, %new ) = @_;
113
114     foreach my $name ( keys %new ) {
115         my $store = $new{$name} or next;
116         $self->auth_stores->{$name}       = $store;
117         $self->auth_store_names->{$store} = $name;
118     }
119 }
120
121 sub auth_stores {
122     my $self = shift;
123     $self->_auth_stores(@_) || $self->_auth_stores( {} );
124 }
125
126 sub auth_store_names {
127     my $self = shift;
128
129     unless ( $self->_auth_store_names ) {
130         tie my %hash, 'Tie::RefHash';
131         $self->_auth_store_names( \%hash );
132     }
133
134     $self->_auth_store_names;
135 }
136
137 sub default_auth_store {
138     my $self = shift;
139
140     if ( my $new = shift ) {
141         $self->register_auth_stores( default => $new );
142     }
143
144     $self->get_auth_store("default");
145 }
146
147 __PACKAGE__;
148
149 __END__
150
151 =pod
152
153 =head1 NAME
154
155 Catalyst::Plugin::Authentication - 
156
157 =head1 SYNOPSIS
158
159         use Catalyst qw/
160                 Authentication
161                 Authentication::Store::Foo
162                 Authentication::Credential::Password
163         /;
164
165 =head1 DESCRIPTION
166
167 The authentication plugin is used by the various authentication and
168 authorization plugins in catalyst.
169
170 It defines the notion of a logged in user, and provides integration with the 
171
172 =head1 METHODS
173
174 =over 4 
175
176 =item logout
177
178 Delete the currently logged in user from C<user> and the session.
179
180 =item user
181
182 Returns the currently logged user or undef if there is none.
183
184 =item get_user $uid
185
186 Delegate C<get_user> to the default store.
187
188 =item default_auth_store
189
190 Returns C<< $c->config->{authentication}{store} >>.
191
192 =back
193
194 =head1 INTERNAL METHODS
195
196 =over 4
197
198 =item set_authenticated $user
199
200 Marks a user as authenticated. Should be called from a
201 C<Catalyst::Plugin::Authentication::Credential> plugin after successful
202 authentication.
203
204 This involves setting C<user> and the internal data in C<session> if
205 L<Catalyst::Plugin::Session> is loaded.
206
207 =item prepare
208
209 Revives a user from the session object if there is one.
210
211 =item setup
212
213 Sets the default configuration parameters.
214
215 =item 
216
217 =back
218
219 =head1 CONFIGURATION
220
221 =over 4
222
223 =item use_session
224
225 Whether or not to store the user's logged in state in the session, if the
226 application is also using the L<Catalyst::Plugin::Authentication> plugin.
227
228 =back
229
230 =cut
231
232