[Jifty-commit] r4264 - in jifty/trunk: . lib/Jifty/Plugin/OAuth lib/Jifty/Plugin/OAuth/Model

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Fri Oct 19 16:22:20 EDT 2007


Author: sartak
Date: Fri Oct 19 16:22:19 2007
New Revision: 4264

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/Consumer.pm
   jifty/trunk/lib/Jifty/Plugin/OAuth/Model/RequestToken.pm
   jifty/trunk/lib/Jifty/Plugin/OAuth/Token.pm
   jifty/trunk/t/TestApp-Plugin-OAuth/t/02-request-token.t

Log:
 r43888 at onn:  sartak | 2007-10-19 16:22:10 -0400
 Refactor timestamp and nonce out of tokens and into consumers
 Thanks to hannesty for discussing how it works


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	Fri Oct 19 16:22:19 2007
@@ -28,6 +28,8 @@
     my %oauth_params  = get_parameters(@params);
     my $consumer      = get_consumer($oauth_params{consumer_key});
     my $signature_key = get_signature_key($oauth_params{signature_method}, $consumer);
+    my ($ok, $msg) = $consumer->is_valid_request(@oauth_params{qw/timestamp nonce/});
+    abortmsg(401, $msg) if !$ok;
 
     # Net::OAuth::Request will die hard if it doesn't get everything it wants
     my $request = eval { Net::OAuth::RequestTokenRequest->new(
@@ -53,13 +55,14 @@
 
     my $token = Jifty::Plugin::OAuth::Model::RequestToken->new(current_user => Jifty::CurrentUser->superuser);
 
-    my ($ok, $msg) = eval {
-        $token->create(nonce => $oauth_params{nonce}, time_stamp => $oauth_params{timestamp}, consumer => $consumer);
+    ($ok, $msg) = eval {
+        $token->create(consumer => $consumer);
     };
 
     abortmsg(401, "Unable to create a Request Token: " . $@ || $msg)
         if $@ || !$ok;
 
+    $consumer->made_request(@oauth_params{qw/timestamp nonce/});
     set oauth_response => {
         oauth_token        => $token->token,
         oauth_token_secret => $token->secret
@@ -96,6 +99,8 @@
     my %oauth_params  = get_parameters(@params);
     my $consumer      = get_consumer($oauth_params{consumer_key});
     my $signature_key = get_signature_key($oauth_params{signature_method}, $consumer);
+    my ($ok, $msg) = $consumer->is_valid_request(@oauth_params{qw/timestamp nonce/});
+    abortmsg(401, $msg) if !$ok;
 
     # is the request token they're using still valid?
     my $request_token = Jifty::Plugin::OAuth::Model::RequestToken->new(current_user => Jifty::CurrentUser->superuser);
@@ -126,14 +131,13 @@
 
     ($ok, $msg) = eval {
         $token->create(consumer => $consumer,
-                       auth_as => $request_token->authorized_by,
-                       time_stamp => $oauth_params{timestamp},
-                       nonce => $oauth_params{nonce});
+                       auth_as  => $request_token->authorized_by);
     };
 
     abortmsg(401, "Unable to create an Access Token: " . $@ || $msg)
         if $@ || !defined($token) || !$ok;
 
+    $consumer->made_request(@oauth_params{qw/timestamp nonce/});
     set oauth_response => {
         oauth_token        => $token->token,
         oauth_token_secret => $token->secret

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	Fri Oct 19 16:22:19 2007
@@ -27,12 +27,6 @@
     column consumer =>
         refers_to Jifty::Plugin::OAuth::Model::Consumer;
 
-    # we use these to make sure we aren't being hit with a replay attack
-    column time_stamp =>
-        type is 'integer';
-
-    column nonce =>
-        type is 'varchar';
 };
 
 1;

Modified: jifty/trunk/lib/Jifty/Plugin/OAuth/Model/Consumer.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Plugin/OAuth/Model/Consumer.pm	(original)
+++ jifty/trunk/lib/Jifty/Plugin/OAuth/Model/Consumer.pm	Fri Oct 19 16:22:19 2007
@@ -33,7 +33,46 @@
         type is 'varchar',
         hints are 'This is only necessary if you want to support RSA-SHA1 signatures';
 
+    # we use these to make sure we aren't being hit with a replay attack
+    column last_timestamp =>
+        type is 'integer',
+        is required,
+        default is 0;
+
+    column nonces =>
+        type is 'blob',
+        filters are 'Jifty::DBI::Filter::Storable';
 };
 
+sub before_set_last_timestamp {
+    my $self = shift;
+    my $new_ts = shift;
+
+    # if this is a new timestamp, then flush the nonces
+    if ($new_ts != $self->last_timestamp) {
+        $self->set_nonces( {} );
+    }
+}
+
+sub is_valid_request {
+    my ($self, $timestamp, $nonce) = @_;
+    return (0, "Timestamp nonincreasing.")
+        if $timestamp < $self->last_timestamp;
+    return 1 if $timestamp > $self->last_timestamp;
+
+    # if this is the same timestamp as the last, we must check that the nonce
+    # is unique across the requests of these timestamps
+    return (0, "Already used this nonce.")
+        if defined $self->nonces->{$nonce};
+
+    return 1;
+}
+
+sub made_request {
+    my ($self, $timestamp, $nonce) = @_;
+    $self->set_last_timestamp($timestamp);
+    $self->nonces->{$nonce} = 1;
+}
+
 1;
 

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	Fri Oct 19 16:22:19 2007
@@ -42,14 +42,6 @@
         type is 'varchar',
         is required;
 
-    # we use these to make sure we aren't being hit with a replay attack
-    column time_stamp =>
-        type is 'integer',
-        is required;
-
-    column nonce =>
-        type is 'varchar',
-        is required;
 };
 
 sub after_set_authorized {

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	Fri Oct 19 16:22:19 2007
@@ -13,21 +13,6 @@
 sub before_create {
     my ($self, $attr) = @_;
 
-    # check if we're seeing a replay attack
-    my $token = $self->new(current_user => Jifty::CurrentUser->superuser);
-    $token->load_by_cols(nonce => $attr->{nonce}, time_stamp => $attr->{time_stamp}, consumer => $attr->{consumer});
-    if ($token->id) {
-        die "Duplicate nonce ($attr->{nonce}) and timestamp ($attr->{time_stamp}) from consumer ".$attr->{consumer}->name.". Possibly a replay attack.";
-    }
-
-    # check to see if the timestamp for this consumer is larger than any previous
-    my $tokens = (blessed($self).'Collection')->new(current_user => Jifty::CurrentUser->superuser);
-    $tokens->limit(column => 'consumer', value => $attr->{consumer});
-    $tokens->limit(column => 'time_stamp', value => $attr->{time_stamp}, operator => '>');
-    if ($tokens->count) {
-        die "Got a timestamp from consumer ".$attr->{consumer}->name." that was smaller than ".$tokens->count." previous timestamps.";
-    }
-
     # attempt 20 times to create a unique token string
     for (1..20) {
         $attr->{token} = generate_token();

Modified: jifty/trunk/t/TestApp-Plugin-OAuth/t/02-request-token.t
==============================================================================
--- jifty/trunk/t/TestApp-Plugin-OAuth/t/02-request-token.t	(original)
+++ jifty/trunk/t/TestApp-Plugin-OAuth/t/02-request-token.t	Fri Oct 19 16:22:19 2007
@@ -8,7 +8,7 @@
 use TestApp::Plugin::OAuth::Test;
 
 if (eval { require Net::OAuth::Request; 1 }) {
-    plan tests => 50;
+    plan tests => 56;
 }
 else {
     plan skip_all => "Net::OAuth isn't installed";
@@ -74,6 +74,29 @@
     oauth_signature_method => 'RSA-SHA1',
 );
 # }}}
+# same timestamp, different nonce {{{
+--$timestamp;
+response_is(
+    code                   => 200,
+    testname               => "200 - RSA-SHA1 signature",
+    consumer_secret        => 'bar',
+    oauth_consumer_key     => 'foo',
+    oauth_nonce            => 'kjfh',
+    signature_key          => $seckey,
+    oauth_signature_method => 'RSA-SHA1',
+);
+# }}}
+# same nonce, different timestamp {{{
+response_is(
+    code                   => 200,
+    testname               => "200 - RSA-SHA1 signature",
+    consumer_secret        => 'bar',
+    oauth_consumer_key     => 'foo',
+    oauth_nonce            => 'kjfh',
+    signature_key          => $seckey,
+    oauth_signature_method => 'RSA-SHA1',
+);
+# }}}}
 
 # get a request token as an RSA-less consumer (PLAINTEXT) {{{
 


More information about the Jifty-commit mailing list