[Jifty-commit] r3603 - in jifty/trunk: . lib/Jifty/Plugin/Authentication/Facebook lib/Jifty/Plugin/Authentication/Facebook/Action lib/Jifty/Plugin/Authentication/Facebook/Mixin lib/Jifty/Plugin/Authentication/Facebook/Mixin/Model

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Tue Jul 3 03:22:39 EDT 2007


Author: trs
Date: Tue Jul  3 03:22:37 2007
New Revision: 3603

Added:
   jifty/trunk/lib/Jifty/Plugin/Authentication/Facebook/
   jifty/trunk/lib/Jifty/Plugin/Authentication/Facebook.pm
   jifty/trunk/lib/Jifty/Plugin/Authentication/Facebook/Action/
   jifty/trunk/lib/Jifty/Plugin/Authentication/Facebook/Action/LoginFacebookUser.pm
   jifty/trunk/lib/Jifty/Plugin/Authentication/Facebook/Dispatcher.pm
   jifty/trunk/lib/Jifty/Plugin/Authentication/Facebook/Mixin/
   jifty/trunk/lib/Jifty/Plugin/Authentication/Facebook/Mixin/Model/
   jifty/trunk/lib/Jifty/Plugin/Authentication/Facebook/Mixin/Model/User.pm
   jifty/trunk/lib/Jifty/Plugin/Authentication/Facebook/View.pm
Modified:
   jifty/trunk/   (props changed)
   jifty/trunk/Makefile.PL

Log:
 r24976 at zot:  tom | 2007-07-03 02:49:39 -0400
 Basic Facebook auth plugin


Modified: jifty/trunk/Makefile.PL
==============================================================================
--- jifty/trunk/Makefile.PL	(original)
+++ jifty/trunk/Makefile.PL	Tue Jul  3 03:22:37 2007
@@ -134,6 +134,10 @@
         recommends('Cache::FileCache'),
         recommends('LWPx::ParanoidAgent'),
     ],
