[Jifty-commit] r3248 - in jifty/trunk/lib/Jifty/Plugin: . OpenID OpenID/Model

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Fri May 18 14:33:20 EDT 2007


Author: gugod
Date: Fri May 18 14:33:19 2007
New Revision: 3248

Added:
   jifty/trunk/lib/Jifty/Plugin/OpenID/
   jifty/trunk/lib/Jifty/Plugin/OpenID.pm
   jifty/trunk/lib/Jifty/Plugin/OpenID/Action/
   jifty/trunk/lib/Jifty/Plugin/OpenID/Action/AuthenticateOpenID.pm
   jifty/trunk/lib/Jifty/Plugin/OpenID/Action/CreateOpenIDUser.pm
   jifty/trunk/lib/Jifty/Plugin/OpenID/Action/VerifyOpenID.pm
   jifty/trunk/lib/Jifty/Plugin/OpenID/Dispatcher.pm
   jifty/trunk/lib/Jifty/Plugin/OpenID/Model/

Log:
This is the OpenID plugin code.
Setting up your app to use OpenID isn't as easy as we thought
it to be. Will need a receipe to teach people how to cook it.


Added: jifty/trunk/lib/Jifty/Plugin/OpenID.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/lib/Jifty/Plugin/OpenID.pm	Fri May 18 14:33:19 2007
@@ -0,0 +1,7 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::OpenID;
+use base qw/Jifty::Plugin/;
+
+1;

Added: jifty/trunk/lib/Jifty/Plugin/OpenID/Action/AuthenticateOpenID.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/lib/Jifty/Plugin/OpenID/Action/AuthenticateOpenID.pm	Fri May 18 14:33:19 2007
@@ -0,0 +1,80 @@
+use warnings;
+use strict;
+
+=head1 NAME
+
+Jifty::Plugin::OpenID::Action::AuthenticateOpenID;
+
+=cut
+
+package Jifty::Plugin::OpenID::Action::AuthenticateOpenID;
+
+use base qw/Jifty::Action/;
+
+use LWPx::ParanoidAgent;
+use Net::OpenID::Consumer;
+use Cache::FileCache;
+
+=head2 arguments
+
+Return the OpenID URL field
+
+=cut
+
+use Jifty::Param::Schema;
+use Jifty::Action schema {
+    param 'openid' =>
+        label is _('OpenID URL'),
+        is mandatory,
+        hints is 'For example: you.livejournal.com';
+
+    param 'return_to' =>
+        default is '/openid/verify';
+};
+
+=head2 take_action
+
+Creates local user if non-existant and redirects to OpenID auth URL
+
+=cut
+
+sub take_action {
+    my $self   = shift;
+    my $openid = $self->argument_value('openid');
+    my $path   = $self->argument_value('return_to');
+
+    my $baseurl = Jifty->web->url;
+    my $csr = Net::OpenID::Consumer->new(
+        ua    => LWPx::ParanoidAgent->new,
+        cache => Cache::FileCache->new,
+        args  => scalar Jifty->handler->cgi->Vars,
+        consumer_secret => Jifty->config->app('OpenIDSecret'),
+        required_root => $baseurl
+    );
+
+    my $claimed_id = $csr->claimed_identity( $openid );
+
+    if ( not defined $claimed_id ) {
+        $self->result->error(_("Invalid OpenID URL.  Please check to make sure it is correct.  (@{[$csr->err]})"));
+        return;
+    }
+
+    $openid = $claimed_id->claimed_url;
+
+    my $return_to = Jifty->web->url( path => $path );
+    if(Jifty->web->request->continuation) {
+        $return_to .= ($return_to =~ /\?/) ? '&' : '?';
+        $return_to .= "J:C=" . Jifty->web->request->continuation->id;
+    }
+
+    my $check_url = $claimed_id->check_url( 
+                        return_to  => $return_to,
+                        trust_root => $baseurl,
+                        delayed_return => 1
+                    );
+
+    Jifty->web->_redirect( $check_url . '&openid.sreg.optional=nickname' );
+    return 1; # should never get here
+}
+
+1;

