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