From: Bogdan Lucaciu Date: Wed, 22 Jul 2009 22:48:51 +0000 (+0000) Subject: oauth credential - initial upload X-Git-Tag: v0.02~7 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Authentication-Credential-OAuth.git;a=commitdiff_plain;h=fc19db6b3200a917704ad81f5bc8804d18ad4b10 oauth credential - initial upload --- diff --git a/Changes b/Changes new file mode 100644 index 0000000..acbefa6 --- /dev/null +++ b/Changes @@ -0,0 +1,5 @@ +Revision history for Catalyst::Authentication::Credential::OAuth + + +0.01 Tue July 08 17:17 2009 + original version diff --git a/MANIFEST.SKIP b/MANIFEST.SKIP new file mode 100644 index 0000000..8fb2024 --- /dev/null +++ b/MANIFEST.SKIP @@ -0,0 +1,8 @@ +.git/ +blib +pm_to_blib +MANIFEST.bak +MANIFEST.SKIP~ +cover_db +Makefile$ +Makefile.old$ diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..e955fce --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,16 @@ +use inc::Module::Install; + +name 'Catalyst-Authentication-Credential-OAuth'; +all_from 'lib/Catalyst/Authentication/Credential/OAuth.pm'; + +requires 'Moose'; +requires 'Net::OAuth'; +requires 'LWP::UserAgent'; +requires 'String::Random'; + +build_requires 'Catalyst::Runtime'; +build_requires 'Test::WWW::Mechanize::Catalyst'; +build_requires 'Test::More'; +build_requires 'ok'; + +WriteAll(); diff --git a/README b/README new file mode 100644 index 0000000..e69de29 diff --git a/lib/Catalyst/Authentication/Credential/OAuth.pm b/lib/Catalyst/Authentication/Credential/OAuth.pm new file mode 100644 index 0000000..834abef --- /dev/null +++ b/lib/Catalyst/Authentication/Credential/OAuth.pm @@ -0,0 +1,218 @@ +package Catalyst::Authentication::Credential::OAuth; +use strict; +use warnings; + +use Moose; + +has _config => ( is => 'rw' ); +has realm => ( is => 'ro' ); +has debug => ( is => 'rw' ); +has defaults => ( is => 'rw' ); +has provider => ( is => 'rw' ); + +our $VERSION = "0.01"; + +use Net::OAuth; +#$Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0A; +use HTTP::Request::Common; +use LWP::UserAgent; +use String::Random qw/ random_string /; + +use Catalyst::Exception (); + +sub new { + my ($class, $config, $c, $realm) = @_; + + my $self = { _config => { + %{ $config }, + %{ $realm->{config} } + } }; + + bless $self, $class; + + $self->debug( $self->_config->{debug} ); + + $self->defaults( { + request_method => 'GET', + signature_method => 'HMAC-SHA1', + nonce => random_string( 'ccccccccccccccccccc' ), + } ); + + return $self; +} + + +sub authenticate { + my ($self, $c, $realm, $auth_info) = @_; + + Catalyst::Exception->throw( "Provider is not defined." ) + unless defined $self->_config->{ $auth_info->{oauth_provider} }; + + $self->provider( $self->_config->{ $auth_info->{oauth_provider} } ); + + $self->defaults( { + %{ $self->defaults }, + timestamp => time, + consumer_key => $self->provider->{key}, + consumer_secret => $self->provider->{secret}, + callback => $c->uri_for( $c->action )->as_string, + } ); + + $c->log_debug( "authenticate() called from " . $c->request->uri ) if $self->debug; + + my $ua = LWP::UserAgent->new; + + if( $c->req->params->{oauth_token} ) { + + my $response = Net::OAuth->response( 'user auth' )->from_hash( $c->req->params ); + + Catalyst::Exception->throw( "access_token_endpoint not defined" ) + unless $self->provider->{access_token_endpoint}; + + my $request = Net::OAuth->request( 'access token' )->new( + %{ $self->defaults }, + token => $response->token, + token_secret => '', + request_url => $self->provider->{access_token_endpoint}, + ); + + $request->sign; + + my $ua_response = $ua->request( GET $request->to_url ); + + Catalyst::Exception->throw( $ua_response->status_line.' '.$ua_response->content ) + unless $ua_response->is_success; + + $response = Net::OAuth->response( 'access token' )->from_post_body( $ua_response->content ); + + my $user = +{ + token => $response->token, + token_secret => $response->token_secret, + extra_params => $response->extra_params + }; + + my $user_obj = $realm->find_user( $user, $c ); + + return $user_obj if ref $user_obj; + + $c->log->debug( 'Verified OAuth identity failed' ) if $self->debug; + + return; + } + else { + + Catalyst::Exception->throw( "request_token_endpoint not defined" ) + unless $self->provider->{request_token_endpoint}; + + my $request = Net::OAuth->request( 'request token' )->new( + %{ $self->defaults }, + request_url => $self->provider->{request_token_endpoint} + ); + + $request->sign; + + my $ua_response = $ua->request( GET $request->to_url ); + + Catalyst::Exception->throw( $ua_response->status_line.' '.$ua_response->content ) + unless $ua_response->is_success; + + my $response = Net::OAuth->response( 'request token' )->from_post_body( $ua_response->content ); + + Catalyst::Exception->throw( "user_auth_endpoint not defined" ) + unless $self->provider->{user_auth_endpoint}; + + $request = Net::OAuth->request( 'user auth' )->new( + %{ $self->defaults }, + token => $response->token, + ); + + $c->res->redirect( $request->to_url( $self->provider->{user_auth_endpoint} ) ); + } + +} + + + +1; + + +__END__ + +=head1 NAME + +Catalyst::Authentication::Credential::OAuth - OAuth credential for Catalyst::Plugin::Authentication framework. + +=head1 VERSION + +0.01 + +=head1 SYNOPSIS + +In MyApp.pm + + use Catalyst qw/ + Authentication + Session + Session::Store::FastMmap + Session::State::Cookie + /; + + +In myapp.conf + + + default_realm oauth + + + + class OAuth + + + key my_app_key + secret my_app_secret + request_token_endpoint http://example.com/oauth/request_token + access_token_endpoint http://example.com/oauth/access_token + user_auth_endpoint http://example.com/oauth/authorize + + + + + + +In controller code, + + sub oauth : Local { + my ($self, $c) = @_; + + if( $c->authenticate( { oauth_provider => 'example_provider' } ) ) { + #do something with $c->user + } + } + + + +=head1 USER METHODS + +=over 4 + +=item $c->user->token + +=item $c->user->token_secret + +=item $c->user->extra_params - whatever other parameters the provider sends back + +=back + +=head1 AUTHOR + +Cosmin Budrica Ecosmin@sinapticode.comE + +Bogdan Lucaciu Ebogdan@sinapticode.comE + +=head1 COPYRIGHT + +Copyright (c) 2009 Sinapticode. All rights reserved + +This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. + +=cut diff --git a/t/00-load.t b/t/00-load.t new file mode 100644 index 0000000..4540932 --- /dev/null +++ b/t/00-load.t @@ -0,0 +1,6 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use Test::More tests => 1; +use ok 'Catalyst::Authentication::Credential::OAuth';