[Jifty-commit] r4257 - in jifty/trunk: . lib/Jifty/Plugin/OAuth
lib/Jifty/Plugin/OAuth/Model t/TestApp-Plugin-OAuth
t/TestApp-Plugin-OAuth/bin t/TestApp-Plugin-OAuth/doc
t/TestApp-Plugin-OAuth/etc t/TestApp-Plugin-OAuth/lib
t/TestApp-Plugin-OAuth/lib/TestApp
t/TestApp-Plugin-OAuth/lib/TestApp/Plugin
t/TestApp-Plugin-OAuth/lib/TestApp/Plugin/OAuth
t/TestApp-Plugin-OAuth/lib/TestApp/Plugin/OAuth/Action
t/TestApp-Plugin-OAuth/log t/TestApp-Plugin-OAuth/share
t/TestApp-Plugin-OAuth/share/po t/TestApp-Plugin-OAuth/share/web
t/TestApp-Plugin-OAuth/share/web/static
t/TestApp-Plugin-OAuth/share/web/templates
t/TestApp-Plugin-OAuth/t t/TestApp-Plugin-OAuth/var
jifty-commit at lists.jifty.org
jifty-commit at lists.jifty.org
Thu Oct 18 19:20:26 EDT 2007
Author: sartak
Date: Thu Oct 18 19:20:24 2007
New Revision: 4257
Added:
jifty/trunk/t/TestApp-Plugin-OAuth/
jifty/trunk/t/TestApp-Plugin-OAuth/Makefile.PL
jifty/trunk/t/TestApp-Plugin-OAuth/bin/
jifty/trunk/t/TestApp-Plugin-OAuth/bin/jifty (contents, props changed)
jifty/trunk/t/TestApp-Plugin-OAuth/doc/
jifty/trunk/t/TestApp-Plugin-OAuth/etc/
jifty/trunk/t/TestApp-Plugin-OAuth/etc/config.yml
jifty/trunk/t/TestApp-Plugin-OAuth/lib/
jifty/trunk/t/TestApp-Plugin-OAuth/lib/TestApp/
jifty/trunk/t/TestApp-Plugin-OAuth/lib/TestApp/Plugin/
jifty/trunk/t/TestApp-Plugin-OAuth/lib/TestApp/Plugin/OAuth/
jifty/trunk/t/TestApp-Plugin-OAuth/lib/TestApp/Plugin/OAuth/Action/
jifty/trunk/t/TestApp-Plugin-OAuth/lib/TestApp/Plugin/OAuth/Model/
jifty/trunk/t/TestApp-Plugin-OAuth/lib/TestApp/Plugin/OAuth/Model/User.pm
jifty/trunk/t/TestApp-Plugin-OAuth/log/
jifty/trunk/t/TestApp-Plugin-OAuth/share/
jifty/trunk/t/TestApp-Plugin-OAuth/share/po/
jifty/trunk/t/TestApp-Plugin-OAuth/share/web/
jifty/trunk/t/TestApp-Plugin-OAuth/share/web/static/
jifty/trunk/t/TestApp-Plugin-OAuth/share/web/templates/
jifty/trunk/t/TestApp-Plugin-OAuth/t/
jifty/trunk/t/TestApp-Plugin-OAuth/t/01-basic.t
jifty/trunk/t/TestApp-Plugin-OAuth/t/02-request-token.t
jifty/trunk/t/TestApp-Plugin-OAuth/t/02-request-token.t-config.yml
jifty/trunk/t/TestApp-Plugin-OAuth/var/
Modified:
jifty/trunk/ (props changed)
jifty/trunk/lib/Jifty/Plugin/OAuth/Dispatcher.pm
jifty/trunk/lib/Jifty/Plugin/OAuth/Model/AccessToken.pm
jifty/trunk/lib/Jifty/Plugin/OAuth/Model/RequestToken.pm
jifty/trunk/lib/Jifty/Plugin/OAuth/Token.pm
jifty/trunk/lib/Jifty/Plugin/OAuth/View.pm
Log:
r43847 at onn: sartak | 2007-10-18 19:20:16 -0400
Start writing tests
Change timestamp to (ugh) time_stamp, because timestamp is a reserved word in a few SQL apps
Modified: jifty/trunk/lib/Jifty/Plugin/OAuth/Dispatcher.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Plugin/OAuth/Dispatcher.pm (original)
+++ jifty/trunk/lib/Jifty/Plugin/OAuth/Dispatcher.pm Thu Oct 18 19:20:24 2007
@@ -12,6 +12,13 @@
before GET '/oauth/authorize' => \&authorize;
before POST '/oauth/access_token' => \&access_token;
+# helper function to abort with a debug message
+sub abortmsg {
+ my ($code, $msg) = @_;
+ Jifty->log->error($msg) if defined($msg);
+ abort($code || 400);
+}
+
# a consumer wants a request token
sub request_token {
my @params = qw/consumer_key signature_method signature
@@ -30,10 +37,10 @@
map { $_ => $oauth_params{$_} } @params
) };
- abort(400) if $@ || !defined($request);
+ abortmsg(400, "Unable to create RequestTokenRequest: $@") if $@ || !defined($request);
# make sure the signature matches the rest of what the consumer gave us
- abort(401) unless $request->verify;
+ abortmsg(401, "Invalid signature.") unless $request->verify;
# ok, everything checks out. send them back a request token
# at this point, the only things that could go wrong are:
@@ -44,11 +51,12 @@
my $token = Jifty::Plugin::OAuth::Model::RequestToken->new(current_user => Jifty::CurrentUser->superuser);
- my ($ok) = eval {
- $token->create(map { $_ => $oauth_params{$_} } qw/timestamp nonce/);
+ my ($ok, $msg) = eval {
+ $token->create(nonce => $oauth_params{nonce}, time_stamp => $oauth_params{timestamp});
};
- abort(401) if $@ || !defined($token) || !$ok;
+ abortmsg(401, "Unable to create a Request Token: " . $@ || $msg)
+ if $@ || !defined($token) || !$ok;
# XXX: actually send the token
}
@@ -86,8 +94,11 @@
# is the request token they're using still valid?
my $request_token = Jifty::Plugin::OAuth::Model::RequestToken->new(current_user => Jifty::CurrentUser->superuser);
$request_token->load_by_cols(consumer => $consumer, token => $oauth_params{token});
- abort(401) unless $request_token->id;
- abort(401) unless $request_token->can_trade_for_access_token;
+
+ abortmsg(401, "No token found for consumer ".$consumer->name." with key $oauth_params{token}") unless $request_token->id;
+
+ my ($ok, $msg) = $request_token->can_trade_for_access_token;
+ abortmsg(401, "Cannot trade request token for access token: $msg") if !$ok;
# Net::OAuth::Request will die hard if it doesn't get everything it wants
my $request = eval { Net::OAuth::AccessTokenRequest->new(
@@ -99,20 +110,22 @@
map { $_ => $oauth_params{$_} } @params
) };
- abort(400) if $@ || !defined($request);
+ abortmsg(400, "Unable to create AccessTokenRequest: $@") if $@ || !defined($request);
# make sure the signature matches the rest of what the consumer gave us
- abort(401) unless $request->verify;
+ abortmsg(401, "Invalid signature.") unless $request->verify;
my $token = Jifty::Plugin::OAuth::Model::AccessToken->new(current_user => Jifty::CurrentUser->superuser);
- my ($ok) = eval {
+ ($ok, $msg) = eval {
$token->create(consumer => $consumer,
auth_as => $request_token->authorized_by,
- map { $_ => $oauth_params{$_} } qw/timestamp nonce/);
+ time_stamp => $oauth_params{timestamp},
+ nonce => $oauth_params{nonce});
};
- abort(401) if $@ || !defined($token) || !$ok;
+ abortmsg(401, "Unable to create an Access Token: " . $@ || $msg)
+ if $@ || !defined($token) || !$ok;
# XXX: actually send the token
}
@@ -121,14 +134,15 @@
my $key = shift;
my $consumer = Jifty::Plugin::OAuth::Model::Consumer->new(current_user => Jifty::CurrentUser->superuser);
$consumer->load_by_cols(consumer_key => $key);
- abort(401) if !$consumer->id;
+ abortmsg(401, "No known consumer with key $key") if !$consumer->id;
return $consumer;
}
my %valid_signature_methods = map { $_ => 1 } qw/PLAINTEXT HMAC-SHA1 RSA-SHA1/;
sub validate_signature_method {
my $method = shift;
- abort(400) unless $valid_signature_methods{$method};
+ return if $valid_signature_methods{$method};
+ abortmsg(400, "Unsupported signature method requested: $method");
}
sub get_parameters {
@@ -137,17 +151,17 @@
# XXX: Check Authorization header
# XXX: Check WWW-Authenticate header
- %p = ((map {
- my $v = Jifty->handler->apache->header_in("oauth_$_");
- defined $v ? ($_ => $v) : ()
- } @_), %p);
-
- # XXX: Check query string
+ my %params = Jifty->handler->apache->params();
+ use Data::Dumper; warn Dumper \%params;
+ @p{@_} = @params{map {"oauth_$_"} @_};
$p{version} ||= '1.0';
unless (get 'no_abort') {
- #abort(400) if grep { !defined($p{$_}) } @_
+ for (@_) {
+ abortmsg(400, "Undefined required parameter: $_")
+ if !defined($p{$_});
+ }
}
return %p;
Modified: jifty/trunk/lib/Jifty/Plugin/OAuth/Model/AccessToken.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Plugin/OAuth/Model/AccessToken.pm (original)
+++ jifty/trunk/lib/Jifty/Plugin/OAuth/Model/AccessToken.pm Thu Oct 18 19:20:24 2007
@@ -28,7 +28,7 @@
refers_to Jifty::Plugin::OAuth::Model::Consumer;
# we use these to make sure we aren't being hit with a replay attack
- column timestamp =>
+ column time_stamp =>
type is 'integer';
column nonce =>
Modified: jifty/trunk/lib/Jifty/Plugin/OAuth/Model/RequestToken.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Plugin/OAuth/Model/RequestToken.pm (original)
+++ jifty/trunk/lib/Jifty/Plugin/OAuth/Model/RequestToken.pm Thu Oct 18 19:20:24 2007
@@ -39,7 +39,7 @@
type is 'varchar';
# we use these to make sure we aren't being hit with a replay attack
- column timestamp =>
+ column time_stamp =>
type is 'integer';
column nonce =>
@@ -53,11 +53,20 @@
sub can_trade_for_access_token {
my $self = shift;
- return 0 if !$self->authorized;
- return 0 if !$self->authorized_by;
- return 0 if $self->used;
- return 0 if $self->valid_until < DateTime->now;
- return 1;
+
+ return (0, "Request token is not authorized")
+ if !$self->authorized;
+
+ return (0, "Request token does not have an authorizing user")
+ if !$self->authorized_by;
+
+ return (0, "Request token already used")
+ if $self->used;
+
+ return (0, "Request token expired")
+ if $self->valid_until < DateTime->now;
+
+ return (1, "Request token valid");
}
1;
Modified: jifty/trunk/lib/Jifty/Plugin/OAuth/Token.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Plugin/OAuth/Token.pm (original)
+++ jifty/trunk/lib/Jifty/Plugin/OAuth/Token.pm Thu Oct 18 19:20:24 2007
@@ -14,7 +14,7 @@
# check if we're seeing a replay attack
my $token = $self->new(current_user => Jifty::CurrentUser->superuser);
- $token->load_by_cols(nonce => $attr->{nonce}, timestamp => $attr->{nonce});
+ $token->load_by_cols(nonce => $attr->{nonce}, time_stamp => $attr->{time_stamp});
return if $token->id;
# attempt 20 times to create a unique token string
Modified: jifty/trunk/lib/Jifty/Plugin/OAuth/View.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Plugin/OAuth/View.pm (original)
+++ jifty/trunk/lib/Jifty/Plugin/OAuth/View.pm Thu Oct 18 19:20:24 2007
@@ -4,6 +4,9 @@
use Jifty::View::Declare -base;
+template 'oauth/request_token' => page { p { "This page is probably not for you!" } };
+template 'oauth/access_token' => page { p { "This page is probably not for you!" } };
+
template 'oauth' => page {
p {
b { a { attr { href => "http://oauth.net/" } "OAuth" } };
Added: jifty/trunk/t/TestApp-Plugin-OAuth/Makefile.PL
==============================================================================
--- (empty file)
+++ jifty/trunk/t/TestApp-Plugin-OAuth/Makefile.PL Thu Oct 18 19:20:24 2007
@@ -0,0 +1,7 @@
+use inc::Module::Install;
+
+name 'TestApp::Plugin::OAuth';
+version '0.01';
+requires 'Jifty' => '0.70824';
+
+WriteAll;
Added: jifty/trunk/t/TestApp-Plugin-OAuth/bin/jifty
==============================================================================
--- (empty file)
+++ jifty/trunk/t/TestApp-Plugin-OAuth/bin/jifty Thu Oct 18 19:20:24 2007
@@ -0,0 +1,11 @@
+#!/usr/bin/env perl
+use warnings;
+use strict;
+use File::Basename qw(dirname);
+use UNIVERSAL::require;
+
+use Jifty;
+use Jifty::Script;
+
+local $SIG{INT} = sub { warn "Stopped\n"; exit; };
+Jifty::Script->dispatch();
Added: jifty/trunk/t/TestApp-Plugin-OAuth/etc/config.yml
==============================================================================
--- (empty file)
+++ jifty/trunk/t/TestApp-Plugin-OAuth/etc/config.yml Thu Oct 18 19:20:24 2007
@@ -0,0 +1,53 @@
+---
+framework:
+ AdminMode: 1
+ ApplicationClass: TestApp::Plugin::OAuth
+ ApplicationName: TestApp-Plugin-OAuth
+ ApplicationUUID: B5461398-7DC0-11DC-83A6-036B06D64C5E
+ ConfigFileVersion: 2
+ Database:
+ CheckSchema: 1
+ Database: testapp_plugin_oauth
+ Driver: SQLite
+ Host: localhost
+ Password: ''
+ RecordBaseClass: Jifty::DBI::Record::Cachable
+ User: ''
+ Version: 0.0.1
+ DevelMode: 1
+ L10N:
+ PoDir: share/po
+ LogLevel: INFO
+ Mailer: Sendmail
+ MailerArgs: []
+
+ Plugins:
+ - LetMe: {}
+ - SkeletonApp: {}
+ - REST: {}
+ - Halo: {}
+ - ErrorTemplates: {}
+ - OnlineDocs: {}
+ - CompressedCSSandJS: {}
+ - AdminUI: {}
+ - OAuth: {}
+
+ PubSub:
+ Backend: Memcached
+ Enable: ~
+ SkipAccessControl: 0
+ TemplateClass: TestApp::Plugin::OAuth::View
+ Web:
+ BaseURL: http://localhost
+ DataDir: var/mason
+ Globals: []
+
+ MasonConfig:
+ autoflush: 0
+ default_escape_flags: h
+ error_format: text
+ error_mode: fatal
+ Port: 8888
+ ServeStaticFiles: 1
+ StaticRoot: share/web/static
+ TemplateRoot: share/web/templates
Added: jifty/trunk/t/TestApp-Plugin-OAuth/lib/TestApp/Plugin/OAuth/Model/User.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/t/TestApp-Plugin-OAuth/lib/TestApp/Plugin/OAuth/Model/User.pm Thu Oct 18 19:20:24 2007
@@ -0,0 +1,17 @@
+package TestApp::Plugin::OAuth::Model::User;
+use base qw/Jifty::Record/;
+
+use Jifty::DBI::Schema;
+use Jifty::Record schema {
+ column 'name' =>
+ type is 'text',
+ is mandatory;
+ column 'email' =>
+ type is 'text',
+ is mandatory;
+ column 'tasty' =>
+ type is 'boolean';
+};
+
+1;
+
Added: jifty/trunk/t/TestApp-Plugin-OAuth/t/01-basic.t
==============================================================================
--- (empty file)
+++ jifty/trunk/t/TestApp-Plugin-OAuth/t/01-basic.t Thu Oct 18 19:20:24 2007
@@ -0,0 +1,25 @@
+#!/usr/bin/env perl
+use warnings;
+use strict;
+
+use lib 't/lib';
+use Jifty::SubTest;
+
+use Jifty::Test tests => 9;
+use Jifty::Test::WWW::Mechanize;
+
+my $server = Jifty::Test->make_server;
+isa_ok($server, 'Jifty::Server');
+my $URL = $server->started_ok;
+my $mech = Jifty::Test::WWW::Mechanize->new();
+
+$mech->get_ok($URL . '/oauth');
+$mech->content_like(qr{/oauth/request_token}, "oauth page mentions request_token URL");
+$mech->content_like(qr{/oauth/authorize}, "oauth page mentions authorize URL");
+$mech->content_like(qr{/oauth/access_token}, "oauth page mentions access_token URL");
+
+$mech->content_like(qr{http://oauth\.net/}, "oauth page mentions OAuth homepage");
+
+$mech->get_ok($URL . '/oauth/authorize');
+$mech->content_like(qr{If you trust this application}, "oauth authorization page exists without fancy headers");
+
Added: jifty/trunk/t/TestApp-Plugin-OAuth/t/02-request-token.t
==============================================================================
--- (empty file)
+++ jifty/trunk/t/TestApp-Plugin-OAuth/t/02-request-token.t Thu Oct 18 19:20:24 2007
@@ -0,0 +1,104 @@
+#!/usr/bin/env perl
+use warnings;
+use strict;
+
+use lib 't/lib';
+use Jifty::SubTest;
+
+use Jifty::Test tests => 9;
+use Jifty::Test::WWW::Mechanize;
+
+my $server = Jifty::Test->make_server;
+isa_ok($server, 'Jifty::Server');
+my $URL = $server->started_ok;
+my $mech = Jifty::Test::WWW::Mechanize->new();
+my $url = $URL . '/oauth/request_token';
+
+# helper functions {{{
+sub response_is ($%;$) {
+ my ($code, $params, $testname) = @_;
+
+ my $method = (delete $params->{method}) || 'POST';
+ my $token_secret = (delete $params->{token_secret}) || '';
+ my $consumer_secret = delete $params->{consumer_secret}
+ or die "consumer_secret not passed to response_is!";
+
+ $params->{oauth_signature} ||= sign($params, $method, $token_secret, $consumer_secret);
+
+ my $r;
+
+ if ($method eq 'POST') {
+ $r = $mech->post($url);
+ }
+ else {
+ $r = $mech->get($url);
+ }
+
+ is($r->code, $code, $testname || "Request got $code");
+}
+
+sub sign {
+ my ($params, $method, $token_secret, $consumer_secret) = @_;
+
+ my $normalized_request_parameters
+ = join '&',
+ map { "$_=" . Jifty->web->escape_uri($params->{$_}||'') }
+ sort keys %$params;
+
+ my $signature_base_string
+ = join '&',
+ map { Jifty->web->escape_uri($params->{$_}||'') }
+ uc($method),
+ $url,
+ $normalized_request_parameters,
+ $consumer_secret,
+ $token_secret;
+
+ # XXX: do some signing based on $params->{signature_method}!
+ return '!!';
+}
+# }}}
+
+# get a request token as a known consumer {{{
+my $consumer = Jifty::Plugin::OAuth::Model::Consumer->new(current_user => Jifty::CurrentUser->superuser);
+my ($ok, $msg) = $consumer->create(
+ consumer_key => 'foo',
+ secret => 'bar',
+ name => 'FooBar industries',
+ url => 'http://foo.bar.example.com',
+);
+ok($ok, $msg);
+
+
+# }}}
+
+# unknown consumer {{{
+response_is 401, {
+ consumer_secret => 'zzz',
+ oauth_consumer_key => 'whoami',
+ oauth_signature_method => 'RSA-SHA1',
+ oauth_timestamp => 100,
+ oauth_nonce => 'haa haa',
+ oauth_version => '1.0',
+};
+# }}}
+# wrong secret {{{
+# }}}
+# wrong signature {{{
+# }}}
+# duplicate timestamp and nonce {{{
+# }}}
+# unknown signature method {{{
+# }}}
+# missing parameters {{{
+# }}}
+# unsupported parameter {{{
+# }}}
+# invalid timestamp (noninteger) {{{
+
+# }}}
+# invalid timestamp (smaller than previous request) {{{
+# }}}
+# GET not POST {{{
+# }}}
+
Added: jifty/trunk/t/TestApp-Plugin-OAuth/t/02-request-token.t-config.yml
==============================================================================
--- (empty file)
+++ jifty/trunk/t/TestApp-Plugin-OAuth/t/02-request-token.t-config.yml Thu Oct 18 19:20:24 2007
@@ -0,0 +1,4 @@
+---
+framework:
+ LogLevel: DEBUG
+
More information about the Jifty-commit
mailing list