Added: jifty/trunk/lib/Jifty/Plugin/OpenID/Action/CreateOpenIDUser.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/lib/Jifty/Plugin/OpenID/Action/CreateOpenIDUser.pm	Fri May 18 14:33:19 2007
@@ -0,0 +1,102 @@
+use strict;
+use warnings;
+
+=head1 NAME
+
+Jifty::Plugin::OpenID::Action::CreateOpenIDUser
+
+=cut
+
+package Jifty::Plugin::OpenID::Action::CreateOpenIDUser;
+use base qw/Jifty::Action::Record/;
+
+sub record_class {
+    Jifty->app_class("Model", "User")
+}
+
+
+=head2 arguments
+
+The fields for C<CreateOpenIDUser> are:
+
+=over 4
+
+=item name: a nickname
+
+=back
+
+=cut
+
+sub arguments {
+    my $self = shift;
+    my $args = $self->SUPER::arguments;
+
+    my %fields = (
+        name => 1,
+    );
+
+    for ( keys %$args ){
+        delete $args->{$_} unless $fields{$_};
+    }
+
+    $args->{'name'}{'ajax_validates'} = 1;
+    return $args;
+}
+
+
+=head2 take_action
+
+=cut
+
+sub take_action {
+    my $self = shift;
+
+    my $openid = Jifty->web->session->get('openid');
+
+    if ( not $openid ) {
+        # Should never get here unless someone's trying weird things
+        $self->result->error("Invalid verification result: '$openid'");
+        return;
+    }
+
+    my $user = Jifty->app_class("Model", "User")->new(current_user => Jifty->app_class("CurrentUser")->superuser );
+
+    $user->load_by_cols( openid => $openid );
+
+    if ( $user->id ) {
+        $self->result->error( "That OpenID already has an account.  Something's gone wrong." );
+        return;
+    }
+
+    $user->create( openid => $openid, name => $self->argument_value('name') );
+
+    if ( not $user->id ) {
+        $self->result->error( "Something bad happened and we couldn't log you in.  Please try again later." );
+        return;
+    }
+
+    my $current_user = Jifty->app_class("CurrentUser")->new( openid => $openid );
+
+    # Actually do the signin thing.
+    Jifty->web->current_user($current_user);
+    Jifty->web->session->expires( undef );
+    Jifty->web->session->set_cookie;
+
+    $self->report_success if not $self->result->failure;
+    Jifty->web->session->remove('openid');
+
+    return 1;
+}
+
+=head2 report_success
+
+=cut
+
+sub report_success {
+    my $self = shift;
+    # Your success message here
+    $self->result->message( _("Welcome, ") . Jifty->web->current_user->user_object->name . "." );
+}
+
+1;
+

Added: jifty/trunk/lib/Jifty/Plugin/OpenID/Action/VerifyOpenID.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/lib/Jifty/Plugin/OpenID/Action/VerifyOpenID.pm	Fri May 18 14:33:19 2007
@@ -0,0 +1,73 @@
+use warnings;
+use strict;
+
+=head1 NAME
+
+Jifty::Plugin::OpenID::Action::VerifyOpenID;
+
+=cut
+
+package Jifty::Plugin::OpenID::Action::VerifyOpenID;
+use base qw/Jifty::Action/;
+
+use Net::OpenID::Consumer;
+use Cache::FileCache;
+use LWPx::ParanoidAgent;
+
+=head2 arguments
+
+No args
+
+=cut
+
+sub arguments { return ( {} ) }
+
+=head2 take_action
+
+Check the result of the login.  If it's good, load the user
+and log them in.  Otherwise, throw an error.
+
+=cut
+
+sub take_action {
+    my $self = shift;
+
+# XXX HACK: some OpenID servers (LJ and myopenid.com included) don't seem
+# to properly escape plus signs (+) in openid.sig when returning the user
+# back to us.  We need to convert the pluses back from spaces to pluses again.
+    my $sig = Jifty->handler->cgi->param('openid.sig');
+    $sig =~ s/ /+/g;
+    Jifty->handler->cgi->param( 'openid.sig' => $sig );
+
+    my $csr = Net::OpenID::Consumer->new(
+        ua              => LWPx::ParanoidAgent->new,
+        cache           => Cache::FileCache->new,
+        args            => scalar Jifty->handler->cgi->Vars,
+        consumer_secret => Jifty->config->app('OpenIDSecret')
+    );
+
+    if ( my $setup = $csr->user_setup_url ) {
+        Jifty->web->_redirect($setup);
+    }
+    elsif ( $csr->user_cancel ) {
+        $self->result->error(
+            _(  'OpenID verification failed.  It looks like you cancelled the OpenID verification request.'
+            )
+        );
+        return;
+    }
+
+    my $ident = $csr->verified_identity;
+
+    if ( not defined $ident ) {
+        $self->result->error( _('OpenID verification failed: ') . $csr->err );
+        return;
+    }
+
+    Jifty->log( "identified as: " . $ident->url );
+    $self->result->content( openid => $ident->url );
+
+    return 1;
+}
+
+1;

