Net-OAuth-0.28000755000770000024 011701507056 12575 5ustar00keithstaff000000000000Net-OAuth-0.28/Build.PL000444000770000024 234211701507056 14227 0ustar00keithstaff000000000000use strict; use warnings; use Module::Build; shift(@ARGV) if defined $ARGV[0] and $ARGV[0] eq 'Build'; # accomodate with CPAN autoinstall my $builder = Module::Build->new( module_name => 'Net::OAuth', license => 'perl', dist_author => 'Keith Grennan ', dist_version_from => 'lib/Net/OAuth.pm', dist_abstract => 'An implementation of the OAuth protocol', build_requires => { 'Test::More' => '0.66', 'Test::Warn' => '0.21', }, requires => { 'Digest::SHA' => '5.47', 'Digest::HMAC_SHA1' => '1.01', 'URI::Escape' => '3.28', 'Class::Accessor' => '0.31', 'Class::Data::Inheritable' => '0.06', 'Digest::SHA1' => '2.12', 'Encode' => '2.35', 'LWP::UserAgent' => '1', }, add_to_cleanup => [ 'Net-OAuth-*' ], create_makefile_pl => 'passthrough', ); $builder->create_build_script(); __END__ # handy lister of installed dependency versions use Data::Dumper; my $requires = $builder->build_requires; for my $mod (keys %$requires) { eval "require $mod"; $requires->{$mod} = eval "\$$mod\::VERSION"; } print "Current dependency versions:\n"; print Dumper $requires; Net-OAuth-0.28/Changes000444000770000024 1137411701507056 14253 0ustar00keithstaff000000000000Revision history for Net-OAuth 0.01 Sun, 30 Sep 2007 13:35:06 UTC First version, released on an unsuspecting world. 0.02 Tue, 02 Oct 2007 07:35:17 UTC Added RSA-SHA1 support 0.03 Mon, 15 Oct 2007 01:35:17 UTC Fixed header parsing 0.04 Fri, 19 Oct 2007 16:45:03 UTC Integrated patch from SARTAK, fixing signature for RequestTokenRequest with HMAC-SHA1 0.05 Mon, 19 Nov 2007 03:30:05 UTC Integrated patch from Nobuo Danjou, for Draft 6 spec compliance 0.06 Sat, 08 Mar 2008 00:57:40 UTC Removed live test that stopped working 0.07 Sun, 01 Jun 2008 16:04:26 UTC Added a factory class, Net::OAuth Added several 'Response' classes Added UserAuthRequest and UserAuthResponse Created a Message base class from which Request and Response inherit Added some introductory documentation Added more tests Phew! 0.08 Mon, 02 Jun 2008 17:41:52 UTC Fixed test failures found in 0.07. More docs. Added more deserialization methods. Changed factory invocation from message('foo') to message('foo')->new(), to allow deserialization methods to be used instead of new(). 0.09 Tue, 03 Jun 2008 03:46:32 UTC Fixed another annoying test failure 0.1 Wed, 04 Jun 2008 16:27:50 UTC Added demo, fixed docs 0.11 Wed, 04 Jun 2008 16:50:14 UTC Doc edits 0.12 Fri, 04 Jul 2008 22:58:23 UTC Added support for extensions - Net::OpenMicroBlogging in particular 0.13 Thu, 13 Nov 2008 22:45:46 UTC Added support for Consumer Request (token-less / two-legged) message type 0.14 Sat, 13 Dec 2008 17:29:36 UTC Add POD for consumer requests 0.15 Fri, 05 Jun 2009 00:48:07 UTC Added Twitter demo consumer Warn if message parameter is already UTF-8 that it will be double-encoded; see I18N section of Net::OAuth manpage Better handling of missing 'realm' parameter in Authorization header methods Better handling of request_url parameter; see REQUEST_URL PARAMETER section of Net::OAuth manpage Fixed http://rt.cpan.org/Public/Bug/Display.html?id=44699 - encode spaces to %20 rather than + in $message->to_url() 0.16 Mon, 15 Jun 2009 18:36:17 UTC Added support for OAuth 1.0A - see POD section 'OAUTH 1.0A' for details - Net::OAuth still defaults to 1.0 for now 0.17 Thu, 25 Jun 2009 16:59:50 UTC Fixed https://rt.cpan.org/Public/Bug/Display.html?id=47293 - Message->from_hash was validating using the incorrect class, causing a 'Parameter X not valid for a message of type Y' message on V1.0a messages. Thanks Jeff Dairiki! 0.18 Thu, 25 Jun 2009 17:18:04 UTC Fixed accidental (though probably harmless) regression in 0.17 0.19 Fri, 26 Jun 2009 17:30:06 UTC Fixed https://rt.cpan.org/Ticket/Display.html?id=47369 - Don't automatically set oauth_version parameter when message is created via from_hash (or from_url, from_post_body, etc). Thanks COSIMO! 0.20 Fri, 13 Nov 2009 18:56:55 UTC Fixed http://rt.cpan.org/Public/Bug/Display.html?id=48867 - error in synopsis - thanks Adam Taylor! Removed UTF8 double-encoding warning. Now Net::OAuth::Message::encode() uses Encode::is_utf8() to determine if the input is already UTF-8 encoded. If so, it runs decode_utf8() on it before sending it to uri_escape_utf8(). Thanks Hector Garcia Alvarez! Potentially fixed an issue found by Marc Mims, where HMAC_SHA1 was failing to load, breaking some CPAN tests. Build.PL now explicitly requires Digest::SHA1 and Encode. Hopefully that fixes it. 0.21 Wed, 10 Mar 2010 22:20:49 UTC Added xAuth support with xAuthAccessTokenRequest (thanks Masayoshi Sekimura and Simon Wistow) Added performance patch to decrease stat() system calls when requiring modules (thanks Brad Whitaker) 0.22 Thu, 11 Mar 2010 00:21:26 UTC Renamed xAuthAccessTokenRequest to XauthAccessTokenRequest for CamelCaseConsistency Added a couple tests for XauthAccessTokenRequest 0.23 Thu, 18 Mar 2010 17:23:36 UTC Removed UNIVERSAL::require dependency Net::OAuth->request constructor now dies if module fails to load (thanks Mike Schleif) Fixed https://rt.cpan.org/Ticket/Display.html?id=55635 Incorrect dependencies (thanks Jens Rehsack) Replaced die() with croak() 0.24 Sun, 21 Mar 2010 03:39:40 UTC Fix test breakage in 0.23 0.25 Sun, 21 Mar 2010 03:50:40 UTC Gah, $VERSION lameness 0.26 Wed, 16 Jun 2010 19:59:04 UTC Message::encode no longer tries fix potential 'double-encoding' (in any case it appeared to be doing it wrong). Now it just complains if you try to pass in undecoded strings. (thanks Daisuke Maki and KATOU Akira) 0.27 Wed, 16 Jun 2010 20:39:59 UTC Added class for Yahoo! access token refresh request (thanks Marc Mims) 0.28 Fri, 06 Jan 2012 05:51:04 UTC Added HMAC-SHA256 support Net-OAuth-0.28/Makefile.PL000444000770000024 226311701507056 14707 0ustar00keithstaff000000000000# Note: this file was auto-generated by Module::Build::Compat version 0.3603 unless (eval "use Module::Build::Compat 0.02; 1" ) { print "This module requires Module::Build to install itself.\n"; require ExtUtils::MakeMaker; my $yn = ExtUtils::MakeMaker::prompt (' Install Module::Build now from CPAN?', 'y'); unless ($yn =~ /^y/i) { die " *** Cannot install without Module::Build. Exiting ...\n"; } require Cwd; require File::Spec; require CPAN; # Save this 'cause CPAN will chdir all over the place. my $cwd = Cwd::cwd(); CPAN::Shell->install('Module::Build::Compat'); CPAN::Shell->expand("Module", "Module::Build::Compat")->uptodate or die "Couldn't install Module::Build, giving up.\n"; chdir $cwd or die "Cannot chdir() back to $cwd: $!"; } eval "use Module::Build::Compat 0.02; 1" or die $@; Module::Build::Compat->run_build_pl(args => \@ARGV); my $build_script = 'Build'; $build_script .= '.com' if $^O eq 'VMS'; exit(0) unless(-e $build_script); # cpantesters convention require Module::Build; Module::Build::Compat->write_makefile(build_class => 'Module::Build'); Net-OAuth-0.28/MANIFEST000444000770000024 227011701507056 14064 0ustar00keithstaff000000000000Build.PL Changes demo/.htaccess demo/app.psgi demo/config.yml demo/dispatch.cgi lib/Net/OAuth.pm lib/Net/OAuth/AccessToken.pm lib/Net/OAuth/AccessTokenRequest.pm lib/Net/OAuth/AccessTokenResponse.pm lib/Net/OAuth/Client.pm lib/Net/OAuth/ConsumerRequest.pm lib/Net/OAuth/Message.pm lib/Net/OAuth/ProtectedResourceRequest.pm lib/Net/OAuth/Request.pm lib/Net/OAuth/RequestTokenRequest.pm lib/Net/OAuth/RequestTokenResponse.pm lib/Net/OAuth/Response.pm lib/Net/OAuth/SignatureMethod/HMAC_SHA1.pm lib/Net/OAuth/SignatureMethod/HMAC_SHA256.pm lib/Net/OAuth/SignatureMethod/PLAINTEXT.pm lib/Net/OAuth/SignatureMethod/RSA_SHA1.pm lib/Net/OAuth/UserAuthRequest.pm lib/Net/OAuth/UserAuthResponse.pm lib/Net/OAuth/V1_0A/AccessTokenRequest.pm lib/Net/OAuth/V1_0A/RequestTokenRequest.pm lib/Net/OAuth/V1_0A/RequestTokenResponse.pm lib/Net/OAuth/V1_0A/UserAuthResponse.pm lib/Net/OAuth/XauthAccessTokenRequest.pm lib/Net/OAuth/YahooAccessTokenRefreshRequest.pm Makefile.PL MANIFEST This list of files README t/01-spec.t t/02-rsa.t t/03-header.t t/04-response.t t/05-auth.t t/06-factory.t t/07-consumer-request.t t/09-encoding.t t/10-misc.t t/11-spec-1.0a.t t/12-xauth.t t/13-hmac-sha256.t t/rsakey t/rsakey.pub META.yml Net-OAuth-0.28/META.yml000444000770000024 504611701507056 14210 0ustar00keithstaff000000000000--- abstract: 'An implementation of the OAuth protocol' author: - 'Keith Grennan ' build_requires: Test::More: 0.66 Test::Warn: 0.21 configure_requires: Module::Build: 0.36 generated_by: 'Module::Build version 0.3603' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Net-OAuth provides: Net::OAuth: file: lib/Net/OAuth.pm version: 0.28 Net::OAuth::AccessToken: file: lib/Net/OAuth/AccessToken.pm Net::OAuth::AccessTokenRequest: file: lib/Net/OAuth/AccessTokenRequest.pm Net::OAuth::AccessTokenResponse: file: lib/Net/OAuth/AccessTokenResponse.pm Net::OAuth::Client: file: lib/Net/OAuth/Client.pm Net::OAuth::ConsumerRequest: file: lib/Net/OAuth/ConsumerRequest.pm Net::OAuth::Message: file: lib/Net/OAuth/Message.pm Net::OAuth::ProtectedResourceRequest: file: lib/Net/OAuth/ProtectedResourceRequest.pm Net::OAuth::Request: file: lib/Net/OAuth/Request.pm version: 0.28 Net::OAuth::RequestTokenRequest: file: lib/Net/OAuth/RequestTokenRequest.pm Net::OAuth::RequestTokenResponse: file: lib/Net/OAuth/RequestTokenResponse.pm Net::OAuth::Response: file: lib/Net/OAuth/Response.pm Net::OAuth::SignatureMethod::HMAC_SHA1: file: lib/Net/OAuth/SignatureMethod/HMAC_SHA1.pm Net::OAuth::SignatureMethod::HMAC_SHA256: file: lib/Net/OAuth/SignatureMethod/HMAC_SHA256.pm Net::OAuth::SignatureMethod::PLAINTEXT: file: lib/Net/OAuth/SignatureMethod/PLAINTEXT.pm Net::OAuth::SignatureMethod::RSA_SHA1: file: lib/Net/OAuth/SignatureMethod/RSA_SHA1.pm Net::OAuth::UserAuthRequest: file: lib/Net/OAuth/UserAuthRequest.pm Net::OAuth::UserAuthResponse: file: lib/Net/OAuth/UserAuthResponse.pm Net::OAuth::V1_0A::AccessTokenRequest: file: lib/Net/OAuth/V1_0A/AccessTokenRequest.pm Net::OAuth::V1_0A::RequestTokenRequest: file: lib/Net/OAuth/V1_0A/RequestTokenRequest.pm Net::OAuth::V1_0A::RequestTokenResponse: file: lib/Net/OAuth/V1_0A/RequestTokenResponse.pm Net::OAuth::V1_0A::UserAuthResponse: file: lib/Net/OAuth/V1_0A/UserAuthResponse.pm Net::OAuth::XauthAccessTokenRequest: file: lib/Net/OAuth/XauthAccessTokenRequest.pm Net::OAuth::YahooAccessTokenRefreshRequest: file: lib/Net/OAuth/YahooAccessTokenRefreshRequest.pm requires: Class::Accessor: 0.31 Class::Data::Inheritable: 0.06 Digest::HMAC_SHA1: 1.01 Digest::SHA: 5.47 Digest::SHA1: 2.12 Encode: 2.35 LWP::UserAgent: 1 URI::Escape: 3.28 resources: license: http://dev.perl.org/licenses/ version: 0.28 Net-OAuth-0.28/README000444000770000024 352711701507056 13621 0ustar00keithstaff000000000000Net-OAuth A Perl wrapper for the OAuth 1.0 specification. http://tools.ietf.org/html/rfc5849 INSTALLATION $ cpan cpan> install Net::OAuth WEB SERVER EXAMPLE (Dancer) # This example is simplified for illustrative purposes, see the complete code in /demo # Note that client_id is the Consumer Key and client_secret is the Consumer Secret use Dancer; use Net::OAuth::Client; sub client { Net::OAuth::Client->new( config->{client_id}, config->{client_secret}, site => 'https://www.google.com/', request_token_path => '/accounts/OAuthGetRequestToken?scope=https%3A%2F%2Fwww.google.com%2Fm8%2Ffeeds%2F', authorize_path => '/accounts/OAuthAuthorizeToken', access_token_path => '/accounts/OAuthGetAccessToken', callback => uri_for("/auth/google/callback"), session => \&session, ); } # Send user to authorize with service provider get '/auth/google' => sub { redirect client->authorize_url; }; # User has returned with token and verifier appended to the URL. get '/auth/google/callback' => sub { # Use the auth code to fetch the access token my $access_token = client->get_access_token(params->{oauth_token}, params->{oauth_verifier}); # Use the access token to fetch a protected resource my $response = $access_token->get('/m8/feeds/contacts/default/full'); # Do something with said resource... if ($response->is_success) { return "Yay, it worked: " . $response->decoded_content; } else { return "Error: " . $response->status_line; } }; dance; LICENSE AND COPYRIGHT Copyright (C) 2011 Keith Grennan This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License. See http://dev.perl.org/licenses/ for more information. Net-OAuth-0.28/demo000755000770000024 011701507056 13521 5ustar00keithstaff000000000000Net-OAuth-0.28/demo/.htaccess000444000770000024 23611701507056 15435 0ustar00keithstaff000000000000RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ /dispatch.cgi/$1 [QSA,L] Order allow,deny Deny from all Net-OAuth-0.28/demo/app.psgi000555000770000024 447511701507056 15337 0ustar00keithstaff000000000000#!/usr/bin/env perl use strict; use warnings; use Dancer; use Net::OAuth::Client; use HTML::Entities; sub client { my $site_id = shift; Net::OAuth::Client->new( config->{sites}{$site_id}{client_id}, config->{sites}{$site_id}{client_secret}, site => config->{sites}{$site_id}{site}, request_token_path => config->{sites}{$site_id}{request_token_path}, authorize_path => config->{sites}{$site_id}{authorize_path}, access_token_path => config->{sites}{$site_id}{access_token_path}, callback => fix_uri(uri_for("/got/$site_id")), session => \&session, debug => 1, ); } get '/get/:site_id' => sub { redirect client(params->{site_id})->authorize_url; }; get '/got/:site_id' => sub { return wrap("Error: Missing access code") if (!defined params->{oauth_verifier}); my $access_token = client(params->{site_id})->get_access_token(params->{oauth_token}, params->{oauth_verifier}); return wrap("Error: " . $access_token->to_string) if ($access_token->{error}); my $content = '

