[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