Added: jifty/trunk/lib/Jifty/Plugin/OpenID/Dispatcher.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/lib/Jifty/Plugin/OpenID/Dispatcher.pm	Fri May 18 14:33:19 2007
@@ -0,0 +1,88 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::OpenID::Dispatcher;
+use Jifty::Dispatcher -base;
+
+before qr'^/(?:openid/link)' => run {
+    tangent('/openid/login') unless (Jifty->web->current_user->id)
+};
+
+before qr'^/openid/verify' => run {
+    Jifty->web->request->add_action(
+        class   => 'VerifyOpenID',
+        moniker => 'verifyopenid'
+    );
+};
+
+on 'openid/verify_and_link' => run {
+    my $result = Jifty->web->response->result('verifyopenid');
+    my $user   = Jifty->web->current_user;
+    if ( defined $result and $result->success and $user->id ) {
+        my $openid = $result->content('openid');
+        my ( $ret, $msg ) = $user->user_object->validate_openid( $openid );
+
+        if ( not $ret ) {
+            $result->error(_("It looks like someone is already using that OpenID."));
+            redirect '/openid/link';
+        }
+        else {
+            $user->user_object->link_to_openid( $openid );
+            $result->message(_("The OpenID '$openid' has been linked to your account."));
+        }
+    }
+    redirect '/';
+};
+
+on 'openid/verify_and_login' => run {
+    my $result = Jifty->web->response->result('verifyopenid');
+
+    if ( defined $result and $result->success ) {
+        my $openid = $result->content('openid');
+        my $user = Jifty->app_class('CurrentUser')->new( openid => $openid );
+        Jifty->log->info("User Class: $user. OpenID: $openid");
+
+        if ( $user->id ) {
+            # Set up our login message
+            $result->message( _("Welcome back, ") . $user->user_object->name . "." );
+
+            # Actually do the signin thing.
+            Jifty->web->current_user($user);
+            Jifty->web->session->expires( undef );
+            Jifty->web->session->set_cookie;
+
+            if(Jifty->web->request->continuation) {
+                Jifty->web->request->continuation->call;
+            } else {
+                redirect '/';
+            }
+        }
+        else {
+            # User needs to create account still
+            Jifty->web->session->set( openid => $openid );
+            Jifty->log->info("got openid: $openid");
+            my $nick = get('openid.sreg.nickname');
+            if ( $nick ) {
+                redirect( Jifty::Web::Form::Clickable->new( url => '/openid/create', parameters => { nickname => $nick, openid => $openid } ));
+            }
+            else {
+                redirect( Jifty::Web::Form::Clickable->new( url => '/openid/create' ) );
+            }
+        }
+    }
+    else {
+        redirect '/openid/login';
+    }
+};
+
+on 'openid/create' => run {
+    if ( not Jifty->web->session->get('openid') ) {
+        redirect '/';
+    }
+
+    set action => Jifty->web->new_action( class => 'CreateOpenIDUser', parameters => { openid => Jifty->web->session->get("openid") } );
+    set 'next' => Jifty->web->request->continuation ||
+                  Jifty::Continuation->new( request => Jifty::Request->new( path => "/" ) );
+};
+
+1;


More information about the Jifty-commit mailing list