[opw-web] Working auth
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [opw-web] Working auth
- Date: Mon, 10 Mar 2014 04:31:37 +0000 (UTC)
commit f4a7088aa590e52ceea1925d4419aaf2eaedba58
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Sat Mar 8 12:27:35 2014 -0500
Working auth
classes/class_user.php | 228 +++++++++++++++++++++++++-------
lang/en-gb.php | 4 +
modules/mod_login.php | 33 +++++-
modules/mod_user_profile.php | 30 ++---
schema.sql | 16 +++
skins/easterngreen/html/tpl_login.html | 18 +++-
6 files changed, 254 insertions(+), 75 deletions(-)
---
diff --git a/classes/class_user.php b/classes/class_user.php
index 39074a0..60585b2 100644
--- a/classes/class_user.php
+++ b/classes/class_user.php
@@ -19,6 +19,7 @@ class user
// Constructor
function __construct()
{
+ $this->_hybridauth = null;
$this->username = null;
$this->sid = null;
$this->is_admin = false;
@@ -26,6 +27,15 @@ class user
$this->max_age = time() - 1800;
}
+ function hybridauth() {
+ if (!isset($this->_hybridauth)) {
+ $authconfig = dirname(__FILE__) . '/../auth/config.php';
+ $this->_hybridauth = new Hybrid_Auth($authconfig);
+ }
+
+ return $this->_hybridauth;
+ }
+
// Method for creating a new session
function create_session($username, $is_admin = false)
{
@@ -128,7 +138,7 @@ class user
}
// Get details of the user from LDAP
- function get_details($username, $entries)
+ function get_details_ldap($username, $entries)
{
global $config, $db, $cache;
@@ -197,74 +207,190 @@ class user
// Method for authenticating a user
function login_openid($openid)
{
- global $config, $db;
- $is_admin = false;
+ $hybridauth = $this->hybridauth();
+ if ($hybridauth->authenticate("OpenID", array (
+ 'openid_identifier' => $openid,
+ 'hauth_return_to' => Hybrid_Auth::getCurrentUrl() . '&p=OpenID'
+ ))) {
+ return $this->finish_login('OpenID');
+ } else {
+ return false;
+ }
+ }
- try {
- $authconfig = dirname(__FILE__) . '/../auth/config.php';
- $hybridauth = new Hybrid_Auth($authconfig);
- $openidauth = $hybridauth->authenticate("OpenID", array (
- 'openid_identifier' => $openid
- ));
+ // Method for authenticating a user
+ function login_google()
+ {
+ $hybridauth = $this->hybridauth();
+ if ($hybridauth->authenticate("Google", array (
+ 'hauth_return_to' => Hybrid_Auth::getCurrentUrl() . '&p=Google'
+ ))) {
+ return $this->finish_login('Google');
+ } else {
+ return false;
+ }
+ }
- /*XXX
- $is_user_logged_in = $openidauth->isUserConnected();
- if (!$is_user_logged_in) {
+ // Method for authenticating a user
+ function login_facebook()
+ {
+ $hybridauth = $this->hybridauth();
+ if ($hybridauth->authenticate("Facebook", array (
+ 'hauth_return_to' => Hybrid_Auth::getCurrentUrl() . '&p=Facebook'
+ ))) {
+ return $this->finish_login('Facebook');
+ } else {
return false;
- }
+ }
+ }
- $user_profile = $openidauth->getUserProfile();
+ function lookup_identity($provider, $identifier)
+ {
+ global $db;
- // access user profile data
- echo "Ohai there! U are connected with: <b>{$openidauth->id}</b><br />";
- echo "As: <b>{$user_profile->displayName}</b><br />";
- echo "And your provider user identifier is: <b>{$user_profile->identifier}</b><br />";
+ $db->escape($provider);
+ $db->escape($identifier);
- // or even inspect it
- echo "<pre>" . print_r( $user_profile, true ) . "</pre><br />";
+ // Get current session data
+ $sql = "SELECT username FROM {$db->prefix}identities " .
+ "WHERE provider = '{$provider}' " .
+ "AND identifier = '{$identifier}'";
+ Hybrid_Logger::info("executing '${sql}'");
+ $row = $db->query($sql, true);
- // uncomment the line below to get user friends list
- // $openidauth->getUserContacts();
+ if (!is_null($row))
+ return $row['username'];
+ else
+ return null;
+ }
- // uncomment the line below to post something to openidauth if you want to
- // $openidauth->setUserStatus( "Hello world!" );
+ function lookup_user($username)
+ {
+ global $db;
- // ex. on how to access the openidauth api with hybridauth
- // Returns the current count of friends, followers, updates (statuses) and favorites of the
authenticating user.
- // https://dev.openidauth.com/docs/api/1/get/account/totals
- $account_totals = $openidauth->api()->get( 'account/totals.json' );
+ $db->escape($username);
- // print recived stats
- echo "Here some of yours stats on Twitter:<br /><pre>" . print_r( $account_totals, true ) .
"</pre>";
+ // Get current session data
+ $sql = "SELECT is_admin, fullname, email FROM {$db->prefix}profiles " .
+ "WHERE username = '{$username}'";
+ $row = $db->query($sql, true);
+ if (is_null($row)) {
+ return null;
+ } else {
+ $values = array();
- // logout
- echo "Logging out..";
- $openidauth->logout();
- */
+ $values['is_admin'] = $row['is_admin'] != 0;
+ $values['fullname'] = $row['fullname'];
+ $values['email'] = $row['email'];
+ return $values;
}
- catch (Exception $e) {
- return false;
+ }
+
+ function create_user($provider, $identifier, $profile)
+ {
+ global $db;
+
+ $suffix = "";
+ $email = $profile->email;
+ if ($email != "") {
+ $pos = strpos($email, "@");
+ if ($pos === false)
+ $username = $email;
+ else
+ $username = substr($email, 0, $pos);
+ } else if ($profile->firstName != '' && $profile->lastName != '') {
+ $username = trim($profile->firstName) . "." . trim($profile->lastName);
+ $suffix = 1;
+ } else {
+ $username = 'user';
}
- /*TODO
- if (true) {
- $is_admin = true;
+ while ($this->lookup_user($username . $suffix)) {
+ if ($suffix === "")
+ $suffix = 1;
+ else
+ $suffix++;
}
- */
- /*TODO
- if (true) {
- // Create a new session for the user
- $this->create_session($username, $is_admin);
+ $username = $username . $suffix;
- // Authentication was successful
- return true;
+ if ($profile->emailVerified != "") {
+ $email = $profile->emailVerified;
+ $emailVerified = 1;
+ } else {
+ $email = $profile->email;
+ $emailVerified = 0;
}
- */
- // Username was not found
- return false;
+ // The OpenID provider sets displayName to a reversed lastname - firstname,
+ // if unset. Detect this to avoid thinking we got a real DisplayName from
+ // the provider.
+ $badDisplayName = trim( $this->user->profile->lastName . " " . $this->user->profile->firstName );
+
+ if ($profile->displayName != '' && $profile->displayName != $badDisplayName)
+ $fullname = $profile->displayName;
+ else if ($profile->firstName != '' && $profile->lastName != '')
+ $fullname = trim($profile->firstName) . " " . trim($profile->lastName);
+ else
+ $fullname = '';
+
+ $db->escape($username);
+ $db->escape($fullname);
+ $db->escape($email);
+
+ $sql = "INSERT INTO {$db->prefix}profiles " .
+ "(username, fullname, email, emailVerified, is_admin) " .
+ "VALUES ('{$username}', '{$fullname}', " .
+ " '{$email}', {$emailVerified}, 0)";
+ Hybrid_Logger::info("running: {$sql}");
+ $db->query($sql);
+
+ $db->escape($provider);
+ $db->escape($identifier);
+
+ $sql = "INSERT INTO {$db->prefix}identities " .
+ "(provider, identifier, username) " .
+ "VALUES ('{$provider}', '{$identifier}', '{$username}')";
+ Hybrid_Logger::info("running: {$sql}");
+ $db->query($sql);
+ }
+
+ function finish_login($provider)
+ {
+ $hybridauth = $this->hybridauth();
+
+ Hybrid_Logger::info("finish_login - $provider");
+
+ if ($provider == "OpenID" && $hybridauth->isConnectedWith("OpenID")) {
+ $adapter = $hybridauth->getAdapter("OpenID");
+ $profile = $adapter->getUserProfile();
+ } else if ($provider == "Google" && $hybridauth->isConnectedWith("Google")) {
+ $adapter = $hybridauth->getAdapter("Google");
+ $profile = $adapter->getUserProfile();
+ } else if ($provider == "Facebook" && $hybridauth->isConnectedWith("Facebook")) {
+ $adapter = $hybridauth->getAdapter("Facebook");
+ $profile = $adapter->getUserProfile();
+ } else {
+ return false;
+ }
+
+ Hybrid_Logger::info("finish_login - connected");
+
+ $identifier = $adapter->getUserProfile()->identifier;
+
+ Hybrid_Logger::info("finish_login - looking up identity");
+ $username = $this->lookup_identity($provider, $identifier);
+
+ if ($username == null) {
+ Hybrid_Logger::info("finish_login - create user");
+ $username = $this->create_user($provider, $identifier, $profile);
+ }
+
+ $info = $this->lookup_user($username);
+ $this->create_session($identifier, $info['is_admin']);
+
+ return true;
}
// Method for logging a user out
@@ -272,6 +398,9 @@ class user
{
global $core, $db;
+ $hybridauth = $this->hybridauth();
+ $hybridauth->logoutAllProviders();
+
// Get username and session ID from cookie
$username = $core->variable('username', '', true);
$sid = $core->variable('session_id', '', true);
@@ -335,4 +464,3 @@ class user
return str_replace(array('*', '\\', '(', ')'), array('\\*', '\\\\', '\\(', '\\)'), $string);
}
}
-
diff --git a/lang/en-gb.php b/lang/en-gb.php
index 1cb7a81..ea5ce70 100644
--- a/lang/en-gb.php
+++ b/lang/en-gb.php
@@ -75,6 +75,10 @@ $lang_data = array(
'login_error' => 'Login failed! Please notify the <a href="mailto:webmaster gnome org">' .
'webmaster</a> if the problem persists',
'iko_credentials' => 'Log into [[site_name]] using OpenID:',
+ 'login_with_openid' => 'Log into [[site_name]] using OpenID:',
+ 'login_with_google' => 'Log into [[site_name]] using your Google account:',
+ 'login_with_facebook' => 'Log into [[site_name]] using your Facebook account:',
+ 'iko_credentials' => 'Log into [[site_name]] using OpenID:',
'password' => 'Password',
'create_account' => 'Create a new account',
'create_account_exp' => 'Don\'t have an account? In order to log into [[site_name]], you\'ll need an
OpenID account.',
diff --git a/modules/mod_login.php b/modules/mod_login.php
index 122e07b..2cc300a 100644
--- a/modules/mod_login.php
+++ b/modules/mod_login.php
@@ -11,6 +11,7 @@ if (!defined('IN_PANDORA')) exit;
$username = $core->variable('username', '', false, true);
$redir_url = $core->variable('r', '');
$dest_url = !empty($redir_url) ? urldecode($redir_url) : $core->path();
+$provider = $core->variable('p', '');
// Log the user out if already logged in
if ($user->is_logged_in)
@@ -18,9 +19,17 @@ if ($user->is_logged_in)
$core->redirect($dest_url);
}
+// If we're on the end of successful authentication request
+if ($provider != '' && $user->finish_login($provider)) {
+ $core->redirect($dest_url);
+}
+
// Login data was submitted
-$login_submit = isset($_POST['login']);
-if ($login_submit) {
+$login_openid = isset($_POST['login_openid']);
+$login_google = isset($_POST['login_google']);
+$login_facebook = isset($_POST['login_facebook']);
+
+if ($login_openid) {
if (!empty($username)) {
// Check if user is banned
$is_banned = $user->is_banned($username);
@@ -45,6 +54,26 @@ if ($login_submit) {
else {
$error_message = $lang->get('enter_openid');
}
+} else if ($login_google) {
+ $login_success = $user->login_google($username);
+
+ // Check if login succeeded
+ if ($login_success) {
+ $core->redirect($dest_url);
+ }
+ else {
+ $error_message = $lang->get('login_error');
+ }
+} else if ($login_facebook) {
+ $login_success = $user->login_facebook($username);
+
+ // Check if login succeeded
+ if ($login_success) {
+ $core->redirect($dest_url);
+ }
+ else {
+ $error_message = $lang->get('login_error');
+ }
}
// Assign skin data
diff --git a/modules/mod_user_profile.php b/modules/mod_user_profile.php
index 69c2975..4b5b8fd 100644
--- a/modules/mod_user_profile.php
+++ b/modules/mod_user_profile.php
@@ -15,34 +15,22 @@ $return_url = urldecode($return_encoded);
$username = urldecode($username_encoded);
// We need username for this module
-$user->restrict(!empty($username));
-
-// Build an array of the data that we need
-$required_data = array(
- $config->ldap_fullname,
- $config->ldap_mail,
- $config->ldap_group,
-);
+if (empty($username)) {
+ $user->restrict(!is_null($user->username));
+ $username = $user->username;
+}
// Get the user data
-$username_data = $user->get_details($username, $required_data);
+$username_data = $user->lookup_user($username);
// Set the template data
-if (isset($username_data[$config->ldap_mail]))
+if (!is_null($username_data))
{
$is_admin = false;
$avatar_url = "?q=user_avatar&u={$username_encoded}";
- $full_name = $username_data[$config->ldap_fullname][0];
- $user_email = $username_data[$config->ldap_mail][0];
-
- // Determine if the user is a site admin
- foreach ($username_data[$config->ldap_group] as $group)
- {
- if ($group == $config->ldap_admin_group)
- {
- $is_admin = true;
- }
- }
+ $full_name = $username_data['fullname'];
+ $user_email = $username_data['email'];
+ $is_admin = $username_data['is_admin'];
// Assign profile variables
$skin->assign(array(
diff --git a/schema.sql b/schema.sql
index 1243378..0bcc94f 100644
--- a/schema.sql
+++ b/schema.sql
@@ -71,3 +71,19 @@ CREATE TABLE `opw_queue` (
PRIMARY KEY (`id`),
FOREIGN KEY (`program_id`) REFERENCES `opw_programs`(`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+CREATE TABLE `opw_identities` (
+ `provider` varchar(20) NOT NULL,
+ `identifier` varchar(255) NOT NULL,
+ `username` varchar(255) NOT NULL,
+ PRIMARY KEY (`provider`, `identifier`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+CREATE TABLE `opw_profiles` (
+ `username` varchar(255) NOT NULL,
+ `fullname` varchar(255) NOT NULL,
+ `email` varchar(255) NOT NULL,
+ `emailVerified` tinyint(1) DEFAULT 0,
+ `is_admin` tinyint(1) DEFAULT 0,
+ PRIMARY KEY (`username`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
diff --git a/skins/easterngreen/html/tpl_login.html b/skins/easterngreen/html/tpl_login.html
index ed8f136..e7de0bc 100644
--- a/skins/easterngreen/html/tpl_login.html
+++ b/skins/easterngreen/html/tpl_login.html
@@ -6,7 +6,7 @@
[[error_message]]
</div>
-<h4>{{iko_credentials}}</h4>
+<h4>{{login_with_openid}}</h4>
<br />
<div class="control-group">
@@ -26,10 +26,24 @@
-->
<div class="form-actions">
- <button type="submit" name="login" class="btn btn-primary">{{log_in}}</button>
+ <button type="submit" name="login_openid" class="btn btn-primary">{{log_in}}</button>
<button type="reset" class="btn">{{reset}}</button>
</div>
+<h4>{{login_with_google}}</h4>
+<br />
+
+<div class="form-actions">
+ <button type="submit" name="login_google" class="btn btn-primary">{{log_in}}</button>
+</div>
+
+<h4>{{login_with_facebook}}</h4>
+<br />
+
+<div class="form-actions">
+ <button type="submit" name="login_facebook" class="btn btn-primary">{{log_in}}</button>
+</div>
+
<!--
<div class="alert alert-info">
<h3>{{create_account}}</h3>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]