oauth credential - initial upload
[catagits/Catalyst-Authentication-Credential-OAuth.git] / lib / Catalyst / Authentication / Credential / OAuth.pm
CommitLineData
fc19db6b 1package Catalyst::Authentication::Credential::OAuth;
2use strict;
3use warnings;
4
5use Moose;
6
7has _config => ( is => 'rw' );
8has realm => ( is => 'ro' );
9has debug => ( is => 'rw' );
10has defaults => ( is => 'rw' );
11has provider => ( is => 'rw' );
12
13our $VERSION = "0.01";
14
15use Net::OAuth;
16#$Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0A;
17use HTTP::Request::Common;
18use LWP::UserAgent;
19use String::Random qw/ random_string /;
20
21use Catalyst::Exception ();
22
23sub new {
24 my ($class, $config, $c, $realm) = @_;
25
26 my $self = { _config => {
27 %{ $config },
28 %{ $realm->{config} }
29 } };
30
31 bless $self, $class;
32
33 $self->debug( $self->_config->{debug} );
34
35 $self->defaults( {
36 request_method => 'GET',
37 signature_method => 'HMAC-SHA1',
38 nonce => random_string( 'ccccccccccccccccccc' ),
39 } );
40
41 return $self;
42}
43
44
45sub authenticate {
46 my ($self, $c, $realm, $auth_info) = @_;
47
48 Catalyst::Exception->throw( "Provider is not defined." )
49 unless defined $self->_config->{ $auth_info->{oauth_provider} };
50
51 $self->provider( $self->_config->{ $auth_info->{oauth_provider} } );
52
53 $self->defaults( {
54 %{ $self->defaults },
55 timestamp => time,
56 consumer_key => $self->provider->{key},
57 consumer_secret => $self->provider->{secret},
58 callback => $c->uri_for( $c->action )->as_string,
59 } );
60
61 $c->log_debug( "authenticate() called from " . $c->request->uri ) if $self->debug;
62
63 my $ua = LWP::UserAgent->new;
64
65 if( $c->req->params->{oauth_token} ) {
66
67 my $response = Net::OAuth->response( 'user auth' )->from_hash( $c->req->params );
68
69 Catalyst::Exception->throw( "access_token_endpoint not defined" )
70 unless $self->provider->{access_token_endpoint};
71
72 my $request = Net::OAuth->request( 'access token' )->new(
73 %{ $self->defaults },
74 token => $response->token,
75 token_secret => '',
76 request_url => $self->provider->{access_token_endpoint},
77 );
78
79 $request->sign;
80
81 my $ua_response = $ua->request( GET $request->to_url );
82
83 Catalyst::Exception->throw( $ua_response->status_line.' '.$ua_response->content )
84 unless $ua_response->is_success;
85
86 $response = Net::OAuth->response( 'access token' )->from_post_body( $ua_response->content );
87
88 my $user = +{
89 token => $response->token,
90 token_secret => $response->token_secret,
91 extra_params => $response->extra_params
92 };
93
94 my $user_obj = $realm->find_user( $user, $c );
95
96 return $user_obj if ref $user_obj;
97
98 $c->log->debug( 'Verified OAuth identity failed' ) if $self->debug;
99
100 return;
101 }
102 else {
103
104 Catalyst::Exception->throw( "request_token_endpoint not defined" )
105 unless $self->provider->{request_token_endpoint};
106
107 my $request = Net::OAuth->request( 'request token' )->new(
108 %{ $self->defaults },
109 request_url => $self->provider->{request_token_endpoint}
110 );
111
112 $request->sign;
113
114 my $ua_response = $ua->request( GET $request->to_url );
115
116 Catalyst::Exception->throw( $ua_response->status_line.' '.$ua_response->content )
117 unless $ua_response->is_success;
118
119 my $response = Net::OAuth->response( 'request token' )->from_post_body( $ua_response->content );
120
121 Catalyst::Exception->throw( "user_auth_endpoint not defined" )
122 unless $self->provider->{user_auth_endpoint};
123
124 $request = Net::OAuth->request( 'user auth' )->new(
125 %{ $self->defaults },
126 token => $response->token,
127 );
128
129 $c->res->redirect( $request->to_url( $self->provider->{user_auth_endpoint} ) );
130 }
131
132}
133
134
135
1361;
137
138
139__END__
140
141=head1 NAME
142
143Catalyst::Authentication::Credential::OAuth - OAuth credential for Catalyst::Plugin::Authentication framework.
144
145=head1 VERSION
146
1470.01
148
149=head1 SYNOPSIS
150
151In MyApp.pm
152
153 use Catalyst qw/
154 Authentication
155 Session
156 Session::Store::FastMmap
157 Session::State::Cookie
158 /;
159
160
161In myapp.conf
162
163 <Plugin::Authentication>
164 default_realm oauth
165 <realms>
166 <oauth>
167 <credential>
168 class OAuth
169 </credential>
170 <example_provider>
171 key my_app_key
172 secret my_app_secret
173 request_token_endpoint http://example.com/oauth/request_token
174 access_token_endpoint http://example.com/oauth/access_token
175 user_auth_endpoint http://example.com/oauth/authorize
176 </example_provider>
177 </oauth>
178 </realms>
179</Plugin::Authentication>
180
181
182In controller code,
183
184 sub oauth : Local {
185 my ($self, $c) = @_;
186
187 if( $c->authenticate( { oauth_provider => 'example_provider' } ) ) {
188 #do something with $c->user
189 }
190 }
191
192
193
194=head1 USER METHODS
195
196=over 4
197
198=item $c->user->token
199
200=item $c->user->token_secret
201
202=item $c->user->extra_params - whatever other parameters the provider sends back
203
204=back
205
206=head1 AUTHOR
207
208Cosmin Budrica E<lt>cosmin@sinapticode.comE<gt>
209
210Bogdan Lucaciu E<lt>bogdan@sinapticode.comE<gt>
211
212=head1 COPYRIGHT
213
214Copyright (c) 2009 Sinapticode. All rights reserved
215
216This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
217
218=cut