Loading classes/CallbackHandler.php +4 −4 Original line number Diff line number Diff line Loading @@ -48,13 +48,13 @@ class CallbackHandler { public static function manageLoginRedirect($user) { global $BASE_PATH, $session; global $BASE_PATH, $session, $log; if (isset($session->callback) && $session->callback !== null) { if ($session->getCallbackURL() !== null) { // External login using token $token = Util::createNewToken(); DAO::get()->insertTokenData($token, $user->id); header('Location: ' . $session->callback . '?token=' . $token); DAO::get()->createLoginToken($token, $user->id); header('Location: ' . $session->getCallbackURL() . '?token=' . $token); } else { // Login in session $session->user = $user; Loading classes/DAO.php +6 −4 Original line number Diff line number Diff line Loading @@ -60,11 +60,13 @@ abstract class DAO { public abstract function createJoinRequest($token, $applicantUserId, $targetUserId); public $config; public abstract function findJoinRequest($token); public function __construct($config) { $this->config = $config; } public abstract function deleteUser($userId); public abstract function joinUsers($userId1, $userId2); public abstract function deleteJoinRequest($token); public static function get() { global $DATABASE; Loading classes/GrouperClient.php 0 → 100644 +110 −0 Original line number Diff line number Diff line <?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 GrouperClient { private $client; function __construct($config) { $this->client = new \SoapClient($config['wsdlURL'], array( 'login' => $config['user'], 'password' => $config['password'], 'trace' => 1, // See: https://bugs.php.net/bug.php?id=36226 'features' => SOAP_SINGLE_ELEMENT_ARRAYS ) ); } private function getBaseRequestParams() { return array( 'clientVersion' => 'v2_3_000' ); } private function startsWith($haystack, $needle) { return strpos($haystack, "$needle", 0) === 0; } private function isSuccess($response) { $success = isset($response->return->resultMetadata) && $response->return->resultMetadata->resultCode === 'SUCCESS'; if (!$success) { throw new \Exception("Web Service Failure. Response=" . json_encode($response)); } return $success; } public function getSubjectGroups($subjectId) { $params = $this->getBaseRequestParams(); $params['subjectLookups'] = array( 'subjectId' => $subjectId, 'subjectSourceId' => 'RAP' ); $response = $this->client->getGroups($params); 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); } } return $groups; } else { throw new \Exception("Wrong results number. Response=" . json_encode($response)); } } } public function addMemberships($subjectId, $groups) { foreach ($groups as $group) { $params = $this->getBaseRequestParams(); $params['subjectId'] = $subjectId; $params['subjectSourceId'] = 'RAP'; $params['groupName'] = $group; $this->client->addMemberLite($params); } } public function removeMemberships($subjectId, $groups) { foreach ($groups as $group) { $params = $this->getBaseRequestParams(); $params['subjectId'] = $subjectId; $params['subjectSourceId'] = 'RAP'; $params['groupName'] = $group; $this->client->deleteMemberLite($params); } } } classes/TokenHandler.php→classes/MailSender.php +3 −13 Original line number Diff line number Diff line Loading @@ -24,20 +24,10 @@ namespace RAP; class TokenHandler { class MailSender { public static function createNewToken($data) { $token = bin2hex(openssl_random_pseudo_bytes(16)); // http://stackoverflow.com/a/18890309/771431 DAO::get()->insertTokenData($token, $data); return $token; } public static function deleteToken($token) { DAO::get()->deleteToken($token); } public static function sendJoinEmail(User $recipientUser, User $applicantUser) { public static function getUserData($token) { return DAO::get()->findTokenData($token); } } classes/MySQLDAO.php +81 −2 Original line number Diff line number Diff line Loading @@ -29,8 +29,12 @@ 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']); global $DATABASE; $connectionString = "mysql:host=" . $DATABASE['hostname'] . ";dbname=" . $DATABASE['dbname']; $dbh = new PDO($connectionString, $DATABASE['username'], $DATABASE['password']); // For transaction errors (see https://stackoverflow.com/a/9659366/771431) $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); return $dbh; } public function createLoginToken($token, $userId) { Loading Loading @@ -130,6 +134,10 @@ class MySQLDAO extends DAO { public function findUserById($userId) { if (!filter_var($userId, FILTER_VALIDATE_INT)) { return null; } $dbh = $this->getDBHandler(); $stmt = $dbh->prepare("SELECT `id`, `type`, `typed_id`, `email`, `local_db_id`, `name`, `surname`, `institution`, `username`, `eppn`" Loading Loading @@ -269,4 +277,75 @@ class MySQLDAO extends DAO { $stmt->execute(); } public function findJoinRequest($token) { $dbh = $this->getDBHandler(); $stmt = $dbh->prepare("SELECT `applicant_user_id`, `target_user_id` FROM `join_request` WHERE `token` = :token"); $stmt->bindParam(':token', $token); $stmt->execute(); $result = $stmt->fetchAll(); switch (count($result)) { case 0: return null; case 1: $row = $result[0]; return [$row['applicant_user_id'], $row['target_user_id']]; default: throw new Exception("Found multiple join request with the same token"); } } public function deleteUser($userId) { $dbh = $this->getDBHandler(); $stmt3 = $dbh->prepare("DELETE FROM TABLE `user` WHERE `id` = :id2"); $stmt3->bindParam(':id2', $userId); $stmt3->execute(); } public function joinUsers($userId1, $userId2) { $dbh = $this->getDBHandler(); try { $dbh->beginTransaction(); // Moving identities from user2 to user1 $stmt1 = $dbh->prepare("UPDATE `identity` SET `user_id` = :id1 WHERE `user_id` = :id2"); $stmt1->bindParam(':id1', $userId1); $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); $stmt3->execute(); // Deleting user2 $stmt4 = $dbh->prepare("DELETE FROM `user` WHERE `id` = :id2"); $stmt4->bindParam(':id2', $userId2); $stmt4->execute(); $dbh->commit(); } catch (Exception $ex) { $dbh->rollBack(); throw $ex; } } public function deleteJoinRequest($token) { $dbh = $this->getDBHandler(); $stmt = $dbh->prepare("DELETE FROM `join_request` WHERE `token` = :token"); $stmt->bindParam(':token', $token); $stmt->execute(); } } Loading
classes/CallbackHandler.php +4 −4 Original line number Diff line number Diff line Loading @@ -48,13 +48,13 @@ class CallbackHandler { public static function manageLoginRedirect($user) { global $BASE_PATH, $session; global $BASE_PATH, $session, $log; if (isset($session->callback) && $session->callback !== null) { if ($session->getCallbackURL() !== null) { // External login using token $token = Util::createNewToken(); DAO::get()->insertTokenData($token, $user->id); header('Location: ' . $session->callback . '?token=' . $token); DAO::get()->createLoginToken($token, $user->id); header('Location: ' . $session->getCallbackURL() . '?token=' . $token); } else { // Login in session $session->user = $user; Loading
classes/DAO.php +6 −4 Original line number Diff line number Diff line Loading @@ -60,11 +60,13 @@ abstract class DAO { public abstract function createJoinRequest($token, $applicantUserId, $targetUserId); public $config; public abstract function findJoinRequest($token); public function __construct($config) { $this->config = $config; } public abstract function deleteUser($userId); public abstract function joinUsers($userId1, $userId2); public abstract function deleteJoinRequest($token); public static function get() { global $DATABASE; Loading
classes/GrouperClient.php 0 → 100644 +110 −0 Original line number Diff line number Diff line <?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 GrouperClient { private $client; function __construct($config) { $this->client = new \SoapClient($config['wsdlURL'], array( 'login' => $config['user'], 'password' => $config['password'], 'trace' => 1, // See: https://bugs.php.net/bug.php?id=36226 'features' => SOAP_SINGLE_ELEMENT_ARRAYS ) ); } private function getBaseRequestParams() { return array( 'clientVersion' => 'v2_3_000' ); } private function startsWith($haystack, $needle) { return strpos($haystack, "$needle", 0) === 0; } private function isSuccess($response) { $success = isset($response->return->resultMetadata) && $response->return->resultMetadata->resultCode === 'SUCCESS'; if (!$success) { throw new \Exception("Web Service Failure. Response=" . json_encode($response)); } return $success; } public function getSubjectGroups($subjectId) { $params = $this->getBaseRequestParams(); $params['subjectLookups'] = array( 'subjectId' => $subjectId, 'subjectSourceId' => 'RAP' ); $response = $this->client->getGroups($params); 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); } } return $groups; } else { throw new \Exception("Wrong results number. Response=" . json_encode($response)); } } } public function addMemberships($subjectId, $groups) { foreach ($groups as $group) { $params = $this->getBaseRequestParams(); $params['subjectId'] = $subjectId; $params['subjectSourceId'] = 'RAP'; $params['groupName'] = $group; $this->client->addMemberLite($params); } } public function removeMemberships($subjectId, $groups) { foreach ($groups as $group) { $params = $this->getBaseRequestParams(); $params['subjectId'] = $subjectId; $params['subjectSourceId'] = 'RAP'; $params['groupName'] = $group; $this->client->deleteMemberLite($params); } } }
classes/TokenHandler.php→classes/MailSender.php +3 −13 Original line number Diff line number Diff line Loading @@ -24,20 +24,10 @@ namespace RAP; class TokenHandler { class MailSender { public static function createNewToken($data) { $token = bin2hex(openssl_random_pseudo_bytes(16)); // http://stackoverflow.com/a/18890309/771431 DAO::get()->insertTokenData($token, $data); return $token; } public static function deleteToken($token) { DAO::get()->deleteToken($token); } public static function sendJoinEmail(User $recipientUser, User $applicantUser) { public static function getUserData($token) { return DAO::get()->findTokenData($token); } }
classes/MySQLDAO.php +81 −2 Original line number Diff line number Diff line Loading @@ -29,8 +29,12 @@ 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']); global $DATABASE; $connectionString = "mysql:host=" . $DATABASE['hostname'] . ";dbname=" . $DATABASE['dbname']; $dbh = new PDO($connectionString, $DATABASE['username'], $DATABASE['password']); // For transaction errors (see https://stackoverflow.com/a/9659366/771431) $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); return $dbh; } public function createLoginToken($token, $userId) { Loading Loading @@ -130,6 +134,10 @@ class MySQLDAO extends DAO { public function findUserById($userId) { if (!filter_var($userId, FILTER_VALIDATE_INT)) { return null; } $dbh = $this->getDBHandler(); $stmt = $dbh->prepare("SELECT `id`, `type`, `typed_id`, `email`, `local_db_id`, `name`, `surname`, `institution`, `username`, `eppn`" Loading Loading @@ -269,4 +277,75 @@ class MySQLDAO extends DAO { $stmt->execute(); } public function findJoinRequest($token) { $dbh = $this->getDBHandler(); $stmt = $dbh->prepare("SELECT `applicant_user_id`, `target_user_id` FROM `join_request` WHERE `token` = :token"); $stmt->bindParam(':token', $token); $stmt->execute(); $result = $stmt->fetchAll(); switch (count($result)) { case 0: return null; case 1: $row = $result[0]; return [$row['applicant_user_id'], $row['target_user_id']]; default: throw new Exception("Found multiple join request with the same token"); } } public function deleteUser($userId) { $dbh = $this->getDBHandler(); $stmt3 = $dbh->prepare("DELETE FROM TABLE `user` WHERE `id` = :id2"); $stmt3->bindParam(':id2', $userId); $stmt3->execute(); } public function joinUsers($userId1, $userId2) { $dbh = $this->getDBHandler(); try { $dbh->beginTransaction(); // Moving identities from user2 to user1 $stmt1 = $dbh->prepare("UPDATE `identity` SET `user_id` = :id1 WHERE `user_id` = :id2"); $stmt1->bindParam(':id1', $userId1); $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); $stmt3->execute(); // Deleting user2 $stmt4 = $dbh->prepare("DELETE FROM `user` WHERE `id` = :id2"); $stmt4->bindParam(':id2', $userId2); $stmt4->execute(); $dbh->commit(); } catch (Exception $ex) { $dbh->rollBack(); throw $ex; } } public function deleteJoinRequest($token) { $dbh = $this->getDBHandler(); $stmt = $dbh->prepare("DELETE FROM `join_request` WHERE `token` = :token"); $stmt->bindParam(':token', $token); $stmt->execute(); } }