Access token retrieved successfully!

'. '

Token: ' . encode_entities($access_token->token) . '

'. '

Secret: ' . encode_entities($access_token->token_secret) . '

'; my $response = $access_token->get(config->{sites}{params->{site_id}}{protected_resource_path}); if ($response->is_success) { $content .= '

Protected resource retrieved successfully!

'; } else { $content .= '

Error: ' . $response->status_line . '

'; } $content =~ s[\n][
\n]g; return wrap($content); }; sub fix_uri { (my $uri = shift) =~ s[/dispatch\.cgi][]; return $uri; } sub wrap { my $content = shift; return < OAuth Test

OAuth Test

$content EOT } get '/' => sub { my $content=''; while (my ($k,$v) = each %{config->{sites}}) { if (defined $v->{client_id} and length $v->{client_id} and defined $v->{client_secret} and length $v->{client_secret}) { $content .= "

" . $v->{name} . ": /get/$k

\n"; } } $content = "You haven't configured any sites yet. Edit your config.yml file!" unless $content; return wrap($content); }; dance; Net-OAuth-0.28/demo/config.yml000444000770000024 125111701507056 15645 0ustar00keithstaff000000000000# Config file for OAuth demo # Note that client_id is your Consumer Key and client_secret is your Consumer Secret log: 'core' access_log: 1 show_errors: 1 session: "YAML" sites: google_contacts: name: 'Google Contacts' client_id: '' client_secret: '' site: 'https://www.google.com/' request_token_path: '/accounts/OAuthGetRequestToken?scope=https%3A%2F%2Fwww.google.com%2Fm8%2Ffeeds%2F' authorize_path: '/accounts/OAuthAuthorizeToken' access_token_path: '/accounts/OAuthGetAccessToken' protected_resource_path: '/m8/feeds/contacts/default/full' Net-OAuth-0.28/demo/dispatch.cgi000555000770000024 50711701507056 16126 0ustar00keithstaff000000000000#!/usr/bin/perl use strict; use warnings; use lib qw( . Net-OAuth/lib /home/kg23/local/share/perl/5.10 /home/kg23/local/share/perl/5.10.0 /home/kg23/local/lib/perl/5.10 /home/kg23/local/lib/perl/5.10.0 ); use Plack::Util; use Plack::Loader; my $app = Plack::Util::load_psgi("app.psgi"); Plack::Loader->auto->run($app); Net-OAuth-0.28/lib000755000770000024 011701507056 13343 5ustar00keithstaff000000000000Net-OAuth-0.28/lib/Net000755000770000024 011701507056 14071 5ustar00keithstaff000000000000Net-OAuth-0.28/lib/Net/OAuth.pm000444000770000024 3465311701507056 15637 0ustar00keithstaff000000000000package Net::OAuth; use warnings; use strict; use Carp; sub PROTOCOL_VERSION_1_0() {1} sub PROTOCOL_VERSION_1_0A() {1.001} sub OAUTH_VERSION() {'1.0'} our $VERSION = '0.28'; our $SKIP_UTF8_DOUBLE_ENCODE_CHECK = 0; our $PROTOCOL_VERSION = PROTOCOL_VERSION_1_0; sub request { my $self = shift; my $what = shift; return $self->message($what . ' Request'); } sub response { my $self = shift; my $what = shift; return $self->message($what . ' Response'); } sub message { my $self = shift; my $base_class = ref $self || $self; my $type = camel(shift); my $class = $base_class . '::' . $type; smart_require($class, 1); return $class; } sub camel { my @words; foreach (@_) { while (/([A-Za-z0-9]+)/g) { (my $word = $1) =~ s/authentication/auth/i; push @words, $word; } } my $name = join('', map("\u$_", @words)); } our %ALREADY_REQUIRED = (); # class_name => rv of ->require sub smart_require { my $required_class = shift; my $croak_on_error = shift || 0; unless (exists $ALREADY_REQUIRED{$required_class}) { $ALREADY_REQUIRED{$required_class} = eval "require $required_class"; croak $@ if $@ and $croak_on_error; } return $ALREADY_REQUIRED{$required_class}; } =head1 NAME Net::OAuth - OAuth 1.0 for Perl =head1 SYNOPSIS # Web Server Example (Dancer) # This example is simplified for illustrative purposes, see the complete code in /demo # Note that client_id is the Consumer Key and client_secret is the Consumer Secret use Dancer; use Net::OAuth::Client; sub client { Net::OAuth::Client->new( config->{client_id}, config->{client_secret}, site => 'https://www.google.com/', request_token_path => '/accounts/OAuthGetRequestToken?scope=https%3A%2F%2Fwww.google.com%2Fm8%2Ffeeds%2F', authorize_path => '/accounts/OAuthAuthorizeToken', access_token_path => '/accounts/OAuthGetAccessToken', callback => uri_for("/auth/google/callback"), session => \&session, ); } # Send user to authorize with service provider get '/auth/google' => sub { redirect client->authorize_url; }; # User has returned with token and verifier appended to the URL. get '/auth/google/callback' => sub { # Use the auth code to fetch the access token my $access_token = client->get_access_token(params->{oauth_token}, params->{oauth_verifier}); # Use the access token to fetch a protected resource my $response = $access_token->get('/m8/feeds/contacts/default/full'); # Do something with said resource... if ($response->is_success) { return "Yay, it worked: " . $response->decoded_content; } else { return "Error: " . $response->status_line; } }; dance; =head1 IMPORTANT Net::OAuth provides a low-level API for reading and writing OAuth messages. You probably should start with L. =head1 ABSTRACT OAuth is "An open protocol to allow secure API authentication in a simple and standard method from desktop and web applications." In practical terms, OAuth is a mechanism for a Consumer to request protected resources from a Service Provider on behalf of a user. Please refer to the OAuth spec: L Net::OAuth provides: =over =item * classes that encapsulate OAuth messages (requests and responses). =item * message signing =item * message serialization and parsing. =item * 2-legged requests (aka. tokenless requests, aka. consumer requests), see L =back Net::OAuth does not provide: =over =item * Consumer or Service Provider encapsulation =item * token/nonce/key storage/management =back =head1 DESCRIPTION =head2 OAUTH MESSAGES An OAuth message is a set of key-value pairs. The following message types are supported: Requests =over =item * Request Token (Net::OAuth::RequestTokenRequest) =item * Access Token (Net::OAuth::AccessTokenRequest) =item * User Authentication (Net::OAuth::UserAuthRequest) =item * Protected Resource (Net::OAuth::ProtectedResourceRequest) =item * Consumer Request (Net::OAuth::ConsumerRequest) (2-legged / token-less request) =back Responses =over =item * Request Token (Net::OAuth::RequestTokenResponse) =item * Access Token (Net::OAuth:AccessTokenResponse) =item * User Authentication (Net::OAuth::UserAuthResponse) =back Each OAuth message type has one or more required parameters, zero or more optional parameters, and most allow arbitrary parameters. All OAuth requests must be signed by the Consumer. Responses from the Service Provider, however, are not signed. To create a message, the easiest way is to use the factory methods (Net::OAuth->request, Net::OAuth->response, Net::OAuth->message). The following method invocations are all equivalent: $request = Net::OAuth->request('user authentication')->new(%params); $request = Net::OAuth->request('user_auth')->new(%params); $request = Net::OAuth->request('UserAuth')->new(%params); $request = Net::OAuth->message('UserAuthRequest')->new(%params); The more verbose way is to use the class directly: use Net::OAuth::UserAuthRequest; $request = Net::OAuth::UserAuthRequest->new(%params); You can also create a message by deserializing it from a Authorization header, URL, query hash, or POST body $request = Net::OAuth->request('protected resource')->from_authorization_header($ENV{HTTP_AUTHORIZATION}, %api_params); $request = Net::OAuth->request('protected resource')->from_url($url, %api_params); $request = Net::OAuth->request('protected resource')->from_hash({$q->Vars}, %api_params); # CGI $request = Net::OAuth->request('protected resource')->from_hash($c->request->params, %api_params); # Catalyst $response = Net::OAuth->response('request token')->from_post_body($response_content, %api_params); Note that the deserialization methods (as opposed to new()) expect OAuth protocol parameters to be prefixed with 'oauth_', as you would expect in a valid OAuth message. Before sending a request, the Consumer must first sign it: $request->sign; When receiving a request, the Service Provider should first verify the signature: die "Signature verification failed" unless $request->verify; When sending a message the last step is to serialize it and send it to wherever it needs to go. The following serialization methods are available: $response->to_post_body # a application/x-www-form-urlencoded POST body $request->to_url # the query string of a URL $request->to_authorization_header # the value of an HTTP Authorization header $request->to_hash # a hash that could be used for some other serialization =head2 API PARAMETERS vs MESSAGE PARAMETERS Net::OAuth defines 'message parameters' as parameters that are part of the transmitted OAuth message. These include any protocol parameter (prefixed with 'oauth_' in the message), and any additional message parameters (the extra_params hash). 'API parameters' are parameters required to build a message object that are not transmitted with the message, e.g. consumer_secret, token_secret, request_url, request_method. There are various methods to inspect a message class to see what parameters are defined: $request->required_message_params; $request->optional_message_params; $request->all_message_params; $request->required_api_params; $request->optional_api_params; $request->all_api_params; $request->all_params; E.g. use Net::OAuth; use Data::Dumper; print Dumper(Net::OAuth->request("protected resource")->required_message_params); $VAR1 = [ 'consumer_key', 'signature_method', 'timestamp', 'nonce', 'token' ]; =head2 ACCESSING PARAMETERS All parameters can be get/set using accessor methods. E.g. my $consumer_key = $request->consumer_key; $request->request_method('POST'); =head2 THE REQUEST_URL PARAMETER Any query parameters in the request_url are removed and added to the extra_params hash when generating the signature. E.g. the following requests are pretty much equivalent: my $request = Net::OAuth->request('Request Token')->new( %params, request_url => 'https://photos.example.net/request_token', extra_params => { foo => 'bar' }, ); my $request = Net::OAuth->request('Request Token')->new( %params, request_url => 'https://photos.example.net/request_token?foo=bar', ); Calling $request->request_url will still return whatever you set it to originally. If you want to get the request_url with the query parameters removed, you can do: my $url = $request->normalized_request_url; =head2 SIGNATURE METHODS The following signature methods are supported: =over =item * PLAINTEXT =item * HMAC-SHA1 =item * HMAC-SHA256 =item * RSA-SHA1 =back The signature method is determined by the value of the signature_method parameter that is passed to the message constructor. If an unknown signature method is specified, the signing/verification will throw an exception. =head3 PLAINTEXT SIGNATURES This method is a trivial signature which adds no security. Not recommended. =head3 HMAC-SHA1 SIGNATURES This method is available if you have Digest::HMAC_SHA1 installed. This is by far the most commonly used method. =head3 HMAC-SHA256 SIGNATURES This method is available if you have Digest::SHA installed. =head3 RSA-SHA1 SIGNATURES To use RSA-SHA1 signatures, pass in a Crypt::OpenSSL::RSA object (or any object that can do $o->sign($str) and/or $o->verify($str, $sig)) E.g. Consumer: use Crypt::OpenSSL::RSA; use File::Slurp; $keystring = read_file('private_key.pem'); $private_key = Crypt::OpenSSL::RSA->new_private_key($keystring); $request = Net::OAuth->request('request token')->new(%params); $request->sign($private_key); Service Provider: use Crypt::OpenSSL::RSA; use File::Slurp; $keystring = read_file('public_key.pem'); $public_key = Crypt::OpenSSL::RSA->new_public_key($keystring); $request = Net::OAuth->request('request token')->new(%params); if (!$request->verify($public_key)) { die "Signature verification failed"; } Note that you can pass the key in as a parameter called 'signature_key' to the message constructor, rather than passing it to the sign/verify method, if you like. =head2 CONSUMER REQUESTS To send a request without including a token, use a Consumer Request: my $request = Net::OAuth->request('consumer')->new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'http://provider.example.net/profile', request_method => 'GET', signature_method => 'HMAC-SHA1', timestamp => '1191242096', nonce => 'kllo9940pd9333jh', ); $request->sign; See L =head2 I18N Per the OAuth spec, when making the signature Net::OAuth first encodes parameters to UTF-8. This means that any parameters you pass to Net::OAuth, if they might be outside of ASCII character set, should be run through Encode::decode() (or an equivalent PerlIO layer) first to decode them to Perl's internal character sructure. =head2 OAUTH 1.0A Background: L L Net::OAuth defaults to OAuth 1.0 spec compliance, and supports OAuth 1.0 Rev A with an optional switch: use Net::OAuth $Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0A; It is recommended that any new projects use this switch if possible, and existing projects move to supporting this switch as soon as possible. Probably the easiest way for existing projects to do this is to turn on the switch and run your test suite. The Net::OAuth constructor will throw an exception where the new protocol parameters (callback, callback_confirmed, verifier) are missing. Internally, the Net::OAuth::Message constructor checks $Net::OAuth::PROTOCOL_VERSION and attempts to load the equivalent subclass in the Net::OAuth::V1_0A:: namespace. So if you instantiate a Net::OAuth::RequestTokenRequest object, you will end up with a Net::OAuth::V1_0A::RequestTokenRequest (a subclass of Net::OAuth::RequestTokenRequest) if the protocol version is set to PROTOCOL_VERSION_1_0A. You can also select a 1.0a subclass on a per-message basis by passing protocol_version => Net::OAuth::PROTOCOL_VERSION_1_0A in the API parameters hash. If you are not sure whether the entity you are communicating with is 1.0A compliant, you can try instantiating a 1.0A message first and then fall back to 1.0 if that fails: use Net::OAuth $Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0A; my $is_oauth_1_0 = 0; my $response = eval{Net::OAuth->response('request token')->from_post_body($res->content)}; if ($@) { if ($@ =~ /Missing required parameter 'callback_confirmed'/) { # fall back to OAuth 1.0 $response = Net::OAuth->response('request token')->from_post_body( $res->content, protocol_version => Net::OAuth::PROTOCOL_VERSION_1_0 ); $is_oauth_1_0 = 1; # from now on treat the server as OAuth 1.0 compliant } else { die $@; } } At some point in the future, Net::OAuth will default to Net::OAuth::PROTOCOL_VERSION_1_0A. =head1 DEMO There is a demo Consumer CGI in this package, also available online at L =head1 SEE ALSO L Check out L - it has a simpler API that may be more to your liking Check out L for a Twitter-specific OAuth API Check out L for a Netflix-specific OAuth API =head1 TODO =over =item * Support for repeating/multivalued parameters =item * Add convenience methods for SPs Something like: # direct from CGI.pm object $request = Net::OAuth->request('Request Token')->from_cgi_query($cgi, %api_params); # direct from Catalyst::Request object $request = Net::OAuth->request('Request Token')->from_catalyst_request($c->req, %api_params); # from Auth header and GET and POST params in one local $/; my $post_body = ; $request = Net::OAuth->request('Request Token')->from_auth_get_and_post( $ENV{HTTP_AUTHORIZATION}, $ENV{QUERY_STRING}, $post_body, %api_params ); =back =head1 AUTHOR Keith Grennan, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2009 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; Net-OAuth-0.28/lib/Net/OAuth000755000770000024 011701507056 15111 5ustar00keithstaff000000000000Net-OAuth-0.28/lib/Net/OAuth/AccessToken.pm000444000770000024 305411701507056 20010 0ustar00keithstaff000000000000package Net::OAuth::AccessToken; use warnings; use strict; use base qw(Class::Accessor::Fast); __PACKAGE__->mk_accessors(qw/client token token_secret session_handle expires_in authorization_expires_in/); sub new { my $class = shift; my %opts = @_; my $self = bless \%opts, $class; return $self; } sub request { my $self = shift; my ($method, $uri, $header, $content, %params) = @_; my $oauth_req = $self->client->_make_request( 'protected resource', request_method => $method, request_url => $self->client->site_url($uri), token => $self->token, token_secret => $self->token_secret, %params, ); $oauth_req->sign; return $self->client->request(HTTP::Request->new( $method => $oauth_req->to_url, $header, $content )); } sub get { return shift->request('GET', @_); } sub post { return shift->request('POST', @_); } sub delete { return shift->request('DELETE', @_); } sub put { return shift->request('PUT', @_); } =head1 NAME Net::OAuth::AccessToken - OAuth Access Token =head1 DESCRIPTION WARNING: Net::OAuth::AccessToken is alpha code. The rest of Net::OAuth is quite stable but this particular module is new, and is under-documented and under-tested. =head1 SEE ALSO L =head1 LICENSE AND COPYRIGHT Copyright 2011 Keith Grennan. This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License. See http://dev.perl.org/licenses/ for more information. =cut 1; Net-OAuth-0.28/lib/Net/OAuth/AccessTokenRequest.pm000444000770000024 122611701507056 21360 0ustar00keithstaff000000000000package Net::OAuth::AccessTokenRequest; use warnings; use strict; use base 'Net::OAuth::Request'; __PACKAGE__->add_required_message_params(qw/token/); __PACKAGE__->add_required_api_params(qw/token_secret/); sub allow_extra_params {0} sub sign_message {1} =head1 NAME Net::OAuth::AccessTokenRequest - An OAuth protocol request for an Access Token =head1 SEE ALSO L, L =head1 AUTHOR Keith Grennan, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2007 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;Net-OAuth-0.28/lib/Net/OAuth/AccessTokenResponse.pm000444000770000024 112411701507056 21523 0ustar00keithstaff000000000000package Net::OAuth::AccessTokenResponse; use warnings; use strict; use base 'Net::OAuth::Response'; __PACKAGE__->add_required_message_params(qw/token_secret/); sub allow_extra_params {1} =head1 NAME Net::OAuth::AccessTokenResponse - An OAuth protocol response for an Access Token =head1 SEE ALSO L, L =head1 AUTHOR Keith Grennan, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2007 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;Net-OAuth-0.28/lib/Net/OAuth/Client.pm000444000770000024 1705011701507056 17045 0ustar00keithstaff000000000000package Net::OAuth::Client; use warnings; use strict; use base qw(Class::Accessor::Fast); __PACKAGE__->mk_accessors(qw/id secret callback is_v1a user_agent site debug session/); use LWP::UserAgent; use URI; use Net::OAuth; use Net::OAuth::Message; use Net::OAuth::AccessToken; use Carp; =head1 NAME Net::OAuth::Client - OAuth 1.0A Client =head1 SYNOPSIS # Web Server Example (Dancer) # This example is simplified for illustrative purposes, see the complete code in /demo # Note that client_id is the Consumer Key and client_secret is the Consumer Secret use Dancer; use Net::OAuth::Client; sub client { Net::OAuth::Client->new( config->{client_id}, config->{client_secret}, site => 'https://www.google.com/', request_token_path => '/accounts/OAuthGetRequestToken?scope=https%3A%2F%2Fwww.google.com%2Fm8%2Ffeeds%2F', authorize_path => '/accounts/OAuthAuthorizeToken', access_token_path => '/accounts/OAuthGetAccessToken', callback => uri_for("/auth/google/callback"), session => \&session, ); } # Send user to authorize with service provider get '/auth/google' => sub { redirect client->authorize_url; }; # User has returned with token and verifier appended to the URL. get '/auth/google/callback' => sub { # Use the auth code to fetch the access token my $access_token = client->get_access_token(params->{oauth_token}, params->{oauth_verifier}); # Use the access token to fetch a protected resource my $response = $access_token->get('/m8/feeds/contacts/default/full'); # Do something with said resource... if ($response->is_success) { return "Yay, it worked: " . $response->decoded_content; } else { return "Error: " . $response->status_line; } }; dance; =head1 DESCRIPTION Net::OAuth::Client represents an OAuth client or consumer. WARNING: Net::OAuth::Client is alpha code. The rest of Net::OAuth is quite stable but this particular module is new, and is under-documented and under-tested. =head1 METHODS =over =item new($client_id, $client_secret, %params) Create a new Client =over =item * $client_id AKA Consumer Key - you get this from the service provider when you register your application. =item * $client_secret AKA Consumer Secret - you get this from the service provider when you register your application. =item * $params{site} =item * $params{request_token_path} =item * $params{authorize_path} =item * $params{access_token_path} =item * $params{callback} =item * $params{session} =back =back =cut sub new { my $class = shift; my $client_id = shift; my $client_secret = shift; my %opts = @_; $opts{user_agent} ||= LWP::UserAgent->new; $opts{id} = $client_id; $opts{secret} = $client_secret; $opts{is_v1a} = defined $opts{callback}; my $self = bless \%opts, $class; return $self; } sub request { my $self = shift; my $response = $self->user_agent->request(@_); } sub _parse_oauth_response { my $self = shift; my $do_what = shift; my $http_res = shift; my $msg = "Unable to $do_what: Request for " . $http_res->request->uri . " failed"; unless ($http_res->is_success) { if ($self->debug) { $msg .= "," . $http_res->as_string . " "; } elsif ( $http_res->content_type eq 'application/x-www-form-urlencoded' and $http_res->decoded_content =~ /\boauth_problem=(\w+)/ ) { $msg .= ", reason: " . $1; } else { $msg .= ": " . $http_res->status_line . " (pass debug=>1 to Net::OAuth::Client->new to dump the entire response)"; } croak $msg; } my $oauth_res = _parse_url_encoding($http_res->decoded_content); foreach my $k (qw/token token_secret/) { croak "Unable to $do_what: server response is missing '$k'" unless defined $oauth_res->{$k}; } return $oauth_res; } sub _parse_url_encoding { my $str = shift; my @pairs = split '&', $str; my %params; foreach my $pair (@pairs) { my ($k,$v) = split /=/, $pair; if (defined $k and defined $v) { $v =~ s/(^"|"$)//g; ($k,$v) = map Net::OAuth::Message::decode($_), $k, $v; $k =~ s/^oauth_//; $params{$k} = $v; } } return \%params; } sub get_request_token { my $self = shift; my %params = @_; my $oauth_req = $self->_make_request( "request token", request_method => $self->request_token_method, request_url => $self->_make_url("request_token"), %params ); $oauth_req->sign; my $http_res = $self->request(HTTP::Request->new( $self->request_token_method => $oauth_req->to_url )); my $oauth_res = $self->_parse_oauth_response('get a request token', $http_res); $self->is_v1a(0) unless defined $oauth_res->{callback_confirmed}; return $oauth_res; } sub authorize_url { my $self = shift; my %params = @_; # allow user to get request token their own way unless (defined $params{token} and defined $params{token_secret}) { my $request_token = $self->get_request_token; $params{token} = $request_token->{token}; $params{token_secret} = $request_token->{token_secret}; } if (defined $self->session) { $self->session->($params{token} => $params{token_secret}); } my $oauth_req = $self->_make_request( 'user auth', %params ); return $oauth_req->to_url($self->_make_url('authorize')); } sub get_access_token { my $self = shift; my $token = shift; my $verifier = shift; my %params = @_; if (defined $self->session) { $params{token_secret} = $self->session->($token); } my $oauth_req = $self->_make_request( 'access token', request_method => $self->access_token_method, request_url => $self->_make_url('access_token'), token => $token, verifier => $verifier, %params ); $oauth_req->sign; my $http_res = $self->request(HTTP::Request->new( $self->access_token_method => $oauth_req->to_url )); my $oauth_res = $self->_parse_oauth_response('get an access token', $http_res); return Net::OAuth::AccessToken->new(%$oauth_res, client => $self); } sub access_token_url { return shift->_make_url('access_token', @_); } sub request_token_url { return shift->_make_url('request_token', @_); } sub access_token_method { return shift->{access_token_method} || 'GET'; } sub request_token_method { return shift->{request_token_method} || 'GET'; } sub _make_request { my $self = shift; my $type = shift; my %params = @_; my %defaults = ( nonce => int( rand( 2**32 ) ), timestamp => time, consumer_key => $self->id, consumer_secret => $self->secret, callback => $self->callback, signature_method => 'HMAC-SHA1', request_method => 'GET', ); $defaults{protocol_version} = Net::OAuth::PROTOCOL_VERSION_1_0A if $self->is_v1a; my $req = Net::OAuth->request($type)->new( %defaults, %params ); return $req; } sub _make_url { my $self = shift; my $thing = shift; my $path = $self->{"${thing}_url"} || $self->{"${thing}_path"} || "/oauth/${thing}"; return $self->site_url($path, @_); } sub site_url { my $self = shift; my $path = shift; my %params = @_; my $url; if (defined $self->{site}) { $url = URI->new_abs($path, $self->{site}); } else { $url = URI->new($path); } if (@_) { $url->query_form($url->query_form , %params); } return $url; } =head1 LICENSE AND COPYRIGHT Copyright 2011 Keith Grennan. This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License. See http://dev.perl.org/licenses/ for more information. =cut 1; 1; Net-OAuth-0.28/lib/Net/OAuth/ConsumerRequest.pm000444000770000024 140711701507056 20752 0ustar00keithstaff000000000000package Net::OAuth::ConsumerRequest; use warnings; use strict; use base 'Net::OAuth::Request'; sub allow_extra_params {1} sub sign_message {1} =head1 NAME Net::OAuth::ConsumerRequest - An OAuth Consumer Request =head1 NOTE Consumer Requests are a proposed extension to OAuth, so other OAuth implementations may or may not support them. =head1 SEE ALSO Consumer Request Extension Draft: L L, L =head1 AUTHOR Keith Grennan, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2007 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;Net-OAuth-0.28/lib/Net/OAuth/Message.pm000444000770000024 2271211701507056 17214 0ustar00keithstaff000000000000package Net::OAuth::Message; use warnings; use strict; use base qw/Class::Data::Inheritable Class::Accessor/; use URI::Escape; use Net::OAuth; use URI; use URI::QueryParam; use Carp; use constant OAUTH_PREFIX => 'oauth_'; our $OAUTH_PREFIX_RE = do {my $p = OAUTH_PREFIX; qr/^$p/}; __PACKAGE__->mk_classdata(extension_param_patterns => []); sub add_required_message_params { my $class = shift; $class->required_message_params([@{$class->required_message_params}, @_]); $class->all_message_params([@{$class->all_message_params}, @_]); $class->all_params([@{$class->all_params}, @_]); $class->mk_accessors(@_); } sub add_optional_message_params { my $class = shift; $class->optional_message_params([@{$class->optional_message_params}, @_]); $class->all_message_params([@{$class->all_message_params}, @_]); $class->all_params([@{$class->all_params}, @_]); $class->mk_accessors(@_); } sub add_required_api_params { my $class = shift; $class->required_api_params([@{$class->required_api_params}, @_]); $class->all_api_params([@{$class->all_api_params}, @_]); $class->all_params([@{$class->all_params}, @_]); $class->mk_accessors(@_); } sub add_extension_param_pattern { my $class = shift; $class->extension_param_patterns([@{$class->extension_param_patterns}, @_]); } sub add_to_signature { my $class = shift; $class->signature_elements([@{$class->signature_elements}, @_]); } sub new { my $proto = shift; my $class = ref $proto || $proto; my %params = @_; $class = get_versioned_class($class, \%params); my $self = bless \%params, $class; $self->set_defaults; $self->check; return $self; } sub get_versioned_class { my $class = shift; my $params = shift; my $protocol_version = $params->{protocol_version} || $Net::OAuth::PROTOCOL_VERSION; if (defined $protocol_version and $protocol_version == Net::OAuth::PROTOCOL_VERSION_1_0A and $class !~ /\::V1_0A\::/) { (my $versioned_class = $class) =~ s/::(\w+)$/::V1_0A::$1/; return $versioned_class if Net::OAuth::smart_require($versioned_class); } return $class; } sub set_defaults { my $self = shift; $self->{extra_params} ||= {}; $self->{version} ||= Net::OAuth::OAUTH_VERSION unless $self->{from_hash}; } sub is_extension_param { my $self = shift; my $param = shift; return grep ($param =~ $_, @{$self->extension_param_patterns}); } sub check { my $self = shift; foreach my $k (@{$self->required_message_params}, @{$self->required_api_params}) { if (not defined $self->{$k}) { croak "Missing required parameter '$k'"; } } if ($self->{extra_params} and $self->allow_extra_params) { foreach my $k (keys %{$self->{extra_params}}) { if ($k =~ $OAUTH_PREFIX_RE) { croak "Parameter '$k' not allowed in arbitrary params" } } } } sub encode { my $str = shift; $str = "" unless defined $str; unless($Net::OAuth::SKIP_UTF8_DOUBLE_ENCODE_CHECK) { if ($str =~ /[\x80-\xFF]/ and !utf8::is_utf8($str)) { warn "Net::OAuth warning: your OAuth message appears to contain some multi-byte characters that need to be decoded via Encode.pm or a PerlIO layer first. This may result in an incorrect signature."; } } return URI::Escape::uri_escape_utf8($str,'^\w.~-'); } sub decode { my $str = shift; return uri_unescape($str); } sub allow_extra_params {1} sub sign_message {0} sub gather_message_parameters { my $self = shift; my %opts = @_; $opts{quote} = "" unless defined $opts{quote}; $opts{params} ||= []; my %params; foreach my $k (@{$self->required_message_params}, @{$self->optional_message_params}, @{$opts{add}}) { next if $k eq 'signature' and (!$self->sign_message or !grep ($_ eq 'signature', @{$opts{add}})); my $message_key = $self->is_extension_param($k) ? $k : OAUTH_PREFIX . $k; my $v = $self->$k; $params{$message_key} = $v if defined $v; } if ($self->{extra_params} and !$opts{no_extra} and $self->allow_extra_params) { foreach my $k (keys %{$self->{extra_params}}) { $params{$k} = $self->{extra_params}{$k}; } if ($self->can('request_url')) { my $url = $self->request_url; _ensure_uri_object($url); foreach my $k ($url->query_param) { $params{$k} = $url->query_param($k); } } } if ($opts{hash}) { return \%params; } my @pairs; while (my ($k,$v) = each %params) { push @pairs, join('=', encode($k), $opts{quote} . encode($v) . $opts{quote}); } return sort(@pairs); } sub normalized_message_parameters { my $self = shift; return join('&', $self->gather_message_parameters); } sub signature_base_string { my $self = shift; return join('&', map(encode($self->$_), @{$self->signature_elements})); } sub sign { my $self = shift; my $class = $self->_signature_method_class; $self->signature($class->sign($self, @_)); } sub verify { my $self = shift; my $class = $self->_signature_method_class; return $class->verify($self, @_); } sub _signature_method_class { my $self = shift; (my $signature_method = $self->signature_method) =~ s/\W+/_/g; my $sm_class = 'Net::OAuth::SignatureMethod::' . $signature_method; croak "Unable to load $signature_method plugin" unless Net::OAuth::smart_require($sm_class); return $sm_class; } sub to_authorization_header { my $self = shift; my $realm = shift; my $sep = shift || ","; if (defined $realm) { $realm = "realm=\"$realm\"$sep"; } else { $realm = ""; } return "OAuth $realm" . join($sep, $self->gather_message_parameters(quote => '"', add => [qw/signature/], no_extra => 1)); } sub from_authorization_header { my $proto = shift; my $header = shift; my $class = ref $proto || $proto; croak "Header must start with \"OAuth \"" unless $header =~ s/OAuth //; my @header = split /[\s]*,[\s]*/, $header; shift @header if $header[0] =~ /^realm=/i; return $class->_from_pairs(\@header, @_) } sub _from_pairs() { my $class = shift; my $pairs = shift; if (ref $pairs ne 'ARRAY') { croak 'Expected an array!'; } my %params; foreach my $pair (@$pairs) { my ($k,$v) = split /=/, $pair; if (defined $k and defined $v) { $v =~ s/(^"|"$)//g; ($k,$v) = map decode($_), $k, $v; $params{$k} = $v; } } return $class->from_hash(\%params, @_); } sub from_hash { my $proto = shift; my $class = ref $proto || $proto; my $hash = shift; if (ref $hash ne 'HASH') { croak 'Expected a hash!'; } my %api_params = @_; # need to do this earlier than Message->new because # the below validation step needs the correct class. # https://rt.cpan.org/Public/Bug/Display.html?id=47293 $class = get_versioned_class($class, \%api_params); my %msg_params; foreach my $k (keys %$hash) { if ($k =~ s/$OAUTH_PREFIX_RE//) { if (!grep ($_ eq $k, @{$class->all_message_params})) { croak "Parameter ". OAUTH_PREFIX ."$k not valid for a message of type $class"; } else { $msg_params{$k} = $hash->{OAUTH_PREFIX . $k}; } } elsif ($class->is_extension_param($k)) { if (!grep ($_ eq $k, @{$class->all_message_params})) { croak "Parameter $k not valid for a message of type $class"; } else { $msg_params{$k} = $hash->{$k}; } } else { $msg_params{extra_params}->{$k} = $hash->{$k}; } } $api_params{from_hash} = 1; return $class->new(%msg_params, %api_params); } sub _ensure_uri_object { $_[0] = UNIVERSAL::isa($_[0], 'URI') ? $_[0] : URI->new($_[0]); } sub from_url { my $proto = shift; my $class = ref $proto || $proto; my $url = shift; _ensure_uri_object($url); return $class->from_hash($url->query_form_hash, @_); } sub to_post_body { my $self = shift; return join('&', $self->gather_message_parameters(add => [qw/signature/])); } sub from_post_body { my $proto = shift; my $class = ref $proto || $proto; my @pairs = split '&', shift; return $class->_from_pairs(\@pairs, @_); } sub to_hash { my $self = shift; return $self->gather_message_parameters(hash => 1, add => [qw/signature/]); } sub to_url { my $self = shift; my $url = shift; if (!defined $url and $self->can('request_url') and defined $self->request_url) { $url = $self->request_url; } if (defined $url) { _ensure_uri_object($url); $url = $url->clone; # don't modify the URL that was passed in $url->query(undef); # remove any existing query params, as these may cause the signature to break my $params = $self->to_hash; my $sep = '?'; foreach my $k (sort keys %$params) { $url .= $sep . encode($k) . '=' . encode( $params->{$k} ); $sep = '&' if $sep eq '?'; } return $url; } else { return $self->to_post_body; } } =head1 NAME Net::OAuth::Message - base class for OAuth messages =head1 SEE ALSO L, L =head1 AUTHOR Keith Grennan, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2007 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; Net-OAuth-0.28/lib/Net/OAuth/ProtectedResourceRequest.pm000444000770000024 125111701507056 22615 0ustar00keithstaff000000000000package Net::OAuth::ProtectedResourceRequest; use warnings; use strict; use base 'Net::OAuth::Request'; __PACKAGE__->add_required_message_params(qw/token/); __PACKAGE__->add_required_api_params(qw/token_secret/); sub allow_extra_params {1} sub sign_message {1} =head1 NAME Net::OAuth::ProtectedResourceRequest - An OAuth protocol request for a Protected Resource =head1 SEE ALSO L, L =head1 AUTHOR Keith Grennan, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2007 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;Net-OAuth-0.28/lib/Net/OAuth/Request.pm000444000770000024 425511701507056 17242 0ustar00keithstaff000000000000package Net::OAuth::Request; use warnings; use strict; use base qw/Net::OAuth::Message/; use URI; use URI::QueryParam; use Net::OAuth; our $VERSION = '0.28'; __PACKAGE__->mk_classdata(required_message_params => [qw/ consumer_key signature_method timestamp nonce /]); __PACKAGE__->mk_classdata(optional_message_params => [qw/ version signature /]); __PACKAGE__->mk_classdata(required_api_params => [qw/ request_method request_url consumer_secret /]); __PACKAGE__->mk_classdata(optional_api_params => [qw/ signature_key token_secret extra_params protocol_version /]); __PACKAGE__->mk_classdata(signature_elements => [qw/ request_method normalized_request_url normalized_message_parameters /]); __PACKAGE__->mk_classdata(all_message_params => [ @{__PACKAGE__->required_message_params}, @{__PACKAGE__->optional_message_params}, ]); __PACKAGE__->mk_classdata(all_api_params => [ @{__PACKAGE__->required_api_params}, @{__PACKAGE__->optional_api_params}, ]); __PACKAGE__->mk_classdata(all_params => [ @{__PACKAGE__->all_api_params}, @{__PACKAGE__->all_message_params}, ]); __PACKAGE__->mk_accessors( @{__PACKAGE__->all_params}, ); sub signature_key { my $self = shift; # For some sig methods (I.e. RSA), users will pass in their own key my $key = $self->get('signature_key'); unless (defined $key) { $key = Net::OAuth::Message::encode($self->consumer_secret) . '&'; $key .= Net::OAuth::Message::encode($self->token_secret) if $self->can('token_secret'); } return $key; } sub normalized_request_url { my $self = shift; my $url = $self->request_url; Net::OAuth::Message::_ensure_uri_object($url); $url = $url->clone; $url->query(undef); return $url; } =head1 NAME Net::OAuth::Request - base class for OAuth requests =head1 SEE ALSO L, L =head1 AUTHOR Keith Grennan, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2007 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; Net-OAuth-0.28/lib/Net/OAuth/RequestTokenRequest.pm000444000770000024 102011701507056 21577 0ustar00keithstaff000000000000package Net::OAuth::RequestTokenRequest; use warnings; use strict; use base 'Net::OAuth::Request'; sub sign_message {1} =head1 NAME Net::OAuth::RequestTokenRequest - An OAuth protocol request for a Request Token =head1 SEE ALSO L, L =head1 AUTHOR Keith Grennan, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2007 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;Net-OAuth-0.28/lib/Net/OAuth/RequestTokenResponse.pm000444000770000024 112711701507056 21755 0ustar00keithstaff000000000000package Net::OAuth::RequestTokenResponse; use warnings; use strict; use base 'Net::OAuth::Response'; __PACKAGE__->add_required_message_params(qw/token_secret/); sub allow_extra_params {1} =head1 NAME Net::OAuth::RequestTokenResponse - An OAuth protocol response for an Request Token =head1 SEE ALSO L, L =head1 AUTHOR Keith Grennan, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2007 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;Net-OAuth-0.28/lib/Net/OAuth/Response.pm000444000770000024 243411701507056 17405 0ustar00keithstaff000000000000package Net::OAuth::Response; use warnings; use strict; use base qw/Net::OAuth::Message/; __PACKAGE__->mk_classdata(required_message_params => [qw/ token /]); __PACKAGE__->mk_classdata(optional_message_params => [qw/ /]); __PACKAGE__->mk_classdata(required_api_params => [qw/ /]); __PACKAGE__->mk_classdata(optional_api_params => [qw/ extra_params protocol_version /]); __PACKAGE__->mk_classdata(signature_elements => [qw/ /]); __PACKAGE__->mk_classdata(all_message_params => [ @{__PACKAGE__->required_message_params}, @{__PACKAGE__->optional_message_params}, ]); __PACKAGE__->mk_classdata(all_api_params => [ @{__PACKAGE__->required_api_params}, @{__PACKAGE__->optional_api_params}, ]); __PACKAGE__->mk_classdata(all_params => [ @{__PACKAGE__->all_api_params}, @{__PACKAGE__->all_message_params}, ]); __PACKAGE__->mk_accessors( @{__PACKAGE__->all_params}, ); =head1 NAME Net::OAuth::Response - base class for OAuth responses =head1 SEE ALSO L, L =head1 AUTHOR Keith Grennan, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2007 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;Net-OAuth-0.28/lib/Net/OAuth/UserAuthRequest.pm000444000770000024 247111701507056 20721 0ustar00keithstaff000000000000package Net::OAuth::UserAuthRequest; use warnings; use strict; use base qw/Net::OAuth::Message/; __PACKAGE__->mk_classdata(required_message_params => [qw/ /]); __PACKAGE__->mk_classdata(optional_message_params => [qw/ token callback /]); __PACKAGE__->mk_classdata(required_api_params => [qw/ /]); __PACKAGE__->mk_classdata(optional_api_params => [qw/ extra_params /]); __PACKAGE__->mk_classdata(signature_elements => [qw/ /]); __PACKAGE__->mk_classdata(all_message_params => [ @{__PACKAGE__->required_message_params}, @{__PACKAGE__->optional_message_params}, ]); __PACKAGE__->mk_classdata(all_api_params => [ @{__PACKAGE__->required_api_params}, @{__PACKAGE__->optional_api_params}, ]); __PACKAGE__->mk_classdata(all_params => [ @{__PACKAGE__->all_api_params}, @{__PACKAGE__->all_message_params}, ]); __PACKAGE__->mk_accessors( @{__PACKAGE__->all_params}, ); =head1 NAME Net::OAuth::UserAuthRequest - request for OAuth User Authentication =head1 SEE ALSO L, L =head1 AUTHOR Keith Grennan, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2007 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; Net-OAuth-0.28/lib/Net/OAuth/UserAuthResponse.pm000444000770000024 104211701507056 21060 0ustar00keithstaff000000000000package Net::OAuth::UserAuthResponse; use warnings; use strict; use base 'Net::OAuth::Response'; use Net::OAuth; sub allow_extra_params {1} =head1 NAME Net::OAuth::UserAuthResponse - An OAuth protocol response for an Access Token =head1 SEE ALSO L, L =head1 AUTHOR Keith Grennan, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2007 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;Net-OAuth-0.28/lib/Net/OAuth/XauthAccessTokenRequest.pm000444000770000024 141711701507056 22374 0ustar00keithstaff000000000000package Net::OAuth::XauthAccessTokenRequest; use warnings; use strict; use base 'Net::OAuth::Request'; __PACKAGE__->add_extension_param_pattern(qr/x_auth_/); __PACKAGE__->add_required_message_params(qw/x_auth_username x_auth_password x_auth_mode/); sub allow_extra_params {0} sub sign_message {1} =head1 NAME Net::OAuth::xAuthAccessTokenRequest - xAuth extension =head1 SEE ALSO L =head1 AUTHOR Keith Grennan, C<< >> =head1 CONTRIBUTORS Masayoshi Sekimura Simon Wistow =head1 COPYRIGHT & LICENSE Copyright 2010 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;Net-OAuth-0.28/lib/Net/OAuth/YahooAccessTokenRefreshRequest.pm000444000770000024 125711701507056 23703 0ustar00keithstaff000000000000package Net::OAuth::YahooAccessTokenRefreshRequest; use warnings; use strict; use base 'Net::OAuth::AccessTokenRequest'; __PACKAGE__->add_required_message_params(qw/session_handle/); sub allow_extra_params {0} sub sign_message {1} =head1 NAME Net::OAuth::YahooAccessTokenRefreshRequest - Yahoo OAuth Extension =head1 SEE ALSO L =head1 AUTHOR Keith Grennan, C<< >> =head1 CONTRIBUTORS Marc Mims =head1 COPYRIGHT & LICENSE Copyright 2010 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; Net-OAuth-0.28/lib/Net/OAuth/SignatureMethod000755000770000024 011701507056 20213 5ustar00keithstaff000000000000Net-OAuth-0.28/lib/Net/OAuth/SignatureMethod/HMAC_SHA1.pm000444000770000024 154411701507056 22176 0ustar00keithstaff000000000000package Net::OAuth::SignatureMethod::HMAC_SHA1; use warnings; use strict; use Digest::HMAC_SHA1; use MIME::Base64; sub sign { my $self = shift; my $request = shift; my $hmac = Digest::HMAC_SHA1->new($request->signature_key); $hmac->add($request->signature_base_string); return encode_base64($hmac->digest, ''); } sub verify { my $self = shift; my $request = shift; return $request->signature eq $self->sign($request); } =head1 NAME Net::OAuth::SignatureMethod::HMAC_SHA1 - HMAC_SHA1 Signature Method for OAuth protocol =head1 SEE ALSO L, L =head1 AUTHOR Keith Grennan, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2007 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;Net-OAuth-0.28/lib/Net/OAuth/SignatureMethod/HMAC_SHA256.pm000444000770000024 160011701507056 22343 0ustar00keithstaff000000000000package Net::OAuth::SignatureMethod::HMAC_SHA256; use warnings; use strict; use Digest::SHA (); use MIME::Base64 (); sub sign { my $self = shift; my $request = shift; my $hmac_digest = Digest::SHA::hmac_sha256( $request->signature_base_string, $request->signature_key ); return MIME::Base64::encode_base64($hmac_digest, ''); } sub verify { my $self = shift; my $request = shift; return $request->signature eq $self->sign($request); } =head1 NAME Net::OAuth::SignatureMethod::HMAC_SHA256 - HMAC_SHA256 Signature Method for OAuth protocol =head1 SEE ALSO L, L =head1 AUTHOR Keith Grennan, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2012 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; Net-OAuth-0.28/lib/Net/OAuth/SignatureMethod/PLAINTEXT.pm000444000770000024 130111701507056 22251 0ustar00keithstaff000000000000package Net::OAuth::SignatureMethod::PLAINTEXT; use warnings; use strict; sub sign { my $self = shift; my $request = shift; return $request->signature_key; } sub verify { my $self = shift; my $request = shift; return $request->signature eq $self->sign($request); } =head1 NAME Net::OAuth::SignatureMethod::PLAINTEXT - PLAINTEXT Signature Method for OAuth protocol =head1 SEE ALSO L, L =head1 AUTHOR Keith Grennan, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2007 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;Net-OAuth-0.28/lib/Net/OAuth/SignatureMethod/RSA_SHA1.pm000444000770000024 224211701507056 22107 0ustar00keithstaff000000000000package Net::OAuth::SignatureMethod::RSA_SHA1; use warnings; use strict; use MIME::Base64; sub sign { my $self = shift; my $request = shift; my $key = shift || $request->signature_key; die '$request->signature_key must be an RSA key object (e.g. Crypt::OpenSSL::RSA) that can sign($text)' unless UNIVERSAL::can($key, 'sign'); return encode_base64($key->sign($request->signature_base_string), ""); } sub verify { my $self = shift; my $request = shift; my $key = shift || $request->signature_key; die 'You must pass an RSA key object (e.g. Crypt::OpenSSL::RSA) that can verify($text,$sig)' unless UNIVERSAL::can($key, 'verify'); return $key->verify($request->signature_base_string, decode_base64($request->signature)); } =head1 NAME Net::OAuth::SignatureMethod::RSA_SHA1 - RSA_SHA1 Signature Method for OAuth protocol =head1 SEE ALSO L, L =head1 AUTHOR Keith Grennan, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2007 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;Net-OAuth-0.28/lib/Net/OAuth/V1_0A000755000770000024 011701507056 15717 5ustar00keithstaff000000000000Net-OAuth-0.28/lib/Net/OAuth/V1_0A/AccessTokenRequest.pm000444000770000024 111211701507056 22160 0ustar00keithstaff000000000000package Net::OAuth::V1_0A::AccessTokenRequest; use warnings; use strict; use base 'Net::OAuth::AccessTokenRequest'; __PACKAGE__->add_required_message_params(qw/verifier/); =head1 NAME Net::OAuth::V1_0A::AccessTokenRequest - An OAuth protocol request for an Access Token =head1 SEE ALSO L, L =head1 AUTHOR Keith Grennan, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2007 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;Net-OAuth-0.28/lib/Net/OAuth/V1_0A/RequestTokenRequest.pm000444000770000024 111511701507056 22412 0ustar00keithstaff000000000000package Net::OAuth::V1_0A::RequestTokenRequest; use warnings; use strict; use base 'Net::OAuth::RequestTokenRequest'; __PACKAGE__->add_required_message_params(qw/callback/); =head1 NAME Net::OAuth::V1_0A::RequestTokenRequest - An OAuth protocol request for a Request Token =head1 SEE ALSO L, L =head1 AUTHOR Keith Grennan, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2007 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;Net-OAuth-0.28/lib/Net/OAuth/V1_0A/RequestTokenResponse.pm000444000770000024 113411701507056 22561 0ustar00keithstaff000000000000package Net::OAuth::V1_0A::RequestTokenResponse; use warnings; use strict; use base 'Net::OAuth::RequestTokenResponse'; __PACKAGE__->add_required_message_params(qw/callback_confirmed/); =head1 NAME Net::OAuth::V1_0A::RequestTokenResponse - An OAuth protocol response for an Request Token =head1 SEE ALSO L, L =head1 AUTHOR Keith Grennan, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2007 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;Net-OAuth-0.28/lib/Net/OAuth/V1_0A/UserAuthResponse.pm000444000770000024 110511701507056 21666 0ustar00keithstaff000000000000package Net::OAuth::V1_0A::UserAuthResponse; use warnings; use strict; use base 'Net::OAuth::UserAuthResponse'; __PACKAGE__->add_required_message_params(qw/verifier/); =head1 NAME Net::OAuth::V1_0A::UserAuthResponse - An OAuth protocol response for an Access Token =head1 SEE ALSO L, L =head1 AUTHOR Keith Grennan, C<< >> =head1 COPYRIGHT & LICENSE Copyright 2007 Keith Grennan, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;Net-OAuth-0.28/t000755000770000024 011701507056 13040 5ustar00keithstaff000000000000Net-OAuth-0.28/t/01-spec.t000444000770000024 1301211701507056 14547 0ustar00keithstaff000000000000#!perl use strict; use warnings; use Test::More tests => 20; BEGIN { use Net::OAuth; $Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0; use_ok( 'Net::OAuth::Request' ); use_ok( 'Net::OAuth::RequestTokenRequest' ); use_ok( 'Net::OAuth::AccessTokenRequest' ); use_ok( 'Net::OAuth::ProtectedResourceRequest' ); } diag( "Testing Net::OAuth $Net::OAuth::VERSION, Perl $], $^X" ); my $request = Net::OAuth::RequestTokenRequest->new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'https://photos.example.net/request_token', request_method => 'POST', signature_method => 'PLAINTEXT', timestamp => '1191242090', nonce => 'hsu94j3884jdopsl', ); $request->sign; ok($request->verify); is($request->to_post_body, 'oauth_consumer_key=dpf43f3p2l4k3l03&oauth_nonce=hsu94j3884jdopsl&oauth_signature=kd94hf93k423kf44%26&oauth_signature_method=PLAINTEXT&oauth_timestamp=1191242090&oauth_version=1.0'); sub sort_uri { my $uri = shift; my @uri = split /\?/, $uri; my @query = sort(split(/&/, pop @uri)); return join('?', @uri, join('&', @query)); } is(sort_uri($request->to_url), sort_uri('https://photos.example.net/request_token?oauth_consumer_key=dpf43f3p2l4k3l03&oauth_signature=kd94hf93k423kf44%26&oauth_signature_method=PLAINTEXT&oauth_timestamp=1191242090&oauth_version=1.0&oauth_nonce=hsu94j3884jdopsl')); # fanciness $request = $request->from_url($request->to_url, consumer_secret => 'kd94hf93k423kf44', request_url => 'https://photos.example.net/request_token', request_method => 'POST', ); is(sort_uri($request->to_url('https://someothersite.example.com/request_token')), sort_uri('https://someothersite.example.com/request_token?oauth_consumer_key=dpf43f3p2l4k3l03&oauth_nonce=hsu94j3884jdopsl&oauth_signature=kd94hf93k423kf44%26&oauth_signature_method=PLAINTEXT&oauth_timestamp=1191242090&oauth_version=1.0')); $request = Net::OAuth::AccessTokenRequest->new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'https://photos.example.net/access_token', request_method => 'POST', signature_method => 'PLAINTEXT', timestamp => '1191242092', nonce => 'dji430splmx33448', token => 'hh5s93j4hdidpola', token_secret => 'hdhd0244k9j7ao03', ); $request->sign; ok($request->verify); is($request->to_post_body, 'oauth_consumer_key=dpf43f3p2l4k3l03&oauth_nonce=dji430splmx33448&oauth_signature=kd94hf93k423kf44%26hdhd0244k9j7ao03&oauth_signature_method=PLAINTEXT&oauth_timestamp=1191242092&oauth_token=hh5s93j4hdidpola&oauth_version=1.0'); $request = Net::OAuth::ProtectedResourceRequest->new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'http://photos.example.net/photos', request_method => 'GET', signature_method => 'HMAC-SHA1', timestamp => '1191242096', nonce => 'kllo9940pd9333jh', token => 'nnch734d00sl2jdk', token_secret => 'pfkkdhi9sl3r4s00', extra_params => { file => 'vacation.jpg', size => 'original', } ); $request->sign; ok($request->verify); is($request->signature_base_string, 'GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal'); is($request->signature, 'tR3+Ty81lMeYAr/Fid0kMTYa/WM='); is($request->to_authorization_header('http://photos.example.net/authorize', ",\n")."\n", <new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'https://photos.example.net/request_token', request_method => 'POST', signature_method => 'HMAC-SHA1', timestamp => '1191242090', nonce => 'hsu94j3884jdopsl', ); $request->sign; ok($request->verify); is($request->signature_base_string, 'POST&https%3A%2F%2Fphotos.example.net%2Frequest_token&oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dhsu94j3884jdopsl%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242090%26oauth_version%3D1.0'); is($request->signature, 'mBRi0bX78DgCdolSsSYibIGen7U='); $request = Net::OAuth::ProtectedResourceRequest->new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'http://photos.example.net/photos?file=vacation.jpg&size=original', request_method => 'GET', signature_method => 'HMAC-SHA1', timestamp => '1191242096', nonce => 'kllo9940pd9333jh', token => 'nnch734d00sl2jdk', token_secret => 'pfkkdhi9sl3r4s00', ); $request->sign; ok($request->verify); is($request->signature_base_string, 'GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal'); is($request->signature, 'tR3+Ty81lMeYAr/Fid0kMTYa/WM='); Net-OAuth-0.28/t/02-rsa.t000444000770000024 323211701507056 14366 0ustar00keithstaff000000000000#!perl use strict; use warnings; use Test::More tests => 2; use Net::OAuth::ProtectedResourceRequest; sub slurp { my $file = shift; my $text = do { local( @ARGV, $/ ) = $file ; <> } ; return $text; } SKIP: { skip "Crypt::OpenSSL::RSA not installed", 2 unless eval 'require Crypt::OpenSSL::RSA'; my $publickey; my $privkey; eval { $privkey = Crypt::OpenSSL::RSA->new_private_key(slurp('t/rsakey')); } or die "unable to read private key"; eval { $publickey = Crypt::OpenSSL::RSA->new_public_key(slurp("t/rsakey.pub")); } or die "unable to read public key"; my $request = Net::OAuth::ProtectedResourceRequest->new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'http://photos.example.net/photos', request_method => 'GET', signature_method => 'RSA-SHA1', timestamp => '1191242096', nonce => 'kllo9940pd9333jh', token => 'nnch734d00sl2jdk', token_secret => 'pfkkdhi9sl3r4s00', extra_params => { file => 'vacation.jpg', size => 'original', }, signature_key => $privkey, ); $request->sign; is($request->signature, "mkZ/wOq5cS7UOyKKdo5Khd4fYpYVhs20K0E8k/DyumO74rjo7s1y+Y+mZ/hBvy2gu6ip/U4XqTRdT0QObAUvrKf+fH/Yfdc6kQsQ9kP3/IgRF1K5Po284UIy8p7DcJGC5udR01aTkNkpqo3XAw+8ljULguhwVC1l+EWHrzKKuZ6li7EOx1It5JxWqCRVn+1+NA8vGlIjcaPb+aIoUmyM2/ytu1041cnvdDGzuiibRgIv770cuXsfkFNtaK5rgjlmhZhDwqULHfWEN9oxcHxY+6EB/HOvwWkYE1CeUoo9Dgm6mn6+DsfkTjfRh4mJRTIyi6jEYaIgY5RaWwSHaXw44A=="); ok($request->verify($publickey)); } Net-OAuth-0.28/t/03-header.t000444000770000024 272511701507056 15040 0ustar00keithstaff000000000000#!perl use strict; use warnings; use Test::More tests => 5; BEGIN { use_ok( 'Net::OAuth::Request' ); use_ok( 'Net::OAuth::ProtectedResourceRequest' ); } my $request = Net::OAuth::ProtectedResourceRequest->new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'http://photos.example.net/photos', request_method => 'GET', signature_method => 'HMAC-SHA1', timestamp => '1191242096', nonce => 'kllo9940pd9333jh', token => 'nnch734d00sl2jdk', token_secret => 'pfkkdhi9sl3r4s00', extra_params => { file => 'vacation.jpg', size => 'original', } ); $request->sign; ok($request->verify); my $header = $request->to_authorization_header('My Realm', ",\n "); is("$header\n",<from_authorization_header( $header, request_method => 'GET', request_url => 'http://photos.example.net/photos', consumer_secret => 'kd94hf93k423kf44', token_secret => 'pfkkdhi9sl3r4s00', extra_params => { file => 'vacation.jpg', size => 'original', }, ); ok($parsed_req->verify);Net-OAuth-0.28/t/04-response.t000444000770000024 136611701507056 15447 0ustar00keithstaff000000000000#!perl use strict; use warnings; use Test::More tests => 5; BEGIN { use Net::OAuth; $Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0; use_ok( 'Net::OAuth::Response' ); use_ok( 'Net::OAuth::RequestTokenResponse' ); use_ok( 'Net::OAuth::AccessTokenResponse' ); } my $response = Net::OAuth::RequestTokenResponse->new( token => 'abcdef', token_secret => '0123456', extra_params => { foo => 'bar', }, ); is($response->to_post_body, 'foo=bar&oauth_token=abcdef&oauth_token_secret=0123456'); $response = Net::OAuth::AccessTokenResponse->new( token => 'abcdef', token_secret => '0123456', extra_params => { foo => 'bar', }, ); is($response->to_post_body, 'foo=bar&oauth_token=abcdef&oauth_token_secret=0123456');Net-OAuth-0.28/t/05-auth.t000444000770000024 144611701507056 14552 0ustar00keithstaff000000000000#!perl use strict; use warnings; use Test::More tests => 6; BEGIN { use Net::OAuth; $Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0; use_ok( 'Net::OAuth::Request' ); use_ok( 'Net::OAuth::Response' ); use_ok( 'Net::OAuth::UserAuthRequest' ); use_ok( 'Net::OAuth::UserAuthResponse' ); } my $request = Net::OAuth::UserAuthRequest->new( token => 'abcdef', callback => 'http://example.com/callback', extra_params => { foo => 'bar', }, ); is($request->to_post_body, 'foo=bar&oauth_callback=http%3A%2F%2Fexample.com%2Fcallback&oauth_token=abcdef'); my $response = Net::OAuth::UserAuthResponse->new( token => 'abcdef', extra_params => { foo => 'bar', }, ); is($response->to_post_body, 'foo=bar&oauth_token=abcdef');Net-OAuth-0.28/t/06-factory.t000444000770000024 615011701507056 15256 0ustar00keithstaff000000000000use strict; use warnings; use Test::More tests => 12; BEGIN { use Net::OAuth; $Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0; } my $request = Net::OAuth->request('user auth')->new( token => 'abcdef', callback => 'http://example.com/callback', extra_params => { foo => 'bar', }, ); is($request->to_post_body, 'foo=bar&oauth_callback=http%3A%2F%2Fexample.com%2Fcallback&oauth_token=abcdef'); my $response = Net::OAuth->response('UserAuth')->new( token => 'abcdef', extra_params => { foo => 'bar', }, ); is($response->to_post_body, 'foo=bar&oauth_token=abcdef'); $response = Net::OAuth->response('user_auth')->new( token => 'abcdef', extra_params => { foo => 'bar', }, ); is($response->to_post_body, 'foo=bar&oauth_token=abcdef'); $response = Net::OAuth->message('user authentication response')->new( token => 'abcdef', extra_params => { foo => 'bar', }, ); is($response->to_post_body, 'foo=bar&oauth_token=abcdef'); $request = Net::OAuth->request('Request Token')->from_hash( { oauth_consumer_key => 'dpf43f3p2l4k3l03', oauth_signature_method => 'PLAINTEXT', oauth_timestamp => '1191242090', oauth_nonce => 'hsu94j3884jdopsl', oauth_version => '1.0', }, consumer_secret => 'kd94hf93k423kf44', request_url => 'https://photos.example.net/request_token', request_method => 'POST', ); $request->sign; ok($request->verify); is($request->to_post_body, 'oauth_consumer_key=dpf43f3p2l4k3l03&oauth_nonce=hsu94j3884jdopsl&oauth_signature=kd94hf93k423kf44%26&oauth_signature_method=PLAINTEXT&oauth_timestamp=1191242090&oauth_version=1.0'); $request = Net::OAuth->request('Protected Resource')->from_hash( { oauth_consumer_key => 'dpf43f3p2l4k3l03', oauth_signature_method => 'HMAC-SHA1', oauth_timestamp => '1191242096', oauth_nonce => 'kllo9940pd9333jh', oauth_token => 'nnch734d00sl2jdk', oauth_signature => 'tR3+Ty81lMeYAr/Fid0kMTYa/WM=', oauth_version => '1.0', file => 'vacation.jpg', size => 'original', }, request_url => 'http://photos.example.net/photos', request_method => 'GET', token_secret => 'pfkkdhi9sl3r4s00', consumer_secret => 'kd94hf93k423kf44', ); ok($request->verify); is($request->signature_base_string, 'GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal'); is($request->consumer_key, 'dpf43f3p2l4k3l03'); $request->consumer_key('foo'); is($request->consumer_key, 'foo'); is($request->signature_base_string, 'GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26oauth_consumer_key%3Dfoo%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal'); eval { Net::OAuth->request('Foo Bar'); }; ok($@, 'should die');Net-OAuth-0.28/t/07-consumer-request.t000444000770000024 225311701507056 17131 0ustar00keithstaff000000000000#!perl use strict; use warnings; use Test::More tests => 6; BEGIN { use_ok( 'Net::OAuth' ); use_ok( 'Net::OAuth::ConsumerRequest' ); } my $request = Net::OAuth->request('consumer')->new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'http://provider.example.net/profile', request_method => 'GET', signature_method => 'HMAC-SHA1', timestamp => '1191242096', nonce => 'kllo9940pd9333jh', ); $request->sign; ok($request->verify); is($request->signature_base_string, 'GET&http%3A%2F%2Fprovider.example.net%2Fprofile&oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26oauth_version%3D1.0'); is($request->signature, 'SGtGiOrgTGF5Dd4RUMguopweOSU='); is($request->to_authorization_header('http://provider.example.net/', ",\n")."\n", < 15; use Test::Warn; use Encode; use utf8; BEGIN { use_ok( 'Net::OAuth::Message' ); } sub is_encoding { my $orig = shift; my $encoded = shift; is(Net::OAuth::Message::encode($orig), $encoded); } is_encoding('abcABC123', 'abcABC123'); is_encoding('-._~', '-._~'); is_encoding('%', '%25'); is_encoding('+', '%2B'); is_encoding(' ', '%20'); is_encoding('&=*', '%26%3D%2A'); is_encoding("\x{000A}", '%0A'); is_encoding("\x{0020}", '%20'); is_encoding("\x{007F}", '%7F'); is_encoding("ç", '%C3%A7'); is_encoding("æ", '%C3%A6'); is_encoding("私はガラスを食べられます。それは私を傷つけません。", "%E7%A7%81%E3%81%AF%E3%82%AC%E3%83%A9%E3%82%B9%E3%82%92%E9%A3%9F%E3%81%B9%E3%82%89%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82%E3%81%9D%E3%82%8C%E3%81%AF%E7%A7%81%E3%82%92%E5%82%B7%E3%81%A4%E3%81%91%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82"); warning_like {is_encoding(Encode::encode_utf8("ç"), '%C3%83%C2%A7')} qr/your OAuth message appears to contain some multi-byte characters that need to be decoded/, "Should see warning about characters needing to be decoded"; Net-OAuth-0.28/t/10-misc.t000444000770000024 362511701507056 14541 0ustar00keithstaff000000000000use strict; use warnings; use Test::More tests => 5; BEGIN { use Net::OAuth; $Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0; } my $request = Net::OAuth->request('user auth')->new( token => 'abcdef', callback => 'http://example.com/callback', extra_params => { foo => 'bar', }, ); is($request->to_post_body, 'foo=bar&oauth_callback=http%3A%2F%2Fexample.com%2Fcallback&oauth_token=abcdef'); use URI; my $url = URI->new('http://example.com?bar=baz'); is($request->to_url($url), 'http://example.com?foo=bar&oauth_callback=http%3A%2F%2Fexample.com%2Fcallback&oauth_token=abcdef'); is($url, 'http://example.com?bar=baz'); $request = Net::OAuth->request('Request Token')->new( consumer_key => 'dpf43f3p2l4k3l03', signature_method => 'PLAINTEXT', timestamp => '1191242090', nonce => 'hsu94j3884jdopsl', consumer_secret => 'kd94hf93k423kf44', request_url => 'https://photos.example.net/request_token', request_method => 'GET', extra_params => { foo => 'this value contains spaces' }, ); $request->sign; is($request->to_url(), 'https://photos.example.net/request_token?foo=this%20value%20contains%20spaces&oauth_consumer_key=dpf43f3p2l4k3l03&oauth_nonce=hsu94j3884jdopsl&oauth_signature=kd94hf93k423kf44%26&oauth_signature_method=PLAINTEXT&oauth_timestamp=1191242090&oauth_version=1.0'); # https://rt.cpan.org/Ticket/Display.html?id=47369 # Make sure signature works without oauth_version $request = Net::OAuth->request('request_token')->from_hash( { "oauth_signature" => "lcdJGdH4NRntuelnX+pAoxtIcLY=", "oauth_timestamp" => "1246037243", "oauth_nonce" => "288f21", "oauth_consumer_key" => "myKey", "oauth_signature_method" => "HMAC-SHA1" }, consumer_secret => 'mySecret', request_method => 'POST', request_url => 'http://localhost/provider/request-token.cgi', ); ok($request->verify);Net-OAuth-0.28/t/11-spec-1.0a.t000444000770000024 2072211701507056 15213 0ustar00keithstaff000000000000#!perl use strict; use warnings; use Test::More tests => 28; use Carp 'confess'; $SIG{__DIE__} = \&confess; BEGIN { use Net::OAuth; $Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0A; use_ok( 'Net::OAuth::Request' ); use_ok( 'Net::OAuth::RequestTokenRequest' ); use_ok( 'Net::OAuth::AccessTokenRequest' ); use_ok( 'Net::OAuth::ProtectedResourceRequest' ); } my $request = Net::OAuth::RequestTokenRequest->new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'https://photos.example.net/request_token', request_method => 'POST', signature_method => 'PLAINTEXT', timestamp => '1191242090', nonce => 'hsu94j3884jdopsl', callback => 'http://printer.example.com/request_token_ready', ); $request->sign; ok($request->verify); ok($request->isa('Net::OAuth::V1_0A::RequestTokenRequest')); eval { Net::OAuth::RequestTokenRequest->new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'https://photos.example.net/request_token', request_method => 'POST', signature_method => 'PLAINTEXT', timestamp => '1191242090', nonce => 'hsu94j3884jdopsl', ); }; ok($@, 'should complain about missing callback parameter'); my $v1req; eval { $v1req = Net::OAuth::RequestTokenRequest->new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'https://photos.example.net/request_token', request_method => 'POST', signature_method => 'PLAINTEXT', timestamp => '1191242090', nonce => 'hsu94j3884jdopsl', protocol_version => Net::OAuth::PROTOCOL_VERSION_1_0, ); }; ok(!$@, 'override default protocol version to produce v1.0 message'); ok(!$v1req->isa('Net::OAuth::V1_0A::RequestTokenRequest')); sub sort_uri { my $uri = shift; my @uri = split /\?/, $uri; my @query = sort(split(/&/, pop @uri)); return join('?', @uri, join('&', @query)); } is(sort_uri($request->to_post_body), sort_uri('oauth_callback=http%3A%2F%2Fprinter.example.com%2Frequest_token_ready&oauth_consumer_key=dpf43f3p2l4k3l03&oauth_nonce=hsu94j3884jdopsl&oauth_signature=kd94hf93k423kf44%26&oauth_signature_method=PLAINTEXT&oauth_timestamp=1191242090&oauth_version=1.0')); is(sort_uri($request->to_url), sort_uri('https://photos.example.net/request_token?oauth_callback=http%3A%2F%2Fprinter.example.com%2Frequest_token_ready&oauth_consumer_key=dpf43f3p2l4k3l03&oauth_signature_method=PLAINTEXT&oauth_signature=kd94hf93k423kf44%26&oauth_timestamp=1191242090&oauth_nonce=hsu94j3884jdopsl&oauth_version=1.0')); # fanciness $request = $request->from_url($request->to_url, consumer_secret => 'kd94hf93k423kf44', request_url => 'https://photos.example.net/request_token', request_method => 'POST', ); is(sort_uri($request->to_url('https://someothersite.example.com/request_token')), sort_uri('https://someothersite.example.com/request_token?oauth_callback=http%3A%2F%2Fprinter.example.com%2Frequest_token_ready&oauth_consumer_key=dpf43f3p2l4k3l03&oauth_signature_method=PLAINTEXT&oauth_signature=kd94hf93k423kf44%26&oauth_timestamp=1191242090&oauth_nonce=hsu94j3884jdopsl&oauth_version=1.0')); $request = Net::OAuth::AccessTokenRequest->new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'https://photos.example.net/access_token', request_method => 'POST', signature_method => 'PLAINTEXT', timestamp => '1191242092', nonce => 'dji430splmx33448', token => 'hh5s93j4hdidpola', token_secret => 'hdhd0244k9j7ao03', verifier => 'hfdp7dh39dks9884', ); $request->sign; ok($request->verify); eval { Net::OAuth::AccessTokenRequest->new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'https://photos.example.net/access_token', request_method => 'POST', signature_method => 'PLAINTEXT', timestamp => '1191242092', nonce => 'dji430splmx33448', token => 'hh5s93j4hdidpola', token_secret => 'hdhd0244k9j7ao03', ); }; ok($@); is(sort_uri($request->to_post_body), sort_uri('oauth_consumer_key=dpf43f3p2l4k3l03&oauth_token=hh5s93j4hdidpola&oauth_signature_method=PLAINTEXT&oauth_signature=kd94hf93k423kf44%26hdhd0244k9j7ao03&oauth_timestamp=1191242092&oauth_nonce=dji430splmx33448&oauth_verifier=hfdp7dh39dks9884&oauth_version=1.0')); $request = Net::OAuth::ProtectedResourceRequest->new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'http://photos.example.net/photos', request_method => 'GET', signature_method => 'HMAC-SHA1', timestamp => '1191242096', nonce => 'kllo9940pd9333jh', token => 'nnch734d00sl2jdk', token_secret => 'pfkkdhi9sl3r4s00', extra_params => { file => 'vacation.jpg', size => 'original', } ); $request->sign; ok($request->verify); is($request->signature_base_string, 'GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal'); is($request->signature, 'tR3+Ty81lMeYAr/Fid0kMTYa/WM='); is($request->to_authorization_header('http://photos.example.net/authorize', ",\n")."\n", <new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'https://photos.example.net/request_token', request_method => 'POST', signature_method => 'HMAC-SHA1', timestamp => '1191242090', nonce => 'hsu94j3884jdopsl', callback => 'http://printer.example.com/request_token_ready', ); $request->sign; ok($request->verify); is($request->signature_base_string, 'POST&https%3A%2F%2Fphotos.example.net%2Frequest_token&oauth_callback%3Dhttp%253A%252F%252Fprinter.example.com%252Frequest_token_ready%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dhsu94j3884jdopsl%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242090%26oauth_version%3D1.0'); is($request->signature, 'Uzhous9sjMdWH6Gte4VToiNQtMc='); $request = Net::OAuth::ProtectedResourceRequest->new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'http://photos.example.net/photos?file=vacation.jpg&size=original', request_method => 'GET', signature_method => 'HMAC-SHA1', timestamp => '1191242096', nonce => 'kllo9940pd9333jh', token => 'nnch734d00sl2jdk', token_secret => 'pfkkdhi9sl3r4s00', ); $request->sign; ok($request->verify); is($request->signature_base_string, 'GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal'); is($request->signature, 'tR3+Ty81lMeYAr/Fid0kMTYa/WM='); # Message->from_hash should validate the message using the correct class # https://rt.cpan.org/Public/Bug/Display.html?id=47293 $Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0; my $response = eval { Net::OAuth->response('request token') ->from_post_body('oauth_token=abc&oauth_token_secret=def&oauth_callback_confirmed=true') }; ok($@); $response = Net::OAuth->response('request token') ->from_post_body('oauth_token=abc&oauth_token_secret=def&oauth_callback_confirmed=true', protocol_version => Net::OAuth::PROTOCOL_VERSION_1_0A ); ok($response); $Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0A; $response = Net::OAuth->response('request token') ->from_post_body('oauth_token=abc&oauth_token_secret=def&oauth_callback_confirmed=true'); ok($response);Net-OAuth-0.28/t/12-xauth.t000444000770000024 445011701507056 14736 0ustar00keithstaff000000000000#!perl use strict; use warnings; use Test::More tests => 5; use Net::OAuth; my $request = Net::OAuth->request('xauth access token')->new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'https://photos.example.net/access_token', request_method => 'POST', signature_method => 'PLAINTEXT', timestamp => '1191242092', nonce => 'dji430splmx33448', token => 'hh5s93j4hdidpola', token_secret => 'hdhd0244k9j7ao03', x_auth_username => 'keeth', x_auth_password => 'foobar', x_auth_mode => 'client_auth', ); $request->sign; ok($request->verify); is($request->to_post_body, 'oauth_consumer_key=dpf43f3p2l4k3l03&oauth_nonce=dji430splmx33448&oauth_signature=kd94hf93k423kf44%26hdhd0244k9j7ao03&oauth_signature_method=PLAINTEXT&oauth_timestamp=1191242092&oauth_version=1.0&x_auth_mode=client_auth&x_auth_password=foobar&x_auth_username=keeth'); eval { $request = Net::OAuth->request('xauth access token')->new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'https://photos.example.net/access_token', request_method => 'POST', signature_method => 'PLAINTEXT', timestamp => '1191242092', nonce => 'dji430splmx33448', token => 'hh5s93j4hdidpola', token_secret => 'hdhd0244k9j7ao03', ); }; ok($@); $request = Net::OAuth->request('yahoo access token refresh')->new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'https://photos.example.net/access_token', request_method => 'POST', signature_method => 'HMAC-SHA1', timestamp => '1191242092', nonce => 'dji430splmx33448', token => 'hh5s93j4hdidpola', token_secret => 'hdhd0244k9j7ao03', session_handle => 'this is my session handle', ); $request->sign; ok($request->verify); is($request->to_post_body, 'oauth_consumer_key=dpf43f3p2l4k3l03&oauth_nonce=dji430splmx33448&oauth_session_handle=this%20is%20my%20session%20handle&oauth_signature=cIkNa1a40fmnGuuWVYHWFOrTE3M%3D&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1191242092&oauth_token=hh5s93j4hdidpola&oauth_version=1.0'); Net-OAuth-0.28/t/13-hmac-sha256.t000444000770000024 171011701507056 15520 0ustar00keithstaff000000000000#!perl use strict; use warnings; use Test::More tests => 3; use Net::OAuth::ProtectedResourceRequest; SKIP: { skip "Digest::SHA not installed", 3 unless eval 'require Digest::SHA; 1'; my $request = Net::OAuth::ProtectedResourceRequest->new( consumer_key => 'dpf43f3p2l4k3l03', consumer_secret => 'kd94hf93k423kf44', request_url => 'http://photos.example.net/photos', request_method => 'GET', signature_method => 'HMAC-SHA256', timestamp => '1191242096', nonce => 'kllo9940pd9333jh', token => 'nnch734d00sl2jdk', token_secret => 'pfkkdhi9sl3r4s00', extra_params => { file => 'vacation.jpg', size => 'original', }, ); $request->sign; is(length($request->signature), 44); is($request->signature, "WVPzl1j6ZsnkIjWr7e3OZ3jkenL57KwaLFhYsroX1hg="); ok($request->verify()); } Net-OAuth-0.28/t/rsakey000444000770000024 321311701507056 14415 0ustar00keithstaff000000000000-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEA35V2Kqf072yvnsZN+aY7rIx+Osa8Akh52npNEBk63dIbnQuP vCoI6xg6w7bnGIsOtN5Uma//j0Fey/aOuzCj++dTiIXBAFSD6iDkXZR3kAyYYvEC t5XhDqiEO3h5CMQss0aopdnFvR/NFlBIxivYT14zxcoViZWrs5gbEyHzcVOpW7YL +S0jsEhQWPP31mPGVwhgn+fFBVU+0TvOzWXwEwl6WCx/QUQop4jWwrOIqrmcl50X 4ghCuGxN+HXd4mCf+HNK8mQJC0BLjeTPcwJFl4kk9ZBizwDSXxY5AIZLQbRxZcBM E9s1tb2lpC/5yEWJYypjHCkArwkrWb26WLHS5wIBIwKCAQAMxrZLlJGnSAoJEqVe uQq5Zx0n7hlfN1drkfXGZ9d6Y8cQSc2y+xZz1X+zaYmMX7eykFybEV8PgBQLp7Bi d87bMcpCUMkzOAeJuLyXohV18hdWHGaOJdJYm+pMioqSyWGj2Cbk599p5I9gXFvu ESJNrZyO9ZrUqXeGmvo7m4pA/VwFlEw9ogVxYwXDCI3s0v+ZHPIzmFznY5UI+M9x UEquqYkW60uZ7wAe+v1IET04VQqzFJvfnA1R7OatokIaRn5bN2ygy/cE9Y26uDXA +DwldzjBw6063F0h3RGs9/9iXl4bnFtq1Z1MQvlWi8mlPPJmdED/1g3G6tLEdzz8 hXE7AoGBAPpQ/LlTFmXAOyaMXzkE3IvEF8ujsLtexbzvadjiEW127WJOjQlsHlWi +QN4pVDT5E1qOb+DSnt2M+nPbgECLOeRxtZmP/tq2CW5sqmfqVnBs1zKnx9nODiO x9XiogSE9eMlFWcpoDySvo5WvO8+kGQNtwJNcVTmYD4XG6nn/vOrAoGBAOSpFhxv g16vyET3fwshGsGbdgZ1TK/VQNHEz8esV2erhTj4icrPT1DmZ4Lc4Ih9BRPverCV kt4ohp9KcFgUYhUqYoeOMqrJnvWQmnkiYM9GL2bsEOvhuDv/sa3K8FGDSx9deqUc oLhsawvi5MG+CpNUgO9Rlbqvm4TUe2Utk6G1AoGADk3FTGsl2e26PLeQaaiBoZYt PtYnWyn8q7XoypCTSBVspoglUP7dKXcG6kFoiEafVOF/pIso09reZSHLxYsYgkLY KYIvirWl84b0RDUCXOZ/RyGFb4I9uhbJlzGFmdu2R352QGjHU+sg1O8De2KpKknt M1Th55giwbgtd2xXticCgYEA3iCZIu/79ZTRLQ2unRjYKco4I4fkGIYEdAEEW5F5 eqaerF8mxQPmplwqChhlFt/ZDA01WxT1ElNA8oLTiMNX902+zNNHKZCpC85M6rOu gDWNIicmYXwvUDo3kuJly4bbQwpZ4jkRKC7OY1FwgbFMGheTMZ+2Bc8pXHajwV95 eIMCgYEAgjJCDDslCUwluUfOYeT11wuiij7AeCRn5Dh91eYZq1VhrZboB/r8yW4E HdWM8DkbsB1e9Z+WPLbFRVCcbWhiZ55hlGesEvUjbycT0ziQ8C0ohJx/Un7/oNuV slDK9TyG0jnvApQ8Mu4MU4fwx+3sIg2vAgFWUuUZ9E6V03uJCCM= -----END RSA PRIVATE KEY----- Net-OAuth-0.28/t/rsakey.pub000444000770000024 70311701507056 15163 0ustar00keithstaff000000000000-----BEGIN PUBLIC KEY----- MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEA35V2Kqf072yvnsZN+aY7 rIx+Osa8Akh52npNEBk63dIbnQuPvCoI6xg6w7bnGIsOtN5Uma//j0Fey/aOuzCj ++dTiIXBAFSD6iDkXZR3kAyYYvECt5XhDqiEO3h5CMQss0aopdnFvR/NFlBIxivY T14zxcoViZWrs5gbEyHzcVOpW7YL+S0jsEhQWPP31mPGVwhgn+fFBVU+0TvOzWXw Ewl6WCx/QUQop4jWwrOIqrmcl50X4ghCuGxN+HXd4mCf+HNK8mQJC0BLjeTPcwJF l4kk9ZBizwDSXxY5AIZLQbRxZcBME9s1tb2lpC/5yEWJYypjHCkArwkrWb26WLHS 5wIBIw== -----END PUBLIC KEY-----