[Jifty-commit] r4272 - in jifty/trunk: . lib/Jifty/Plugin/OAuth
lib/Jifty/Plugin/OAuth/Model t/TestApp-Plugin-OAuth/etc
jifty-commit at lists.jifty.org
jifty-commit at lists.jifty.org
Sat Oct 20 00:34:35 EDT 2007
Author: sartak
Date: Sat Oct 20 00:34:31 2007
New Revision: 4272
Modified:
jifty/trunk/ (props changed)
jifty/trunk/Makefile.PL
jifty/trunk/lib/Jifty/Plugin/OAuth/Dispatcher.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/lib/Jifty/Plugin/OAuth/View.pm
jifty/trunk/t/TestApp-Plugin-OAuth/etc/config.yml
jifty/trunk/t/TestApp-Plugin-OAuth/lib/TestApp/Plugin/OAuth/Model/User.pm
Log:
r43915 at onn: sartak | 2007-10-20 00:34:20 -0400
A lot of POD for OAuth, and some tiny fixes elsewhere
Modified: jifty/trunk/Makefile.PL
==============================================================================
--- jifty/trunk/Makefile.PL (original)
+++ jifty/trunk/Makefile.PL Sat Oct 20 00:34:31 2007
@@ -168,9 +168,12 @@
'OAuth Plugin' => [
-default => 0,
recommends('Net::OAuth::Request' => '0.04'),
+ recommends('Net::OAuth::RequestTokenRequest' => '0.04'),
+ recommends('Net::OAuth::AccessTokenRequest' => '0.04'),
+ recommends('Net::OAuth::ProtectedResourceRequest' => '0.04'),
+
recommends('Crypt::OpenSSL::RSA'),
recommends('Digest::HMAC_SHA1'),
- recommends('MIME::Base64'),
],
);
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 Sat Oct 20 00:34:31 2007
@@ -13,14 +13,25 @@
before GET '/oauth/authorize' => \&authorize;
on POST '/oauth/access_token' => \&access_token;
-# helper function to abort with a debug message
+=head2 abortmsg CODE, MSG
+
+Helper function to abort with a debug message. Maybe should be factored into
+the C<abort> procedure?
+
+=cut
+
sub abortmsg {
my ($code, $msg) = @_;
Jifty->log->debug($msg) if defined($msg);
abort($code || 400);
}
-# a consumer wants a request token
+=head2 request_token
+
+The consumer wants a request token
+
+=cut
+
sub request_token {
my @params = qw/consumer_key signature_method signature
timestamp nonce version/;
@@ -71,7 +82,12 @@
show 'oauth/response';
}
-# the user is authorizing (or denying) a consumer's request token
+=head2 authorize
+
+The user is authorizing (or denying) a consumer's request token
+
+=cut
+
sub authorize {
my @params = qw/token callback/;
@@ -93,7 +109,12 @@
}
}
-# the consumer is trying to trade a request token for an access token
+=head2 access_token
+
+The consumer is trying to trade a request token for an access token
+
+=cut
+
sub access_token {
my @params = qw/consumer_key signature_method signature
timestamp nonce token version/;
@@ -148,6 +169,13 @@
show 'oauth/response';
}
+=head2 get_consumer CONSUMER KEY
+
+Helper function to load a consumer by consumer key. Will abort if the key
+is unknown.
+
+=cut
+
sub get_consumer {
my $key = shift;
my $consumer = Jifty::Plugin::OAuth::Model::Consumer->new(current_user => Jifty::CurrentUser->superuser);
@@ -156,6 +184,18 @@
return $consumer;
}
+=head2 get_signature_key SIGNATURE METHOD, CONSUMER
+
+Figures out the signature key for this consumer. Will abort if the signature
+method is unsupported, or if the consumer lacks the prerequisites for this
+signature method.
+
+Will return C<undef> is the signature key is consumer independent, as is the
+case for C<PLAINTEXT> and C<HMAC-SHA1>. C<RSA-SHA1> depends on the consumer
+having the C<rsa_key> field.
+
+=cut
+
{
my %valid_signature_methods = map { $_ => 1 }
qw/PLAINTEXT HMAC-SHA1 RSA-SHA1/;
@@ -185,6 +225,31 @@
}
}
+=head2 get_parameters REQUIRED PARAMETERS
+
+This will retrieve all the request paremeters. This gets parameters besides
+the ones in the OAuth spec, because the signature is based on all such request
+parameters.
+
+Pass in by name all the OAuth-required parameters. Do not include the C<oauth_>
+prefix.
+
+The precedence of parameters, from highest priority to lowest priority, is:
+
+=over 4
+
+=item Authorization header
+
+=item WWW-Authenticate header
+
+=item POST parameters
+
+=item GET parameters (aka URL's query string)
+
+=back
+
+=cut
+
sub get_parameters {
my %p;
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 Sat Oct 20 00:34:31 2007
@@ -52,16 +52,46 @@
sub table {'oauth_consumers'}
+=head2 before_set_last_timestamp
+
+If the new timestamp is different from the last_timestamp, then clear any
+nonces we've used. Nonces must only be unique for requests of a given
+timestamp.
+
+Note that you should ALWAYS call is_valid_request before updating the
+last_timestamp. You should also verify the signature and make sure the request
+all went through before updating the last_timestamp. Otherwise an attacker
+may be able to create a request with an extraordinarily high timestamp and
+screw up the regular consumer.
+
+=cut
+
sub before_set_last_timestamp {
my $self = shift;
my $new_ts = shift;
+ # uh oh, looks like sloppy coding..
+ if ($new_ts < $self->last_timestamp) {
+ die "The new timestamp is LESS than the last timestamp. You forgot to call is_valid_request!";
+ }
+
# if this is a new timestamp, then flush the nonces
if ($new_ts != $self->last_timestamp) {
$self->set_nonces( {} );
}
}
+=head2 is_valid_request TIMESTAMP, NONCE
+
+This will do some sanity checks (as required for security by the OAuth spec).
+It will make sure that the timestamp is not less than the latest timestamp for
+this consumer. It will also make sure that the nonce hasn't been seen for
+this timestamp (very important).
+
+ALWAYS call this method when handling OAuth requests. EARLY.
+
+=cut
+
sub is_valid_request {
my ($self, $timestamp, $nonce) = @_;
return (0, "Timestamp nonincreasing.")
@@ -76,6 +106,15 @@
return 1;
}
+=head2 made_request TIMESTAMP, NONCE
+
+This method is to be called just before you're done processing an OAuth
+request. Parameters were valid, no errors occurred, everything's generally
+hunky-dory. This updates the C<last_timestamp> of the consumer, and sets the
+nonce as "used" for this new timestamp.
+
+=cut
+
sub made_request {
my ($self, $timestamp, $nonce) = @_;
$self->set_last_timestamp($timestamp);
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 Sat Oct 20 00:34:31 2007
@@ -52,11 +52,27 @@
sub table {'oauth_request_tokens'}
+=head2 after_set_authorized
+
+This will set the C<authorized_by> to the current user.
+
+=cut
+
sub after_set_authorized {
my $self = shift;
$self->set_authorized_by(Jifty->web->current_user->id);
}
+=head2 can_trade_for_access_token
+
+This neatly encapsulates the "is this request 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 can_trade_for_access_token {
my $self = shift;
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 Sat Oct 20 00:34:31 2007
@@ -4,12 +4,38 @@
use warnings;
use Scalar::Util 'blessed';
-# this just provides some helper methods for both token classes to use
+=head1 DESCRIPTION
+
+This just provides some helper methods for both token classes to use
+
+=cut
+
+=head2 generate_token
+
+This will create a randomly generated 20-character token for use as
+a request or access token. The string is hexadecimal.
+
+This does not check for uniqueness.
+
+=cut
sub generate_token {
return join '', map { unpack('H2', chr(int rand 256)) } 1..10;
}
+=head2 before_create
+
+This does some checks and provides some defaults.
+
+It tries a number of times to create a unique C<token> using C<generate_token>.
+If that fails, this method will DIE.
+
+It will also create a secret using C<generate_token>.
+
+Finally, it will create a default C<valid_until> of 1 hour from now.
+
+=cut
+
sub before_create {
my ($self, $attr) = @_;
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 Sat Oct 20 00:34:31 2007
@@ -4,6 +4,20 @@
use Jifty::View::Declare -base;
+=head1 NAME
+
+Jifty::Plugin::OAuth::View - Views for OAuth-ey bits
+
+=cut
+
+=head2 oauth/response
+
+Internal template. Do not use.
+
+It returns OAuth parameters to the consumer in the HTTP response body.
+
+=cut
+
template 'oauth/response' => sub {
my $params = get 'oauth_response';
if (ref($params) eq 'HASH') {
@@ -15,6 +29,13 @@
}
};
+=head2 oauth
+
+An OAuth description page very much geared towards Consumers, since they'll
+most likely be the only ones visiting yourapp.com/oauth
+
+=cut
+
template 'oauth' => page {
p {
b { a { attr { href => "http://oauth.net/" } "OAuth" } };
@@ -65,6 +86,14 @@
}
};
+=head2 oauth/authorize
+
+This is the page that Users see when authorizing a request token. It renders
+the "insert token here" textbox if the consumer didn't put the request token
+in the GET query, and (always) renders Allow/Deny buttons.
+
+=cut
+
template 'oauth/authorize' => page { title => 'Someone wants stuff!' }
content {
show '/oauth/help';
@@ -100,6 +129,12 @@
Jifty->web->form->end();
};
+=head2 oauth/help
+
+This provides a very, very layman description of OAuth for users
+
+=cut
+
private template 'oauth/help' => sub {
div {
p {
@@ -112,6 +147,12 @@
}
};
+=head2 oauth/consumer
+
+Renders the consumer's name, and if available, its URL as a link.
+
+=cut
+
private template 'oauth/consumer' => sub {
my $consumer = (get 'consumer') || 'Some application';
Modified: jifty/trunk/t/TestApp-Plugin-OAuth/etc/config.yml
==============================================================================
--- jifty/trunk/t/TestApp-Plugin-OAuth/etc/config.yml (original)
+++ jifty/trunk/t/TestApp-Plugin-OAuth/etc/config.yml Sat Oct 20 00:34:31 2007
@@ -22,15 +22,12 @@
MailerArgs: []
Plugins:
- - LetMe: {}
- - SkeletonApp: {}
- REST: {}
- Halo: {}
- - ErrorTemplates: {}
- - OnlineDocs: {}
- CompressedCSSandJS: {}
- AdminUI: {}
- OAuth: {}
+ - Authentication::Password: {}
PubSub:
Backend: Memcached
Modified: jifty/trunk/t/TestApp-Plugin-OAuth/lib/TestApp/Plugin/OAuth/Model/User.pm
==============================================================================
--- jifty/trunk/t/TestApp-Plugin-OAuth/lib/TestApp/Plugin/OAuth/Model/User.pm (original)
+++ jifty/trunk/t/TestApp-Plugin-OAuth/lib/TestApp/Plugin/OAuth/Model/User.pm Sat Oct 20 00:34:31 2007
@@ -3,15 +3,12 @@
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';
};
+use Jifty::Plugin::User::Mixin::Model::User;
+use Jifty::Plugin::Authentication::Password::Mixin::Model::User;
+
1;
More information about the Jifty-commit
mailing list