c3c4f7e36f9540e5d28a196ea84f477aa8411203
[catagits/Catalyst-Authentication-Credential-HTTP-Proxy.git] / lib / Catalyst / Plugin / Authentication / Credential / TypeKey.pm
1 package Catalyst::Plugin::Authentication::Credential::TypeKey;
2
3 use strict;
4 use warnings;
5
6 use Authen::TypeKey;
7 use File::Spec;
8 use Catalyst::Utils ();
9 use NEXT;
10 use UNIVERSAL::require;
11 use Scalar::Util ();
12
13 our $VERSION = '0.2';
14
15 sub setup {
16     my $c = shift;
17
18     my $config = $c->config->{authentication}{typekey} ||= {};
19
20     $config->{typekey_object} ||= do {
21         ( $config->{user_class} ||=
22               "Catalyst::Plugin::Authentication::User::Hash" )->require;
23
24         $config->{key_cache} ||=
25           File::Spec->catfile( Catalyst::Utils::class2tempdir( $c, 1 ),
26             'regkeys.txt' );
27
28         my $typekey = Authen::TypeKey->new;
29
30         for ( grep { exists $config->{$_} }
31             qw/expires key_cache key_url token version skip_expiry_check/ )
32         {
33             $typekey->$_( $config->{$_} );
34         }
35
36         $typekey;
37     };
38
39     $c->NEXT::setup(@_);
40 }
41
42 sub authenticate_typekey {
43     my ( $c, @p ) = @_;
44
45     my ( $user, $p );
46     if ( @p == 1 ) {
47         if ( Scalar::Util::blessed( $p[0] ) ) {
48             $user = $p[0];
49             Catalyst::Exception->throw(
50                     "Attempted to authenticate user object, but "
51                   . "user doesnt't support 'typekey_credentials'" )
52               unless $user->supports(qw/typekey_credentials/);
53             $p = $user->typekey_credentials;
54         }
55         else {
56             $p = $p[0];
57         }
58     }
59     else {
60         $p = @p ? {@p} : undef;
61     }
62
63     my $config = $c->config->{authentication}{typekey};
64
65     my $typekey = $p && delete( $p->{typekey_object} )
66       || $config->{typekey_object};
67
68     $p ||= $c->req;
69
70     if ( my $res = $typekey->verify($p) ) {
71         $c->log->debug("Successfully authenticated user '$res->{name}'.")
72           if $c->debug;
73
74         if ( !$user and my $store = $config->{auth_store} ) {
75             $store = $c->get_auth_store($store) unless ref $store;
76             $user = $store->get_user( $p, $res );
77         }
78
79         if ( !$user ) {
80             my $user_class = $config->{user_class};
81             $user = $user_class->new($res);
82         }
83
84         $c->set_authenticated($user);
85
86         return 1;
87     }
88     else {
89         $c->log->debug(
90             sprintf "Failed to authenticate user '%s'. Reason: '%s'",
91             $p->{name} || $p->param("name"),
92             $typekey->errstr
93           )
94           if $c->debug;
95
96         return;
97     }
98 }
99
100 1;
101
102 __END__
103
104 =head1 NAME
105
106 Catalyst::Plugin::Authentication::Credential::TypeKey - TypeKey Authentication
107 for Catalyst.
108
109 =head1 SYNOPSIS
110
111     use Catalyst qw/Authentication::Credential::TypeKey/;
112
113     MyApp->config->{authentication}{typekey} = {
114         token => 'xxxxxxxxxxxxxxxxxxxx',
115     };
116
117     sub foo : Local {
118                 my ( $self, $c ) = @_;
119
120                 if ( $c->authenticate_typekey ) {
121
122                 # you can also specify the params manually: $c->authenticate_typekey(
123                 #       name => $name,
124                 #       email => $email,
125                 #       ...
126                 #)
127
128                         # successful autentication
129
130                         $c->user; # this is set
131                 }
132         }
133
134
135         sub auto : Private {
136                 my ( $self, $c ) = @_;
137
138                 $c->authenticate_typekey; # uses $c->req
139
140                 return 1;
141         }
142
143 =head1 TYPEKEY BROKED-NESS
144
145 Please watch:
146
147         http://rt.cpan.org/NoAuth/Bugs.html?Dist=Authen-TypeKey
148
149 I could only get this to properly work with TypeKey version 1 (not 1.1).
150
151 To get around this problem configure the plugin to use version 1:
152
153         __PACKAGE__->config(
154                 authentication => {
155                         typekey => {
156                                 version => 1,
157                                 token => ..., # doesn't really matter in version 1
158                         },
159                 },
160         );
161
162 =head1 DESCRIPTION
163
164 This module integrates L<Authen::TypeKey> with
165 L<Catalyst::Plugin::Authentication>.
166
167 =head1 METHODS
168
169 =head3 authenticate_typekey %parameters
170
171 =head3 authenticate_typekey
172
173 =head3 EXTENDED METHODS
174
175 =head3 setup
176
177 Fills the config with defaults.
178
179 =head1 CONFIGURATION
180
181 C<<$c->config->{autentication}{typekey}>> is a hash with these fields (all can
182 be left out):
183
184 =over 4
185
186 =item typekey_object
187
188 If this field does not exist an L<Authen::TypeKey> object will be created based
189 on the other param and put here.
190
191 =item expires
192
193 =item key_url
194
195 =item token
196
197 =item version
198
199 See L<Authen::TypeKey> for all of these. If they aren't specified
200 L<Authen::TypeKey>'s defaults will be used.
201
202 =item key_cache
203
204 Also see L<Authen::TypeKey>.
205
206 Defaults to C<regkeys.txt> under L<Catalyst::Utils/class2tempdir>.
207
208 =item auth_store
209
210 A store (or store name) to retrieve the user from.
211
212 When a user is successfully authenticated it will call this:
213
214         $store->get_user( $parameters, $result_of_verify );
215
216 Where C<$parameters> is a the hash reference passed to
217 L<Authen::TypeKey/verify>, and C<$result_of_verify> is the value returned by
218 L<Authen::TypeKey/verify>.
219
220 If this is unset, L<Catalyst::Plugin::Authentication/default_auth_store> will
221 be used instead.
222
223 =item user_class
224
225 If C<auth_store> or the default store returns nothing from get_user, this class
226 will be used to instantiate an object by calling C<new> on the class with the
227 return value from L<Authen::TypeKey/verify>.
228
229 =back
230
231 =head1 SEE ALSO
232
233 L<Authen::TypeKey>, L<Catalyst>, L<Catalyst::Plugin::Authentication>.
234
235 =head1 AUTHOR
236
237 Christian Hansen
238
239 Yuval Kogman, C<nothingmuch@woobling.org>
240
241 =head1 LICENSE
242
243 This library is free software . You can redistribute it and/or modify it under
244 the same terms as perl itself.
245
246 =cut