diff --git a/auth/oauth2/facebook_token.php b/auth/oauth2/facebook_token.php index 1daca05bde24a7711f9191d52f55dfdb5fa4f5e0..b914131878a739a5f0f83468c9b5c84d6428a5e0 100755 --- a/auth/oauth2/facebook_token.php +++ b/auth/oauth2/facebook_token.php @@ -80,7 +80,7 @@ $fbUser = $response->getGraphUser(); $typedId = $fbUser["id"]; -$user = RAP\UserHandler::findUserByIdentity(RAP\Identity::FACEBOOK, $typedId); +$user = $userHandler->findUserByIdentity(RAP\Identity::FACEBOOK, $typedId); if ($user === null) { $user = new RAP\User(); @@ -93,8 +93,8 @@ if ($user === null) { $user->addIdentity($identity); - RAP\UserHandler::saveUser($user); + $userHandler->saveUser($user); } -RAP\CallbackHandler::manageLoginRedirect($user); +$callbackHandler->manageLoginRedirect($user, $session); ?> diff --git a/auth/oauth2/google_token.php b/auth/oauth2/google_token.php index 59e9c014873c9ec099805eb38846a0b2ef91bdb5..a44c19af72e9d4670705ecc6916f0d86e7b4e7a8 100644 --- a/auth/oauth2/google_token.php +++ b/auth/oauth2/google_token.php @@ -74,7 +74,7 @@ if ($client->getAccessToken()) { $typedId = explode('/', $res->getResourceName())[1]; - $user = RAP\UserHandler::findUserByIdentity(RAP\Identity::GOOGLE, $typedId); + $user = $userHandler->findUserByIdentity(RAP\Identity::GOOGLE, $typedId); if ($user === null) { $user = new RAP\User(); @@ -87,10 +87,10 @@ if ($client->getAccessToken()) { $user->addIdentity($identity); - RAP\UserHandler::saveUser($user); + $userHandler->saveUser($user); } - RAP\CallbackHandler::manageLoginRedirect($user); + $callbackHandler->manageLoginRedirect($user, $session); die(); } else { diff --git a/auth/saml2/aai.php b/auth/saml2/aai.php index 02a728d79af0c585b2c8e5d00ef4a45fb5d5faa0..cb93949c0107ae4b882c20e6ec8ce0bf6cb7ad67 100644 --- a/auth/saml2/aai.php +++ b/auth/saml2/aai.php @@ -29,7 +29,7 @@ if (isset($_SERVER['Shib-Session-ID'])) { $eppn = $_SERVER['eppn']; - $user = RAP\UserHandler::findUserByIdentity(RAP\Identity::EDU_GAIN, $eppn); + $user = $userHandler->findUserByIdentity(RAP\Identity::EDU_GAIN, $eppn); if ($user === null) { $user = new RAP\User(); @@ -39,14 +39,15 @@ if (isset($_SERVER['Shib-Session-ID'])) { $identity->name = $_SERVER['givenName']; $identity->surname = $_SERVER['sn']; $identity->typedId = $eppn; + $identity->eppn = $eppn; //$_SERVER['Shib-Identity-Provider'] $user->addIdentity($identity); - RAP\UserHandler::saveUser($user); + $userHandler->saveUser($user); } - RAP\CallbackHandler::manageLoginRedirect($user); + $callbackHandler->manageLoginRedirect($user, $session); } else { http_response_code(500); die("Shib-Session-ID not found!"); diff --git a/auth/x509/certlogin.php b/auth/x509/certlogin.php index e2319ea6ad1dc425e51cd6f74727526668d716e1..e0ce9ea501a7b91384bccabc39bedf00db736ea0 100644 --- a/auth/x509/certlogin.php +++ b/auth/x509/certlogin.php @@ -28,7 +28,7 @@ startSession(); function saveUserFromX509Data($x509Data) { - global $session; + global $session, $userHandler; $user = new RAP\User(); @@ -41,7 +41,7 @@ function saveUserFromX509Data($x509Data) { $user->addIdentity($identity); - RAP\UserHandler::saveUser($user); + $userHandler->saveUser($user); $session->x509DataToRegister = null; @@ -58,7 +58,7 @@ if ($session->x509DataToRegister !== null && $session->x509DataToRegister->name $x509Data = RAP\X509Data::parse($_SERVER); - $user = RAP\UserHandler::findUserByIdentity(RAP\Identity::X509, $x509Data->serialNumber); + $user = $userHandler->findUserByIdentity(RAP\Identity::X509, $x509Data->serialNumber); if ($user === null) { @@ -77,4 +77,4 @@ if ($session->x509DataToRegister !== null && $session->x509DataToRegister->name } } -RAP\CallbackHandler::manageLoginRedirect($user); +$callbackHandler->manageLoginRedirect($user, $session); diff --git a/classes/CallbackHandler.php b/classes/CallbackHandler.php index 85d33e978b8c3d128ab6fe642a5751dedee85f9a..a569844e481c03492c11043410941c4e402b3aa9 100644 --- a/classes/CallbackHandler.php +++ b/classes/CallbackHandler.php @@ -26,6 +26,16 @@ namespace RAP; class CallbackHandler { + private $dao; + private $basePath; + private $callbacks; + + public function __construct(DAO $dao, $basePath, $callbacks) { + $this->dao = $dao; + $this->basePath = $basePath; + $this->callbacks = $callbacks; + } + /** * returns null if the callback URL is not listed in configuration file. */ @@ -35,9 +45,7 @@ class CallbackHandler { return "Account Management"; } - global $CALLBACKS; - - foreach ($CALLBACKS as $callback) { + foreach ($this->callbacks as $callback) { if ($callback['url'] === $callbackURL) { return $callback['title']; } @@ -46,21 +54,19 @@ class CallbackHandler { throw new \Exception("Unauthorized callback URL"); } - public static function manageLoginRedirect($user) { - - global $BASE_PATH, $session, $log; + public function manageLoginRedirect($user, SessionData $session) { if ($session->getCallbackURL() !== null) { // External login using token $token = Util::createNewToken(); - DAO::get()->createLoginToken($token, $user->id); + $this->dao->createLoginToken($token, $user->id); header('Location: ' . $session->getCallbackURL() . '?token=' . $token); } else { // Login in session $session->user = $user; $session->save(); // Return to index - header('Location: ' . $BASE_PATH); + header('Location: ' . $this->basePath); } } diff --git a/classes/DAO.php b/classes/DAO.php index 888f66c71e0a754c3f92a9f7eead4a7b58b1679c..9a28d92f582d5dd429beb67264522c8941364b2b 100644 --- a/classes/DAO.php +++ b/classes/DAO.php @@ -24,58 +24,46 @@ namespace RAP; -abstract class DAO { +interface DAO { - public abstract function getDBHandler(); + function getDBHandler(); - public abstract function createLoginToken($token, $userId); + function createLoginToken($token, $userId); - public abstract function findLoginToken($token); + function findLoginToken($token); - public abstract function deleteLoginToken($token); + function deleteLoginToken($token); /** * Return the new identity ID. */ - public abstract function insertIdentity(Identity $identity, $userId); + function insertIdentity(Identity $identity, $userId); /** * Return the new user ID. */ - public abstract function createUser(); + function createUser(); - public abstract function findUserById($userId); + function findUserById($userId); + + function setPrimaryIdentity($userId, $identityId); /** * 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 */ - public abstract function findUserByIdentity($type, $identifier); - - public abstract function searchUser($searchText); - - public abstract function addEmailToUser($email, $userId); - - public abstract function createJoinRequest($token, $applicantUserId, $targetUserId); + function findUserByIdentity($type, $identifier); - public abstract function findJoinRequest($token); + function searchUser($searchText); - public abstract function deleteUser($userId); + function createJoinRequest($token, $applicantUserId, $targetUserId); - public abstract function joinUsers($userId1, $userId2); - - public abstract function deleteJoinRequest($token); + function findJoinRequest($token); - public static function get() { - global $DATABASE; + function deleteUser($userId); - switch ($DATABASE['dbtype']) { - case 'MySQL': - return new MySQLDAO($DATABASE); - default: - throw new \Exception($DATABASE['dbtype'] . ' not supported yet'); - } - } + function joinUsers($userId1, $userId2); + function deleteJoinRequest($token); } diff --git a/classes/GrouperClient.php b/classes/GrouperClient.php index 2bef66b38c7c04ee42eec2b85b52f6809dd33e8e..fb8927bfec3729fd0a6c25c1940544f2c9a07cff 100644 --- a/classes/GrouperClient.php +++ b/classes/GrouperClient.php @@ -71,9 +71,11 @@ class GrouperClient { if ($this->isSuccess($response)) { if (count($response->return->results) === 1) { $groups = []; - foreach ($response->return->results[0]->wsGroups as $group) { - if (!$this->startsWith($group->name, 'etc:')) { - array_push($groups, $group->name); + if ($response->return->results[0]->wsGroups !== null) { + foreach ($response->return->results[0]->wsGroups as $group) { + if (!$this->startsWith($group->name, 'etc:')) { + array_push($groups, $group->name); + } } } return $groups; diff --git a/classes/Identity.php b/classes/Identity.php index e731aaba914c59c2300944b24c0af8778cc59596..fc82a1d4fd25292f69bf226c9cac978e909ffcf1 100644 --- a/classes/Identity.php +++ b/classes/Identity.php @@ -76,6 +76,11 @@ class Identity { */ public $eppn; + /** + * True if this has been selected as the primary identity. + */ + public $primary; + public function __construct($userType) { $isAllowedType = false; foreach (Identity::$ALLOWED_TYPES as $type) { @@ -89,6 +94,8 @@ class Identity { } $this->type = $userType; + + $this->primary = false; } } diff --git a/classes/MySQLDAO.php b/classes/MySQLDAO.php index d6343b2bcba89d101b566fb8dd0a44cb4a8b632d..536882d47c411dcdc51e81a8953d0cfb19ecaa0f 100644 --- a/classes/MySQLDAO.php +++ b/classes/MySQLDAO.php @@ -26,12 +26,17 @@ namespace RAP; use PDO; -class MySQLDAO extends DAO { +class MySQLDAO implements DAO { + + private $config; + + public function __construct($config) { + $this->config = $config; + } public function getDBHandler() { - global $DATABASE; - $connectionString = "mysql:host=" . $DATABASE['hostname'] . ";dbname=" . $DATABASE['dbname']; - $dbh = new PDO($connectionString, $DATABASE['username'], $DATABASE['password']); + $connectionString = "mysql:host=" . $this->config['hostname'] . ";dbname=" . $this->config['dbname']; + $dbh = new PDO($connectionString, $this->config['username'], $this->config['password']); // For transaction errors (see https://stackoverflow.com/a/9659366/771431) $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); return $dbh; @@ -39,8 +44,6 @@ class MySQLDAO extends DAO { public function createLoginToken($token, $userId) { - global $log; - $dbh = $this->getDBHandler(); $stmt = $dbh->prepare("INSERT INTO login_token (token, user_id) VALUES(:token, :user_id)"); @@ -52,7 +55,7 @@ class MySQLDAO extends DAO { if ($stmt->execute($params)) { return $token; } else { - $log->error($stmt->errorInfo()[2]); + error_log($stmt->errorInfo()[2]); throw new \Exception("SQL error while storing user token"); } } @@ -118,6 +121,7 @@ class MySQLDAO extends DAO { $identity = new Identity($row['type']); $identity->id = $row['id']; + $identity->primary = $row['primary']; $identity->typedId = $row['typed_id']; $identity->email = $row['email']; $identity->name = $row['name']; @@ -136,8 +140,11 @@ class MySQLDAO extends DAO { $dbh = $this->getDBHandler(); - $stmt = $dbh->prepare("SELECT `id`, `type`, `typed_id`, `email`, `name`, `surname`, `institution`, `eppn`" - . " FROM identity WHERE user_id = :user_id"); + $stmt = $dbh->prepare("SELECT (u.`primary_identity` = i.`id`) AS `primary`," + . " i.`id`, `type`, `typed_id`, `email`, `name`, `surname`, `institution`, `eppn`" + . " FROM identity i" + . " JOIN `user` u on u.id = i.user_id" + . " WHERE i.user_id = :user_id"); $stmt->bindParam(':user_id', $userId); $stmt->execute(); @@ -155,16 +162,19 @@ class MySQLDAO extends DAO { $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 setPrimaryIdentity($userId, $identityId) { + + $dbh = $this->getDBHandler(); + + $stmt = $dbh->prepare("UPDATE `user` SET `primary_identity` = :identity_id WHERE `id` = :user_id"); + $stmt->bindParam(':identity_id', $identityId); + $stmt->bindParam(':user_id', $userId); + $stmt->execute(); + } + public function findUserByIdentity($type, $identifier) { $dbh = $this->getDBHandler(); @@ -194,10 +204,11 @@ class MySQLDAO extends DAO { $dbh = $this->getDBHandler(); - // TODO: Add additional email search... - - $query = "SELECT `user_id`, `id`, `type`, `typed_id`, `email`, `name`, `surname`, `institution`, `eppn`" - . " FROM identity WHERE `email` LIKE :email OR `name` LIKE :name OR `surname` LIKE :surname"; + $query = "SELECT `user_id`, (u.`primary_identity` = i.`id`) AS `primary`," + . " i.`id`, `type`, `typed_id`, `email`, `name`, `surname`, `institution`, `eppn`" + . " FROM identity i" + . " JOIN `user` u on u.id = i.user_id" + . " WHERE `email` LIKE :email OR `name` LIKE :name OR `surname` LIKE :surname"; $stmt = $dbh->prepare($query); @@ -233,17 +244,6 @@ class MySQLDAO extends DAO { return $users; } - 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(); - } - public function createJoinRequest($token, $applicantUserId, $targetUserId) { $dbh = $this->getDBHandler(); @@ -298,12 +298,6 @@ class MySQLDAO extends DAO { $stmt1->bindParam(':id2', $userId2); $stmt1->execute(); - // Moving additional email addresses from user2 to user1 - $stmt2 = $dbh->prepare("UPDATE `additional_email` SET `user_id` = :id1 WHERE `user_id` = :id2"); - $stmt2->bindParam(':id1', $userId1); - $stmt2->bindParam(':id2', $userId2); - $stmt2->execute(); - // Deleting user2 join requests $stmt3 = $dbh->prepare("DELETE FROM `join_request` WHERE `target_user_id` = :id2"); $stmt3->bindParam(':id2', $userId2); diff --git a/classes/SessionData.php b/classes/SessionData.php index cc578f21031ade8cfaf4e26ee6242c5942830fe6..8dd9f52aef31003d8c71f55fb8646e30efcfceaa 100644 --- a/classes/SessionData.php +++ b/classes/SessionData.php @@ -26,28 +26,33 @@ namespace RAP; class SessionData { + private $dao; private $callbackURL; private $callbackTitle; public $user; public $userSearchResults; public $x509DataToRegister; + public function __construct(DAO $dao) { + $this->dao = $dao; + } + public function save() { $_SESSION['SessionData'] = $this; } - public static function get() { + public static function get(DAO $dao) { if (!isset($_SESSION['SessionData'])) { - $session = new SessionData(); + $session = new SessionData($dao); $session->save(); } return $_SESSION['SessionData']; } - public function setCallbackURL($callbackURL) { + public function setCallbackURL(CallbackHandler $callbackHandler, $callbackURL) { $this->callbackURL = $callbackURL; - $this->callbackTitle = CallbackHandler::getCallbackTitle($callbackURL); + $this->callbackTitle = $callbackHandler->getCallbackTitle($callbackURL); $this->save(); } @@ -60,7 +65,7 @@ class SessionData { } public function searchUser($searchText) { - $users = DAO::get()->searchUser($searchText); + $users = $this->dao->searchUser($searchText); $this->userSearchResults = []; foreach ($users as $user) { @@ -74,4 +79,10 @@ class SessionData { $this->save(); } + public function updatePrimaryIdentity($identityId) { + foreach ($this->user->identities as $identity) { + $identity->primary = ($identity->id === $identityId); + } + } + } diff --git a/classes/User.php b/classes/User.php index 1d7a6cb9b9250637224eb8c4d3b4a357b38d7cef..e82db49d2f42c4a707db4eee35aa32fbbf02f82f 100644 --- a/classes/User.php +++ b/classes/User.php @@ -28,22 +28,22 @@ 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); - } - public function getPrimaryEmail() { - return $this->identities[0]->email; + foreach ($this->identities as $identity) { + if ($identity->primary) { + return $identity->email; + } + } + throw new \Exception("No primary identity defined for user " . $this->id); } + } diff --git a/classes/UserHandler.php b/classes/UserHandler.php index 58c046248fbd838b53953d33187f3237f5d36714..47824bbe0810e965cdcc5c25979e03998ccba373 100644 --- a/classes/UserHandler.php +++ b/classes/UserHandler.php @@ -26,45 +26,51 @@ namespace RAP; class UserHandler { - public static function saveUser(User $user) { + private $dao; + private $grouperConfig; - $dao = DAO::get(); + public function __construct(DAO $dao, $grouperConfig) { + $this->dao = $dao; + $this->grouperConfig = $grouperConfig; + } + + public function saveUser(User $user) { + $primarySpecified = true; + + // If new user if ($user->id === null) { - $user->id = $dao->createUser(); + $primarySpecified = false; + $user->id = $this->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)) { - + $identity->id = $this->dao->insertIdentity($identity, $user->id); + if (!$primarySpecified) { + $this->dao->setPrimaryIdentity($user->id, $identity->id); + $identity->primary = true; + } } } } - public static function findUserByIdentity($type, $identifier) { + public function findUserByIdentity($type, $identifier) { - return DAO::get()->findUserByIdentity($type, $identifier); + return $this->dao->findUserByIdentity($type, $identifier); } - public static function joinUsers($userId1, $userId2) { - - global $GROUPER; + public function joinUsers($userId1, $userId2) { - if (isset($GROUPER)) { - $gc = new GrouperClient($GROUPER); + if ($this->grouperConfig !== null) { + $gc = new GrouperClient($this->grouperConfig); $groupsToMove = $gc->getSubjectGroups('RAP:' . $userId2); $gc->addMemberships('RAP:' . $userId1, $groupsToMove); $gc->removeMemberships('RAP:' . $userId2, $groupsToMove); } - DAO::get()->joinUsers($userId1, $userId2); + $this->dao->joinUsers($userId1, $userId2); } } diff --git a/classes/X509Data.php b/classes/X509Data.php index c1bb523d9c1ded4aa10b7c1cef60492efd0cbdcc..3c774111bd090605597f182aa384b3653eaf489e 100644 --- a/classes/X509Data.php +++ b/classes/X509Data.php @@ -128,11 +128,7 @@ class X509Data { $parsedData = new X509Data(); if (isset($server['SSL_CLIENT_CERT'])) { - $parsedData->parseUsingOpenSSL(['SSL_CLIENT_CERT']); - // If all mandatory information has been parsed return the object - if ($parsedData->email !== null && $parsedData->fullName !== null && $parsedData->serialNumber !== null) { - return $parsedData; - } + $parsedData->parseUsingOpenSSL($server['SSL_CLIENT_CERT']); } if ($parsedData->fullName === null) { @@ -158,7 +154,6 @@ class X509Data { // Here a hex->dec conversion is performed, in order to store the // serial number in a consistent format: $hexSerial = $server['SSL_CLIENT_M_SERIAL']; - // TODO $parsedData->serialNumber = X509Data::bchexdec($hexSerial); } else { throw new Exception("Unable to retrieve serial number from certificate"); diff --git a/css/animation.css b/css/animation.css new file mode 100644 index 0000000000000000000000000000000000000000..ac5a9562fbd637637048f00b8a8eb86e6dbb4f88 --- /dev/null +++ b/css/animation.css @@ -0,0 +1,85 @@ +/* + Animation example, for spinners +*/ +.animate-spin { + -moz-animation: spin 2s infinite linear; + -o-animation: spin 2s infinite linear; + -webkit-animation: spin 2s infinite linear; + animation: spin 2s infinite linear; + display: inline-block; +} +@-moz-keyframes spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@-webkit-keyframes spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@-o-keyframes spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@-ms-keyframes spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} diff --git a/css/style.css b/css/style.css index 9affc9a218da8eb85aadc4e0a952242850cdf9e6..cc7f30afc9cf325a7d089d2eb0e4046b83d27698 100644 --- a/css/style.css +++ b/css/style.css @@ -3,6 +3,30 @@ body { padding-bottom: 150px; } +.waiting { + position: fixed; + top: 0; + bottom: 0; + right: 0; + left: 0; + background-color: rgba(255, 255, 255, 0.5); + z-index: 100000; + font-size: 40px; + text-align: center; +} + +.waiting .icon-wrapper { + position: absolute; + width: 100%; + height: 100%; + display: table; +} + +.waiting .glyphicon { + display: table-cell; + vertical-align: middle; +} + @keyframes pulse { from { transform: scale(1, 1); @@ -141,3 +165,13 @@ body { font-size: 30px; } +.primary-identity-icon { + font-size: 17px; + color: #4ea64e; +} +.primary-identity-icon a { + color: #ddd; +} +.primary-identity-icon a:hover { + color: #888; +} \ No newline at end of file diff --git a/include/footer.php b/include/footer.php index 0de7f71286b14074892fc0ca7fe0144ed099a376..5d0b79f247b35a8184b75b34a6afb30da2e3b2a1 100644 --- a/include/footer.php +++ b/include/footer.php @@ -1,4 +1,9 @@ </div> +<div class="waiting hide"> + <span class="icon-wrapper"> + <span class="glyphicon glyphicon-refresh animate-spin"></span> + </span> +</div> <footer id="main-footer-wrapper" class="text-center"> <p id="footer-credits">This software has been adapted by the IA2 team from the Remote Authentication Portal written by Franco Tinarelli at INAF-IRA.</p> <div id="main-footer"> diff --git a/include/front-controller.php b/include/front-controller.php index 8c334d7cbe48fe26f3a22f3f80287f4d8617a56a..f1996e20b225a4733acf0a7693ede42d2ed0d450 100644 --- a/include/front-controller.php +++ b/include/front-controller.php @@ -8,10 +8,10 @@ // function setCallback() { - global $session; + global $session, $callbackHandler; $callback = Flight::request()->data['callback']; - $session->setCallbackURL(isset($callback) ? $callback : null); + $session->setCallbackURL($callbackHandler, isset($callback) ? $callback : null); } Flight::route('/', function() { @@ -56,7 +56,7 @@ Flight::route('GET /confirm-join', function() { die("Token not found"); } - $dao = RAP\DAO::get(); + global $dao; $userIds = $dao->findJoinRequest($token); if ($userIds === null) { @@ -75,6 +75,8 @@ Flight::route('GET /confirm-join', function() { Flight::route('POST /confirm-join', function() { + global $dao, $userHandler; + $token = Flight::request()->data['token']; if ($token === null) { @@ -82,15 +84,13 @@ Flight::route('POST /confirm-join', function() { die("Token not found"); } - $dao = RAP\DAO::get(); - $userIds = $dao->findJoinRequest($token); if ($userIds === null) { http_response_code(422); die("Invalid token"); } - RAP\UserHandler::joinUsers($userIds[0], $userIds[1]); + $userHandler->joinUsers($userIds[0], $userIds[1]); $dao->deleteJoinRequest($token); // Force user to relogin to see changes to him/her identities @@ -120,7 +120,7 @@ Flight::route('GET /x509-name-surname', function() { Flight::route('POST /submit-x509-name', function() { $selectedNameIndex = Flight::request()->data['selected-name']; - + startSession(); global $session, $BASE_PATH; diff --git a/include/gui-backend.php b/include/gui-backend.php index 2506bbbb735495d2fe3c157cf97f72900900863d..0d1b28115e83564a3292c5c89f05cd3e2d5238bc 100644 --- a/include/gui-backend.php +++ b/include/gui-backend.php @@ -35,15 +35,31 @@ Flight::route('GET /user', function() { Flight::route('POST /join', function() { checkSession(); - global $session; + global $session, $dao; $selectedUserIndex = Flight::request()->data['selectedUserIndex']; $selectedSearchResult = $session->userSearchResults[$selectedUserIndex]; $targetUserId = $selectedSearchResult->getUser()->id; $token = RAP\Util::createNewToken(); - RAP\DAO::get()->createJoinRequest($token, $session->user->id, $targetUserId); + $dao->createJoinRequest($token, $session->user->id, $targetUserId); RAP\MailSender::sendJoinEmail($selectedSearchResult->getUser(), $session->user); echo $selectedSearchResult->userDisplayText; }); + + +Flight::route('POST /primary-identity', function() { + + checkSession(); + global $session, $dao; + + $identityId = Flight::request()->data['id']; + + $dao->setPrimaryIdentity($session->user->id, $identityId); + $session->updatePrimaryIdentity($identityId); + + // Following variable is used to render user-data + $user = $session->user; + include 'user-data.php'; +}); diff --git a/include/header.php b/include/header.php index 7413c9aa95ee9d648dadfdede27e9df3d6782e3c..45b48d5e4444515ef4a3531bde4439cc76872359 100644 --- a/include/header.php +++ b/include/header.php @@ -8,6 +8,8 @@ <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> <link rel="stylesheet" href="css/style.css" /> + <link rel="stylesheet" href="css/animation.css" /> + <script src="js/script.js"></script> </head> <body> <header id="main-header"> diff --git a/include/init.php b/include/init.php index 086d512461d038c60f952177a096019f21803651..dccbb58e6b4d7750e32089660ae98e95ba800940 100644 --- a/include/init.php +++ b/include/init.php @@ -45,8 +45,19 @@ date_default_timezone_set("Europe/Rome"); $log = new Monolog\Logger('mainLogger'); $log->pushHandler(new Monolog\Handler\StreamHandler($LOG_PATH, $LOG_LEVEL)); +switch ($DATABASE['dbtype']) { + case 'MySQL': + $dao = new RAP\MySQLDAO($DATABASE); + break; + default: + throw new Exception($DATABASE['dbtype'] . ' not supported yet'); +} + +$callbackHandler = new RAP\CallbackHandler($dao, $BASE_PATH, $CALLBACKS); +$userHandler = new RAP\UserHandler($dao, $GROUPER); + function startSession() { session_start(); - global $session; - $session = RAP\SessionData::get(); + global $session, $dao; + $session = RAP\SessionData::get($dao); } diff --git a/include/rest-web-service.php b/include/rest-web-service.php index 2eca4f1a0dc0194785daa851b242d21475030ab3..27aca4c81db10b482bead590619a21964df4c798 100644 --- a/include/rest-web-service.php +++ b/include/rest-web-service.php @@ -8,15 +8,17 @@ $WS_PREFIX = '/ws'; Flight::route('GET ' . $WS_PREFIX . '/user-info', function() { + global $dao; + $token = Flight::request()->query['token']; - $userData = RAP\DAO::get()->findLoginToken($token); + $userData = $dao->findLoginToken($token); if (is_null($userData)) { http_response_code(404); die("Token not found"); } - RAP\DAO::get()->deleteLoginToken($token); + $dao->deleteLoginToken($token); header('Content-Type: text/plain'); echo $userData; @@ -24,7 +26,9 @@ Flight::route('GET ' . $WS_PREFIX . '/user-info', function() { Flight::route('GET ' . $WS_PREFIX . '/user/@userId', function($userId) { - $user = RAP\DAO::get()->findUserById($userId); + global $dao; + + $user = $dao->findUserById($userId); if ($user !== null) { header('Content-Type: application/json'); echo json_encode($user); @@ -36,8 +40,10 @@ Flight::route('GET ' . $WS_PREFIX . '/user/@userId', function($userId) { Flight::route('GET ' . $WS_PREFIX . '/user', function() { + global $dao; + $searchText = Flight::request()->query['search']; - $users = RAP\DAO::get()->searchUser($searchText); + $users = $dao->searchUser($searchText); echo json_encode($users); }); diff --git a/include/user-data.php b/include/user-data.php index 755cfcd9acfa5a483f55604cdd0af9041263a6fa..92219036c1c580bd6daa1160edd0bbce14a5a806 100644 --- a/include/user-data.php +++ b/include/user-data.php @@ -1,6 +1,19 @@ <?php foreach ($user->identities as $identity) { ?> <dl class="dl-horizontal"> - <dt>Type</dt> + <dt> + <?php if ($identity->primary) { ?> + <span class="primary-identity-icon" data-toggle="tooltip" data-placement="left" title="This is your primary identity. You will receive email messages on the address related to this identity."> + <span class="glyphicon glyphicon-star"></span> + </span> + <?php } else { ?> + <span class="primary-identity-icon" data-toggle="tooltip" data-placement="left" title="Click on this icon to set this as the primary identity"> + <a href="#" onclick="setPrimaryIdentity(<?php echo $identity->id; ?>);"> + <span class="glyphicon glyphicon-star-empty"></span> + </a> + </span> + <?php } ?> + Type + </dt> <dd><?php echo $identity->type; ?></dd> <dt>E-mail</dt> <dd><?php echo $identity->email; ?></dd> @@ -8,10 +21,6 @@ <dt>EduPersonPrincipalName</dt> <dd><?php echo $identity->eppn; ?></dd> <?php } ?> - <?php if ($identity->username !== null) { ?> - <dt>Username</dt> - <dd><?php echo $identity->username; ?></dd> - <?php } ?> <?php if ($identity->name !== null) { ?> <dt>Name</dt> <dd><?php echo $identity->name; ?></dd> diff --git a/js/index.js b/js/index.js index bc1a24912f0b0cf0963f036dafa5204d193bf5ac..7ca705780f22db0aa06120a4857979892095b30f 100644 --- a/js/index.js +++ b/js/index.js @@ -34,6 +34,20 @@ } } + window.setPrimaryIdentity = function (identityId) { + $.post('primary-identity', { + id: identityId + }, function (response) { + $('#panel-identities .panel-body').html(response); + // restore tooltips + loadTooltips(); + }); + }; + + function loadTooltips() { + $('.primary-identity-icon').tooltip(); + } + // When the document is loaded $(document).ready(function () { @@ -52,6 +66,8 @@ $(document).on('click', '#info-message-alert .close', function () { $('#info-message-alert').addClass('hide'); }); + + loadTooltips(); }); })(jQuery); \ No newline at end of file diff --git a/js/script.js b/js/script.js new file mode 100644 index 0000000000000000000000000000000000000000..744088f5a496bb7552150503c5872c39dcbc71e8 --- /dev/null +++ b/js/script.js @@ -0,0 +1,14 @@ +(function ($) { + + // Loading/waiting animation + window.showWaiting = function () { + $('.waiting').removeClass('hide'); + }; + window.hideWaiting = function () { + $('.waiting').addClass('hide'); + }; + + $(document).ajaxStart(showWaiting); + $(document).ajaxStop(hideWaiting); + +})(jQuery); \ No newline at end of file diff --git a/sql/setup-database.sql b/sql/setup-database.sql index 60bdc47858125b2832c28a9938c56e82ca392f96..8bb38e087f120b4dd5720fbe035cdda090eb01bb 100644 --- a/sql/setup-database.sql +++ b/sql/setup-database.sql @@ -1,5 +1,6 @@ CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, + `primary_identity` bigint(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -17,13 +18,9 @@ CREATE TABLE `identity` ( 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; +SET FOREIGN_KEY_CHECKS=0; +ALTER TABLE `user` ADD FOREIGN KEY (`primary_identity`) REFERENCES `identity`(`id`); +SET FOREIGN_KEY_CHECKS=1; CREATE TABLE `login_token` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, diff --git a/views/confirm-join.php b/views/confirm-join.php index 60ef13782a4f7d2a4dbec215895f46f8ee2a15e3..aafd5fda9fdbd7f54655209097d6796ffdb2f783 100644 --- a/views/confirm-join.php +++ b/views/confirm-join.php @@ -35,7 +35,7 @@ include 'include/header.php'; <div class="row"> <div class="col-xs-12 text-center"> - <p>Pressing the following button the identities listed below will be joined.</p> + <p>Pressing the following button the identities listed above will be joined.</p> <form action="confirm-join" method="POST"> <input type="hidden" name="token" value="<?php echo $token; ?>" /> <input type="submit" class="btn btn-success btn-lg" value="Join users" /> diff --git a/views/index.php b/views/index.php index e5ba7470c53b1d9d79743b7d2b8150dd4219824e..053d47880c349b4137c5589ffe66d432c075d3c0 100644 --- a/views/index.php +++ b/views/index.php @@ -67,7 +67,7 @@ include 'include/header.php'; </div> <div class="row"> <div class="col-sm-5 col-xs-12"> - <div class="panel panel-default"> + <div class="panel panel-default" id="panel-identities"> <div class="panel-heading"> <h3 class="panel-title">Your identities</h3> </div>