diff options
author | Frédéric Guillot <fguillot@users.noreply.github.com> | 2014-05-03 22:24:03 -0400 |
---|---|---|
committer | Frédéric Guillot <fguillot@users.noreply.github.com> | 2014-05-03 22:24:03 -0400 |
commit | 560a12f0bd6347a335f8ed5201d6d9562d03d4bc (patch) | |
tree | 00510d25c1cf5e747573543fa88d44ef003b1c9a /models | |
parent | 9531e439cd99fb7dbcfb039f422f1d1ba414ec30 (diff) |
Add Google authentication
Diffstat (limited to 'models')
-rw-r--r-- | models/acl.php | 4 | ||||
-rw-r--r-- | models/base.php | 1 | ||||
-rw-r--r-- | models/google.php | 151 | ||||
-rw-r--r-- | models/last_login.php | 2 | ||||
-rw-r--r-- | models/user.php | 26 |
5 files changed, 178 insertions, 6 deletions
diff --git a/models/acl.php b/models/acl.php index 622aca9a..9667a1e3 100644 --- a/models/acl.php +++ b/models/acl.php @@ -19,7 +19,7 @@ class Acl extends Base * @var array */ private $public_actions = array( - 'user' => array('login', 'check'), + 'user' => array('login', 'check', 'google'), 'task' => array('add'), 'board' => array('readonly'), ); @@ -36,7 +36,7 @@ class Acl extends Base 'project' => array('tasks', 'index', 'forbidden'), 'task' => array('show', 'create', 'save', 'edit', 'update', 'close', 'confirmclose', 'open', 'confirmopen', 'description', 'duplicate'), 'comment' => array('save', 'confirm', 'remove', 'update', 'edit'), - 'user' => array('index', 'edit', 'update', 'forbidden', 'logout', 'index'), + 'user' => array('index', 'edit', 'update', 'forbidden', 'logout', 'index', 'unlinkgoogle'), 'config' => array('index', 'removeremembermetoken'), ); diff --git a/models/base.php b/models/base.php index 7731b584..f2a3194e 100644 --- a/models/base.php +++ b/models/base.php @@ -13,6 +13,7 @@ require __DIR__.'/../vendor/SimpleValidator/Validators/Equals.php'; require __DIR__.'/../vendor/SimpleValidator/Validators/AlphaNumeric.php'; require __DIR__.'/../vendor/SimpleValidator/Validators/GreaterThan.php'; require __DIR__.'/../vendor/SimpleValidator/Validators/Date.php'; +require __DIR__.'/../vendor/SimpleValidator/Validators/Email.php'; /** * Base model class diff --git a/models/google.php b/models/google.php new file mode 100644 index 00000000..51367a60 --- /dev/null +++ b/models/google.php @@ -0,0 +1,151 @@ +<?php + +namespace Model; + +require_once __DIR__.'/base.php'; +require __DIR__.'/../vendor/OAuth/bootstrap.php'; + +use \OAuth\Common\Storage\Session; +use \OAuth\Common\Consumer\Credentials; +use \OAuth\Common\Http\Uri\UriFactory; +use \OAuth\ServiceFactory; +use \OAuth\Common\Http\Exception\TokenResponseException; + +/** + * Google model + * + * @package model + * @author Frederic Guillot + */ +class Google extends Base +{ + /** + * Authenticate a Google user + * + * @access public + * @param string $google_id Google unique id + * @return boolean + */ + public function authenticate($google_id) + { + $userModel = new User($this->db, $this->event); + $user = $userModel->getByGoogleId($google_id); + + if ($user) { + + // Create the user session + $userModel->updateSession($user); + + // Update login history + $lastLogin = new LastLogin($this->db, $this->event); + $lastLogin->create( + LastLogin::AUTH_GOOGLE, + $user['id'], + $userModel->getIpAddress(), + $userModel->getUserAgent() + ); + + return true; + } + + return false; + } + + /** + * Unlink a Google account for a given user + * + * @access public + * @param integer $user_id User id + * @return boolean + */ + public function unlink($user_id) + { + $userModel = new User($this->db, $this->event); + + return $userModel->update(array( + 'id' => $user_id, + 'google_id' => '', + )); + } + + /** + * Update the user table based on the Google profile information + * + * @access public + * @param integer $user_id User id + * @param array $profile Google profile + * @return boolean + */ + public function updateUser($user_id, array $profile) + { + $userModel = new User($this->db, $this->event); + + return $userModel->update(array( + 'id' => $user_id, + 'google_id' => $profile['id'], + 'email' => $profile['email'], + 'name' => $profile['name'], + )); + } + + /** + * Get the Google service instance + * + * @access public + * @return \OAuth\OAuth2\Service\Google + */ + public function getService() + { + $uriFactory = new UriFactory(); + $currentUri = $uriFactory->createFromSuperGlobalArray($_SERVER); + $currentUri->setQuery('controller=user&action=google'); + + $storage = new Session(false); + + $credentials = new Credentials( + GOOGLE_CLIENT_ID, + GOOGLE_CLIENT_SECRET, + $currentUri->getAbsoluteUri() + ); + + $serviceFactory = new ServiceFactory(); + + return $serviceFactory->createService( + 'google', + $credentials, + $storage, + array('userinfo_email', 'userinfo_profile') + ); + } + + /** + * Get the authorization URL + * + * @access public + * @return \OAuth\Common\Http\Uri\Uri + */ + public function getAuthorizationUrl() + { + return $this->getService()->getAuthorizationUri(); + } + + /** + * Get Google profile information from the API + * + * @access public + * @param string $code Google authorization code + * @return bool|array + */ + public function getGoogleProfile($code) + { + try { + + $googleService = $this->getService(); + $googleService->requestAccessToken($code); + return json_decode($googleService->request('https://www.googleapis.com/oauth2/v1/userinfo'), true); + } + catch (TokenResponseException $e) {} + + return false; + } +} diff --git a/models/last_login.php b/models/last_login.php index 96cc6108..a991ee30 100644 --- a/models/last_login.php +++ b/models/last_login.php @@ -24,7 +24,7 @@ class LastLogin extends Base * * @var integer */ - const NB_LOGINS = 15; + const NB_LOGINS = 10; /** * Authentication methods diff --git a/models/user.php b/models/user.php index 7334373c..bb54fc2e 100644 --- a/models/user.php +++ b/models/user.php @@ -42,6 +42,18 @@ class User extends Base } /** + * Get a specific user by the Google id + * + * @access public + * @param string $google_id Google unique id + * @return array + */ + public function getByGoogleId($google_id) + { + return $this->db->table(self::TABLE)->eq('google_id', $google_id)->findOne(); + } + + /** * Get a specific user by the username * * @access public @@ -64,7 +76,7 @@ class User extends Base return $this->db ->table(self::TABLE) ->asc('username') - ->columns('id', 'username', 'is_admin', 'default_project_id', 'is_ldap_user') + ->columns('id', 'username', 'name', 'email', 'is_admin', 'default_project_id', 'is_ldap_user') ->findAll(); } @@ -115,8 +127,13 @@ class User extends Base unset($values['password']); } - if (isset($values['confirmation'])) unset($values['confirmation']); - if (isset($values['current_password'])) unset($values['current_password']); + if (isset($values['confirmation'])) { + unset($values['confirmation']); + } + + if (isset($values['current_password'])) { + unset($values['current_password']); + } $result = $this->db->table(self::TABLE)->eq('id', $values['id'])->update($values); @@ -191,6 +208,7 @@ class User extends Base new Validators\Equals('password', 'confirmation', t('Passwords doesn\'t matches')), new Validators\Integer('default_project_id', t('This value must be an integer')), new Validators\Integer('is_admin', t('This value must be an integer')), + new Validators\Email('email', t('Email address invalid')), )); return array( @@ -220,6 +238,7 @@ class User extends Base new Validators\Unique('username', t('The username must be unique'), $this->db->getConnection(), self::TABLE, 'id'), new Validators\Integer('default_project_id', t('This value must be an integer')), new Validators\Integer('is_admin', t('This value must be an integer')), + new Validators\Email('email', t('Email address invalid')), )); return array( @@ -250,6 +269,7 @@ class User extends Base new Validators\Equals('password', 'confirmation', t('Passwords doesn\'t matches')), new Validators\Integer('default_project_id', t('This value must be an integer')), new Validators\Integer('is_admin', t('This value must be an integer')), + new Validators\Email('email', t('Email address invalid')), )); if ($v->execute()) { |