diff --git a/.gitignore b/.gitignore index ca46cded4f38e74bc74aa61ca19405b48d59a3c0..5287a346274b7fb0fcba96b863751747a91784a6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ vendor composer.lock nbproject - +logs diff --git a/classes/DAO.php b/classes/DAO.php index 72255197bcacb800e7f63a0bdf8934272f3069b7..ccbabd8da1301d281064c2621212f34ff0d22d89 100644 --- a/classes/DAO.php +++ b/classes/DAO.php @@ -24,61 +24,52 @@ namespace RAP; -use PDO; +abstract class DAO { -class DAO { + public abstract function getDBHandler(); - private static function getDBHandler() { - global $PDO; - return new PDO($PDO['connection_string'], $PDO['user'], $PDO['password']); - } - - public static function insertLogin($user) { - - global $log; - - $token = bin2hex(openssl_random_pseudo_bytes(16)); // http://stackoverflow.com/a/18890309/771431 - - $dbh = DAO::getDBHandler(); - - $stmt = $dbh->prepare("INSERT INTO token (token, data) VALUES(:token, :data)"); + public abstract function insertTokenData($token, $data); - $params = array( - ':token' => $token, - ':data' => json_encode($user) - ); + public abstract function findTokenData($token); - if ($stmt->execute($params)) { - return $token; - } else { - $log->error($stmt->errorInfo()[2]); - throw new \Exception("SQL error while storing user token"); - } - } + public abstract function deleteToken($token); - public static function getTokenData($token) { + /** + * Return the new identity ID. + */ + public abstract function insertIdentity(Identity $identity, $userId); - $dbh = DAO::getDBHandler(); + /** + * Return the new user ID. + */ + public abstract function createUser(); - $stmt = $dbh->prepare("SELECT data FROM token WHERE token = :token AND CURRENT_TIMESTAMP < TIMESTAMPADD(MINUTE,1,creation_time)"); - $stmt->bindParam(':token', $token); + public abstract function findUserById($userId); + + /** + * Return a User object, null if nothing was found. + * @param type $type Identity type (EDU_GAIN, X509, GOOGLE, ...) + * @param type $identifier value used to search the identity in the database + * @param type $dbIdentifier identifier of the database (used only for local identities) + */ + public abstract function findUserByIdentity($type, $identifier, $dbIdentifier); - $stmt->execute(); + public abstract function addEmailToUser($email, $userId); - foreach ($stmt->fetchAll() as $row) { - return $row['data']; - } + public $config; - return null; + public function __construct($config) { + $this->config = $config; } - public static function deleteToken($token) { - - $dbh = DAO::getDBHandler(); - - $stmt = $dbh->prepare("DELETE FROM token WHERE token = :token"); - $stmt->bindParam(':token', $token); - $stmt->execute(); + public static function get() { + $config = parse_ini_file(ROOT . '/config.ini', true); + switch ($config['dbtype']) { + case 'MySQL': + return new MySQLDAO($config); + default: + throw new \Exception($config['dbtype'] . ' not supported yet'); + } } } diff --git a/classes/Identity.php b/classes/Identity.php new file mode 100644 index 0000000000000000000000000000000000000000..e792c17a3649ea5d46dc73ad0b8363e494f02e63 --- /dev/null +++ b/classes/Identity.php @@ -0,0 +1,108 @@ +<?php + +/* ---------------------------------------------------------------------------- + * INAF - National Institute for Astrophysics + * IRA - Radioastronomical Institute - Bologna + * OATS - Astronomical Observatory - Trieste + * ---------------------------------------------------------------------------- + * + * Copyright (C) 2016 Istituto Nazionale di Astrofisica + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License Version 3 as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +namespace RAP; + +class Identity { + + const EDU_GAIN = "eduGAIN"; + const X509 = "X.509"; + const GOOGLE = "Google"; + const FACEBOOK = "Facebook"; + const LINKEDIN = "LinkedIn"; + const LOCAL = "Local"; + + private static $ALLOWED_TYPES = [Identity::EDU_GAIN, Identity::X509, Identity::GOOGLE, Identity::FACEBOOK, Identity::LINKEDIN, Identity::LOCAL]; + + /** + * Identity id in the database. Mandatory field. + */ + public $id; + + /** + * One of the types specified above. Mandatory field. + */ + private $type; + + /** + * Data related to specific account type (shibboleth persistent id, facebook id, etc, ...). Mandatory field. + */ + public $typedId; + + /** + * Primary email related to this identity. Mandatory field. + * User can have additional email addresses. These are stored into User class. + */ + public $email; + + /** + * Unique identifier for local user database (specified in configuration file). + */ + public $localDBId; + + /** + * First name + */ + public $name; + + /** + * Last name / Family name + */ + public $surname; + + /** + * Institution / Organization. Not mandatory. + */ + public $institution; + + /** + * For local identities. + */ + public $username; + + /** + * For eduGAIN identities. + */ + public $eppn; + + public function __construct($userType) { + $isAllowedType = false; + foreach (Identity::$ALLOWED_TYPES as $type) { + if ($userType === $type) { + $isAllowedType = true; + break; + } + } + if (!$isAllowedType) { + throw new \Exception($userType . " is not a supported user type"); + } + + $this->type = $userType; + } + + public function getType() { + return $this->type; + } + +} diff --git a/classes/MySQLDAO.php b/classes/MySQLDAO.php new file mode 100644 index 0000000000000000000000000000000000000000..e484c927b3e5d72fb5abf7ac955907ba40a7eb9b --- /dev/null +++ b/classes/MySQLDAO.php @@ -0,0 +1,186 @@ +<?php + +/* ---------------------------------------------------------------------------- + * INAF - National Institute for Astrophysics + * IRA - Radioastronomical Institute - Bologna + * OATS - Astronomical Observatory - Trieste + * ---------------------------------------------------------------------------- + * + * Copyright (C) 2016 Istituto Nazionale di Astrofisica + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License Version 3 as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +namespace RAP; + +use PDO; + +class MySQLDAO extends DAO { + + public function getDBHandler() { + $connectionString = "mysql:host=" . $this->config['hostname'] . ";dbname=" . $this->config['dbname']; + return new PDO($connectionString, $this->config['username'], $this->config['password']); + } + + public function insertTokenData($token, $data) { + + global $log; + + $dbh = $this->getDBHandler(); + $stmt = $dbh->prepare("INSERT INTO token (token, data) VALUES(:token, :data)"); + + $params = array( + ':token' => $token, + ':data' => $data + ); + + if ($stmt->execute($params)) { + return $token; + } else { + $log->error($stmt->errorInfo()[2]); + throw new \Exception("SQL error while storing user token"); + } + } + + public function findTokenData($token) { + + $dbh = $this->getDBHandler(); + + $stmt = $dbh->prepare("SELECT data FROM token WHERE token = :token AND CURRENT_TIMESTAMP < TIMESTAMPADD(MINUTE,1,creation_time)"); + $stmt->bindParam(':token', $token); + + $stmt->execute(); + + foreach ($stmt->fetchAll() as $row) { + return $row['data']; + } + + return null; + } + + public function deleteToken($token) { + + $dbh = $this->getDBHandler(); + + $stmt = $dbh->prepare("DELETE FROM token WHERE token = :token"); + $stmt->bindParam(':token', $token); + $stmt->execute(); + } + + public function insertIdentity(Identity $identity, $userId) { + + $dbh = $this->getDBHandler(); + + $stmt = $dbh->prepare("INSERT INTO identity(`user_id`, `type`, `email`, `name`, `surname`, `institution`, `username`, `local_db_id`, `typed_id`, `eppn`)" + . " VALUES(:user_id, :type, :email, :name, :surname, :institution, :username, :local_db_id, :typed_id, :eppn)"); + + $stmt->bindParam(':user_id', $userId); + $stmt->bindParam(':type', $identity->getType()); + $stmt->bindParam(':email', $identity->email); + $stmt->bindParam(':name', $identity->name); + $stmt->bindParam(':surname', $identity->surname); + $stmt->bindParam(':institution', $identity->institution); + $stmt->bindParam(':username', $identity->username); + $stmt->bindParam(':local_db_id', $identity->localDBId); + $stmt->bindParam(':typed_id', $identity->typedId); + $stmt->bindParam(':eppn', $identity->eppn); + + $stmt->execute(); + + return $dbh->lastInsertId(); + } + + public function createUser() { + + $dbh = $this->getDBHandler(); + + $stmt = $dbh->prepare("INSERT INTO user() VALUES()"); + $stmt->execute(); + + return $dbh->lastInsertId(); + } + + public function findUserById($userId) { + + $dbh = $this->getDBHandler(); + + $stmt = $dbh->prepare("SELECT `id`, `type`, `typed_id`, `email`, `local_db_id`, `name`, `surname`, `institution`, `username`, `eppn`" + . " FROM identity WHERE user_id = :user_id"); + + $stmt->bindParam(':user_id', $userId); + $stmt->execute(); + + $user = new User(); + $user->id = $userId; + + foreach ($stmt->fetchAll() as $row) { + $identity = new Identity($row['type']); + $identity->id = $row['id']; + $identity->typedId = $row['typed_id']; + $identity->email = $row['email']; + $identity->localDBId = $row['local_db_id']; + $identity->name = $row['name']; + $identity->surname = $row['surname']; + $identity->institution = $row['institution']; + $identity->username = $row['username']; + $identity->eppn = $row['eppn']; + $user->addIdentity($identity); + } + + $stmtMail = $dbh->prepare("SELECT `email` FROM `additional_email` WHERE `user_id` = :user_id"); + $stmtMail->bindParam(':user_id', $userId); + $stmtMail->execute(); + foreach ($stmtMail->fetchAll() as $row) { + $user->addAdditionalEmail($row['email']); + } + + return $user; + } + + public function findUserByIdentity($type, $identifier, $dbIdentifier) { + + $dbh = $this->getDBHandler(); + + $stmt = $dbh->prepare("SELECT user_id FROM identity WHERE type = :type AND typed_id = :typed_id AND local_db_id = :local_db_id"); + $stmt->bindParam(':type', $type); + $stmt->bindParam(':typed_id', $identifier); + $stmt->bindParam(':local_db_id', $dbIdentifier); + + $stmt->execute(); + + $result = $stmt->fetchAll(); + + if (count($result) === 0) { + return null; + } + if (count($result) > 1) { + throw new Exception("Found multiple users associated to the same identity!"); + } + + $userId = $result[0]['user_id']; + return $this->findUserById($userId); + } + + public function addEmailToUser($email, $userId) { + + $dbh = $this->getDBHandler(); + + $stmt = $dbh->prepare("INSERT INTO `additional_email`(`user_id`, `email`) VALUES(:user_id, :email)"); + $stmt->bindParam(':user_id', $userId); + $stmt->bindParam(':email', $email); + + $stmt->execute(); + } + +} diff --git a/classes/SessionData.php b/classes/SessionData.php new file mode 100644 index 0000000000000000000000000000000000000000..c6d807741a67a3433cfad618e6c567d136e87590 --- /dev/null +++ b/classes/SessionData.php @@ -0,0 +1,44 @@ +<?php + +/* ---------------------------------------------------------------------------- + * INAF - National Institute for Astrophysics + * IRA - Radioastronomical Institute - Bologna + * OATS - Astronomical Observatory - Trieste + * ---------------------------------------------------------------------------- + * + * Copyright (C) 2016 Istituto Nazionale di Astrofisica + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License Version 3 as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +namespace RAP; + +class SessionData { + + public $callback; + public $user; + + public function save() { + $_SESSION['SessionData'] = $this; + } + + public static function get() { + + if (!isset($_SESSION['SessionData'])) { + $session = new SessionData(); + $session->save(); + } + return $_SESSION['SessionData']; + } +} diff --git a/classes/TokenHandler.php b/classes/TokenHandler.php new file mode 100644 index 0000000000000000000000000000000000000000..c096a01710e9f52969e21bb8f25a311cd34804fc --- /dev/null +++ b/classes/TokenHandler.php @@ -0,0 +1,42 @@ +<?php + +/* ---------------------------------------------------------------------------- + * INAF - National Institute for Astrophysics + * IRA - Radioastronomical Institute - Bologna + * OATS - Astronomical Observatory - Trieste + * ---------------------------------------------------------------------------- + * + * Copyright (C) 2016 Istituto Nazionale di Astrofisica + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License Version 3 as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +namespace RAP; + +class TokenHandler { + + public static function createNewToken($data) { + $token = bin2hex(openssl_random_pseudo_bytes(16)); // http://stackoverflow.com/a/18890309/771431 + DAO::get()->insertTokenData($token, $data); + } + + public static function deleteToken($token) { + DAO::get()->deleteToken($token); + } + + public static function getUserData($token) { + return DAO::get()->findTokenData($token); + } + +} diff --git a/classes/User.php b/classes/User.php new file mode 100644 index 0000000000000000000000000000000000000000..220c6f088c4a28f7e851ff708f712f072e37d2c3 --- /dev/null +++ b/classes/User.php @@ -0,0 +1,46 @@ +<?php + +/* ---------------------------------------------------------------------------- + * INAF - National Institute for Astrophysics + * IRA - Radioastronomical Institute - Bologna + * OATS - Astronomical Observatory - Trieste + * ---------------------------------------------------------------------------- + * + * Copyright (C) 2016 Istituto Nazionale di Astrofisica + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License Version 3 as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +namespace RAP; + +class User { + + public $id; + public $identities; + public $additionalEmailAddresses; + + public function __construct() { + $this->identities = []; + $this->additionalEmailAddresses = []; + } + + public function addIdentity(Identity $identity) { + array_push($this->identities, $identity); + } + + public function addAdditionalEmail($email) { + array_push($this->additionalEmailAddresses, $email); + } + +} diff --git a/classes/UserHandler.php b/classes/UserHandler.php new file mode 100644 index 0000000000000000000000000000000000000000..bb3bb3eceb9efa616702bcfb4682df5e08a233ba --- /dev/null +++ b/classes/UserHandler.php @@ -0,0 +1,55 @@ +<?php + +/* ---------------------------------------------------------------------------- + * INAF - National Institute for Astrophysics + * IRA - Radioastronomical Institute - Bologna + * OATS - Astronomical Observatory - Trieste + * ---------------------------------------------------------------------------- + * + * Copyright (C) 2016 Istituto Nazionale di Astrofisica + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License Version 3 as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +namespace RAP; + +class UserHandler { + + public static function saveUser(User $user) { + + $dao = DAO::get(); + + if ($user->id === null) { + $user->id = $dao->createUser(); + } + + foreach ($user->identities as $identity) { + if ($identity->id === null) { + $identity->id = $dao->insertIdentity($identity, $user->id); + } + } + + foreach ($user->additionalEmailAddresses as $email) { + if (!in_array($email, $user->additionalEmailAddresses)) { + + } + } + } + + public static function findUserByIdentity($type, $identifier, $dbIdentifier) { + + return DAO::get()->findUserByIdentity($type, $identifier, $dbIdentifier); + } + +} diff --git a/config.ini b/config.ini new file mode 100644 index 0000000000000000000000000000000000000000..2065065c528b35849d8c65f91530a3e4de6b91f8 --- /dev/null +++ b/config.ini @@ -0,0 +1,8 @@ + +;connection_string = mysql:host=localhost;dbname=rap" +dbtype = MySQL +hostname = localhost +port = 3306 +username = rap +password = ***REMOVED*** +dbname = rap diff --git a/img/eduGain-200.png b/img/eduGain-200.png new file mode 100755 index 0000000000000000000000000000000000000000..5235aa8fcd435d54d4e4bec1374f6aa151a0c3d4 Binary files /dev/null and b/img/eduGain-200.png differ diff --git a/img/facebook-60.png b/img/facebook-60.png new file mode 100755 index 0000000000000000000000000000000000000000..a1badec4e1c2c5186f25c51590890bfa96cb183b Binary files /dev/null and b/img/facebook-60.png differ diff --git a/img/google-60.png b/img/google-60.png new file mode 100755 index 0000000000000000000000000000000000000000..fe63b937d17bc06b18ee1a3f401231dfd9989d32 Binary files /dev/null and b/img/google-60.png differ diff --git a/img/linkedin-60.png b/img/linkedin-60.png new file mode 100755 index 0000000000000000000000000000000000000000..0d8772a6e85a1e0d6c5eb314a1a07b0dc0283740 Binary files /dev/null and b/img/linkedin-60.png differ diff --git a/img/x509-200.png b/img/x509-200.png new file mode 100755 index 0000000000000000000000000000000000000000..e1921f8ec165cb5cf527ef374e6f372466f69a2e Binary files /dev/null and b/img/x509-200.png differ diff --git a/include/footer.php b/include/footer.php new file mode 100644 index 0000000000000000000000000000000000000000..9943ff0f851844f5daaccd7e1adca02a193936dc --- /dev/null +++ b/include/footer.php @@ -0,0 +1,3 @@ +</div> +</body> +</html> diff --git a/include/header.php b/include/header.php new file mode 100644 index 0000000000000000000000000000000000000000..92c810d6804db1bcd19937e8f5a83fd149166a48 --- /dev/null +++ b/include/header.php @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> + <head> + <title><?php echo $title; ?></title> + <!-- jQuery and Bootstrap --> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous" /> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous" /> + <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> + </head> + <body> + <div class="container"> diff --git a/include/init.php b/include/init.php index 1bfefedc717e87d27ac854be36bcc7a8a2875427..e6124cf334fb2bd854a60655bfc38b845626d3c6 100644 --- a/include/init.php +++ b/include/init.php @@ -39,3 +39,6 @@ include ROOT . '/config.php'; $log = new Monolog\Logger('mainLogger'); $log->pushHandler(new Monolog\Handler\StreamHandler($LOG_PATH, $LOG_LEVEL)); + +session_start(); +$session = RAP\SessionData::get(); diff --git a/index.php b/index.php index f1521219932ad13e3b9f2a52aff2eece9c996484..8241bc3ffe5b8cc06cb4b91d4b73845a5d01e16d 100644 --- a/index.php +++ b/index.php @@ -27,18 +27,28 @@ include './include/init.php'; /** * REST Web Service using http://flightphp.com/ */ -Flight::route('/', function() { +Flight::route('/demo', function() { $callback = (isset($_SERVER['HTTPS']) ? "https" : "http") . '://' . $_SERVER['HTTP_HOST'] . "/rap-service/user-info"; Flight::render('demo.php', array('callback' => $callback)); }); -Flight::route('POST /google', function() { +Flight::route('/', function() { + global $session; + Flight::render('index.php', array('title' => 'RAP', 'session' => $session)); +}); + +Flight::route('GET /logout', function() { + session_destroy(); + Flight::redirect('/'); +}); + +Flight::route('/google', function() { + global $session; + $callback = Flight::request()->data['callback']; - if (!isset($callback)) { - throw new Exception("Callback URL not set!"); - } - session_start(); - $_SESSION['rap_callback'] = $callback; + $session->callback = isset($callback) ? $callback : null; + $session->save(); + Flight::redirect('/oauth2/google_token.php'); }); @@ -68,4 +78,17 @@ Flight::route('GET /user-info', function() { echo $userData; }); +Flight::route('GET /user/@userId', function($userId) { + + $user = RAP\DAO::get()->findUserById($userId); + if ($user !== null) { + global $log; + $log->debug(count($user->identities)); + echo json_encode($user); + } else { + http_response_code(404); + die("User not found"); + } +}); + Flight::start(); diff --git a/oauth2/google_token.php b/oauth2/google_token.php index b0d58007e8917d81575da1dcde3c18728f6bb75d..553bbb03666660be22538b21baedd354312dce6c 100644 --- a/oauth2/google_token.php +++ b/oauth2/google_token.php @@ -24,14 +24,6 @@ include '../include/init.php'; -session_start(); - -$callback = $_SESSION['rap_callback']; -if (!isset($callback)) { - http_response_code(422); - die("Callback URL not set!"); -} - $client = new Google_Client(array( 'client_id' => $Google['id'], 'client_secret' => $Google['secret'], @@ -77,17 +69,36 @@ if ($client->getAccessToken()) { array_push($emailAddresses, $addr->value); } - // Creating user object - $user = array( - "type" => "Google", - "name" => $name, - "surname" => $surname, - "emailAddresses" => $emailAddresses, - "typed_id" => explode('/', $res->getResourceName())[1] - ); - - $token = RAP\DAO::insertLogin($user); - header('Location: ' . $callback . '?token=' . $token); + $typedId = explode('/', $res->getResourceName())[1]; + + $user = RAP\UserHandler::findUserByIdentity(RAP\Identity::GOOGLE, $typedId, null); + + if ($user === null) { + $user = new RAP\User(); + + $identity = new RAP\Identity(RAP\Identity::GOOGLE); + $identity->email = $emailAddresses[0]; + $identity->name = $name; + $identity->surname = $surname; + $identity->typedId = $typedId; + + $user->addIdentity($identity); + + RAP\UserHandler::saveUser($user); + } + + if (isset($session->callback) && $session->callback !== null) { + // External login using token + $token = RAP\TokenHandler::createNewToken($user->id); + header('Location: ' . $session->callback . '?token=' . $token); + } else { + // Login in session + $session->user = $user; + $session->save(); + // Return to index + header('Location: ' . $BASE_PATH); + } + die(); } else { // Redirect to Google authorization URL for obtaining an access token diff --git a/setup-database.sql b/setup-database.sql deleted file mode 100644 index 9630ab493016fd8e0ceb00270bcabe2a2b31c9ee..0000000000000000000000000000000000000000 --- a/setup-database.sql +++ /dev/null @@ -1,14 +0,0 @@ -CREATE TABLE `token` ( - `id` bigint(20) NOT NULL AUTO_INCREMENT, - `token` varchar(255) DEFAULT NULL, - `data` text, - `creation_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE EVENT tokens_cleanup - ON SCHEDULE - EVERY 1 MINUTE - COMMENT 'Remove expired tokens' - DO - DELETE FROM token WHERE CURRENT_TIMESTAMP > TIMESTAMPADD(MINUTE,1,creation_time); diff --git a/sql/setup-database.sql b/sql/setup-database.sql new file mode 100644 index 0000000000000000000000000000000000000000..5ea15e11748c60a6028e6f7f272b2f1ae2a4a909 --- /dev/null +++ b/sql/setup-database.sql @@ -0,0 +1,43 @@ +CREATE TABLE `user` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `identity` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `user_id` bigint(20) NOT NULL, + `type` varchar(50) NOT NULL, + `typed_id` varchar(255) NOT NULL, + `email` varchar(255) NOT NULL, + `name` varchar(255) DEFAULT NULL, + `surname` varchar(255) DEFAULT NULL, + `institution` varchar(255) DEFAULT NULL, + `username` varchar(255) DEFAULT NULL, + `local_db_id` varchar(255) DEFAULT NULL, + `eppn` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `additional_email` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `user_id` bigint(20) NOT NULL, + `email` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `token` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `token` varchar(255) NOT NULL, + `data` text, + `creation_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE EVENT tokens_cleanup + ON SCHEDULE + EVERY 1 MINUTE + COMMENT 'Remove expired tokens' + DO + DELETE FROM token WHERE CURRENT_TIMESTAMP > TIMESTAMPADD(MINUTE,1,creation_time); diff --git a/views/index.php b/views/index.php new file mode 100644 index 0000000000000000000000000000000000000000..52a446c8e5a0ad43994a137df6ba0ff5033440f7 --- /dev/null +++ b/views/index.php @@ -0,0 +1,16 @@ +<?php +include 'include/header.php'; +?> + +<?php if ($session->user === null) { ?> + <a href="google"> + <img src="img/google-60.png" alt="Google Logo" /> + </a> +<?php } else { ?> + <?php echo json_encode($session->user); ?> + <a href="logout">Logout</a> +<?php } ?> + +<?php +include 'include/footer.php'; +