[Jifty-commit] r4386 - in jifty/trunk: lib/Jifty/Plugin/OAuth
lib/Jifty/Plugin/OAuth/Model
jifty-commit at lists.jifty.org
jifty-commit at lists.jifty.org
Tue Nov 6 21:45:51 EST 2007
Author: sartak
Date: Tue Nov 6 21:45:50 2007
New Revision: 4386
Modified:
jifty/trunk/ (props changed)
jifty/trunk/lib/Jifty/Plugin/OAuth/Dispatcher.pm
jifty/trunk/lib/Jifty/Plugin/OAuth/Model/AccessToken.pm
Log:
r44749 at onn: sartak | 2007-11-06 21:45:14 -0500
First cut of protected resource requests
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 Tue Nov 6 21:45:50 2007
@@ -13,9 +13,10 @@
before GET '/oauth/authorize' => \&authorize;
on POST '/oauth/authorize' => \&authorize_post;
on POST '/oauth/access_token' => \&access_token;
-
on '/oauth/authorized' => run { redirect '/oauth/authorize' };
+before '*' => \&try_oauth;
+
=head2 abortmsg CODE, MSG
Helper function to abort with a debug message. Maybe should be factored into
@@ -26,7 +27,7 @@
sub abortmsg {
my ($code, $msg) = @_;
Jifty->log->debug($msg) if defined($msg);
- abort($code || 400);
+ abort($code) if $code;
}
=head2 request_token
@@ -190,6 +191,64 @@
show 'oauth/response';
}
+=head2 try_oauth
+
+If this is a protected resource request, see if we can authorize the request
+with an access token.
+
+This is dissimilar to the other OAuth requests because if anything fails, you
+just don't set a current_user, and then the rest of the dispatcher rules will
+take care of it. Thus, failure is handled quite differently in this rule. We
+try to abort as early as possible to make OAuth less of a hit on all requests.
+
+=cut
+
+sub try_oauth
+{
+ my @params = qw/consumer_key signature_method signature
+ timestamp nonce token version/;
+ set no_abort => 1;
+ my %oauth_params = get_parameters(@params);
+ for (@params) {
+ return if !defined($oauth_params{$_});
+ }
+
+ my $consumer = get_consumer($oauth_params{consumer_key});
+ return if !$consumer->id;
+
+ my $signature_key = get_signature_key($oauth_params{signature_method}, $consumer);
+ return if !$signature_key;
+
+ my ($ok, $msg) = $consumer->is_valid_request(@oauth_params{qw/timestamp nonce/});
+ abortmsg(undef, $msg), return if !$ok;
+
+ my $access_token = Jifty::Plugin::OAuth::Model::AccessToken->new(current_user => Jifty::CurrentUser->superuser);
+ $access_token->load_by_cols(consumer => $consumer, token => $oauth_params{token});
+
+ abortmsg(undef, "No token found for consumer ".$consumer->name." with key $oauth_params{token}"), return unless $access_token->id;
+
+ ($ok, $msg) = $access_token->is_valid;
+ abortmsg(undef, "Cannot access protected resources with this access token: $msg"), return if !$ok;
+
+ # Net::OAuth::Request will die hard if it doesn't get everything it wants
+ my $request = eval { Net::OAuth::ProtectedResourceRequest->new(
+ request_url => Jifty->web->url(path => Jifty->web->request->path),
+ request_method => Jifty->handler->apache->method(),
+ consumer_secret => $consumer->secret,
+ token_secret => $access_token->secret,
+ signature_key => $signature_key,
+
+ map { $_ => $oauth_params{$_} } @params
+ ) };
+
+ abortmsg(undef, "Unable to create ProtectedResourceRequest: $@"), return if $@ || !defined($request);
+
+ abortmsg(undef, "Invalid signature (type: $oauth_params{signature_method})."), return unless $request->verify;
+
+ $consumer->made_request(@oauth_params{qw/timestamp nonce/});
+ Jifty->web->current_user(BTDT::CurrentUser->new(id => $access_token->auth_as));
+}
+
=head2 get_consumer CONSUMER KEY
Helper function to load a consumer by consumer key. Will abort if the key
@@ -201,7 +260,7 @@
my $key = shift;
my $consumer = Jifty::Plugin::OAuth::Model::Consumer->new(current_user => Jifty::CurrentUser->superuser);
$consumer->load_by_cols(consumer_key => $key);
- abortmsg(401, "No known consumer with key $key") if !$consumer->id;
+ abortmsg(401, "No known consumer with key $key") unless $consumer->id || get 'no_abort';
return $consumer;
}
@@ -225,7 +284,9 @@
sub get_signature_key {
my ($method, $consumer) = @_;
if (!$valid_signature_methods{$method}) {
- abortmsg(400, "Unsupported signature method requested: $method");
+ abortmsg(400, "Unsupported signature method requested: $method")
+ unless get 'no_abort';
+ return;
}
my $field = $key_field{$method};
@@ -235,8 +296,10 @@
my $key = $consumer->$field;
- abortmsg(400, "Consumer does not have necessary field $field required for signature method $method")
- unless defined $key;
+ if (!defined $key) {
+ abortmsg(400, "Consumer does not have necessary field $field required for signature method $method") unless get 'no_abort';
+ return;
+ }
if ($method eq 'RSA-SHA1') {
$key = Crypt::OpenSSL::RSA->new_public_key($key);
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 Tue Nov 6 21:45:50 2007
@@ -43,5 +43,30 @@
sub table {'oauth_access_tokens'}
+=head2 is_valid
+
+This neatly encapsulates the "is this access token perfect?" check.
+
+This will return a (boolean, message) pair, with boolean indicating success
+(true means the token is good) and message indicating error (or another
+affirmation of success).
+
+=cut
+
+sub is_valid {
+ my $self = shift;
+
+ return (0, "Access token has no authorizing user")
+ if !$self->auth_as;
+
+ return (0, "Request token does not have an authorizing user")
+ if !$self->authorized_by;
+
+ return (0, "Access token expired")
+ if $self->valid_until < DateTime->now;
+
+ return (1, "Request token valid");
+}
+
1;
More information about the Jifty-commit
mailing list