[Jifty-commit] r4254 - in jifty/trunk: lib/Jifty/Plugin
lib/Jifty/Plugin/Authentication/Password/Action
lib/Jifty/Plugin/OAuth lib/Jifty/Plugin/OAuth/Action
lib/Jifty/Plugin/OAuth/Model
jifty-commit at lists.jifty.org
jifty-commit at lists.jifty.org
Thu Oct 18 15:36:38 EDT 2007
Author: sartak
Date: Thu Oct 18 15:36:32 2007
New Revision: 4254
Added:
jifty/trunk/lib/Jifty/Plugin/OAuth/Action/
jifty/trunk/lib/Jifty/Plugin/OAuth/Action/AuthorizeRequestToken.pm
Modified:
jifty/trunk/ (props changed)
jifty/trunk/lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm
jifty/trunk/lib/Jifty/Plugin/OAuth.pm
jifty/trunk/lib/Jifty/Plugin/OAuth/Dispatcher.pm
jifty/trunk/lib/Jifty/Plugin/OAuth/Model/AccessToken.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
Log:
r43835 at onn: sartak | 2007-10-18 15:36:22 -0400
Many improvements, including some pages
Modified: jifty/trunk/lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm (original)
+++ jifty/trunk/lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm Thu Oct 18 15:36:32 2007
@@ -97,3 +97,102 @@
}
1;
+use warnings;
+use strict;
+
+=head1 NAME
+
+Jifty::Plugin::Authentication::Password::Action::SendPasswordReminder
+
+=cut
+
+package Jifty::Plugin::Authentication::Password::Action::SendPasswordReminder;
+use base qw/Jifty::Action/;
+
+
+__PACKAGE__->mk_accessors(qw(user_object));
+
+=head2 arguments
+
+The field for C<SendLostPasswordReminder> is:
+
+=over 4
+
+=item address: the email address
+
+=back
+
+=cut
+
+sub arguments {
+ return (
+ {
+ address => {
+ label => _('Email'),
+ mandatory => 1,
+ },
+ }
+ );
+
+}
+
+=head2 setup
+
+Create an empty user object to work with
+
+=cut
+
+sub setup {
+ my $self = shift;
+ my $LoginUser = Jifty->app_class('Model','User');
+ my $CurrentUser = Jifty->app_class('CurrentUser');
+
+
+
+ # Make a blank user object
+ $self->user_object(
+ $LoginUser->new( current_user => $CurrentUser->superuser ) );
+}
+
+=head2 validate_address
+
+Make sure there's actually an account by that name.
+
+=cut
+
+sub validate_address {
+ my $self = shift;
+ my $email = shift;
+ my $LoginUser = Jifty->app_class('Model','User');
+ my $CurrentUser = Jifty->app_class('CurrentUser');
+
+
+ return $self->validation_error(
+ address => _("That doesn't look like an email address.") )
+ unless ( $email =~ /\S\@\S/ );
+
+ $self->user_object(
+ $LoginUser->new( current_user => $CurrentUser->superuser ) );
+ $self->user_object->load_by_cols( email => $email );
+ return $self->validation_error(
+ address => _("It doesn't look like there's an account by that name.") )
+ unless ( $self->user_object->id );
+
+ return $self->validation_ok('address');
+}
+
+=head2 take_action
+
+Send out a Reminder email giving a link to a password-reset form.
+
+=cut
+
+sub take_action {
+ my $self = shift;
+ Jifty->app_class('Notification','ConfirmLostPassword')->new(
+ to => $self->user_object )->send;
+ return $self->result->message(
+ _("A link to reset your password has been sent to your email account."));
+}
+
+1;
Modified: jifty/trunk/lib/Jifty/Plugin/OAuth.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Plugin/OAuth.pm (original)
+++ jifty/trunk/lib/Jifty/Plugin/OAuth.pm Thu Oct 18 15:36:32 2007
@@ -28,4 +28,36 @@
=cut
+=head2 init
+
+Provides defaults for the three URLs that OAuth needs:
+
+=over 4
+
+=item request_token: Request a RequestToken
+
+/oauth/request_token
+
+=item authorize: Authorize a RequestToken
+
+/oauth/authorize
+
+=item access_token: Exchange a RequestToken for an Accesstoken
+
+/oauth/access_token
+
+=cut
+
+our %CONFIG;
+
+sub init {
+ my $self = shift;
+ %CONFIG = (
+ request_token => '/oauth/request_token',
+ authorize => '/oauth/authorize',
+ access_token => '/oauth/access_token',
+ @_
+ );
+}
+
1;
Added: jifty/trunk/lib/Jifty/Plugin/OAuth/Action/AuthorizeRequestToken.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/lib/Jifty/Plugin/OAuth/Action/AuthorizeRequestToken.pm Thu Oct 18 15:36:32 2007
@@ -0,0 +1,74 @@
+package Jifty::Plugin::OAuth::Action::AuthorizeRequestToken;
+use warnings;
+use strict;
+use base qw/Jifty::Action/;
+
+=head1 NAME
+
+Jifty::Plugin::OAuth::Action::AuthorizeRequestToken
+
+=cut
+
+use Jifty::Param::Schema;
+use Jifty::Action schema {
+
+ param 'token',
+ render as 'text',
+ max_length is 30,
+ hints are 'The site you just came from should have provided it';
+
+ param 'authorize',
+ valid_values are qw(allow deny);
+
+};
+
+=head2 validate_token
+
+Make sure we have such a token, and that it is not already authorized
+
+=cut
+
+sub validate_token {
+ my $self = shift;
+ my $token = shift;
+
+ my $request_token = Jifty::Plugin::OAuth::Model::RequestToken->new(current_user => Jifty::CurrentUser->superuser);
+ $request_token->load_by_cols(
+ token => $token,
+ authorized => 'f',
+ );
+
+ return $self->validation_error(token => "I don't know of that request token.") unless $request_token->id;
+
+ return $self->validation_ok('token');
+}
+
+=head2 take_action
+
+Actually authorize or deny this request token
+
+=cut
+
+sub take_action {
+ my $self = shift;
+
+ my $token = Jifty::Plugin::OAuth::Model::RequestToken->new(current_user => Jifty::CurrentUser->superuser);
+ $token->load_by_cols(
+ token => $self->argument_value('token'),
+ user => Jifty->web->current_user->id
+ );
+
+ if ($self->argument_value('authorize') eq 'allow') {
+ $token->set_authorized('t');
+ $self->result->message("Allowing " . $token->consumer->name . " to access your stuff.");
+ }
+ else {
+ $token->delete;
+ $self->result->message("Denying " . $token->consumer->name . " the right to access your stuff.");
+ }
+
+ return 1;
+}
+
+1;
+
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 Thu Oct 18 15:36:32 2007
@@ -8,13 +8,9 @@
use Net::OAuth::AccessTokenRequest;
use Net::OAuth::ProtectedResourceRequest;
-my $request_token_url = '/oauth/request_token';
-my $authorize_url = '/oauth/authorize';
-my $access_token_url = '/oauth/access_token';
-
-before POST $request_token_url => \&request_token;
-before GET $authorize_url => \&authorize;
-before POST $access_token_url => \&access_token;
+before POST $Jifty::Plugin::OAuth::CONFIG{request_token} => \&request_token;
+before GET $Jifty::Plugin::OAuth::CONFIG{authorize} => \&authorize;
+before POST $Jifty::Plugin::OAuth::CONFIG{access_token} => \&access_token;
# a consumer wants a request token
sub request_token {
@@ -27,7 +23,7 @@
# Net::OAuth::Request will die hard if it doesn't get everything it wants
my $request = eval { Net::OAuth::RequestTokenRequest->new(
- request_url => $request_token_url,
+ request_url => Jifty->web->url(path => $Jifty::Plugin::OAuth::CONFIG{request_token}),
request_method => Jifty->handler->apache->method(),
consumer_secret => $consumer->secret,
@@ -59,23 +55,47 @@
# the user is authorizing (or denying) a consumer's request token
sub authorize {
+ my @params = qw/token callback/;
+ set no_abort => 1;
+ my %oauth_params = get_parameters(@params);
+
+ set next => $oauth_params{callback};
+
+ if ($oauth_params{token}) {
+ my $request_token = Jifty::Plugin::OAuth::Model::RequestToken->new(current_user => Jifty::CurrentUser->superuser);
+ $request_token->load_by_cols(token => $oauth_params{token});
+
+ if ($request_token->id) {
+ set consumer => $request_token->consumer;
+ set token => $oauth_params{token};
+ }
+ }
+
+ default consumer => 'Some application';
}
# the consumer is trying to trade a request token for an access token
sub access_token {
my @params = qw/consumer_key signature_method signature
- timestamp nonce token token_secret version/;
+ timestamp nonce token version/;
my %oauth_params = get_parameters(@params);
validate_signature_method($oauth_params{signature_method});
my $consumer = get_consumer($oauth_params{consumer_key});
+ # is the request token they're using still valid?
+ my $request_token = Jifty::Plugin::OAuth::Model::RequestToken->new(current_user => Jifty::CurrentUser->superuser);
+ $request_token->load_by_cols(consumer => $consumer, token => $oauth_params{token});
+ abort(401) unless $request_token->id;
+ abort(401) unless $request_token->can_trade_for_access_token;
+
# Net::OAuth::Request will die hard if it doesn't get everything it wants
my $request = eval { Net::OAuth::AccessTokenRequest->new(
- request_url => $request_token_url,
+ request_url => Jifty->web->url(path => $Jifty::Plugin::OAuth::CONFIG{access_token}),
request_method => Jifty->handler->apache->method(),
consumer_secret => $consumer->secret,
+ token_secret => $request_token->secret,
map { $_ => $oauth_params{$_} } @params
) };
@@ -85,12 +105,6 @@
# make sure the signature matches the rest of what the consumer gave us
abort(401) unless $request->verify;
- # is the request token they're using still valid?
- my $request_token = Jifty::Plugin::OAuth::Model::RequestToken->new(current_user => Jifty::CurrentUser->superuser);
- $request_token->load_by_cols(consumer => $consumer, token => $oauth_params{token}, token_secret => $oauth_params{token_secret});
- abort(401) unless $request_token->id;
- abort(401) unless $request_token->can_trade_for_access_token;
-
my $token = Jifty::Plugin::OAuth::Model::AccessToken->new(current_user => Jifty::CurrentUser->superuser);
my ($ok) = eval {
@@ -122,6 +136,7 @@
my %p;
# XXX: Check Authorization header
+ # XXX: Check WWW-Authenticate header
%p = ((map {
my $v = Jifty->handler->apache->header_in("oauth_$_");
@@ -131,7 +146,11 @@
# XXX: Check query string
$p{version} ||= '1.0';
- abort(400) if grep { !defined($p{$_}) } @_;
+
+ unless (get 'no_abort') {
+ abort(400) if grep { !defined($p{$_}) } @_
+ }
+
return %p;
}
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 Thu Oct 18 15:36:32 2007
@@ -21,7 +21,7 @@
type is 'timestamp',
filters are 'Jifty::DBI::Filter::DateTime';
- column token_secret =>
+ column secret =>
type is 'varchar';
column consumer =>
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 Thu Oct 18 15:36:32 2007
@@ -35,7 +35,7 @@
column token =>
type is 'varchar';
- column token_secret =>
+ column secret =>
type is 'varchar';
# we use these to make sure we aren't being hit with a replay attack
@@ -46,7 +46,7 @@
type is 'varchar';
};
-sub set_authorized {
+sub after_set_authorized {
my $self = shift;
$self->set_authorized_by(Jifty->web->current_user->id);
}
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 Thu Oct 18 15:36:32 2007
@@ -28,7 +28,7 @@
return if !defined($attr->{token});
# generate a secret. need not be unique, just hard to guess
- $attr->{token_secret} = generate_token();
+ $attr->{secret} = generate_token();
# default the lifetime of this token to 1 hour
$attr->{valid_until} ||= DateTime->now->add(hours => 1);
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 Thu Oct 18 15:36:32 2007
@@ -4,5 +4,115 @@
use Jifty::View::Declare -base;
+template 'oauth' => page {
+ p {
+ b { a { attr { href => "http://oauth.net/" } "OAuth" } };
+ outs " is an open protocol to allow secure authentication to users' private data."
+ }
+
+ p {
+ "This application supports OAuth. If you'd like to access the private resources of users of this site, you must first establish a Consumer Key and Consumer Secret with us. You can do so by contacting " . (Jifty->config->framework('AdminEmail')||'us') . ".";
+ }
+
+ p {
+ "Once you have a Consumer Key and Consumer Secret, you may begin letting users grant you access to our site. The relevant URLs are:"
+ }
+
+ dl {
+ dt {
+ outs "Request a Request Token";
+ dd { Jifty->web->url(path => $Jifty::Plugin::OAuth::CONFIG{request_token}) }
+ }
+ dt {
+ outs "Obtain user authorization for a Request Token";
+ dd { Jifty->web->url(path => $Jifty::Plugin::OAuth::CONFIG{authorize}) }
+ }
+ dt {
+ outs "Exchange a Request Token for an Access Token";
+ dd { Jifty->web->url(path => $Jifty::Plugin::OAuth::CONFIG{access_token}) }
+ }
+ }
+
+ p {
+ my $restful = 0;
+ for (@{ Jifty->config->framework('Plugins') }) {
+ if (defined $_->{REST}) {
+ $restful = 1;
+ last;
+ }
+ }
+
+ outs "While you have a valid access token, you may browse the site as the user normally does.";
+
+ if ($restful) {
+ outs " You may also use our REST interface. See ";
+ a {
+ attr { href => Jifty->web->url(path => '=/help') }
+ Jifty->web->url(path => '=/help')
+ }
+ }
+ }
+};
+
+template 'oauth/authorize' => page { title => 'Someone wants stuff!' }
+content {
+ show '/oauth/help';
+
+ my $authorize = Jifty->web->new_action(
+ moniker => 'authorize_request_token',
+ class => 'AuthorizeRequestToken',
+ );
+
+ Jifty->web->form->start( call => get('next') );
+
+ # if the site put the token in the request, then use it
+ # otherwise, prompt the user for it
+ my %args;
+ my $token = get 'token';
+ if ($token) {
+ $args{token} = $token;
+ }
+ else {
+ $authorize->form_field('token')->render;
+ }
+
+ $authorize->button(
+ label => 'Allow',
+ arguments => { %args, authorize => 'allow' },
+ );
+
+ $authorize->button(
+ label => 'Deny',
+ arguments => { %args, authorize => 'deny' },
+ );
+
+ Jifty->web->form->end();
+};
+
+private template 'oauth/help' => sub {
+ div {
+ p {
+ show '/oauth/consumer';
+ outs ' is trying to access some of your data on this site. If you trust this application, you may grant it access. Note that access is read-only and will expire in one hour.';
+ }
+ p {
+ "If you're at all uncomfortable with the idea of someone rifling through your things, click Deny."
+ }
+ }
+};
+
+private template 'oauth/consumer' => sub {
+ my $consumer = get 'consumer' || 'Some application';
+
+ span {
+ outs ref($consumer) ? $consumer->name : $consumer;
+ if (ref($consumer) && $consumer->url) {
+ outs ' (';
+ a { attr { $consumer->url } $consumer->url };
+ outs ')';
+ }
+ }
+};
+
1;
More information about the Jifty-commit
mailing list