1 package Catalyst::Authentication::Credential::OAuth;
3 use MooseX::Types::Moose qw/ Bool HashRef /;
4 use MooseX::Types::Common::String qw/ NonEmptySimpleStr /;
6 #$Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0A;
8 use HTTP::Request::Common;
9 use String::Random qw/ random_string /;
10 use Catalyst::Exception ();
11 use namespace::autoclean;
13 our $VERSION = '0.04';
15 has debug => ( is => 'ro', isa => Bool );
16 has providers => ( is => 'ro', isa => HashRef, required => 1 );
17 has ua => ( is => 'ro', lazy_build => 1, init_arg => undef, isa => 'LWP::UserAgent' );
20 my ($self, $config, $c, $realm) = @_;
27 $self->ua; # Ensure lazy value is built.
37 my ($self, $c, $realm, $auth_info) = @_;
39 Catalyst::Exception->throw( "Provider is not defined." )
40 unless defined $auth_info->{provider} || defined $self->providers->{ $auth_info->{provider} };
42 my $provider = $self->providers->{ $auth_info->{provider} };
44 for ( qw/ consumer_key consumer_secret request_token_endpoint access_token_endpoint user_auth_endpoint extra_params / ) {
45 Catalyst::Exception->throw( $_ . " is not defined for provider ". $auth_info->{provider} )
46 unless $provider->{$_};
50 consumer_key => $provider->{consumer_key},
51 consumer_secret => $provider->{consumer_secret},
53 nonce => random_string( 'ccccccccccccccccccc' ),
54 request_method => 'GET',
55 signature_method => 'HMAC-SHA1',
56 oauth_version => '1.0a',
57 callback => $c->uri_for( $c->action, $c->req->captures, @{ $c->req->args } )->as_string,
58 ( defined $provider->{extra_params}
59 ? ( extra_params => $provider->{extra_params} )
64 $c->log_debug( "authenticate() called from " . $c->request->uri ) if $self->debug;
66 my $oauth_token = $c->req->method eq 'GET'
67 ? $c->req->query_params->{oauth_token}
68 : $c->req->body_params->{oauth_token};
72 my $response = Net::OAuth->response( 'user auth' )->from_hash( { %{$c->req->params}, %{$provider->{extra_params}} } );
74 my $request = Net::OAuth->request( 'access token' )->new(
76 token => $response->token,
78 request_url => $provider->{access_token_endpoint},
79 verifier => $c->req->params->{oauth_verifier},
83 my $ua_response = $self->ua->request( GET $request->to_url );
84 Catalyst::Exception->throw( $ua_response->status_line.' '.$ua_response->content )
85 unless $ua_response->is_success;
87 $response = Net::OAuth->response( 'access token' )->from_post_body( $ua_response->content );
90 token => $response->token,
91 token_secret => $response->token_secret,
92 extra_params => $response->extra_params
95 my $user_obj = $realm->find_user( $user, $c );
97 return $user_obj if ref $user_obj;
99 $c->log->debug( 'Verified OAuth identity failed' ) if $self->debug;
104 my $request = Net::OAuth->request( 'request token' )->new(
106 request_url => $provider->{request_token_endpoint}
110 my $ua_response = $self->ua->request( GET $request->to_url );
112 Catalyst::Exception->throw( $ua_response->status_line.' '.$ua_response->content )
113 unless $ua_response->is_success;
115 my $response = Net::OAuth->response( 'request token' )->from_post_body( $ua_response->content );
117 $request = Net::OAuth->request( 'user auth' )->new(
119 token => $response->token,
122 $c->res->redirect( $request->to_url( $provider->{user_auth_endpoint} ) );
136 Catalyst::Authentication::Credential::OAuth - OAuth credential for Catalyst::Plugin::Authentication framework.
149 Session::Store::FastMmap
150 Session::State::Cookie
156 <Plugin::Authentication>
164 consumer_key my_app_key
165 consumer_secret my_app_secret
166 request_token_endpoint http://example.com/oauth/request_token
167 access_token_endpoint http://example.com/oauth/access_token
168 user_auth_endpoint http://example.com/oauth/authorize
174 </Plugin::Authentication>
182 if( $c->authenticate( { provider => 'example.com' } ) ) {
183 #do something with $c->user
193 =item $c->user->token
195 =item $c->user->token_secret
197 =item $c->user->extra_params - whatever other params the provider sends back
203 Cosmin Budrica E<lt>cosmin@sinapticode.comE<gt>
205 Bogdan Lucaciu E<lt>bogdan@sinapticode.comE<gt>
207 With contributions from:
209 Tomas Doran E<lt>bobtfish@bobtfish.netE</gt>
214 Only tested with twitter
218 Copyright (c) 2009 Sinapticode. All rights reserved
220 This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.