+    'Facebook Login Plugin' => [
+        -default => 0,
+        recommends('WWW::Facebook::API' => '0.3.6'),
+    ],
     'Jifty console' => [
         -default => 0,
         recommends('Devel::EvalContext')

Added: jifty/trunk/lib/Jifty/Plugin/Authentication/Facebook.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/lib/Jifty/Plugin/Authentication/Facebook.pm	Tue Jul  3 03:22:37 2007
@@ -0,0 +1,66 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::Authentication::Facebook;
+use base qw/Jifty::Plugin/;
+
+use WWW::Facebook::API;
+
+=head1 NAME
+
+Jifty::Plugin::Authentication::Facebook
+
+=head1 SYNOPSIS
+
+In your jifty config.yml under the C<framework> section:
+
+    Plugins:
+        - Authentication::Facebook:
+            api_key: xxx
+            secret: xxx
+
+You may set any options which the C<new> method of
+L<WWW::Facebook::API> understands.
+
+=head2 DESCRIPTION
+
+Provides Facebook authentication for your Jifty application.
+It adds the columns C<facebook_name>, C<facebook_uid>, C<facebook_session>,
+and C<facebook_session_expires> to your C<User> model class.
+
+=cut
+
+our %CONFIG = ( );
+
+=head2 init
+
+=cut
+
+sub init {
+    my $self = shift;
+    %CONFIG  = @_;
+}
+
+=head2 api
+
+Generates a new L<WWW::Facebook::API> for the current user
+
+=cut
+
+sub api {
+    my $self = shift;
+    my $api  = WWW::Facebook::API->new( %CONFIG );
+    
+    if ( Jifty->web->current_user->id ) {
+        my $user = Jifty->web->current_user->user_object;
+        $api->session(
+            uid     => $user->facebook_uid,
+            key     => $user->facebook_session,
+            expires => $user->facebook_session_expires
+        ) if $user->facebook_uid;
+    }
+
+    return $api;
+}
+
+1;

Added: jifty/trunk/lib/Jifty/Plugin/Authentication/Facebook/Action/LoginFacebookUser.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/lib/Jifty/Plugin/Authentication/Facebook/Action/LoginFacebookUser.pm	Tue Jul  3 03:22:37 2007
@@ -0,0 +1,106 @@
+use warnings;
+use strict;
+
+=head1 NAME
+
+Jifty::Plugin::Authentication::Facebook::Action::LoginFacebookUser;
+
+=cut
+
+package Jifty::Plugin::Authentication::Facebook::Action::LoginFacebookUser;
+use base qw/Jifty::Action/;
+
+=head1 ARGUMENTS
+
+=head2 auth_token
+
+=cut
+
+use Jifty::Param::Schema;
+use Jifty::Action schema {
+    param auth_token =>
+        type is 'text',
+        is mandatory;
+};
+
+=head1 METHODS
+
+=head2 take_action
+
+Get the session key using the Facebook API.  Check for existing user.
+If none, autocreate.  Login user.
+
+=cut
+
+sub take_action {
+    my $self    = shift;
+    my ($plugin)  = Jifty->find_plugin('Jifty::Plugin::Authentication::Facebook');
+    my $api       = $plugin->api;
+
+    # Get the session
+    $api->auth->get_session( $self->argument_value('auth_token') );
+
+    # Load up the user
+    my $current_user = Jifty->app_class('CurrentUser');
+    my $user = $current_user->new( facebook_uid => $api->session_uid );
+
+    # Autocreate the user if necessary
+    if ( not $user->id ) {
+        my $action = Jifty->web->new_action(
+            class           => 'CreateUser',
+            current_user    => $current_user->superuser,
+            arguments       => {
+                facebook_uid     => $api->session_uid,
+                facebook_session => $api->session_key,
+                facebook_session_expires => $api->session_expires
+            }
+        );
+        $action->run;
+
+        if ( not $action->result->success ) {
+            # Should this be less "friendly"?
+            $self->result->error(_("Sorry, something weird happened (we couldn't create a user for you).  Try again later."));
+            return;
+        }
+
+        $user = $current_user->new( facebook_uid => $api->session_uid );
+    }
+
+    my $name = $api->users->get_info(
+        uids    => $api->session_uid,
+        fields  => 'name'
+    )->[0]{'name'};
+
+    my $u = $user->user_object;
+
+    # Always check name
+    $u->__set( column => 'facebook_name', value => $name )
+        if not defined $u->facebook_name or $u->facebook_name ne $name;
+
+    # Update, just in case
+    if ( $u->__value('facebook_session') ne $api->session_key ) {
+        $u->__set( column => 'facebook_session', value => $api->session_key );
+        $u->__set( column => 'facebook_session_expires', value => $api->session_expires );
+    }
+
+    # Login!
+    Jifty->web->current_user( $user );
+    Jifty->web->session->expires( (not $api->session_expires) ? '+1y' : undef );
+    Jifty->web->session->set_cookie;
+
+    # Success!
+    $self->report_success;
+
+    return 1;
+}
+
+=head2 report_success
+
+=cut
+
+sub report_success {
+    my $self = shift;
+    $self->result->message(_("Hi %1!", Jifty->web->current_user->user_object->facebook_name ));
+}
+
+1;

Added: jifty/trunk/lib/Jifty/Plugin/Authentication/Facebook/Dispatcher.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/lib/Jifty/Plugin/Authentication/Facebook/Dispatcher.pm	Tue Jul  3 03:22:37 2007
@@ -0,0 +1,50 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::Authentication::Facebook::Dispatcher;
+use Jifty::Dispatcher -base;
+
+=head1 NAME
+
+Jifty::Plugin::Authentication::Facebook::Dispatcher
+
+=head1 DESCRIPTION
+
+All the dispatcher rules jifty needs to support L<Jifty::Authentication::Facebook>
+
+=head1 RULES
+
+=head2 before '/facebook/callback'
+
+=cut
+
+before '/facebook/callback' => run {
+    Jifty->web->request->add_action(
+        moniker   => 'facebooklogin',
+        class     => 'LoginFacebookUser',
+        arguments => {
+            auth_token => get('auth_token'),
+        }
+    );
+    if ( Jifty->web->request->continuation ) {
+        Jifty->web->request->continuation->call;
+    }
+    else {
+        redirect '/';
+    }
+};
+
+=head2 before '/facebook/logout'
+
+=cut
+
+before '/facebook/logout' => run {
+    if ( Jifty->web->current_user->id ) {
+        Jifty->web->current_user( undef );
+        my ($plugin) = Jifty->find_plugin('Jifty::Plugin::Authentication::Facebook');
+        $plugin->api->auth->logout;
+    };
+    redirect '/';
+};
+
+1;

Added: jifty/trunk/lib/Jifty/Plugin/Authentication/Facebook/Mixin/Model/User.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/lib/Jifty/Plugin/Authentication/Facebook/Mixin/Model/User.pm	Tue Jul  3 03:22:37 2007
@@ -0,0 +1,39 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::Authentication::Facebook::Mixin::Model::User;
+use Jifty::DBI::Schema;
+use base 'Jifty::DBI::Record::Plugin';
+
+use Jifty::Plugin::Authentication::Facebook::Record schema {
+
+    column facebook_name => 
+        type is 'text';
+
+    column facebook_uid => 
+        type is 'int',
+        is immutable,
+        is distinct;
+
+    column facebook_session =>
+        type is 'text';
+
+    column facebook_session_expires =>
+        type is 'int';
+
+};
+
+=head2 set_facebook_uid INT
+
+Sets the user's Facebook ID
+
+=cut
+
+sub set_facebook_uid {
+    my $self = shift;
+    my $id   = shift;
+    $self->_set( column => 'facebook_uid', value => $id );
+}
+
+1;
+

Added: jifty/trunk/lib/Jifty/Plugin/Authentication/Facebook/View.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/lib/Jifty/Plugin/Authentication/Facebook/View.pm	Tue Jul  3 03:22:37 2007
@@ -0,0 +1,33 @@
+use warnings;
+use strict;
+package Jifty::Plugin::Authentication::Facebook::View;
+
+use Jifty::View::Declare -base;
+
+=head1 NAME
+
+Jifty::Plugin::Authentication::Facebook::View
+
+=head1 DESCRIPTION
+
+Provides the Facebook login regions for L<Jifty::Plugin::Authentication::Facebook>
+
+=cut
+
+template 'facebook/login' => sub {
+    my ($plugin) = Jifty->find_plugin('Jifty::Plugin::Authentication::Facebook');
+    my $next     = '/facebook/callback';
+
+    if ( Jifty->web->request->continuation ) {
+        $next .= '?J:C=' . Jifty->web->request->continuation->id;
+    }
+
+    div {{ id is 'facebook_login' };
+        span { _("Login to Facebook now to get started!") };
+        a {{ href is $plugin->api->get_login_url( next => $next ) };
+            img {{ src is 'http://static.ak.facebook.com/images/devsite/facebook_login.gif', border is '0' }};
+        };
+    };
+};
+
+1;


More information about the Jifty-commit mailing list