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