Net-OAuth-0.31/0000755000175000017500000000000014773527226011050 5ustar rrrrNet-OAuth-0.31/META.json0000664000175000017500000000304214773527226012472 0ustar rrrr{ "abstract" : "OAuth 1.0 for Perl", "author" : [ "Robert Rothenberg " ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.72, CPAN::Meta::Converter version 2.150010", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Net-OAuth", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "Class::Accessor" : "0.31", "Class::Data::Inheritable" : "0.06", "Crypt::URandom" : "0.37", "Digest::SHA" : "5.47", "Encode" : "2.35", "LWP::UserAgent" : "1", "Test::More" : "0.66", "Test::Warn" : "0.21", "URI" : "5.15" } }, "test" : { "requires" : { "Test::More" : "0.66", "Test::Warn" : "0.21" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://rt.cpan.org/Public/Dist/Display.html?Name=Net-OAuth" }, "repository" : { "url" : "https://github.com/keeth/Net-OAuth.git" } }, "version" : "0.31", "x_serialization_backend" : "JSON::PP version 4.06" } Net-OAuth-0.31/MANIFEST0000644000175000017500000000230514773526762012205 0ustar rrrrChanges 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 META.json META.yml README SECURITY.md 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 Net-OAuth-0.31/t/0000755000175000017500000000000014773527226011313 5ustar rrrrNet-OAuth-0.31/t/rsakey0000644000175000017500000000321314733627432012527 0ustar rrrr-----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.31/t/09-encoding.t0000644000175000017500000000217714733627432013517 0ustar rrrr#!perl use strict; use warnings; use Test::More tests => 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.31/t/06-factory.t0000644000175000017500000000615014733627432013370 0ustar rrrruse 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.31/t/05-auth.t0000644000175000017500000000144614733627432012664 0ustar rrrr#!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.31/t/03-header.t0000644000175000017500000000272514733627432013152 0ustar rrrr#!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.31/t/02-rsa.t0000644000175000017500000000343214734240675012503 0ustar rrrr#!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"; # Crypt::OpenSSL::RSA changed its default to sha256 in 0.29_01 $privkey->use_sha1_hash; $publickey->use_sha1_hash; 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.31/t/12-xauth.t0000644000175000017500000000445014733627432013050 0ustar rrrr#!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.31/t/07-consumer-request.t0000644000175000017500000000225314733627432015243 0ustar rrrr#!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", < 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.31/t/10-misc.t0000644000175000017500000000362514733627432012653 0ustar rrrruse 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.31/t/04-response.t0000644000175000017500000000136614733627432013561 0ustar rrrr#!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.31/t/13-hmac-sha256.t0000644000175000017500000000171014733627432013632 0ustar rrrr#!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.31/t/rsakey.pub0000644000175000017500000000070314733627432013315 0ustar rrrr-----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----- Net-OAuth-0.31/t/01-spec.t0000644000175000017500000001301214733627432012641 0ustar rrrr#!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.31/lib/0000755000175000017500000000000014773527226011616 5ustar rrrrNet-OAuth-0.31/lib/Net/0000755000175000017500000000000014773527226012344 5ustar rrrrNet-OAuth-0.31/lib/Net/OAuth/0000755000175000017500000000000014773527226013364 5ustar rrrrNet-OAuth-0.31/lib/Net/OAuth/UserAuthResponse.pm0000644000175000017500000000113314735566072017177 0ustar rrrrpackage 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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 COPYRIGHT & LICENSE Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/lib/Net/OAuth/V1_0A/0000755000175000017500000000000014773527226014172 5ustar rrrrNet-OAuth-0.31/lib/Net/OAuth/V1_0A/UserAuthResponse.pm0000644000175000017500000000110514733627432020000 0ustar rrrrpackage 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.31/lib/Net/OAuth/V1_0A/AccessTokenRequest.pm0000644000175000017500000000120314735566072020277 0ustar rrrrpackage 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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 COPYRIGHT & LICENSE Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/lib/Net/OAuth/V1_0A/RequestTokenRequest.pm0000644000175000017500000000120614735566072020531 0ustar rrrrpackage 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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 COPYRIGHT & LICENSE Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/lib/Net/OAuth/V1_0A/RequestTokenResponse.pm0000644000175000017500000000122514735566072020700 0ustar rrrrpackage 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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 COPYRIGHT & LICENSE Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/lib/Net/OAuth/AccessTokenRequest.pm0000644000175000017500000000131714735566072017477 0ustar rrrrpackage 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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 COPYRIGHT & LICENSE Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/lib/Net/OAuth/ProtectedResourceRequest.pm0000644000175000017500000000134214735566072020734 0ustar rrrrpackage 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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 COPYRIGHT & LICENSE Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/lib/Net/OAuth/AccessToken.pm0000644000175000017500000000326514735566072016132 0ustar rrrrpackage 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 AUTHOR Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 LICENSE AND COPYRIGHT Copyright 2007-2012, 2024-2025 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.31/lib/Net/OAuth/RequestTokenRequest.pm0000644000175000017500000000111114735566072017716 0ustar rrrrpackage 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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 COPYRIGHT & LICENSE Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/lib/Net/OAuth/XauthAccessTokenRequest.pm0000644000175000017500000000151014735566072020504 0ustar rrrrpackage 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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 CONTRIBUTORS Masayoshi Sekimura Simon Wistow =head1 COPYRIGHT & LICENSE Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/lib/Net/OAuth/Client.pm0000644000175000017500000001736314773514503015144 0ustar rrrrpackage 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; use Crypt::URandom qw( urandom ); our $VERSION = '0.31'; =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 = ( timestamp => time, consumer_key => $self->id, consumer_secret => $self->secret, callback => $self->callback, signature_method => 'HMAC-SHA1', request_method => 'GET', ); $defaults{nonce} = unpack("H*", urandom(16)) unless exists $params{nonce}; $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 AUTHOR Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 LICENSE AND COPYRIGHT Copyright 2007-2012, 2024-2025 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.31/lib/Net/OAuth/UserAuthRequest.pm0000644000175000017500000000255314735566072017040 0ustar rrrrpackage 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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 COPYRIGHT & LICENSE Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/lib/Net/OAuth/ConsumerRequest.pm0000644000175000017500000000150014735566072017062 0ustar rrrrpackage 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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 COPYRIGHT & LICENSE Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/lib/Net/OAuth/Response.pm0000644000175000017500000000252214735566072015521 0ustar rrrrpackage 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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 COPYRIGHT & LICENSE Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/lib/Net/OAuth/SignatureMethod/0000755000175000017500000000000014773527226016466 5ustar rrrrNet-OAuth-0.31/lib/Net/OAuth/SignatureMethod/RSA_SHA1.pm0000644000175000017500000000233314735566072020226 0ustar rrrrpackage 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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 COPYRIGHT & LICENSE Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/lib/Net/OAuth/SignatureMethod/HMAC_SHA1.pm0000644000175000017500000000163614773514401020305 0ustar rrrrpackage Net::OAuth::SignatureMethod::HMAC_SHA1; use warnings; use strict; use Digest::SHA (); use MIME::Base64; sub sign { my $self = shift; my $request = shift; my $hmac_digest = Digest::SHA::hmac_sha1( $request->signature_base_string, $request->signature_key ); 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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 COPYRIGHT & LICENSE Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/lib/Net/OAuth/SignatureMethod/HMAC_SHA256.pm0000644000175000017500000000167014735566072020470 0ustar rrrrpackage 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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 COPYRIGHT & LICENSE Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/lib/Net/OAuth/SignatureMethod/PLAINTEXT.pm0000644000175000017500000000137214735566072020377 0ustar rrrrpackage 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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 COPYRIGHT & LICENSE Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/lib/Net/OAuth/RequestTokenResponse.pm0000644000175000017500000000122014735566072020065 0ustar rrrrpackage 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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 COPYRIGHT & LICENSE Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/lib/Net/OAuth/Message.pm0000644000175000017500000002275314735566072015317 0ustar rrrrpackage 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); } 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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 COPYRIGHT & LICENSE Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/lib/Net/OAuth/YahooAccessTokenRefreshRequest.pm0000644000175000017500000000134714735566072022021 0ustar rrrrpackage 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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 CONTRIBUTORS Marc Mims =head1 COPYRIGHT & LICENSE Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/lib/Net/OAuth/AccessTokenResponse.pm0000644000175000017500000000121714735566072017644 0ustar rrrrpackage 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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 LICENSE AND COPYRIGHT Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/lib/Net/OAuth/Request.pm0000644000175000017500000000434314773514503015350 0ustar rrrrpackage Net::OAuth::Request; use warnings; use strict; use base qw/Net::OAuth::Message/; use URI; use URI::QueryParam; use Net::OAuth; our $VERSION = '0.31'; __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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 COPYRIGHT & LICENSE Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/lib/Net/OAuth.pm0000644000175000017500000003470214773514503013722 0ustar rrrrpackage 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.31'; 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::SHA 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 structure. =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 Originally by Keith Grennan Currently maintained by Robert Rothenberg =head1 COPYRIGHT & LICENSE Copyright 2007-2012, 2024-2025 Keith Grennan 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.31/Changes0000644000175000017500000001457714773526561012362 0ustar rrrrRevision history for Net-OAuth [Bug Fixes] - Added missing dependency RT#70407. - Removed use of Digest::HMAC_SHA1. [Documentation] - Updated Changes for v0.29 with CVE. - Updated the security policy. [Toolchain] - Remove Build.PL and just use Makefile.PL. 0.30 Fri, 03 Jan 2025 09:46 GMT [Bug Fixes] - Fixed syntax error in Net::OAuth::Client (oops). - Added missing VERSION to Net::OAuth::Client. 0.29 Fri, 03 Jan 2025 09:15 GMT [Security] - Net::OAuth::Client uses a better source of randomness for generating the nonce CVE-2025-22376 [Bug Fixes] - Removed unnecessary prerequisite RT#69810 GH#4 GH#6 - Fix broken dependency for URI::Escape GH#4 (thanks oiami) - Fix handling of uri_escape_utf RT#73705 (thanks Tomaž Šolc) [Documentation] - Reorganised Changes to almost follow CPAN::Changes::Spec - Updated author and maintainer information - Changed to consistent copyright information - Fixed typo RT#125292 RT#90007 GH#6 (thanks Gregor Herrmann) - Added a Security Policy (SECURITY.md) to the distribution [Tests] - Fixed randomly failing t/02-rsa.t test RT#125291 RT#125482 (thanks Gregor Herrmann) [Other] - Maintenance taken over by Robert Rothenberg - Added .mailmap to the repo - Distribution metadata now has the git repository (thanks Sergey Romanov) GH#6 - Set up config_requires in Build.PL - Updated Build.PL configuration - Updated MANIFEST.SKIP rules 0.28 Fri, 06 Jan 2012 05:51:04 UTC - Added HMAC-SHA256 support 0.27 Wed, 16 Jun 2010 20:39:59 UTC - Added class for Yahoo! access token refresh request (thanks Marc Mims) 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.25 Sun, 21 Mar 2010 03:50:40 UTC - Gah, $VERSION lameness 0.24 Sun, 21 Mar 2010 03:39:40 UTC - Fix test breakage in 0.23 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 RT#55635 Incorrect dependencies (thanks Jens Rehsack) - Replaced die() with croak() 0.22 Thu, 11 Mar 2010 00:21:26 UTC - Renamed xAuthAccessTokenRequest to XauthAccessTokenRequest for CamelCaseConsistency - Added a couple tests for XauthAccessTokenRequest 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.20 Fri, 13 Nov 2009 18:56:55 UTC - Fixed RT#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.19 Fri, 26 Jun 2009 17:30:06 UTC [Bug Fixes] - Fixed RT#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.18 Thu, 25 Jun 2009 17:18:04 UTC [Bug Fixes] - Fixed accidental (though probably harmless) regression in 0.17 0.17 Thu, 25 Jun 2009 16:59:50 UTC [Bug Fixes] - Fixed RT#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.16 Mon, 15 Jun 2009 18:36:17 UTC [Enhancements] - Added support for OAuth 1.0A - see POD section 'OAUTH 1.0A' for details - Net::OAuth still defaults to 1.0 for now 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 RT#44699 - encode spaces to %20 rather than + in $message->to_url() 0.14 Sat, 13 Dec 2008 17:29:36 UTC - Add POD for consumer requests 0.13 Thu, 13 Nov 2008 22:45:46 UTC - Added support for Consumer Request (token-less / two-legged) message type 0.12 Fri, 04 Jul 2008 22:58:23 UTC - Added support for extensions - Net::OpenMicroBlogging in particular 0.11 Wed, 04 Jun 2008 16:50:14 UTC - Doc edits 0.1 Wed, 04 Jun 2008 16:27:50 UTC - Added demo, fixed docs 0.09 Tue, 03 Jun 2008 03:46:32 UTC - Fixed another annoying test failure 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.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 0.06 Sat, 08 Mar 2008 00:57:40 UTC - Removed live test that stopped working 0.05 Mon, 19 Nov 2007 03:30:05 UTC - Integrated patch from Nobuo Danjou, for Draft 6 spec compliance 0.04 Fri, 19 Oct 2007 16:45:03 UTC - Integrated patch from SARTAK, fixing signature for RequestTokenRequest with HMAC-SHA1 0.03 Mon, 15 Oct 2007 01:35:17 UTC - Fixed header parsing 0.02 Tue, 02 Oct 2007 07:35:17 UTC - Added RSA-SHA1 support 0.01 Sun, 30 Sep 2007 13:35:06 UTC - First version, released on an unsuspecting world. Net-OAuth-0.31/README0000644000175000017500000000372214735566072011734 0ustar rrrrNet-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; AUTHOR Originally by Keith Grennan Currently maintained by Robert Rothenberg LICENSE AND COPYRIGHT Copyright 2007-2012, 2024-2025 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.31/SECURITY.md0000644000175000017500000000645014773525465012651 0ustar rrrrThis is the Security Policy for the Perl distribution Net-OAuth. The latest version of this Security Policy can be found in the Git Repository for [Net-OAuth](https://github.com/keeth/Net-OAuth). This text is based on the CPAN Security Group's [Guidelines for Adding a Security Policy to Perl Distributions](https://security.metacpan.org/docs/guides/security-policy-for-authors.html) (version 1.2.0). # How to Report a Security Vulnerability Security vulnerabilities can be reported using this project's GitHub [Security Advisories](https://github.com/keeth/Net-OAuth/security/advisories). Please include as many details as possible, including code samples or test cases, so that we can reproduce the issue. Check that your report does not expose any sensitive data, such as passwords, tokens, or personal information. If you would like any help with triaging the issue, or if the issue is being actively exploited, please copy the report to the CPAN Security Group (CPANSec) at . Please *do not* use the public issue reporting system on RT or GitHub issues for reporting security vulnerabilities. Please do not disclose the security vulnerability in public forums until past any proposed date for public disclosure, or it has been made public by the maintainers or CPANSec. That includes patches or pull requests. For more information, see [Report a Security Issue](https://security.metacpan.org/docs/report.html) on the CPANSec website. ## Response to Reports The maintainer(s) aim to acknowledge your security report as soon as possible. However, this project is maintained by a small group of volunteers in their spare time, and they cannot guarantee a rapid response. If you have not received a response from them within a week, then please send a reminder to them and copy the report to CPANSec at . Please note that the initial response to your report will be an acknowledgement, with a possible query for more information. It will not necessarily include any fixes for the issue. The project maintainer(s) may forward this issue to the security contacts for other projects where we believe it is relevant. This may include embedded libraries, system libraries, prerequisite modules or downstream software that uses this software. They may also forward this issue to CPANSec. # What Software this Policy Applies to Any security vulnerabilities in Net-OAuth are covered by this policy. Security vulnerabilities are considered anything that allows users to execute unauthorised code, access unauthorised resources, or to have an adverse impact on accessibility or performance of a system. Security vulnerabilities in upstream software (embedded libraries, prerequisite modules or system libraries, or in Perl), are not covered by this policy unless they affect Net-OAuth, or Net-OAuth can be used to exploit vulnerabilities in them. Security vulnerabilities in downstream software (any software that uses Net-OAuth, or plugins to it that are not included with the Net-OAuth distribution) are not covered by this policy. ## Which Versions of this Software are Supported? The maintainer(s) will only commit to releasing security fixes for the latest version of Net-OAuth. # Installation and Usage Issues Please see the module documentation for more information. Net-OAuth-0.31/META.yml0000664000175000017500000000161514773527226012326 0ustar rrrr--- abstract: 'OAuth 1.0 for Perl' author: - 'Robert Rothenberg ' build_requires: ExtUtils::MakeMaker: '0' Test::More: '0.66' Test::Warn: '0.21' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.72, CPAN::Meta::Converter version 2.150010' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Net-OAuth no_index: directory: - t - inc requires: Class::Accessor: '0.31' Class::Data::Inheritable: '0.06' Crypt::URandom: '0.37' Digest::SHA: '5.47' Encode: '2.35' LWP::UserAgent: '1' Test::More: '0.66' Test::Warn: '0.21' URI: '5.15' resources: bugtracker: https://rt.cpan.org/Public/Dist/Display.html?Name=Net-OAuth repository: https://github.com/keeth/Net-OAuth.git version: '0.31' x_serialization_backend: 'CPAN::Meta::YAML version 0.020' Net-OAuth-0.31/Makefile.PL0000644000175000017500000000222214773526405013016 0ustar rrrr# Note: this file was auto-generated by Module::Build::Compat version 0.4234 use ExtUtils::MakeMaker; WriteMakefile( 'NAME' => 'Net::OAuth', 'AUTHOR' => 'Robert Rothenberg ', "LICENSE" => 'perl', 'ABSTRACT_FROM' => 'lib/Net/OAuth.pm', 'VERSION_FROM' => 'lib/Net/OAuth.pm', 'TEST_REQUIRES' => { 'Test::More' => '0.66', 'Test::Warn' => '0.21', }, 'PREREQ_PM' => { 'Class::Accessor' => '0.31', 'Class::Data::Inheritable' => '0.06', 'Crypt::URandom' => '0.37', 'Digest::SHA' => '5.47', 'Encode' => '2.35', 'LWP::UserAgent' => '1', 'Test::More' => '0.66', 'Test::Warn' => '0.21', 'URI' => '5.15' }, 'INSTALLDIRS' => 'site', 'EXE_FILES' => [], 'PL_FILES' => {}, 'META_MERGE' => { resources => { bugtracker => 'https://rt.cpan.org/Public/Dist/Display.html?Name=Net-OAuth', repository => 'https://github.com/keeth/Net-OAuth.git', }, }, ); Net-OAuth-0.31/demo/0000755000175000017500000000000014773527226011774 5ustar rrrrNet-OAuth-0.31/demo/app.psgi0000755000175000017500000000447514733627432013451 0ustar rrrr#!/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.31/demo/config.yml0000644000175000017500000000125114733627432013757 0ustar rrrr# 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.31/demo/.htaccess0000644000175000017500000000023614733627432013567 0ustar rrrrRewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ /dispatch.cgi/$1 [QSA,L] Order allow,deny Deny from all Net-OAuth-0.31/demo/dispatch.cgi0000755000175000017500000000050714733627432014260 0ustar rrrr#!/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);