added facebook auth
This commit is contained in:
parent
4da8638444
commit
61bd01b5f3
10 changed files with 415 additions and 1 deletions
|
|
@ -1,4 +1,5 @@
|
|||
8.0.0
|
||||
- Replaced the existing caching mechanism with memcached, which results in a 400% improvement to cache speed. See migration.txt for API changes and gotcha.txt for prereq changes.
|
||||
- Added "hot sessions" so sessions interact with the database less.
|
||||
- Added Facebook Auth and FacebookLogin macro.
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ save you many hours of grief.
|
|||
* WebGUI now requires the following modules
|
||||
- Moose
|
||||
- CHI
|
||||
- Facebook::Graph
|
||||
|
||||
7.9.8
|
||||
--------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@
|
|||
# List the authentication plug-ins you wish to be available on
|
||||
# this site.
|
||||
|
||||
"authMethods" : [ "LDAP", "WebGUI" ],
|
||||
"authMethods" : [ "LDAP", "WebGUI", "Twitter", "Facebook"],
|
||||
|
||||
# List the merchant gateways you have installed and wish to be
|
||||
# available on this site.
|
||||
|
|
@ -821,6 +821,7 @@
|
|||
"EditableToggle" : "EditableToggle",
|
||||
"e" : "e_companyEmail",
|
||||
"Extras" : "Extras",
|
||||
"FacebookLogin" : "FacebookLogin",
|
||||
"FetchMimeType" : "FetchMimeType",
|
||||
"FilePump" : "FilePump",
|
||||
"FileUrl" : "FileUrl",
|
||||
|
|
|
|||
295
lib/WebGUI/Auth/Facebook.pm
Normal file
295
lib/WebGUI/Auth/Facebook.pm
Normal file
|
|
@ -0,0 +1,295 @@
|
|||
package WebGUI::Auth::Facebook;
|
||||
|
||||
=head1 LEGAL
|
||||
|
||||
-------------------------------------------------------------------
|
||||
WebGUI is Copyright 2001-2010 Plain Black Corporation.
|
||||
-------------------------------------------------------------------
|
||||
Please read the legal notices (docs/legal.txt) and the license
|
||||
(docs/license.txt) that came with this distribution before using
|
||||
this software.
|
||||
-------------------------------------------------------------------
|
||||
http://www.plainblack.com info@plainblack.com
|
||||
-------------------------------------------------------------------
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use base 'WebGUI::Auth';
|
||||
use Facebook::Graph;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
WebGUI::Auth::Facebook -- Facebook auth for WebGUI
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Allow Facebook users to authenticate to WebGUI
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
These methods are available from this class:
|
||||
|
||||
=cut
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 new ( ... )
|
||||
|
||||
Create a new object
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my $self = shift->SUPER::new(@_);
|
||||
return bless $self, __PACKAGE__; # Auth requires rebless
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 createFacebookUser ( fbuser )
|
||||
|
||||
my $user = $self->createFacebookUser( $fb->fetch('me') );
|
||||
|
||||
Create a new Facebook::Graph user.
|
||||
|
||||
=cut
|
||||
|
||||
sub createFacebookUser {
|
||||
my ( $self, $fbuser ) = @_;
|
||||
my $user = WebGUI::User->create( $self->session );
|
||||
$user->username( $fbuser->{name} );
|
||||
$user->profileField('email', $fbuser->{email});
|
||||
$user->profileField('firstName', $fbuser->{first_name});
|
||||
$user->profileField('lastName', $fbuser->{last_name});
|
||||
$self->saveParams( $user->userId, $self->authMethod, {
|
||||
"facebookUserId" => $fbuser->{id},
|
||||
} );
|
||||
return $user;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 editUserSettingsForm ( )
|
||||
|
||||
Return the form to edit the settings of this Auth module
|
||||
|
||||
=cut
|
||||
|
||||
sub editUserSettingsForm {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my ( $setting ) = $session->quick(qw( setting ));
|
||||
my $i18n = WebGUI::International->new( $session, 'Auth_Facebook' );
|
||||
|
||||
my $f = WebGUI::HTMLForm->new( $session );
|
||||
|
||||
$f->yesNo(
|
||||
name => 'facebookAuthEnabled',
|
||||
value => $setting->get( 'facebookAuthEnabled' ),
|
||||
label => $i18n->get('enabled'),
|
||||
hoverHelp => $i18n->get('enabled help'),
|
||||
);
|
||||
|
||||
$f->text(
|
||||
name => 'facebookAuthAppId',
|
||||
value => $setting->get( 'facebookAuthAppId' ),
|
||||
label => $i18n->get('app id'),
|
||||
hoverHelp => $i18n->get('app id help'),
|
||||
subtext => $i18n->get('get app id'),
|
||||
);
|
||||
|
||||
$f->text(
|
||||
name => 'facebookAuthSecret',
|
||||
value => $setting->get( 'facebookAuthSecret' ),
|
||||
label => $i18n->get('secret'),
|
||||
hoverHelp => $i18n->get('secret help'),
|
||||
);
|
||||
|
||||
$f->template(
|
||||
name => 'facebookAuthTemplateIdChooseUsername',
|
||||
value => $setting->get( 'facebookAuthTemplateIdChooseUsername' ),
|
||||
label => $i18n->get('choose username template'),
|
||||
hoverHelp => $i18n->get('choose username template help'),
|
||||
namespace => 'Auth/Facebook/ChooseUsername',
|
||||
);
|
||||
|
||||
return $f->printRowsOnly;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 editUserSettingsFormSave ( )
|
||||
|
||||
Process the form for this Auth module's settings
|
||||
|
||||
=cut
|
||||
|
||||
sub editUserSettingsFormSave {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my ( $form, $setting ) = $session->quick(qw( form setting ));
|
||||
|
||||
my @fields = qw(
|
||||
facebookAuthEnabled facebookAuthAppId facebookAuthSecret
|
||||
facebookAuthTemplateIdChooseUsername
|
||||
);
|
||||
for my $field ( @fields ) {
|
||||
$setting->set( $field, $form->get( $field ) );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getTemplateChooseUsername ( )
|
||||
|
||||
Get the template to choose a username
|
||||
|
||||
=cut
|
||||
|
||||
sub getTemplateChooseUsername {
|
||||
my ( $self ) = @_;
|
||||
my $templateId = $self->session->setting->get('facebookAuthTemplateIdChooseUsername');
|
||||
return WebGUI::Asset->newById( $self->session, $templateId );
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getFacebook ( )
|
||||
|
||||
Get the Facebook::Graph object with the appropriate keys
|
||||
|
||||
=cut
|
||||
|
||||
sub getFacebook {
|
||||
my ( $self ) = @_;
|
||||
my ( $url, $scratch, $setting ) = $self->session->quick( qw( url scratch setting ) );
|
||||
if ( !$self->{_fb} ) {
|
||||
my $fb = Facebook::Graph->new(
|
||||
app_id => $setting->get( 'facebookAuthAppId' ),
|
||||
secret => $setting->get( 'facebookAuthSecret' ),
|
||||
postback => $url->getSiteURL . $url->page('op=auth&authType=Facebook&method=callback'),
|
||||
);
|
||||
if ($scratch->get('facebookAuthAccessToken')) {
|
||||
$fb->access_token($scratch->get('facebookAuthAccessToken'));
|
||||
}
|
||||
$self->{_fb} = $fb;
|
||||
}
|
||||
return $self->{_fb};
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 www_login ( )
|
||||
|
||||
Begin the login procedure
|
||||
|
||||
=cut
|
||||
|
||||
sub www_login {
|
||||
my ( $self ) = @_;
|
||||
my $session = $self->session;
|
||||
my ( $url, $scratch, $setting ) = $session->quick( qw( url scratch setting ) );
|
||||
|
||||
my $auth_url = $self->getFacebook
|
||||
->authorize
|
||||
->extend_permissions(qw(email))
|
||||
->uri_as_string;
|
||||
|
||||
$session->http->setRedirect($auth_url);
|
||||
return "redirect";
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 www_callback ( )
|
||||
|
||||
Callback from the Facebook authentication. Try to log the user in, creating a
|
||||
new user account if necessary.
|
||||
|
||||
If the username is taken, allow the user to choose a new one.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_callback {
|
||||
my ( $self ) = @_;
|
||||
my $session = $self->session;
|
||||
my ( $form, $scratch, $db, $setting ) = $session->quick(qw( form scratch db setting ));
|
||||
|
||||
# handle facebook stuff
|
||||
my $fb = $self->getFacebook;
|
||||
$fb->request_access_token($form->get('code'));
|
||||
$scratch->set('facebookAuthAccessToken', $fb->access_token);
|
||||
my $fbuser = $fb->fetch('me');
|
||||
|
||||
|
||||
### Log the user in
|
||||
# Find their FB user ID
|
||||
my $userId = $db->quickScalar(
|
||||
"SELECT userId FROM authentication WHERE authMethod = ? AND fieldName = ? AND fieldData = ?",
|
||||
[ "Facebook", "facebookUserId", $fbuser->{id} ],
|
||||
);
|
||||
|
||||
# Returning user
|
||||
if ( $userId ) {
|
||||
my $user = WebGUI::User->new( $session, $userId );
|
||||
$self->user( $user );
|
||||
return $self->login;
|
||||
}
|
||||
# Otherwise see if their screen name exists and create a user
|
||||
elsif ( !WebGUI::User->newByUsername( $session, $fbuser->{name}) ) {
|
||||
my $user = $self->createFacebookUser( $fbuser );
|
||||
$self->user( $user );
|
||||
return $self->login;
|
||||
}
|
||||
|
||||
# Otherwise ask them for a new username to use
|
||||
my $i18n = WebGUI::International->new( $session, 'Auth_Facebook' );
|
||||
my $tmpl = $self->getTemplateChooseUsername;
|
||||
my $var = {
|
||||
message => sprintf( $i18n->get("username taken"), $fbuser->{name} ),
|
||||
};
|
||||
|
||||
return $tmpl->process( $var );
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 www_setUsername ( )
|
||||
|
||||
Set the username for a fb user. Only used as part of the initial fb
|
||||
registration.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_setUsername {
|
||||
my ( $self ) = @_;
|
||||
my $session = $self->session;
|
||||
my ( $form, $scratch, $db ) = $session->quick(qw( form scratch db ));
|
||||
my $i18n = WebGUI::International->new( $session, 'Auth_Facebook' );
|
||||
|
||||
# Don't allow just anybody to set a username
|
||||
my $fb = $self->getFacebook;
|
||||
return if $fb->access_token eq '';
|
||||
|
||||
my $fbuser = $fb->fetch('me');
|
||||
$fbuser->{name} = $form->get('newUsername');
|
||||
|
||||
if ( !WebGUI::User->newByUsername( $session, $fbuser->{name} ) ) {
|
||||
my $user = $self->createFacebookUser( $fbuser );
|
||||
$self->user( $user );
|
||||
return $self->login;
|
||||
}
|
||||
|
||||
# Username is again taken! Noooooo!
|
||||
my $tmpl = $self->getTemplateChooseUsername;
|
||||
my $var = {
|
||||
message => sprintf( $i18n->get("username taken"), $fbuser->{name} ),
|
||||
};
|
||||
|
||||
return $tmpl->process( $var );
|
||||
}
|
||||
|
||||
1;
|
||||
37
lib/WebGUI/Macro/FacebookLogin.pm
Normal file
37
lib/WebGUI/Macro/FacebookLogin.pm
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
package WebGUI::Macro::FacebookLogin;
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2010 Plain Black Corporation.
|
||||
#-------------------------------------------------------------------
|
||||
# Please read the legal notices (docs/legal.txt) and the license
|
||||
# (docs/license.txt) that came with this distribution before using
|
||||
# this software.
|
||||
#-------------------------------------------------------------------
|
||||
# http://www.plainblack.com info@plainblack.com
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
use strict;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Package WebGUI::Macro::FacebookLogin
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Works with the Facebook Auth plugin to allow users to log in using facebook.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
sub process {
|
||||
my $session = shift;
|
||||
my $url = $session->url;
|
||||
return sprintf '<a href="%s"><img src="%s" alt="login with Facebook" /></a>',
|
||||
$url->page('op=auth;authType=Facebook;method=login'),
|
||||
$url->extras('macro/FacebookLogin/login-button.png');
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
#vim:ft=perl
|
||||
74
lib/WebGUI/i18n/English/Auth_Facebook.pm
Normal file
74
lib/WebGUI/i18n/English/Auth_Facebook.pm
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
package WebGUI::i18n::English::Auth_Facebook;
|
||||
|
||||
use strict;
|
||||
|
||||
our $I18N = {
|
||||
'enabled' => {
|
||||
message => q{Enabled},
|
||||
lastUpdated => 0,
|
||||
context => q{Label for auth setting field},
|
||||
},
|
||||
|
||||
'enabled help' => {
|
||||
message => q{Enabled Facebook-based login},
|
||||
lastUpdated => 0,
|
||||
context => q{Hover help for auth setting field},
|
||||
},
|
||||
|
||||
'get app id' => {
|
||||
message => q{Get a Facebook App Id from <a href="http://apps.facebook.com/developer">http://apps.facebook.com/developer</a>},
|
||||
lastUpdated => 0,
|
||||
context => q{Link to get a Facebook App Id},
|
||||
},
|
||||
|
||||
'app id' => {
|
||||
message => q{Application Id},
|
||||
lastUpdated => 0,
|
||||
context => q{Label for auth setting field},
|
||||
},
|
||||
|
||||
'app id help' => {
|
||||
message => q{The Application ID from your Facebook application settings},
|
||||
lastUpdated => 0,
|
||||
context => q{Hover help for auth setting field},
|
||||
},
|
||||
|
||||
'secret' => {
|
||||
message => q{Application Secret},
|
||||
lastUpdated => 0,
|
||||
context => q{Label for auth setting field},
|
||||
},
|
||||
|
||||
'secret help' => {
|
||||
message => q{The Facebook Application Secret from your application settings},
|
||||
lastUpdated => 0,
|
||||
context => q{Hover help for auth setting field},
|
||||
},
|
||||
|
||||
'choose username title' => {
|
||||
message => q{Choose a Username},
|
||||
lastUpdated => 0,
|
||||
context => q{Title for screen to choose a username},
|
||||
},
|
||||
|
||||
'username taken' => {
|
||||
message => q{That username "%s" is taken. Please choose a new username.},
|
||||
lastUpdated => 0,
|
||||
context => q{An error message for the choose a username screen},
|
||||
},
|
||||
|
||||
'choose username template' => {
|
||||
message => q{Choose Username Template},
|
||||
lastUpdated => 0,
|
||||
context => q{Label for auth setting field},
|
||||
},
|
||||
|
||||
'choose username template help' => {
|
||||
message => q{The template to choose a username if the user's screen name already exists},
|
||||
lastUpdated => 0,
|
||||
context => q{Hover help for auth setting field},
|
||||
},
|
||||
};
|
||||
|
||||
1;
|
||||
#vim:ft=perl
|
||||
|
|
@ -157,6 +157,7 @@ checkModule('HTTP::Exception', );
|
|||
checkModule('Net::Twitter', "3.13006" );
|
||||
checkModule('Number::Format', );
|
||||
checkModule('Email::Valid', );
|
||||
checkModule('Facebook::Graph', '0.0505' );
|
||||
|
||||
failAndExit("Required modules are missing, running no more checks.") if $missingModule;
|
||||
|
||||
|
|
|
|||
4
share/upgrades/7.9.12-8.0.0/facebook_auth.sql
Normal file
4
share/upgrades/7.9.12-8.0.0/facebook_auth.sql
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
insert into settings values ('facebookAuthEnabled',0);
|
||||
insert into settings values ('facebookAuthAppId','');
|
||||
insert into settings values ('facebookAuthSecret','');
|
||||
insert into settings values ('facebookAuthTemplateIdChooseUsername','anlFXped9lqXPThZTdFX0A');
|
||||
Binary file not shown.
BIN
www/extras/macro/FacebookLogin/login-button.png
Normal file
BIN
www/extras/macro/FacebookLogin/login-button.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
Loading…
Add table
Add a link
Reference in a new issue