[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