diff --git a/auth/saml2/aai.php b/auth/saml2/aai.php deleted file mode 100644 index 0b8277958298ca17ce7f111d99336cdf8c878078..0000000000000000000000000000000000000000 --- a/auth/saml2/aai.php +++ /dev/null @@ -1,71 +0,0 @@ -<?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. - */ - -/* This page MUST be protected by Shibboleth authentication - * On Apache httpd: - * AuthType shibboleth - * ShibRequestSetting requireSession 1 - * Require valid-user - */ - -include '../../include/init.php'; -startSession(); - -if (isset($_SERVER['Shib-Session-ID'])) { - - // Retrieving eduPersonPrincipalName (eppn) - $eppn = $_SERVER['eppn']; - - // Search if the user is already registered into RAP using the eppn. - // The persistent id should be a more appropriate identifier, however at IA2 - // we need to import all INAF user into RAP, even if they will never register, - // and in that case we know only their eppn. - $user = $userHandler->findUserByIdentity(RAP\Identity::EDU_GAIN, $eppn); - - if ($user === null) { - // Creating a new user - $user = new RAP\User(); - - $identity = new RAP\Identity(RAP\Identity::EDU_GAIN); - $identity->email = $_SERVER['mail']; - $identity->name = $_SERVER['givenName']; - $identity->surname = $_SERVER['sn']; - $identity->typedId = $eppn; - $identity->eppn = $eppn; - //$_SERVER['Shib-Identity-Provider'] - - $user->addIdentity($identity); - - $session->userToLogin = $user; - $session->save(); - header('Location: ' . $BASE_PATH . '/tou-check'); - die(); - } - - $auditLog->info("LOGIN,eduGAIN," . $user->id); - $callbackHandler->manageLoginRedirect($user, $session); -} else { - http_response_code(500); - die("Shib-Session-ID not found!"); -} diff --git a/auth/social/facebook_login.php b/auth/social/facebook_login.php deleted file mode 100755 index 844cf9f6a6dc8c677f1f43c1229a89e949d3bda3..0000000000000000000000000000000000000000 --- a/auth/social/facebook_login.php +++ /dev/null @@ -1,46 +0,0 @@ -<?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. - */ - -/* This page uses the Facebook API for generating the redirect URL to use for Facebook login */ - -include '../../include/init.php'; -startSession(); - -// Retrieve Facebook configuration -$Facebook = $AUTHENTICATION_METHODS['Facebook']; - -$fb = new Facebook\Facebook([ - 'app_id' => $Facebook['id'], - 'app_secret' => $Facebook['secret'], - 'default_graph_version' => $Facebook['version'], - ]); - -$helper = $fb->getRedirectLoginHelper(); - -$permissions = ['email']; // Optional permissions: we need user email - -$loginUrl = $helper->getLoginUrl($Facebook['callback'], $permissions); - -header("Location: $loginUrl"); -?> diff --git a/auth/social/facebook_token.php b/auth/social/facebook_token.php deleted file mode 100755 index ef7446143aea2c92d8cf87bcd2bcbe322a60bc0e..0000000000000000000000000000000000000000 --- a/auth/social/facebook_token.php +++ /dev/null @@ -1,111 +0,0 @@ -<?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. - */ - -/* Facebook callback page */ - -include '../../include/init.php'; -startSession(); - -// Retrieve Facebook configuration -$Facebook = $AUTHENTICATION_METHODS['Facebook']; - -$fb = new Facebook\Facebook([ - 'app_id' => $Facebook['id'], - 'app_secret' => $Facebook['secret'], - 'default_graph_version' => $Facebook['version'], - ]); - -$helper = $fb->getRedirectLoginHelper(); -if (isset($_GET['state'])) { - $helper->getPersistentDataHandler()->set('state', $_GET['state']); -} - -try { - // obtaining current URL without query string - $url = "https://$_SERVER[HTTP_HOST]" . strtok($_SERVER["REQUEST_URI"], '?'); - $accessToken = $helper->getAccessToken($url); -} catch (Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - http_response_code(500); - die('Graph returned an error: ' . $e->getMessage()); -} catch (Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - http_response_code(500); - die('Facebook SDK returned an error: ' . $e->getMessage()); -} -if (!isset($accessToken)) { - if ($helper->getError()) { - $errorMessage = "Error: " . $helper->getError() . "<br>"; - $errorMessage = $errorMessage . "Error Code: " . $helper->getErrorCode() . "<br>"; - $errorMessage = $errorMessage . "Error Reason: " . $helper->getErrorReason() . "<br>"; - $errorMessage = $errorMessage . "Error Description: " . $helper->getErrorDescription(); - } else { - $errorMessage = "Bad request"; - } - - http_response_code(500); - die($errorMessage); -} - -try { - // Returns a `Facebook\FacebookResponse` object - $response = $fb->get('/me?fields=id,first_name,last_name,email', $accessToken); -} catch (Facebook\Exceptions\FacebookResponseException $e) { - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch (Facebook\Exceptions\FacebookSDKException $e) { - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -$_SESSION['fb_access_token'] = (string) $accessToken; - -$fbUser = $response->getGraphUser(); - -$typedId = $fbUser["id"]; - -// Search if the user is already registered into RAP using the Facebook ID. -$user = $userHandler->findUserByIdentity(RAP\Identity::FACEBOOK, $typedId); - -if ($user === null) { - // Create new user - $user = new RAP\User(); - - $identity = new RAP\Identity(RAP\Identity::FACEBOOK); - $identity->email = $fbUser["email"]; - $identity->name = $fbUser["first_name"]; - $identity->surname = $fbUser["last_name"]; - $identity->typedId = $typedId; - - $user->addIdentity($identity); - - $session->userToLogin = $user; - $session->save(); - header('Location: ' . $BASE_PATH . '/tou-check'); - die(); -} - -$auditLog->info("LOGIN,Facebook," . $user->id); -$callbackHandler->manageLoginRedirect($user, $session); -?> diff --git a/auth/social/google_token.php b/auth/social/google_token.php deleted file mode 100644 index 16831cc69bb0a67df476cc4a2e6a4f29b86d5db8..0000000000000000000000000000000000000000 --- a/auth/social/google_token.php +++ /dev/null @@ -1,111 +0,0 @@ -<?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. - */ - -/* Google redirect and callback page */ - -include '../../include/init.php'; -startSession(); - -// Retrieve Google configuration -$Google = $AUTHENTICATION_METHODS['Google']; - -$client = new Google_Client(array( - 'client_id' => $Google['id'], - 'client_secret' => $Google['secret'], - 'redirect_uri' => $Google['callback'], - )); - -// Ask permission to obtain user email and profile information -$client->setScopes(array(Google_Service_People::USERINFO_EMAIL, Google_Service_People::USERINFO_PROFILE)); - -if (isset($_REQUEST['logout'])) { -// Reset the access token stored into the session - unset($_SESSION['access_token']); -} - -if (isset($_GET['code'])) { -// An access token has been returned from the auth URL. - $client->authenticate($_GET['code']); - $_SESSION['access_token'] = $client->getAccessToken(); -} - -//if (isset($_SESSION['access_token'])) { -// $client->setAccessToken($_SESSION['access_token']); -//} - -if ($client->getAccessToken()) { - - // Query web service for retrieving user information - $service = new Google_Service_People($client); - - try { - $res = $service->people->get('people/me', array('requestMask.includeField' => 'person.names,person.email_addresses')); - } catch (Google_Service_Exception $e) { - echo '<p>' . json_encode($e->getErrors()) . '</p>'; - $thisPage = $PROTOCOL . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']; - echo '<p><a href="' . $thisPage . '?logout">Click here to unset the access token</a></p>'; - } - - $name = $res->getNames()[0]->getGivenName(); - $surname = $res->getNames()[0]->getFamilyName(); - - $emailAddresses = []; - foreach ($res->getEmailAddresses() as $addr) { - array_push($emailAddresses, $addr->value); - } - - $typedId = explode('/', $res->getResourceName())[1]; - - // Search if the user is already registered into RAP using the Google ID. - $user = $userHandler->findUserByIdentity(RAP\Identity::GOOGLE, $typedId); - - if ($user === null) { - // Create new user - $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); - - $session->userToLogin = $user; - $session->save(); - header('Location: ' . $BASE_PATH . '/tou-check'); - die(); - } - - $auditLog->info("LOGIN,Google," . $user->id); - $callbackHandler->manageLoginRedirect($user, $session); - - die(); -} else { - // Redirect to Google authorization URL for obtaining an access token - $authUrl = $client->createAuthUrl(); - header('Location: ' . $authUrl); - die(); -} -?> diff --git a/auth/social/linkedin_login.php b/auth/social/linkedin_login.php deleted file mode 100644 index 2c64969c6e03d78549090327a7af3cc67fa5b61a..0000000000000000000000000000000000000000 --- a/auth/social/linkedin_login.php +++ /dev/null @@ -1,40 +0,0 @@ -<?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. - */ - -/* This page redirects to LinkedIn login page */ - -include '../../include/init.php'; -startSession(); - -// Retrieve LinkedIn configuration -$LinkedIn = $AUTHENTICATION_METHODS['LinkedIn']; - -$url = "https://www.linkedin.com/oauth/v2/authorization?response_type=code"; -$url .= "&client_id=" . $LinkedIn['id']; -$url .= "&redirect_uri=" . $LinkedIn['callback']; -$url .= "&state=789654123"; -$url .= "&scope=r_basicprofile r_emailaddress"; - -header("Location: $url"); -?> diff --git a/auth/social/linkedin_token.php b/auth/social/linkedin_token.php deleted file mode 100644 index 64a564733dcc1ddd1d79c8cfa1ba866aaf0e2046..0000000000000000000000000000000000000000 --- a/auth/social/linkedin_token.php +++ /dev/null @@ -1,136 +0,0 @@ -<?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. - */ - -/* LinkedIn callback page. Curl is used, because LinkedIn doesn't provide official PHP API. */ - -include '../../include/init.php'; -startSession(); - -// Retrieve LinkedIn configuration -$LinkedIn = $AUTHENTICATION_METHODS['LinkedIn']; - -if (!isset($_REQUEST['code'])) { - die("Unable to get LinkedIn client code"); -} - -//create array of data to be posted to get AccessToken -$post_data = array( - 'grant_type' => "authorization_code", - 'code' => $_REQUEST['code'], - 'redirect_uri' => $LinkedIn['callback'], - 'client_id' => $LinkedIn['id'], - 'client_secret' => $LinkedIn['secret']); - -//traverse array and prepare data for posting (key1=value1) -foreach ($post_data as $key => $value) { - $post_items[] = $key . '=' . $value; -} - -//create the final string to be posted -$post_string = implode('&', $post_items); - -//create cURL connection -$conn1 = curl_init('https://www.linkedin.com/oauth/v2/accessToken'); - -//set options -curl_setopt($conn1, CURLOPT_CONNECTTIMEOUT, 30); -curl_setopt($conn1, CURLOPT_RETURNTRANSFER, true); -curl_setopt($conn1, CURLOPT_SSL_VERIFYPEER, true); -curl_setopt($conn1, CURLOPT_FOLLOWLOCATION, 1); - -//set data to be posted -curl_setopt($conn1, CURLOPT_POSTFIELDS, $post_string); - -//perform our request -$result1 = curl_exec($conn1); -$info1 = curl_getinfo($conn1); - -if ($info1['http_code'] === 200) { - $my_token = json_decode($result1, TRUE); - $access_token = $my_token['access_token']; - $expires_in = $my_token['expires_in']; - curl_close($conn1); -} else { - //show information regarding the error - $errorMessage = "Error: LinkedIn server response code: " . $info1['http_code'] . " - "; - $errorMessage .= curl_error($conn1); - curl_close($conn1); - http_response_code(500); - die($errorMessage); -} - -// Call to API -$conn2 = curl_init(); -curl_setopt($conn2, CURLOPT_URL, "https://api.linkedin.com/v1/people/~:(first-name,last-name,email-address,id)?format=json"); -curl_setopt($conn2, CURLOPT_HTTPHEADER, array( - 'Authorization: Bearer ' . $access_token -)); - -curl_setopt($conn2, CURLOPT_RETURNTRANSFER, true); -$result = curl_exec($conn2); -$info2 = curl_getinfo($conn2); - -if ($info2['http_code'] === 200) { - $data = json_decode($result, TRUE); - - curl_close($conn2); - - if (isset($data['errorCode'])) { - $errorMessage = $data['message']; - die($errorMessage); - } - - $typedId = $data['id']; - - // Search if the user is already registered into RAP using the LinkedIn ID. - $user = $userHandler->findUserByIdentity(RAP\Identity::LINKEDIN, $typedId); - - if ($user === null) { - // Create new user - $user = new RAP\User(); - - $identity = new RAP\Identity(RAP\Identity::LINKEDIN); - $identity->email = $data['emailAddress']; - $identity->name = $data['firstName']; - $identity->surname = $data['lastName']; - $identity->typedId = $typedId; - - $user->addIdentity($identity); - - $session->userToLogin = $user; - $session->save(); - header('Location: ' . $BASE_PATH . '/tou-check'); - die(); - } - - $auditLog->info("LOGIN,LinkedIn," . $user->id); - $callbackHandler->manageLoginRedirect($user, $session); -} else { - //show information regarding the error - $errorMessage = "Error: LinkedIn server response code: " . $info2['http_code'] . " - "; - $errorMessage = $errorMessage . curl_error($conn2); - curl_close($conn2); - die($errorMessage); -} -?> diff --git a/auth/x509/certlogin.php b/auth/x509/certlogin.php deleted file mode 100644 index c811cd83f49fbd3d9df74134901c9fca3f38120c..0000000000000000000000000000000000000000 --- a/auth/x509/certlogin.php +++ /dev/null @@ -1,69 +0,0 @@ -<?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. - */ - -/* This page must be protected by client certificate authentication - * On Apache httpd: - * SSLVerifyClient require - * SSLVerifyDepth 10 - * SSLOptions +ExportCertData - */ - -include '../../include/init.php'; -startSession(); - -if (isset($_SERVER['SSL_CLIENT_VERIFY']) && isset($_SERVER['SSL_CLIENT_V_REMAIN']) && - $_SERVER['SSL_CLIENT_VERIFY'] === 'SUCCESS' && $_SERVER['SSL_CLIENT_V_REMAIN'] > 0) { - - $x509Data = RAP\X509Data::parse($_SERVER); - - $user = $userHandler->findUserByIdentity(RAP\Identity::X509, $x509Data->serialNumber); - - if ($user === null) { - /** - * We want to extract name and surname from the X.509 certificate, however X.509 - * puts name and surname together (inside the CN field). - * If name and surname are single words it is possible to retrieve them splitting - * on the space character, otherwise the user has to choose the correct combination. - * In that case partial X.509 data is temporarily stored into the user session and - * the page views/x509-name-surname.php is shown to the user before completing the - * registration, in order to allow him/her selecting the correct name and surname. - */ - if ($x509Data->name === null) { - $session->x509DataToRegister = $x509Data; - $session->save(); - header('Location: ' . $BASE_PATH . '/x509-name-surname'); - } else { - $session->userToLogin = $x509Data->toUser(); - $session->save(); - header('Location: ' . $BASE_PATH . '/tou-check'); - } - die(); - } else { - $auditLog->info("LOGIN,X.509," . $user->id); - $callbackHandler->manageLoginRedirect($user, $session); - } -} else { - http_response_code(500); - die("Unable to verify client certificate"); -} diff --git a/classes/CallbackHandler.php b/classes/CallbackHandler.php deleted file mode 100644 index 5c5fbbee0b5b804c8d222ec6d8bbee9c299d7896..0000000000000000000000000000000000000000 --- a/classes/CallbackHandler.php +++ /dev/null @@ -1,126 +0,0 @@ -<?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; - -/** - * Manage callback URL validation and redirection - */ -class CallbackHandler { - - private $locator; - - public function __construct(Locator $locator) { - $this->locator = $locator; - } - - /** - * If a callback URL is not in the configured list we should return null. - */ - public function filterCallbackURL($callbackURL) { - foreach ($this->callbacks as $callback) { - if ($callback['url'] === $callbackURL) { - return $callbackURL; - } - } - return null; - } - - /** - * Each callback has a title and a logo in order to avoid confusion in users - * and show in which application they are logging in using RAP. - * @param type $callbackURL - * @return type the callback title or null if the callback URL is not listed - * in configuration file or it doesn't have a title. - */ - public function getCallbackTitle($callbackURL) { - - foreach ($this->callbacks as $callback) { - if ($callback['url'] === $callbackURL) { - return $callback['title']; - } - } - - return null; - } - - /** - * Each callback has a title and a logo in order to avoid confusion in users - * and show in which application they are logging in using RAP. - * @param type $callbackURL - * @return type the callback logo or null if the callback URL is not listed - * in configuration file or it doesn't have a logo. - */ - public function getCallbackLogo($callbackURL) { - - foreach ($this->callbacks as $callback) { - if ($callback['url'] === $callbackURL) { - if (array_key_exists('logo', $callback)) { - return $callback['logo']; - } else { - return null; - } - } - } - - return null; - } - - public function manageLoginRedirect(User $user, SessionData $session) { - - if($session->getOAuth2Data() !== null) { - $session->user = $user; - $session->save(); - $redirectUrl = $this->locator->getOAuth2RequestHandler()->getCodeResponseUrl(); - $session->setOAuth2Data(null); - header('Location: ' . $redirectUrl); - die(); - } - - if ($session->getCallbackURL() === null) { - http_response_code(401); - die("Unauthorized callback URL"); - } - - if ($session->getCallbackURL() === $this->basePath . '/') { - // Login in session - $session->user = $user; - $session->save(); - // Return to index - header('Location: ' . $this->basePath); - die(); - } else { - // External login using token - header('Location: ' . $this->getLoginWithTokenURL($user->id, $session->getCallbackURL())); - die(); - } - } - - public function getLoginWithTokenURL($userId, $callbackURL) { - $token = Util::createNewToken(); - $this->dao->createLoginToken($token, $userId); - return $callbackURL . '?token=' . $token; - } - -} diff --git a/classes/IdTokenBuilder.php b/classes/IdTokenBuilder.php index 4150c0ccdcbc0c146f6003682589be46cb189db5..cef3321aa36d6ca8752660bf89e1570ddc276ca6 100644 --- a/classes/IdTokenBuilder.php +++ b/classes/IdTokenBuilder.php @@ -23,7 +23,7 @@ class IdTokenBuilder { private function createPayloadArray(AccessToken $accessToken) { - $user = $this->locator->getDAO()->findUserById($accessToken->userId); + $user = $this->locator->getUserDAO()->findUserById($accessToken->userId); $payloadArr = array( 'iss' => $this->locator->config->jwtIssuer, diff --git a/classes/Locator.php b/classes/Locator.php index a1e5942891b89601e66ad292862c684041768880..35fe98275fd6c16848b37d7469e57b664b537d50 100644 --- a/classes/Locator.php +++ b/classes/Locator.php @@ -32,11 +32,21 @@ class Locator { return $this->getProtocol() . $_SERVER['HTTP_HOST'] . $this->config->contextRoot; } - public function getDAO(): DAO { + public function getUserDAO(): UserDAO { $databaseConfig = $this->config->databaseConfig; switch ($databaseConfig->dbtype) { case 'MySQL': - return new MySQLDAO($this); + return new MySQLUserDAO($this); + default: + throw new \Exception($databaseConfig->dbtype . ' not supported yet'); + } + } + + public function getOAuth2ClientDAO(): OAuth2ClientDAO { + $databaseConfig = $this->config->databaseConfig; + switch ($databaseConfig->dbtype) { + case 'MySQL': + return new MySQLOAuth2ClientDAO($this); default: throw new \Exception($databaseConfig->dbtype . ' not supported yet'); } @@ -61,13 +71,13 @@ class Locator { throw new \Exception($databaseConfig->dbtype . ' not supported yet'); } } - + public function getCallbackHandler(): CallbackHandler { return new CallbackHandler($this); } public function getUserHandler(): UserHandler { - return new UserHandler($this->getDAO()); + return new UserHandler($this); } public function getMailSender(): MailSender { diff --git a/classes/OAuth2RequestHandler.php b/classes/OAuth2RequestHandler.php index 4d801f64edaa8fe2a7a8a3525a252a6298e1c02e..aa95981059a57aa6bac7446d4033957652eba073 100644 --- a/classes/OAuth2RequestHandler.php +++ b/classes/OAuth2RequestHandler.php @@ -20,7 +20,7 @@ class OAuth2RequestHandler { throw new BadRequestException("Redirect URI is required"); } - $client = $this->locator->getDAO()->getOAuth2ClientByClientId($params['client_id']); + $client = $this->locator->getOAuth2ClientDAO()->getOAuth2ClientByClientId($params['client_id']); if ($client === null) { throw new BadRequestException("Invalid client id: " . $params['client_id']); } @@ -60,7 +60,7 @@ class OAuth2RequestHandler { $accessToken = new \RAP\AccessToken(); $accessToken->code = base64_encode(bin2hex(openssl_random_pseudo_bytes(64))); $accessToken->token = base64_encode(bin2hex(openssl_random_pseudo_bytes(128))); - $accessToken->userId = $session->user->id; + $accessToken->userId = $session->getUser()->id; $accessToken->clientId = $session->getOAuth2Data()->clientId; $accessToken->redirectUri = $session->getOAuth2Data()->redirectUrl; $accessToken->scope = $session->getOAuth2Data()->scope; @@ -128,7 +128,7 @@ class OAuth2RequestHandler { } $accessToken = $this->locator->getAccessTokenDAO()->getAccessToken($token); - $user = $this->locator->getDAO()->findUserById($accessToken->userId); + $user = $this->locator->getUserDAO()->findUserById($accessToken->userId); $result = []; $result['exp'] = $this->getExpiresIn($accessToken); diff --git a/classes/UserHandler.php b/classes/UserHandler.php index ec0002910d5c447a683dd73558934ab1d9f03003..b98ccdc314024cfb4df33581c0c57d1d2481ddb2 100644 --- a/classes/UserHandler.php +++ b/classes/UserHandler.php @@ -31,8 +31,8 @@ class UserHandler { private $dao; - public function __construct(DAO $dao) { - $this->dao = $dao; + public function __construct(Locator $locator) { + $this->dao = $locator->getUserDAO(); } /** diff --git a/classes/X509Data.php b/classes/X509Data.php index ddfb4028bd44088b4c043b8f4b8127bc3cfd2148..3b8a931378138c4863bca14fa28e617ea3257a76 100644 --- a/classes/X509Data.php +++ b/classes/X509Data.php @@ -203,9 +203,7 @@ class X509Data { return $parsedData; } - public function toUser() { - - $user = new User(); + public function toIdentity() { $identity = new Identity(Identity::X509); $identity->email = $this->email; @@ -214,9 +212,7 @@ class X509Data { $identity->typedId = $this->serialNumber; $identity->institution = $this->institution; - $user->addIdentity($identity); - - return $user; + return $identity; } } diff --git a/classes/datalayer/OAuth2ClientDAO.php b/classes/datalayer/OAuth2ClientDAO.php new file mode 100644 index 0000000000000000000000000000000000000000..9ea29d8af5f66ac7fb1679989554464d6d3473f4 --- /dev/null +++ b/classes/datalayer/OAuth2ClientDAO.php @@ -0,0 +1,23 @@ +<?php + +namespace RAP; + +/** + * CRUD methods for OAuth2Clients (used by admin interface). + */ +interface OAuth2ClientDAO { + + function getOAuth2Clients(): array; + + function createOAuth2Client($client): OAuth2Client; + + function updateOAuth2Client($client): OAuth2Client; + + function deleteOAuth2Client($clientId); + + /** + * Retrieve the client from the configured client id (the one associated to + * the secret, not the database id). + */ + function getOAuth2ClientByClientId($clientId): ?OAuth2Client; +} diff --git a/classes/datalayer/DAO.php b/classes/datalayer/UserDAO.php similarity index 84% rename from classes/datalayer/DAO.php rename to classes/datalayer/UserDAO.php index 4de0886db83f7d9859c8b09d15a6664e0e065577..e37603ee7cd81881cf5bc2921984592e77c311fb 100644 --- a/classes/datalayer/DAO.php +++ b/classes/datalayer/UserDAO.php @@ -24,11 +24,7 @@ namespace RAP; -/** - * Data Access Object interface for accessing the RAP database. - * Current implementations: RAP\MySQLDAO - */ -interface DAO { +interface UserDAO { /** * Create a new identity. @@ -98,20 +94,4 @@ interface DAO { */ function deleteJoinRequest($token); - /** - * CRUD methods for OAuth2Clients (used by admin interface). - */ - function getOAuth2Clients(); - - function createOAuth2Client($client): OAuth2Client; - - function updateOAuth2Client($client): OAuth2Client; - - function deleteOAuth2Client($clientId); - - /** - * Retrieve the client from the configured client id (the one associated to - * the secret, not the database id). - */ - function getOAuth2ClientByClientId($clientId): ?OAuth2Client; } diff --git a/classes/datalayer/mysql/MySQLOAuth2ClientDAO.php b/classes/datalayer/mysql/MySQLOAuth2ClientDAO.php new file mode 100644 index 0000000000000000000000000000000000000000..20cc7a45d299337ad053508fce086f8df65b15cf --- /dev/null +++ b/classes/datalayer/mysql/MySQLOAuth2ClientDAO.php @@ -0,0 +1,200 @@ +<?php + +namespace RAP; + +class MySQLOAuth2ClientDAO extends BaseMySQLDAO implements OAuth2ClientDAO { + + public function __construct($config) { + parent::__construct($config); + } + + function getOAuth2Clients(): array { + $dbh = $this->getDBHandler(); + + // Load clients info + $queryClient = "SELECT id, title, icon, client, secret, redirect_url, scope FROM oauth2_client"; + $stmtClients = $dbh->prepare($queryClient); + $stmtClients->execute(); + + $clientsMap = []; + + foreach ($stmtClients->fetchAll() as $row) { + $client = new OAuth2Client(); + $client->id = $row['id']; + $client->title = $row['title']; + $client->icon = $row['icon']; + $client->client = $row['client']; + $client->secret = $row['secret']; + $client->redirectUrl = $row['redirect_url']; + $client->scope = $row['scope']; + $clientsMap[$client->id] = $client; + } + + // Load authentication methods info + $queryAuthNMethods = "SELECT client_id, auth_method FROM oauth2_client_auth_methods"; + + $stmtAuthNMethods = $dbh->prepare($queryAuthNMethods); + $stmtAuthNMethods->execute(); + + foreach ($stmtAuthNMethods->fetchAll() as $row) { + $id = $row['client_id']; + array_push($clientsMap[$id]->authMethods, $row['auth_method']); + } + + $clients = []; + foreach ($clientsMap as $id => $client) { + array_push($clients, $client); + } + + return $clients; + } + + function createOAuth2Client($client): OAuth2Client { + $dbh = $this->getDBHandler(); + + try { + $dbh->beginTransaction(); + + $stmt = $dbh->prepare("INSERT INTO `oauth2_client`(`title`, `icon`, `client`, `secret`, `redirect_url`, `scope`)" + . " VALUES(:title, :icon, :client, :secret, :redirect_url, :scope)"); + + $stmt->bindParam(':title', $client->title); + $stmt->bindParam(':icon', $client->icon); + $stmt->bindParam(':client', $client->client); + $stmt->bindParam(':secret', $client->secret); + $stmt->bindParam(':redirect_url', $client->redirectUrl); + $stmt->bindParam(':scope', $client->scope); + + $stmt->execute(); + + $client->id = $dbh->lastInsertId(); + + foreach ($client->authMethods as $method) { + $stmt = $dbh->prepare("INSERT INTO `oauth2_client_auth_methods`(`client_id`, `auth_method`)" + . " VALUES(:client_id, :auth_method)"); + + $stmt->bindParam(':client_id', $client->id); + $stmt->bindParam(':auth_method', $method); + + $stmt->execute(); + } + + $dbh->commit(); + } catch (Exception $ex) { + $dbh->rollBack(); + throw $ex; + } + + return $client; + } + + function updateOAuth2Client($client): OAuth2Client { + $dbh = $this->getDBHandler(); + + try { + $dbh->beginTransaction(); + + $stmt = $dbh->prepare("UPDATE `oauth2_client` SET `title` = :title, `icon` = :icon, " + . " `client` = :client, `secret` = :secret, `redirect_url` = :redirect_url, `scope` = :scope " + . " WHERE id = :id"); + + $stmt->bindParam(':title', $client->title); + $stmt->bindParam(':icon', $client->icon); + $stmt->bindParam(':client', $client->client); + $stmt->bindParam(':secret', $client->secret); + $stmt->bindParam(':redirect_url', $client->redirectUrl); + $stmt->bindParam(':scope', $client->scope); + $stmt->bindParam(':id', $client->id); + + $stmt->execute(); + + // Delete old authentication methods + $stmt = $dbh->prepare("DELETE FROM oauth2_client_auth_methods WHERE client_id = :id"); + $stmt->bindParam(':id', $client->id); + + $stmt->execute(); + + // Re-add authentication methods + foreach ($client->authMethods as $method) { + $stmt = $dbh->prepare("INSERT INTO `oauth2_client_auth_methods`(`client_id`, `auth_method`)" + . " VALUES(:client_id, :auth_method)"); + + $stmt->bindParam(':client_id', $client->id); + $stmt->bindParam(':auth_method', $method); + + $stmt->execute(); + } + + $dbh->commit(); + } catch (Exception $ex) { + $dbh->rollBack(); + throw $ex; + } + + return $client; + } + + function deleteOAuth2Client($clientId) { + $dbh = $this->getDBHandler(); + try { + $dbh->beginTransaction(); + + $stmt = $dbh->prepare("DELETE FROM `oauth2_client_auth_methods` WHERE client_id = :id"); + $stmt->bindParam(':id', $clientId); + $stmt->execute(); + + $stmt = $dbh->prepare("DELETE FROM `oauth2_client` WHERE id = :id"); + $stmt->bindParam(':id', $clientId); + $stmt->execute(); + + $dbh->commit(); + } catch (Exception $ex) { + $dbh->rollBack(); + throw $ex; + } + } + + function getOAuth2ClientByClientId($clientId): ?OAuth2Client { + $dbh = $this->getDBHandler(); + + // Load clients info + $queryClient = "SELECT id, title, icon, client, secret, redirect_url, scope FROM oauth2_client WHERE client = :client"; + $stmtClient = $dbh->prepare($queryClient); + $stmtClient->bindParam(':client', $clientId); + $stmtClient->execute(); + + $result = $stmtClient->fetchAll(); + + if (count($result) === 0) { + return null; + } + if (count($result) > 1) { + throw new Exception("Found multiple clients associated to the same client id!"); + } + + $row = $result[0]; + + $client = new OAuth2Client(); + $client->id = $row['id']; + $client->title = $row['title']; + $client->icon = $row['icon']; + $client->client = $row['client']; + $client->secret = $row['secret']; + $client->redirectUrl = $row['redirect_url']; + $client->scope = $row['scope']; + + // Load authentication methods info + $queryAuthNMethods = "SELECT auth_method FROM oauth2_client_auth_methods WHERE client_id = :id"; + + $stmtAuthNMethods = $dbh->prepare($queryAuthNMethods); + $stmtAuthNMethods->bindParam(':id', $client->id); + $stmtAuthNMethods->execute(); + + foreach ($stmtAuthNMethods->fetchAll() as $row) { + array_push($client->authMethods, $row['auth_method']); + } + + return $client; + } + +} diff --git a/classes/MySQLDAO.php b/classes/datalayer/mysql/MySQLUserDAO.php similarity index 58% rename from classes/MySQLDAO.php rename to classes/datalayer/mysql/MySQLUserDAO.php index 7208695b7467cc5b9c46f6921556dcb8a3d3e218..19a02b5625db1ba4d85a0a647fa3291dd974357f 100644 --- a/classes/MySQLDAO.php +++ b/classes/datalayer/mysql/MySQLUserDAO.php @@ -27,7 +27,7 @@ namespace RAP; /** * MySQL implementation of the DAO interface. See comments on the DAO interface. */ -class MySQLDAO extends BaseMySQLDAO implements DAO { +class MySQLUserDAO extends BaseMySQLDAO implements UserDAO { public function __construct(Locator $locator) { parent::__construct($locator); @@ -277,193 +277,4 @@ class MySQLDAO extends BaseMySQLDAO implements DAO { $stmt->execute(); } - function getOAuth2Clients() { - $dbh = $this->getDBHandler(); - - // Load clients info - $queryClient = "SELECT id, title, icon, client, secret, redirect_url, scope FROM oauth2_client"; - $stmtClients = $dbh->prepare($queryClient); - $stmtClients->execute(); - - $clientsMap = []; - - foreach ($stmtClients->fetchAll() as $row) { - $client = new OAuth2Client(); - $client->id = $row['id']; - $client->title = $row['title']; - $client->icon = $row['icon']; - $client->client = $row['client']; - $client->secret = $row['secret']; - $client->redirectUrl = $row['redirect_url']; - $client->scope = $row['scope']; - $clientsMap[$client->id] = $client; - } - - // Load authentication methods info - $queryAuthNMethods = "SELECT client_id, auth_method FROM oauth2_client_auth_methods"; - - $stmtAuthNMethods = $dbh->prepare($queryAuthNMethods); - $stmtAuthNMethods->execute(); - - foreach ($stmtAuthNMethods->fetchAll() as $row) { - $id = $row['client_id']; - array_push($clientsMap[$id]->authMethods, $row['auth_method']); - } - - $clients = []; - foreach ($clientsMap as $id => $client) { - array_push($clients, $client); - } - - return $clients; - } - - function createOAuth2Client($client): OAuth2Client { - $dbh = $this->getDBHandler(); - - try { - $dbh->beginTransaction(); - - $stmt = $dbh->prepare("INSERT INTO `oauth2_client`(`title`, `icon`, `client`, `secret`, `redirect_url`, `scope`)" - . " VALUES(:title, :icon, :client, :secret, :redirect_url, :scope)"); - - $stmt->bindParam(':title', $client->title); - $stmt->bindParam(':icon', $client->icon); - $stmt->bindParam(':client', $client->client); - $stmt->bindParam(':secret', $client->secret); - $stmt->bindParam(':redirect_url', $client->redirectUrl); - $stmt->bindParam(':scope', $client->scope); - - $stmt->execute(); - - $client->id = $dbh->lastInsertId(); - - foreach ($client->authMethods as $method) { - $stmt = $dbh->prepare("INSERT INTO `oauth2_client_auth_methods`(`client_id`, `auth_method`)" - . " VALUES(:client_id, :auth_method)"); - - $stmt->bindParam(':client_id', $client->id); - $stmt->bindParam(':auth_method', $method); - - $stmt->execute(); - } - - $dbh->commit(); - } catch (Exception $ex) { - $dbh->rollBack(); - throw $ex; - } - - return $client; - } - - function updateOAuth2Client($client): OAuth2Client { - $dbh = $this->getDBHandler(); - - try { - $dbh->beginTransaction(); - - $stmt = $dbh->prepare("UPDATE `oauth2_client` SET `title` = :title, `icon` = :icon, " - . " `client` = :client, `secret` = :secret, `redirect_url` = :redirect_url, `scope` = :scope " - . " WHERE id = :id"); - - $stmt->bindParam(':title', $client->title); - $stmt->bindParam(':icon', $client->icon); - $stmt->bindParam(':client', $client->client); - $stmt->bindParam(':secret', $client->secret); - $stmt->bindParam(':redirect_url', $client->redirectUrl); - $stmt->bindParam(':scope', $client->scope); - $stmt->bindParam(':id', $client->id); - - $stmt->execute(); - - // Delete old authentication methods - $stmt = $dbh->prepare("DELETE FROM oauth2_client_auth_methods WHERE client_id = :id"); - $stmt->bindParam(':id', $client->id); - - $stmt->execute(); - - // Re-add authentication methods - foreach ($client->authMethods as $method) { - $stmt = $dbh->prepare("INSERT INTO `oauth2_client_auth_methods`(`client_id`, `auth_method`)" - . " VALUES(:client_id, :auth_method)"); - - $stmt->bindParam(':client_id', $client->id); - $stmt->bindParam(':auth_method', $method); - - $stmt->execute(); - } - - $dbh->commit(); - } catch (Exception $ex) { - $dbh->rollBack(); - throw $ex; - } - - return $client; - } - - function deleteOAuth2Client($clientId) { - $dbh = $this->getDBHandler(); - try { - $dbh->beginTransaction(); - - $stmt = $dbh->prepare("DELETE FROM `oauth2_client_auth_methods` WHERE client_id = :id"); - $stmt->bindParam(':id', $clientId); - $stmt->execute(); - - $stmt = $dbh->prepare("DELETE FROM `oauth2_client` WHERE id = :id"); - $stmt->bindParam(':id', $clientId); - $stmt->execute(); - - $dbh->commit(); - } catch (Exception $ex) { - $dbh->rollBack(); - throw $ex; - } - } - - function getOAuth2ClientByClientId($clientId): ?OAuth2Client { - $dbh = $this->getDBHandler(); - - // Load clients info - $queryClient = "SELECT id, title, icon, client, secret, redirect_url, scope FROM oauth2_client WHERE client = :client"; - $stmtClient = $dbh->prepare($queryClient); - $stmtClient->bindParam(':client', $clientId); - $stmtClient->execute(); - - $result = $stmtClient->fetchAll(); - - if (count($result) === 0) { - return null; - } - if (count($result) > 1) { - throw new Exception("Found multiple clients associated to the same client id!"); - } - - $row = $result[0]; - - $client = new OAuth2Client(); - $client->id = $row['id']; - $client->title = $row['title']; - $client->icon = $row['icon']; - $client->client = $row['client']; - $client->secret = $row['secret']; - $client->redirectUrl = $row['redirect_url']; - $client->scope = $row['scope']; - - // Load authentication methods info - $queryAuthNMethods = "SELECT auth_method FROM oauth2_client_auth_methods WHERE client_id = :id"; - - $stmtAuthNMethods = $dbh->prepare($queryAuthNMethods); - $stmtAuthNMethods->bindParam(':id', $client->id); - $stmtAuthNMethods->execute(); - - foreach ($stmtAuthNMethods->fetchAll() as $row) { - array_push($client->authMethods, $row['auth_method']); - } - - return $client; - } - } diff --git a/classes/login/FacebookLogin.php b/classes/login/FacebookLogin.php new file mode 100644 index 0000000000000000000000000000000000000000..3b3b9e6779ed99420fcc92cd480dbd0abb614328 --- /dev/null +++ b/classes/login/FacebookLogin.php @@ -0,0 +1,97 @@ +<?php + +namespace RAP; + +class FacebookLogin extends LoginHandler { + + public function __construct(Locator $locator) { + parent::__construct($locator, Identity::FACEBOOK); + } + + public function login() { + + // Retrieve Facebook configuration + $Facebook = $this->locator->config->authenticationMethods->Facebook; + + $fb = new \Facebook\Facebook([ + 'app_id' => $Facebook->id, + 'app_secret' => $Facebook->secret, + 'default_graph_version' => $Facebook->version, + ]); + + $helper = $fb->getRedirectLoginHelper(); + + $permissions = ['email']; // Optional permissions: we need user email + + $loginUrl = $helper->getLoginUrl($Facebook->callback, $permissions); + + header("Location: $loginUrl"); + } + + public function retrieveToken() { + // Retrieve Facebook configuration + $Facebook = $this->locator->config->authenticationMethods->Facebook; + + $fb = new \Facebook\Facebook([ + 'app_id' => $Facebook->id, + 'app_secret' => $Facebook->secret, + 'default_graph_version' => $Facebook->version, + ]); + + $helper = $fb->getRedirectLoginHelper(); + if (isset($_GET['state'])) { + $helper->getPersistentDataHandler()->set('state', $_GET['state']); + } + + try { + // obtaining current URL without query string + $url = "https://$_SERVER[HTTP_HOST]" . strtok($_SERVER["REQUEST_URI"], '?'); + $accessToken = $helper->getAccessToken($url); + } catch (Facebook\Exceptions\FacebookResponseException $e) { + // When Graph returns an error + http_response_code(500); + die('Graph returned an error: ' . $e->getMessage()); + } catch (Facebook\Exceptions\FacebookSDKException $e) { + // When validation fails or other local issues + http_response_code(500); + die('Facebook SDK returned an error: ' . $e->getMessage()); + } + if (!isset($accessToken)) { + if ($helper->getError()) { + $errorMessage = "Error: " . $helper->getError() . "<br>"; + $errorMessage = $errorMessage . "Error Code: " . $helper->getErrorCode() . "<br>"; + $errorMessage = $errorMessage . "Error Reason: " . $helper->getErrorReason() . "<br>"; + $errorMessage = $errorMessage . "Error Description: " . $helper->getErrorDescription(); + } else { + $errorMessage = "Bad request"; + } + + http_response_code(500); + die($errorMessage); + } + + try { + // Returns a `Facebook\FacebookResponse` object + $response = $fb->get('/me?fields=id,first_name,last_name,email', $accessToken); + } catch (Facebook\Exceptions\FacebookResponseException $e) { + echo 'Graph returned an error: ' . $e->getMessage(); + exit; + } catch (Facebook\Exceptions\FacebookSDKException $e) { + echo 'Facebook SDK returned an error: ' . $e->getMessage(); + exit; + } + + $_SESSION['fb_access_token'] = (string) $accessToken; + + $fbUser = $response->getGraphUser(); + + $typedId = $fbUser["id"]; + + return $this->onIdentityDataReceived($typedId, function($identity) use($fbUser) { + $identity->email = $fbUser["email"]; + $identity->name = $fbUser["first_name"]; + $identity->surname = $fbUser["last_name"]; + }); + } + +} diff --git a/classes/social/GoogleLogin.php b/classes/login/GoogleLogin.php similarity index 65% rename from classes/social/GoogleLogin.php rename to classes/login/GoogleLogin.php index f2174d092a40fef77e5648783b5032d7d218feaa..82079aae58bb820a21216e121b8cff8007ed5a89 100644 --- a/classes/social/GoogleLogin.php +++ b/classes/login/GoogleLogin.php @@ -2,15 +2,13 @@ namespace RAP; -class GoogleLogin { - - protected $locator; +class GoogleLogin extends LoginHandler { public function __construct(Locator $locator) { - $this->locator = $locator; + parent::__construct($locator, Identity::GOOGLE); } - public function call() { + public function login() { // Retrieve Google configuration $Google = $this->locator->config->authenticationMethods->Google; @@ -58,40 +56,19 @@ class GoogleLogin { $typedId = explode('/', $res->getResourceName())[1]; - // Search if the user is already registered into RAP using the Google ID. - $user = $this->locator->getUserHandler()->findUserByIdentity(Identity::GOOGLE, $typedId); - - $session = $this->locator->getSession(); - - if ($user === null) { - // Create new user - $user = new \RAP\User(); - - $identity = new Identity(Identity::GOOGLE); - $identity->email = $emailAddresses[0]; - $identity->name = $name; - $identity->surname = $surname; - $identity->typedId = $typedId; - - $user->addIdentity($identity); - - $session->userToLogin = $user; - $session->save(); - - header('Location: ' . $this->locator->getBasePath() . '/tou-check'); - die(); - } - - $this->locator->getAuditLogger()->info("LOGIN,Google," . $user->id); - $this->locator->getCallbackHandler()->manageLoginRedirect($user, $session); - - die(); + return $this->onIdentityDataReceived($typedId, function($identity) use($emailAddresses, $name, $surname) { + $identity->email = $emailAddresses[0]; + $identity->name = $name; + $identity->surname = $surname; + }); } else { // Redirect to Google authorization URL for obtaining an access token $authUrl = $client->createAuthUrl(); header('Location: ' . $authUrl); die(); } + + return null; } } diff --git a/classes/login/LinkedInLogin.php b/classes/login/LinkedInLogin.php new file mode 100644 index 0000000000000000000000000000000000000000..7f686ed2efc9bc040da6d8b52315d70d0dd3d3e2 --- /dev/null +++ b/classes/login/LinkedInLogin.php @@ -0,0 +1,118 @@ +<?php + +namespace RAP; + +class LinkedInLogin extends LoginHandler { + + public function __construct(Locator $locator) { + parent::__construct($locator, Identity::FACEBOOK); + } + + public function login() { + // Retrieve LinkedIn configuration + $LinkedIn = $this->locator->config->authenticationMethods->LinkedIn; + + $url = "https://www.linkedin.com/oauth/v2/authorization?response_type=code"; + $url .= "&client_id=" . $LinkedIn->id; + $url .= "&redirect_uri=" . $LinkedIn->callback; + $url .= "&state=789654123"; + $url .= "&scope=r_basicprofile r_emailaddress"; + + header("Location: $url"); + } + + public function retrieveToken() { + // Retrieve LinkedIn configuration + $LinkedIn = $this->locator->config->authenticationMethods->LinkedIn; + + if (!isset($_REQUEST['code'])) { + die("Unable to get LinkedIn client code"); + } + + //create array of data to be posted to get AccessToken + $post_data = array( + 'grant_type' => "authorization_code", + 'code' => $_REQUEST['code'], + 'redirect_uri' => $LinkedIn->callback, + 'client_id' => $LinkedIn->id, + 'client_secret' => $LinkedIn->secret + ); + + //traverse array and prepare data for posting (key1=value1) + foreach ($post_data as $key => $value) { + $post_items[] = $key . '=' . $value; + } + + //create the final string to be posted + $post_string = implode('&', $post_items); + + //create cURL connection + $conn1 = curl_init('https://www.linkedin.com/oauth/v2/accessToken'); + + //set options + curl_setopt($conn1, CURLOPT_CONNECTTIMEOUT, 30); + curl_setopt($conn1, CURLOPT_RETURNTRANSFER, true); + curl_setopt($conn1, CURLOPT_SSL_VERIFYPEER, true); + curl_setopt($conn1, CURLOPT_FOLLOWLOCATION, 1); + + //set data to be posted + curl_setopt($conn1, CURLOPT_POSTFIELDS, $post_string); + + //perform our request + $result1 = curl_exec($conn1); + $info1 = curl_getinfo($conn1); + + if ($info1['http_code'] === 200) { + $my_token = json_decode($result1, TRUE); + $access_token = $my_token['access_token']; + $expires_in = $my_token['expires_in']; + curl_close($conn1); + } else { + //show information regarding the error + $errorMessage = "Error: LinkedIn server response code: " . $info1['http_code'] . " - "; + $errorMessage .= curl_error($conn1); + curl_close($conn1); + http_response_code(500); + die($errorMessage); + } + + // Call to API + $conn2 = curl_init(); + curl_setopt($conn2, CURLOPT_URL, "https://api.linkedin.com/v1/people/~:(first-name,last-name,email-address,id)?format=json"); + curl_setopt($conn2, CURLOPT_HTTPHEADER, array( + 'Authorization: Bearer ' . $access_token + )); + + curl_setopt($conn2, CURLOPT_RETURNTRANSFER, true); + $result = curl_exec($conn2); + $info2 = curl_getinfo($conn2); + + if ($info2['http_code'] === 200) { + $data = json_decode($result, TRUE); + + curl_close($conn2); + + if (isset($data['errorCode'])) { + $errorMessage = $data['message']; + die($errorMessage); + } + + $typedId = $data['id']; + + return $this->onIdentityDataReceived($typedId, function($identity) use($data) { + $identity->email = $data['emailAddress']; + $identity->name = $data['firstName']; + $identity->surname = $data['lastName']; + }); + } else { + //show information regarding the error + $errorMessage = "Error: LinkedIn server response code: " . $info2['http_code'] . " - "; + $errorMessage = $errorMessage . curl_error($conn2); + curl_close($conn2); + die($errorMessage); + } + + return null; + } + +} diff --git a/classes/login/LoginHandler.php b/classes/login/LoginHandler.php new file mode 100644 index 0000000000000000000000000000000000000000..245c9285c69c7eb39ad09540d3bbf2e98a87637e --- /dev/null +++ b/classes/login/LoginHandler.php @@ -0,0 +1,68 @@ +<?php + +namespace RAP; + +class LoginHandler { + + protected $locator; + private $identityType; + + public function __construct(Locator $locator, string $identityType) { + $this->locator = $locator; + $this->identityType = $identityType; + } + + public function onIdentityDataReceived(string $typedId, \Closure $fillIdentityData): string { + + $user = $this->locator->getUserHandler()->findUserByIdentity($this->identityType, $typedId); + + if ($user === null) { + return $this->handleNewUser($typedId, $fillIdentityData); + } + + return $this->getAfterLoginRedirect($user); + } + + protected function handleNewUser(string $typedId, \Closure $fillIdentityData): string { + + $session = $this->locator->getSession(); + + // Create new user + $user = new \RAP\User(); + + $identity = new Identity($this->identityType); + $identity->typedId = $typedId; + $fillIdentityData($identity); + + $user->addIdentity($identity); + + $session->setUser($user); + + // Redirect to Term of Use acceptance page + return $this->locator->getBasePath() . '/tou-check'; + } + + public function getAfterLoginRedirect(User $user): string { + + $session = $this->locator->getSession(); + $this->locator->getAuditLogger()->info("LOGIN," . $this->identityType . "," . $user->id); + + if ($session->getOAuth2Data() !== null) { + $session->setUser($user); + $redirectUrl = $this->locator->getOAuth2RequestHandler()->getCodeResponseUrl(); + session_destroy(); + return $redirectUrl; + } + + if ($session->getAction() !== null) { + $session->setUser($user); + $action = $session->getAction(); + if ($action === 'account' || $action === 'join' || $action === 'admin') { + return $this->locator->getBasePath() . '/' . $action; + } + } + + throw new \Exception("Unable to find a proper redirect"); + } + +} diff --git a/classes/login/ShibbolethLogin.php b/classes/login/ShibbolethLogin.php new file mode 100644 index 0000000000000000000000000000000000000000..2dc425c5e5adb20eb24c8bfda71a4ace9804f38d --- /dev/null +++ b/classes/login/ShibbolethLogin.php @@ -0,0 +1,34 @@ +<?php + +namespace RAP; + +class ShibbolethLogin extends LoginHandler { + + public function __construct(Locator $locator) { + parent::__construct($locator, Identity::EDU_GAIN); + } + + public function login() { + if (isset($_SERVER['Shib-Session-ID'])) { + + // Retrieving eduPersonPrincipalName (eppn) + $eppn = $_SERVER['eppn']; + + // Search if the user is already registered into RAP using the eppn. + // The persistent id should be a more appropriate identifier, however at IA2 + // we need to import all INAF user into RAP, even if they will never register, + // and in that case we know only their eppn. + + $this->onIdentityDataReceived($eppn, function($identity) use($eppn) { + $identity->email = $_SERVER['mail']; + $identity->name = $_SERVER['givenName']; + $identity->surname = $_SERVER['sn']; + $identity->eppn = $eppn; + }); + } else { + http_response_code(500); + die("Shib-Session-ID not found!"); + } + } + +} diff --git a/classes/login/X509Login.php b/classes/login/X509Login.php new file mode 100644 index 0000000000000000000000000000000000000000..87173dcce6ba4e35a0d9316c7636a880faec2184 --- /dev/null +++ b/classes/login/X509Login.php @@ -0,0 +1,70 @@ +<?php + +namespace RAP; + +class X509Login extends LoginHandler { + + private $x509Data; + + public function __construct(Locator $locator) { + parent::__construct($locator, Identity::X509); + } + + public function login(): string { + if (isset($_SERVER['SSL_CLIENT_VERIFY']) && isset($_SERVER['SSL_CLIENT_V_REMAIN']) && + $_SERVER['SSL_CLIENT_VERIFY'] === 'SUCCESS' && $_SERVER['SSL_CLIENT_V_REMAIN'] > 0) { + + $x509Data = RAP\X509Data::parse($_SERVER); + $this->x509Data = $x509Data; + + return $this->onIdentityDataReceived($x509Data->serialNumber, function($identity) use ($x509Data) { + $this->fillIdentity($identity, $x509Data); + }); + } else { + http_response_code(500); + die("Unable to verify client certificate"); + } + + return null; + } + + public function afterNameSurnameSelection($x509Data) { + $redirect = $this->onIdentityDataReceived($x509Data->serialNumber, function($identity) use ($x509Data) { + $this->fillIdentity($identity, $x509Data); + }); + + $session = $this->locator->getSession(); + $session->setX509DataToRegister(null); + + return $redirect; + } + + private function fillIdentity($identity, $x509Data) { + $identity->email = $x509Data->email; + $identity->name = $x509Data->name; + $identity->surname = $x509Data->surname; + $identity->institution = $x509Data->institution; + } + + /** + * We want to extract name and surname from the X.509 certificate, however X.509 + * puts name and surname together (inside the CN field). + * If name and surname are single words it is possible to retrieve them splitting + * on the space character, otherwise the user has to choose the correct combination. + * In that case partial X.509 data is temporarily stored into the user session and + * the page views/x509-name-surname.php is shown to the user before completing the + * registration, in order to allow him/her selecting the correct name and surname. + */ + protected function handleNewUser(string $typedId, \Closure $fillIdentityData): string { + + $session = $this->locator->getSession(); + + if ($this->x509Data->name === null) { + $session->setX509DataToRegister($this->x509Data); + return $this->locator->getBasePath() . '/x509-name-surname'; + } else { + return parent::handleNewUser($typedId, $fillIdentityData); + } + } + +} diff --git a/classes/AuthenticationMethods.php b/classes/model/AuthenticationMethods.php similarity index 100% rename from classes/AuthenticationMethods.php rename to classes/model/AuthenticationMethods.php diff --git a/classes/Identity.php b/classes/model/Identity.php similarity index 100% rename from classes/Identity.php rename to classes/model/Identity.php diff --git a/classes/model/InternalClient.php b/classes/model/InternalClient.php index dfff4a31f8ff8c1ca346ae155bde1f09cfe314b3..36a81aa85f08e73f0844591ace4ae368964afc65 100644 --- a/classes/model/InternalClient.php +++ b/classes/model/InternalClient.php @@ -4,8 +4,11 @@ namespace RAP; class InternalClient extends RAPClient { - public function __construct() { + public $action; + + public function __construct(string $action) { $this->authMethods = AuthenticationMethods::getAllMethods(); + $this->action = $action; } public function getIconBasePath() { diff --git a/classes/model/SessionData.php b/classes/model/SessionData.php index ee0e0bc000ce46c56e58dafbecc0d28c37a4871b..1473ce824695b2bc5e6ec34f6c7f28977bae4a1c 100644 --- a/classes/model/SessionData.php +++ b/classes/model/SessionData.php @@ -32,20 +32,18 @@ class SessionData { const KEY = "SessionData"; - public $user; - public $userSearchResults; - public $x509DataToRegister; - // user which is going to perform the login (we need to store this in the - // session because we need to check the Terms of Use user consensus, so we - // redirect to another page after retrieving user data. - public $userToLogin; - public $oauth2Data; + private $user; + private $x509DataToRegister; + private $oauth2Data; + private $action; - /** - * Store the data into the $_SESSION PHP variable - */ - public function save() { - $_SESSION[SessionData::KEY] = $this; + public function setUser(?User $user): void { + $this->user = $user; + $this->save(); + } + + public function getUser(): ?User { + return $this->user; } /** @@ -54,13 +52,23 @@ class SessionData { * the database. * @param int $identityId */ - public function updatePrimaryIdentity($identityId) { + public function updatePrimaryIdentity($identityId): void { foreach ($this->user->identities as $identity) { $identity->primary = ($identity->id === $identityId); } + $this->save(); + } + + public function setX509DataToRegister(?X509Data $x509DataToRegister): void { + $this->x509DataToRegister = $x509DataToRegister; + $this->save(); + } + + public function getX509DataToRegister(): ?X509Data { + return $this->x509DataToRegister; } - public function setOAuth2Data(?OAuth2Data $oauth2Data) { + public function setOAuth2Data(?OAuth2Data $oauth2Data): void { $this->oauth2Data = $oauth2Data; $this->save(); } @@ -69,4 +77,20 @@ class SessionData { return $this->oauth2Data; } + public function setAction(?string $action): void { + $this->action = $action; + $this->save(); + } + + public function getAction(): ?string { + return $this->action; + } + + /** + * Store the data into the $_SESSION PHP variable + */ + public function save() { + $_SESSION[SessionData::KEY] = $this; + } + } diff --git a/config-example.json b/config-example.json index 36e73d850e28a665f4f4fd97bcca19645b900a01..92f9edd77142e67dddafcb3445562328ee1ecc80 100644 --- a/config-example.json +++ b/config-example.json @@ -32,7 +32,7 @@ "callback": "/auth/social/linkedin_token.php" }, "X.509": {}, - "DirectIdP": { + "LocalIdP": { "url": "https://sso.ia2.inaf.it/Shibboleth.sso/Login?entityID=https://sso.ia2.inaf.it/idp/shibboleth&target=https://sso.ia2.inaf.it/rap-ia2/auth/saml2/aai.php", "logo": "img/ia2-logo-60x60.png", "logo_alt": "IA2 logo", diff --git a/include/admin.php b/include/admin.php index 4479012f37a57599f24f2b8a3f76ed534f56352f..b8814ce96dca381611b7684c1805f945c072cdd2 100644 --- a/include/admin.php +++ b/include/admin.php @@ -10,7 +10,7 @@ function checkUser() { startSession(); global $session; - if ($session->user === null) { + if ($session->getUser() === null) { http_response_code(401); die("You must be registered to perform this action"); } diff --git a/include/front-controller.php b/include/front-controller.php index 818c1167f369ceaab858b4495d73796889d9f28f..ae907a1b8a5bd04e1c5907bcd1b93248571286c4 100644 --- a/include/front-controller.php +++ b/include/front-controller.php @@ -27,11 +27,24 @@ Flight::route('/', function() { global $locator; $action = Flight::request()->query['action']; + $locator->getSession()->setAction($action); switch ($action) { case "oaut2client": $clientId = $locator->getSession()->getOAuth2Data()->clientId; - $client = $locator->getDAO()->getOAuth2ClientByClientId($clientId); + $client = $locator->getOAuth2ClientDAO()->getOAuth2ClientByClientId($clientId); + $authPageModel = new \RAP\AuthPageModel($locator, $client); + renderMainPage($authPageModel); + break; + case "account": + $client = new \RAP\InternalClient('account'); + $client->icon = 'account-manager.png'; + $client->title = 'Account Management'; + $authPageModel = new \RAP\AuthPageModel($locator, $client); + renderMainPage($authPageModel); + break; + case "admin": + $client = new \RAP\InternalClient('admin'); $authPageModel = new \RAP\AuthPageModel($locator, $client); renderMainPage($authPageModel); break; @@ -90,7 +103,7 @@ Flight::route('POST /auth/oauth2/check_token', function() { global $locator; $token = filter_input(INPUT_POST, 'token', FILTER_SANITIZE_STRING); - + $requestHandler = new \RAP\OAuth2RequestHandler($locator); $result = $requestHandler->handleCheckTokenRequest($token); @@ -125,28 +138,57 @@ Flight::route('/auth/social/google', function() { session_start(); global $locator; $googleLogin = new \RAP\GoogleLogin($locator); - $googleLogin->call(); + $redirect = $googleLogin->login(); + if ($redirect !== null) { + Flight::redirect($redirect); + } +}); + +Flight::route('/auth/social/facebook', function() { + session_start(); + global $locator; + $facebookLogin = new \RAP\FacebookLogin($locator); + $facebookLogin->login(); }); -Flight::route('/facebook', function() { - sendAuthRedirect('/auth/social/facebook_login.php'); +Flight::route('/auth/social/facebook/token', function() { + session_start(); + global $locator; + $facebookLogin = new \RAP\FacebookLogin($locator); + $facebookLogin->retrieveToken(); }); -Flight::route('/linkedIn', function() { - sendAuthRedirect('/auth/social/linkedin_login.php'); +Flight::route('/auth/social/linkedIn', function() { + session_start(); + global $locator; + $linkedInLogin = new \RAP\LinkedInLogin($locator); + $linkedInLogin->login(); }); -Flight::route('/eduGAIN', function() { - sendAuthRedirect('/auth/saml2/aai.php'); +Flight::route('/auth/social/linkedIn/token', function() { + session_start(); + global $locator; + $linkedInLogin = new \RAP\LinkedInLogin($locator); + $linkedInLogin->retrieveToken(); }); -Flight::route('/x509', function() { - sendAuthRedirect('/auth/x509/certlogin.php'); +Flight::route('/auth/eduGAIN', function() { + session_start(); + global $locator; + $shibbolethLogin = new \RAP\ShibbolethLogin($locator); + $shibbolethLogin->login(); +}); + +Flight::route('/auth/x509', function() { + session_start(); + global $locator; + $x509Login = new \RAP\X509Login($locator); + $x509Login->login(); }); Flight::route('/local', function() { global $AUTHENTICATION_METHODS; - sendAuthRedirect($AUTHENTICATION_METHODS['DirectIdP']['url']); + sendAuthRedirect($AUTHENTICATION_METHODS['LocalIdP']['url']); }); /** @@ -158,11 +200,11 @@ Flight::route('GET /x509-name-surname', function() { startSession(); global $session, $BASE_PATH, $VERSION; - if ($session->x509DataToRegister !== null && $session->x509DataToRegister->name === null) { + if ($session->getX509DataToRegister() !== null && $session->getX509DataToRegister()->name === null) { Flight::render('x509-name-surname.php', array('title' => 'Select name and surname', 'version' => $VERSION, - 'fullName' => $session->x509DataToRegister->fullName, - 'candidateNames' => $session->x509DataToRegister->candidateNames)); + 'fullName' => $session->getX509DataToRegister()->fullName, + 'candidateNames' => $session->getX509DataToRegister()->candidateNames)); } else { // Redirect to index header("Location: " . $BASE_PATH); @@ -172,63 +214,79 @@ Flight::route('GET /x509-name-surname', function() { /** * Complete the X.509 registration selecting the correct name and surname specified - * by the user. + * by the user (special case of composite names). */ Flight::route('POST /submit-x509-name', function() { + session_start(); + $selectedNameIndex = Flight::request()->data['selected-name']; - error_log('index=' . $selectedNameIndex); + global $locator; + $session = $locator->getSession(); - startSession(); - global $session, $BASE_PATH; - - if ($session->x509DataToRegister !== null) { - $session->x509DataToRegister->selectCandidateName($selectedNameIndex); - $session->userToLogin = $session->x509DataToRegister->toUser(); - $session->x509DataToRegister = null; - $session->save(); - header("Location: " . $BASE_PATH . '/tou-check'); - die(); + if ($session->getX509DataToRegister() !== null) { + $session->getX509DataToRegister()->selectCandidateName($selectedNameIndex); + $loginHandler = new \RAP\X509Login($locator); + $redirect = $loginHandler->afterNameSurnameSelection($session->getX509DataToRegister()); + Flight::redirect($redirect); } else { die('X.509 data not returned'); } }); +/** + * Display Term of Use acceptance page. + */ Flight::route('GET /tou-check', function() { session_start(); global $locator; - if ($locator->getSession()->userToLogin === null) { + if ($locator->getSession()->getUser() === null) { die("User data not retrieved."); } else { Flight::render('tou-check.php', array('title' => 'Terms of Use acceptance', - 'user' => $locator->getSession()->userToLogin, + 'user' => $locator->getSession()->getUser(), 'version' => $locator->getVersion(), 'registration_url' => $locator->getBasePath() . '/register')); } }); +/** + * Stores the user data into the database after he/she accepted the Terms of Use. + */ Flight::route('GET /register', function() { session_start(); global $locator; - if ($locator->getSession()->userToLogin === null) { + if ($locator->getSession()->user === null) { die("User data not retrieved."); } else { - $session = $locator->getSession(); - - $user = $session->userToLogin; + $user = $locator->getSession()->user; + $locator->getUserHandler()->saveUser($user); - $session->userToLogin = null; - $session->save(); + $loginHandler = new \RAP\LoginHandler($locator, $user->identities[0]->type); + Flight::redirect($loginHandler->getAfterLoginRedirect($user)); + } +}); + +/** + * Shows Account Management page. + */ +Flight::route('GET /account', function () { + + session_start(); + global $locator; - $locator->getAuditLogger()->info("LOGIN," . $user->identities[0]->type . "," . $user->id); - $locator->getCallbackHandler()->manageLoginRedirect($user, $session); + if ($locator->getSession()->getUser() === null) { + Flight::redirect('/'); + } else { + Flight::render('account-management.php', array('title' => 'RAP Account Management', + 'version' => $locator->getVersion(), 'session' => $locator->getSession())); } }); diff --git a/include/gui-backend.php b/include/gui-backend.php index 5cc8dcf023202197c9d9239846bf59b80db13a34..0c311193dae02ca84dcd2ca00ce3f9f56292b7c5 100644 --- a/include/gui-backend.php +++ b/include/gui-backend.php @@ -10,31 +10,12 @@ function checkSession() { startSession(); global $session; - if ($session->user === null) { + if ($session->getUser() === null) { http_response_code(401); die("You must be registered to perform this action"); } } -/** - * This is called when an user search for other users into the join modal dialog. - */ -Flight::route('GET /user', function() { - - checkSession(); - global $session; - - $searchText = Flight::request()->query['search']; - $session->searchUser($searchText); - - $jsRes = []; - foreach ($session->userSearchResults as $searchResult) { - array_push($jsRes, $searchResult->userDisplayText); - } - - Flight::json($jsRes); -}); - Flight::route('POST /join', function() { checkSession(); @@ -69,6 +50,6 @@ Flight::route('POST /primary-identity', function() { $session->updatePrimaryIdentity($identityId); // Following variable is used to render user-data - $user = $session->user; + $user = $session->getUser(); include 'user-data.php'; }); diff --git a/include/init.php b/include/init.php index e0c98813b73b7cacc6dbc691e3838487d65e2bc0..de9808cdb95cc9798dc81d7ee64f9c945cc11aea 100644 --- a/include/init.php +++ b/include/init.php @@ -36,7 +36,7 @@ spl_autoload_register(function ($class) { $fileName = substr($class, $len, strlen($class) - $len); - $classDirectories = ['/', '/social/', '/exceptions/', '/datalayer/', '/model/']; + $classDirectories = ['/', '/login/', '/exceptions/', '/datalayer/', '/model/']; foreach ($classDirectories as $directory) { $classpath = ROOT . '/classes' . $directory . $fileName . '.php'; if (file_exists($classpath)) { diff --git a/index.php b/index.php index 653a6ef0f2dad64ea7a895d6b0e45afd6918c2e0..485f948484f111466c27fd32bd362fc971b1f4b2 100644 --- a/index.php +++ b/index.php @@ -29,12 +29,16 @@ include './include/gui-backend.php'; include './include/rest-web-service.php'; // Error handling -Flight::map('error', function(Exception $ex) { +Flight::map('error', function(\Exception $ex) { if ($ex instanceof \RAP\BadRequestException) { http_response_code(400); echo "Bad request: " . $ex->message; } else { - echo $ex->getTraceAsString(); + if ($ex->getMessage() !== null) { + echo $ex->getMessage(); + } else { + echo $ex->getTraceAsString(); + } } }); diff --git a/tests/IdTokenBuilderTest.php b/tests/IdTokenBuilderTest.php index aa79a567ea97486baa3583169eec7eb4fef9b385..67a2596bf4f98a63bf97d4ebff53f5d5efc6a151 100644 --- a/tests/IdTokenBuilderTest.php +++ b/tests/IdTokenBuilderTest.php @@ -27,8 +27,8 @@ final class IdTokenBuilderTest extends TestCase { $identity->institution = "INAF"; $user->addIdentity($identity); - $daoStub = $this->createMock(\RAP\DAO::class); - $locatorStub->method('getDAO')->willReturn($daoStub); + $daoStub = $this->createMock(\RAP\UserDAO::class); + $locatorStub->method('getUserDAO')->willReturn($daoStub); $daoStub->method('findUserById')->willReturn($user); $locatorStub->config = json_decode('{"jwtIssuer": "issuer"}'); diff --git a/tests/OAuth2RequestHandlerTest.php b/tests/OAuth2RequestHandlerTest.php index 8095f1b26cd0edfcf851b892dee178b320c65883..216c4d17c1674b0732e0ccb54535ecde3b51db0f 100644 --- a/tests/OAuth2RequestHandlerTest.php +++ b/tests/OAuth2RequestHandlerTest.php @@ -30,11 +30,11 @@ final class OAuth2RequestHandlerTest extends TestCase { "scope" => "email%20profile" ]; - $daoStub = $this->createMock(\RAP\DAO::class); + $daoStub = $this->createMock(\RAP\OAuth2ClientDAO::class); $daoStub->method('getOAuth2ClientByClientId')->willReturn(new \RAP\OAuth2Client()); $locatorStub = $this->createMock(\RAP\Locator::class); - $locatorStub->method('getDAO')->willReturn($daoStub); + $locatorStub->method('getOAuth2ClientDAO')->willReturn($daoStub); $requestHandler = new \RAP\OAuth2RequestHandler($locatorStub); $requestHandler->handleAuthorizeRequest($params); @@ -50,7 +50,7 @@ final class OAuth2RequestHandlerTest extends TestCase { "scope" => "email%20profile" ]; - $daoStub = $this->createMock(\RAP\DAO::class); + $daoStub = $this->createMock(\RAP\OAuth2ClientDAO::class); $client = new \RAP\OAuth2Client(); $client->redirectUrl = "redirect_uri"; $daoStub->method('getOAuth2ClientByClientId')->willReturn($client); @@ -58,7 +58,7 @@ final class OAuth2RequestHandlerTest extends TestCase { $sessionStub = $this->createMock(\RAP\SessionData::class); $locatorStub = $this->createMock(\RAP\Locator::class); - $locatorStub->method('getDAO')->willReturn($daoStub); + $locatorStub->method('getOAuth2ClientDAO')->willReturn($daoStub); $locatorStub->method('getSession')->willReturn($sessionStub); $sessionStub->expects($this->once()) diff --git a/views/account-management.php b/views/account-management.php index d985159160428c526fe0ca167bd94ef5c2896d61..f6b28308f6dc13c209a16c9535c915806576f7b4 100644 --- a/views/account-management.php +++ b/views/account-management.php @@ -20,7 +20,7 @@ include 'include/header.php'; </div> <div class="panel-body"> <?php - $user = $session->user; + $user = $session->getUser(); include 'include/user-data.php'; ?> </div> diff --git a/views/services-list.php b/views/services-list.php index f74215ce00e839b8c09ca32526d3d97efacf8e05..bc441d1b58de1d346b41defcf4591ce24f6e872b 100644 --- a/views/services-list.php +++ b/views/services-list.php @@ -20,10 +20,7 @@ include 'include/header.php'; </form> </li> <li> - <form action="<?php echo $action; ?>" method="POST"> - <input name="callback" type="hidden" value="<?php echo $action; ?>" /> - <input type="submit" class="btn btn-link" value="RAP Account Management" /> - </form> + <a href="?action=account">RAP Account Management</a> </li> <li> <form action="<?php echo $action; ?>" method="POST">