[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