summaryrefslogtreecommitdiff
path: root/app/Model
diff options
context:
space:
mode:
authorFrédéric Guillot <fred@kanboard.net>2014-06-30 21:52:02 -0300
committerFrédéric Guillot <fred@kanboard.net>2014-06-30 21:52:02 -0300
commit06d0b7048ebcdfdf6e24eec3ac7dc8fb0327dd6f (patch)
treeeb006b4c560781186f1debd2437c02edf6008878 /app/Model
parentf70ac7d65fa0e7f1e6a9559242d9c141ba5c9eb3 (diff)
Merge pull-request: Github authentication #162
Diffstat (limited to 'app/Model')
-rw-r--r--app/Model/Acl.php4
-rw-r--r--app/Model/GitHub.php178
-rw-r--r--app/Model/LastLogin.php1
-rw-r--r--app/Model/User.php12
4 files changed, 193 insertions, 2 deletions
diff --git a/app/Model/Acl.php b/app/Model/Acl.php
index 035fd7c3..8a87a6b2 100644
--- a/app/Model/Acl.php
+++ b/app/Model/Acl.php
@@ -17,7 +17,7 @@ class Acl extends Base
* @var array
*/
private $public_actions = array(
- 'user' => array('login', 'check', 'google'),
+ 'user' => array('login', 'check', 'google', 'github'),
'task' => array('add'),
'board' => array('readonly'),
);
@@ -32,7 +32,7 @@ class Acl extends Base
'app' => array('index'),
'board' => array('index', 'show', 'assign', 'assigntask', 'save', 'check'),
'project' => array('tasks', 'index', 'forbidden', 'search'),
- 'user' => array('index', 'edit', 'update', 'forbidden', 'logout', 'index', 'unlinkgoogle'),
+ 'user' => array('index', 'edit', 'update', 'forbidden', 'logout', 'index', 'unlinkgoogle', 'unlinkgithub'),
'config' => array('index', 'removeremembermetoken'),
'comment' => array('create', 'save', 'confirm', 'remove', 'update', 'edit', 'forbidden'),
'file' => array('create', 'save', 'download', 'confirm', 'remove', 'open', 'image'),
diff --git a/app/Model/GitHub.php b/app/Model/GitHub.php
new file mode 100644
index 00000000..3380218d
--- /dev/null
+++ b/app/Model/GitHub.php
@@ -0,0 +1,178 @@
+<?php
+
+namespace Model;
+
+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;
+
+/**
+ * GitHub model
+ *
+ * @package model
+ */
+class GitHub extends Base
+{
+ /**
+ * Authenticate a GitHub user
+ *
+ * @access public
+ * @param string $github_id GitHub user id
+ * @return boolean
+ */
+ public function authenticate($github_id)
+ {
+ $userModel = new User($this->db, $this->event);
+
+ $user = $userModel->getByGitHubId($github_id);
+
+ if ($user) {
+
+ // Create the user session
+ $userModel->updateSession($user);
+
+ // Update login history
+ $lastLogin = new LastLogin($this->db, $this->event);
+ $lastLogin->create(
+ LastLogin::AUTH_GITHUB,
+ $user['id'],
+ $userModel->getIpAddress(),
+ $userModel->getUserAgent()
+ );
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Unlink a GitHub 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,
+ 'github_id' => '',
+ ));
+ }
+
+ /**
+ * Update the user table based on the GitHub profile information
+ *
+ * @access public
+ * @param integer $user_id User id
+ * @param array $profile GitHub profile
+ * @return boolean
+ * @todo Don't overwrite existing email/name with empty GitHub data
+ */
+ public function updateUser($user_id, array $profile)
+ {
+ $userModel = new User($this->db, $this->event);
+
+ return $userModel->update(array(
+ 'id' => $user_id,
+ 'github_id' => $profile['id'],
+ 'email' => $profile['email'],
+ 'name' => $profile['name'],
+ ));
+ }
+
+ /**
+ * Get the GitHub service instance
+ *
+ * @access public
+ * @return \OAuth\OAuth2\Service\GitHub
+ */
+ public function getService()
+ {
+ $uriFactory = new UriFactory();
+ $currentUri = $uriFactory->createFromSuperGlobalArray($_SERVER);
+ $currentUri->setQuery('controller=user&action=gitHub');
+
+ $storage = new Session(false);
+
+ $credentials = new Credentials(
+ GITHUB_CLIENT_ID,
+ GITHUB_CLIENT_SECRET,
+ $currentUri->getAbsoluteUri()
+ );
+
+ $serviceFactory = new ServiceFactory();
+
+ return $serviceFactory->createService(
+ 'gitHub',
+ $credentials,
+ $storage,
+ array('')
+ );
+ }
+
+ /**
+ * Get the authorization URL
+ *
+ * @access public
+ * @return \OAuth\Common\Http\Uri\Uri
+ */
+ public function getAuthorizationUrl()
+ {
+ return $this->getService()->getAuthorizationUri();
+ }
+
+ /**
+ * Get GitHub profile information from the API
+ *
+ * @access public
+ * @param string $code GitHub authorization code
+ * @return bool|array
+ */
+ public function getGitHubProfile($code)
+ {
+ try {
+ $gitHubService = $this->getService();
+ $gitHubService->requestAccessToken($code);
+
+ return json_decode($gitHubService->request('user'), true);
+ }
+ catch (TokenResponseException $e) {
+ return false;
+ }
+
+ return false;
+ }
+
+ /**
+ * Revokes this user's GitHub tokens for Kanboard
+ *
+ * @access public
+ * @return bool|array
+ * @todo Currently this simply removes all our tokens for this user, ideally it should
+ * restrict itself to the one in question
+ */
+ public function revokeGitHubAccess()
+ {
+ try {
+ $gitHubService = $this->getService();
+
+ $basicAuthHeader = array('Authorization' => 'Basic ' .
+ base64_encode(GITHUB_CLIENT_ID.':'.GITHUB_CLIENT_SECRET));
+
+ return json_decode($gitHubService->request('/applications/'.GITHUB_CLIENT_ID.'/tokens', 'DELETE', null, $basicAuthHeader), true);
+ }
+ catch (TokenResponseException $e) {
+ return false;
+ }
+
+ return false;
+ }
+}
diff --git a/app/Model/LastLogin.php b/app/Model/LastLogin.php
index 56739b48..db4c4a57 100644
--- a/app/Model/LastLogin.php
+++ b/app/Model/LastLogin.php
@@ -33,6 +33,7 @@ class LastLogin extends Base
const AUTH_REMEMBER_ME = 'remember_me';
const AUTH_LDAP = 'ldap';
const AUTH_GOOGLE = 'google';
+ const AUTH_GITHUB = 'github';
/**
* Create a new record
diff --git a/app/Model/User.php b/app/Model/User.php
index 8769d69a..ba1acb90 100644
--- a/app/Model/User.php
+++ b/app/Model/User.php
@@ -52,6 +52,18 @@ class User extends Base
}
/**
+ * Get a specific user by the GitHub id
+ *
+ * @access public
+ * @param string $github_id GitHub user id
+ * @return array
+ */
+ public function getByGitHubId($github_id)
+ {
+ return $this->db->table(self::TABLE)->eq('github_id', $github_id)->findOne();
+ }
+
+ /**
* Get a specific user by the username
*
* @access public