Commit | Line | Data |
2e823d32 |
1 | package Catalyst::Plugin::Authentication::Credential::TypeKey; |
3bb8633b |
2 | |
3 | use strict; |
19c14a20 |
4 | use warnings; |
5 | |
3bb8633b |
6 | use Authen::TypeKey; |
3bb8633b |
7 | use File::Spec; |
19c14a20 |
8 | use Catalyst::Utils (); |
9 | use NEXT; |
10 | use UNIVERSAL::require; |
209fb56b |
11 | use Scalar::Util (); |
3bb8633b |
12 | |
13 | our $VERSION = '0.1'; |
14 | |
19c14a20 |
15 | sub setup { |
16 | my $c = shift; |
17 | |
18 | my $config = $c->config->{authentication}{typekey} ||= {}; |
19 | |
20 | $config->{typekey_object} ||= do { |
52262613 |
21 | ( $config->{user_class} ||= |
209fb56b |
22 | "Catalyst::Plugin::Authentication::User::Hash" )->require; |
19c14a20 |
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 | |
209fb56b |
30 | for ( grep { exists $config->{$_} } |
31 | qw/expires key_cache key_url token version skip_expiry_check/ ) |
32 | { |
6f758b52 |
33 | $typekey->$_( $config->{$_} ); |
19c14a20 |
34 | } |
35 | |
36 | $typekey; |
37 | }; |
38 | |
39 | $c->NEXT::setup(@_); |
40 | } |
e42cd610 |
41 | |
3bb8633b |
42 | sub authenticate_typekey { |
e0a35f10 |
43 | my ( $c, @p ) = @_; |
209fb56b |
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 | } |
3bb8633b |
62 | |
19c14a20 |
63 | my $config = $c->config->{authentication}{typekey}; |
3bb8633b |
64 | |
e0a35f10 |
65 | my $typekey = $p && delete( $p->{typekey_object} ) |
19c14a20 |
66 | || $config->{typekey_object}; |
67 | |
209fb56b |
68 | $p ||= $c->req; |
69 | |
70 | if ( my $res = $typekey->verify($p) ) { |
e0a35f10 |
71 | $c->log->debug("Successfully authenticated user '$res->{name}'.") |
19c14a20 |
72 | if $c->debug; |
3bb8633b |
73 | |
209fb56b |
74 | if ( !$user and my $store = $config->{auth_store} ) { |
19c14a20 |
75 | $store = $c->get_auth_store($store) unless ref $store; |
e0a35f10 |
76 | $user = $store->get_user( $p, $res ); |
19c14a20 |
77 | } |
52262613 |
78 | |
209fb56b |
79 | if ( !$user ) { |
19c14a20 |
80 | my $user_class = $config->{user_class}; |
209fb56b |
81 | $user = $user_class->new($res); |
19c14a20 |
82 | } |
83 | |
84 | $c->set_authenticated($user); |
85 | |
86 | return 1; |
3bb8633b |
87 | } |
19c14a20 |
88 | else { |
89 | $c->log->debug( |
90 | sprintf "Failed to authenticate user '%s'. Reason: '%s'", |
209fb56b |
91 | $p->{name} || $p->param("name"), |
92 | $typekey->errstr |
93 | ) |
19c14a20 |
94 | if $c->debug; |
3bb8633b |
95 | |
19c14a20 |
96 | return; |
97 | } |
3bb8633b |
98 | } |
99 | |
100 | 1; |
101 | |
102 | __END__ |
103 | |
104 | =head1 NAME |
105 | |
2e823d32 |
106 | Catalyst::Plugin::Authentication::Credential::TypeKey - TypeKey Authentication |
19c14a20 |
107 | for Catalyst. |
3bb8633b |
108 | |
109 | =head1 SYNOPSIS |
110 | |
e0a35f10 |
111 | use Catalyst qw/Authentication::Credential::TypeKey/; |
3bb8633b |
112 | |
e0a35f10 |
113 | MyApp->config->{authentication}{typekey} = { |
114 | token => 'xxxxxxxxxxxxxxxxxxxx', |
3bb8633b |
115 | }; |
116 | |
19c14a20 |
117 | sub foo : Local { |
118 | my ( $self, $c ) = @_; |
119 | |
e0a35f10 |
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 | |
19c14a20 |
128 | # successful autentication |
129 | |
e0a35f10 |
130 | $c->user; # this is set |
19c14a20 |
131 | } |
132 | } |
133 | |
134 | |
135 | sub auto : Private { |
136 | my ( $self, $c ) = @_; |
137 | |
e0a35f10 |
138 | $c->authenticate_typekey; # uses $c->req |
19c14a20 |
139 | |
140 | return 1; |
141 | } |
3bb8633b |
142 | |
e0a35f10 |
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 | |
3bb8633b |
162 | =head1 DESCRIPTION |
163 | |
19c14a20 |
164 | This module integrates L<Authen::TypeKey> with |
165 | L<Catalyst::Plugin::Authentication>. |
166 | |
167 | =head1 METHODS |
168 | |
169 | =item authenticate_typekey %parameters |
170 | |
171 | =item authenticate_typekey |
172 | |
173 | =item EXTENDED METHODS |
174 | |
175 | =item 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 | |
e0a35f10 |
214 | $store->get_user( $parameters, $result_of_verify ); |
19c14a20 |
215 | |
e0a35f10 |
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>. |
19c14a20 |
219 | |
97676d77 |
220 | If this is unset, L<Catalyst::Plugin::Authentication/default_auth_store> will |
221 | be used instead. |
222 | |
19c14a20 |
223 | =item user_class |
224 | |
97676d77 |
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>. |
19c14a20 |
228 | |
229 | =back |
3bb8633b |
230 | |
231 | =head1 SEE ALSO |
232 | |
19c14a20 |
233 | L<Authen::TypeKey>, L<Catalyst>, L<Catalyst::Plugin::Authentication>. |
3bb8633b |
234 | |
235 | =head1 AUTHOR |
236 | |
19c14a20 |
237 | Christian Hansen |
238 | |
239 | Yuval Kogman, C<nothingmuch@woobling.org> |
3bb8633b |
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 |