diff --git a/app/controllers/AuthController.php b/app/controllers/AuthController.php
index b3a84ba..08331e7 100644
--- a/app/controllers/AuthController.php
+++ b/app/controllers/AuthController.php
@@ -54,8 +54,19 @@ class AuthController extends ControllerBase
// NOTE: Should pass $state here also.
$data = $client->authenticate($code);
- $this->auth->loginOauth($data);
- $this->response->redirect('/');
+ $result = $this->auth->loginOauth($data);
+
+ // There was an error when creating the account
+ if (is_array($result)) {
+ $msg = '';
+ foreach($result as $message) {
+ $msg .= '
' . $message->getMessage() . '';
+ }
+ $this->flash->message('error', "Failed to create account: ");
+ $this->response->redirect('/login');
+ } else {
+ $this->response->redirect('/');
+ }
} catch(\Exception $e) {
$this->flash->message('error', 'Failed to authenticate.');
$this->response->redirect('/login');
diff --git a/app/library/Auth.php b/app/library/Auth.php
index f65579c..75c622b 100644
--- a/app/library/Auth.php
+++ b/app/library/Auth.php
@@ -43,34 +43,28 @@ class Auth extends Component
/**
* Login using OAuth
*
- * @param UserDataInterface $auth
+ * @param UserDataInterface $data
+ * @return bool|\Phalcon\Mvc\Model\MessageInterface[]
*/
- public function loginOauth(UserDataInterface $auth)
+ public function loginOauth(UserDataInterface $data)
{
- // Look for a user with this email.
- $user = User::findFirstByEmail($auth->getEmail());
+ $user = User::findFirstByOAuthID($data);
if (!$user) {
// Did not find any user. create him.
- if (strlen($auth->getUsername()) > 0) {
- $name = $auth->getUsername();
- } else if(strlen($auth->getName()) > 0) {
- $name = $auth->getName();
- } else {
- $name = '';
+ $user = User::createFromOAuthData($data);
+
+ if ($user->save() === false) {
+ return $user->getMessages();
}
-
- $user = new User();
- $user->setEmail($auth->getEmail())
- ->setUsername($name);
-
- $user->save();
}
$this->setIdentity($user->getId());
$this->_eventsManager->fire('auth:onLogin', $this,
- "OAuth {$auth->getProvider()}");
+ "OAuth {$data->getProvider()}");
+
+ return true;
}
/**
diff --git a/app/library/OAuth/Adapter/League.php b/app/library/OAuth/Adapter/League.php
index cf85b14..878b6e6 100644
--- a/app/library/OAuth/Adapter/League.php
+++ b/app/library/OAuth/Adapter/League.php
@@ -15,6 +15,7 @@ class League implements AdapterInterface
protected $_providerClasses = array(
'github' => '\League\OAuth2\Client\Provider\Github',
'gitlab' => '\Omines\OAuth2\Client\Provider\Gitlab',
+ 'google' => '\League\OAuth2\Client\Provider\Google',
);
/**
@@ -36,7 +37,7 @@ class League implements AdapterInterface
public function __construct($provider_name, $options)
{
if (!array_key_exists($provider_name, $this->_providerClasses)) {
- throw new Exception("Provider '{$provider_name}' is not supported.");
+ throw new \Exception("Provider '{$provider_name}' is not supported.");
}
$className = $this->_providerClasses[$provider_name];
@@ -44,7 +45,7 @@ class League implements AdapterInterface
if (!($provider instanceof AbstractProvider)) {
// TODO: Throw a better exception class :)
- throw new Exception("Provider object must be an instance of League\\OAuth2\\Client\\Provider\\AbstractProvider");
+ throw new \Exception("Provider object must be an instance of League\\OAuth2\\Client\\Provider\\AbstractProvider");
}
$this->_provider = $provider;
diff --git a/app/library/OAuth/UserData/Google.php b/app/library/OAuth/UserData/Google.php
new file mode 100644
index 0000000..86a80ab
--- /dev/null
+++ b/app/library/OAuth/UserData/Google.php
@@ -0,0 +1,59 @@
+data = $data;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getProvider()
+ {
+ return 'Google';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getId()
+ {
+ return (int) $this->data['id'];
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getUsername()
+ {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getName()
+ {
+ return $this->data['displayName'];
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getEmail()
+ {
+ if (isset($this->data['emails'][0]['value'])) {
+ return $this->data['emails'][0]['value'];
+ }
+ return null;
+ }
+}
diff --git a/app/migrations/20180419133825_user_oauth_ids.php b/app/migrations/20180419133825_user_oauth_ids.php
new file mode 100644
index 0000000..fffb5de
--- /dev/null
+++ b/app/migrations/20180419133825_user_oauth_ids.php
@@ -0,0 +1,22 @@
+table('user')
+ ->addColumn('gitlab_id', 'integer', [
+ 'limit' => 14,
+ 'null' => true,
+ 'after' => 'github_user'
+ ])
+ ->addColumn('google_id', 'integer', [
+ 'limit' => 21,
+ 'null' => true,
+ 'after' => 'gitlab_id'
+ ])->save();
+ }
+}
diff --git a/app/migrations/20180607222058_user_remove_github_user.php b/app/migrations/20180607222058_user_remove_github_user.php
new file mode 100644
index 0000000..901bd89
--- /dev/null
+++ b/app/migrations/20180607222058_user_remove_github_user.php
@@ -0,0 +1,14 @@
+table('user')
+ ->removeColumn('github_user')
+ ->save();
+ }
+}
diff --git a/app/models/Data/User.php b/app/models/Data/User.php
index a676be5..82c438e 100644
--- a/app/models/Data/User.php
+++ b/app/models/Data/User.php
@@ -2,8 +2,11 @@
namespace App\Model\Data;
-use Phalcon\Mvc\Model;
-use InvalidArgumentException;
+use Phalcon\Mvc\Model,
+ Phalcon\Validation,
+ Phalcon\Validation\Validator\Uniqueness,
+ InvalidArgumentException,
+ Httpcb\OAuth\UserData\UserDataInterface;
class User extends Model
{
@@ -27,6 +30,10 @@ class User extends Model
protected $github_user;
+ protected $gitlab_id;
+
+ protected $google_id;
+
public function initialize()
{
$this->useDynamicUpdate(true);
@@ -38,6 +45,17 @@ class User extends Model
$this->setEventsManager($this->getDI()->get('eventsManager'));
}
+ public function validation()
+ {
+ // Validation
+ $validator = new Validation();
+
+ $validator->add('username', new Uniqueness(['message' => 'The username already exists.']));
+ $validator->add('email', new Uniqueness(['message' => 'The email address already exists.']));
+
+ return $this->validate($validator);
+ }
+
/**
* @return mixed
*/
@@ -193,6 +211,55 @@ class User extends Model
return $this;
}
+ /**
+ * @return mixed
+ */
+ public function getGitlabId()
+ {
+ return $this->gitlab_id;
+ }
+
+ /**
+ * @param mixed $gitlab_id
+ * @return User
+ */
+ public function setGitlabId($gitlab_id)
+ {
+ $this->gitlab_id = $gitlab_id;
+ return $this;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getGoogleId()
+ {
+ return $this->google_id;
+ }
+
+ /**
+ * @param mixed $google_id
+ * @return User
+ */
+ public function setGoogleId($google_id)
+ {
+ $this->google_id = $google_id;
+ return $this;
+ }
+
+ static public function createFromOAuthData(UserDataInterface $data)
+ {
+ $oauth_id = 'set' . $data->getProvider() . 'Id';
+
+ $user = new self();
+ $user->setUsername($data->getUsername())
+ ->setName($data->getName())
+ ->setEmail($data->getEmail())
+ ->{$oauth_id}($data->getId());
+
+ return $user;
+ }
+
/**
* Find the first user by Username or Email
*
@@ -207,6 +274,16 @@ class User extends Model
]);
}
+ static public function findFirstByOAuthID(UserDataInterface $oauth)
+ {
+ $column = strtolower($oauth->getProvider());
+
+ return self::findFirst([
+ "{$column}_id = :id:",
+ "bind" => [ 'id' => $oauth->getId() ]
+ ]);
+ }
+
public function beforeSave()
{
// Fire event on password create/changed.