From 10cb0602667116c02564157f6661cc862eb234cf Mon Sep 17 00:00:00 2001 From: Sonia Zorba <zorba@oats.inaf.it> Date: Mon, 17 Jul 2017 12:57:04 +0200 Subject: [PATCH] Added services list when no callback is defined and other improvements --- auth/oauth2/linkedin_token.php | 13 +- classes/CallbackHandler.php | 46 +++++-- classes/GrouperClient.php | 171 ------------------------- classes/MailSender.php | 7 +- classes/MySQLDAO.php | 4 +- classes/SessionData.php | 8 +- classes/UserHandler.php | 53 +++++--- config.php | 17 ++- css/animation.css | 206 ++++++++++++++++++++---------- css/style.css | 15 ++- include/footer.php | 15 +++ include/front-controller.php | 7 +- include/header.php | 4 +- service-logos/account-manager.png | Bin 0 -> 4686 bytes service-logos/asiago.gif | Bin 0 -> 2672 bytes service-logos/grouper.png | Bin 0 -> 4787 bytes service-logos/tng.png | Bin 0 -> 3996 bytes views/index.php | 11 +- views/services-list.php | 37 ++++++ 19 files changed, 327 insertions(+), 287 deletions(-) delete mode 100644 classes/GrouperClient.php create mode 100644 service-logos/account-manager.png create mode 100644 service-logos/asiago.gif create mode 100644 service-logos/grouper.png create mode 100644 service-logos/tng.png create mode 100644 views/services-list.php diff --git a/auth/oauth2/linkedin_token.php b/auth/oauth2/linkedin_token.php index d4e88e4..e2ec275 100644 --- a/auth/oauth2/linkedin_token.php +++ b/auth/oauth2/linkedin_token.php @@ -61,17 +61,19 @@ curl_setopt($conn1, CURLOPT_POSTFIELDS, $post_string); //perform our request $result1 = curl_exec($conn1); +$info1 = curl_getinfo($conn1); -if ($result1) { +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 = curl_errno($conn1) . "-"; - $errorMessage = $errorMessage . curl_error($conn1); + $errorMessage = "Error: LinkedIn server response code: " . $info1['http_code'] . " - "; + $errorMessage .= curl_error($conn1); curl_close($conn1); + http_response_code(500); die($errorMessage); } @@ -84,8 +86,9 @@ curl_setopt($conn2, CURLOPT_HTTPHEADER, array( curl_setopt($conn2, CURLOPT_RETURNTRANSFER, true); $result = curl_exec($conn2); +$info2 = curl_getinfo($conn2); -if ($result) { +if ($info2['http_code'] === 200) { $data = json_decode($result, TRUE); curl_close($conn2); @@ -116,7 +119,7 @@ if ($result) { $callbackHandler->manageLoginRedirect($user, $session); } else { //show information regarding the error - $errorMessage = curl_errno($conn2) . "-"; + $errorMessage = "Error: LinkedIn server response code: " . $info2['http_code'] . " - "; $errorMessage = $errorMessage . curl_error($conn2); curl_close($conn2); die($errorMessage); diff --git a/classes/CallbackHandler.php b/classes/CallbackHandler.php index bd48a0d..4484061 100644 --- a/classes/CallbackHandler.php +++ b/classes/CallbackHandler.php @@ -36,37 +36,65 @@ class CallbackHandler { $this->callbacks = $callbacks; } + /** + * 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; + } + /** * returns null if the callback URL is not listed in configuration file. */ public function getCallbackTitle($callbackURL) { - if ($callbackURL === null) { - return "Account Management"; + foreach ($this->callbacks as $callback) { + if ($callback['url'] === $callbackURL) { + return $callback['title']; + } } + return null; + } + + public function getCallbackLogo($callbackURL) { + foreach ($this->callbacks as $callback) { if ($callback['url'] === $callbackURL) { - return $callback['title']; + if (array_key_exists('logo', $callback)) { + return $callback['logo']; + } else { + return null; + } } } - throw new \Exception("Unauthorized callback URL"); + return null; } public function manageLoginRedirect($user, SessionData $session) { - if ($session->getCallbackURL() !== null) { - // External login using token - header('Location: ' . $this->getLoginWithTokenURL($user->id, $session->getCallbackURL())); - die(); - } else { + 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(); } } diff --git a/classes/GrouperClient.php b/classes/GrouperClient.php deleted file mode 100644 index 73029c3..0000000 --- a/classes/GrouperClient.php +++ /dev/null @@ -1,171 +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; - -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 = []; - 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; - } else { - throw new \Exception("Wrong results number. Response=" . json_encode($response)); - } - } - } - - public function getSubjectPrivileges($subjectId) { - - $params = $this->getBaseRequestParams(); - $params['subjectId'] = $subjectId; - $params['subjectSourceId'] = 'RAP'; - - $response = $this->client->getGrouperPrivilegesLite($params); - - $privilegesMap = []; - if ($this->isSuccess($response)) { - if ($response->return->privilegeResults !== null) { - foreach ($response->return->privilegeResults as $item) { - $groupName = $item->wsGroup->name; - $privilege = $item->privilegeName; - - if (!array_key_exists($groupName, $privilegesMap)) { - $groupPrivileges = []; - } else { - $groupPrivileges = $privilegesMap[$groupName]; - } - $groupPrivileges[] = $privilege; - $privilegesMap[$groupName] = $groupPrivileges; - } - } - } - - return $privilegesMap; - } - - private function getBasePrivilegeRequestParams($subjectId, $groupName, $privilegeNames) { - $params = $this->getBaseRequestParams(); - $params['wsSubjectLookups'] = array( - 'subjectId' => $subjectId, - 'subjectSourceId' => 'RAP' - ); - $params['wsGroupLookup'] = array( - 'groupName' => $groupName - ); - $params['privilegeNames'] = $privilegeNames; - - return $params; - } - - public function assignPrivileges($subjectId, $groupName, $privilegeNames) { - - $params = $this->getBasePrivilegeRequestParams($subjectId, $groupName, $privilegeNames); - $params['allowed'] = 'T'; // true - - return $this->client->assignGrouperPrivileges($params); - } - - public function removePrivileges($subjectId, $groupName, $privilegeNames) { - - $params = $this->getBasePrivilegeRequestParams($subjectId, $groupName, $privilegeNames); - $params['allowed'] = 'F'; // false - - return $this->client->assignGrouperPrivileges($params); - } - - 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); - } - } - -} diff --git a/classes/MailSender.php b/classes/MailSender.php index 606743d..67742f4 100644 --- a/classes/MailSender.php +++ b/classes/MailSender.php @@ -72,9 +72,12 @@ class MailSender { $body .= "<br/>"; } - $body .= "<br/>If you and this user are the same person click on the following link for joining your accounts:<br/>"; + $body .= "<br/>If you and this user are <b>the same person</b> click on the following link for joining your accounts:<br/>"; $body .= "<a href=\"$confirmJoinURL\" target=\"blank_\">$confirmJoinURL</a>"; - $body .= "<br/><br/>Otherwise you can ignore this email<br/><br/>"; + $body .= "<br/><br/>Otherwise you can ignore this email.<br/>"; + + $body .= '<p><b>Please don\'t use this functionality for sharing resources between your coworkers</b>, use <a href="https://sso.ia2.inaf.it/grouper">Grouper</a> for that.</p>'; + $body .= '<br/>'; $body .= "<b>*** This is an automatically generated email, please do not reply to this message ***</b><br/>"; $body .= "If you need information please contact <a href=\"mailto:ia2@oats.inaf.it\">IA2 Staff</a>"; diff --git a/classes/MySQLDAO.php b/classes/MySQLDAO.php index 4dc5bcc..02dea0d 100644 --- a/classes/MySQLDAO.php +++ b/classes/MySQLDAO.php @@ -208,7 +208,8 @@ class MySQLDAO implements DAO { . " 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"; + . " WHERE `email` LIKE :email OR `name` LIKE :name OR `surname` LIKE :surname" + . " OR CONCAT(`name`,' ',`surname`) LIKE :namesurname"; $stmt = $dbh->prepare($query); @@ -216,6 +217,7 @@ class MySQLDAO implements DAO { $stmt->bindParam(':email', $searchParam); $stmt->bindParam(':name', $searchParam); $stmt->bindParam(':surname', $searchParam); + $stmt->bindParam(':namesurname', $searchParam); $stmt->execute(); diff --git a/classes/SessionData.php b/classes/SessionData.php index 8dd9f52..4b365a8 100644 --- a/classes/SessionData.php +++ b/classes/SessionData.php @@ -29,6 +29,7 @@ class SessionData { private $dao; private $callbackURL; private $callbackTitle; + private $callbackLogo; public $user; public $userSearchResults; public $x509DataToRegister; @@ -51,8 +52,9 @@ class SessionData { } public function setCallbackURL(CallbackHandler $callbackHandler, $callbackURL) { - $this->callbackURL = $callbackURL; + $this->callbackURL = $callbackHandler->filterCallbackURL($callbackURL); $this->callbackTitle = $callbackHandler->getCallbackTitle($callbackURL); + $this->callbackLogo = $callbackHandler->getCallbackLogo($callbackURL); $this->save(); } @@ -64,6 +66,10 @@ class SessionData { return $this->callbackTitle; } + public function getCallbackLogo() { + return $this->callbackLogo; + } + public function searchUser($searchText) { $users = $this->dao->searchUser($searchText); diff --git a/classes/UserHandler.php b/classes/UserHandler.php index b0b7330..5f1d52d 100644 --- a/classes/UserHandler.php +++ b/classes/UserHandler.php @@ -60,30 +60,47 @@ class UserHandler { return $this->dao->findUserByIdentity($type, $identifier); } - public function joinUsers($userId1, $userId2) { + private function getJoinURL() { + $joinURL = $this->grouperConfig['wsURL']; - if ($this->grouperConfig !== null) { - $gc = new GrouperClient($this->grouperConfig); + if (substr($joinURL, -1) !== '/') { + $joinURL .= '/'; + } + $joinURL .= 'ia2join'; - $grouperUser1 = 'RAP:' . $userId1; - $grouperUser2 = 'RAP:' . $userId2; + return $joinURL; + } - $groupsToMove = $gc->getSubjectGroups($grouperUser2); - $privilegesMap = $gc->getSubjectPrivileges($grouperUser2); + public function joinUsers($userId1, $userId2) { - // Adding memberships - $gc->addMemberships($grouperUser1, $groupsToMove); - // Adding privileges - foreach ($privilegesMap as $groupName => $privileges) { - $gc->assignPrivileges($grouperUser1, $groupName, $privileges); - } + if ($this->grouperConfig !== null) { - // Removing privileges - foreach ($privilegesMap as $groupName => $privileges) { - $gc->removePrivileges($grouperUser2, $groupName, $privileges); + //create cURL connection + $conn = curl_init($this->getJoinURL()); + + //set options + curl_setopt($conn, CURLOPT_CONNECTTIMEOUT, 30); + curl_setopt($conn, CURLOPT_RETURNTRANSFER, true); + curl_setopt($conn, CURLOPT_SSL_VERIFYPEER, true); + curl_setopt($conn, CURLOPT_FOLLOWLOCATION, 1); + curl_setopt($conn, CURLOPT_USERPWD, $this->grouperConfig['user'] . ":" . $this->grouperConfig['password']); + + //set data to be posted + curl_setopt($conn, CURLOPT_POST, 1); + curl_setopt($conn, CURLOPT_POSTFIELDS, "subject1Id=RAP:$userId1&subject2Id=RAP:$userId2"); + + //perform the request + $response = curl_exec($conn); + $info = curl_getinfo($conn); + + if ($info['http_code'] === 200) { + curl_close($conn); + } else { + //show information regarding the error + curl_close($conn); + http_response_code(500); + die('Error: Grouper response code: ' . $info['http_code']); } - // Removing memberships - $gc->removeMemberships($grouperUser2, $groupsToMove); } $this->dao->joinUsers($userId1, $userId2); diff --git a/config.php b/config.php index d4cc396..d73e7e8 100644 --- a/config.php +++ b/config.php @@ -23,7 +23,7 @@ */ $CONTEXT_ROOT = "/rap-ia2"; -$VERSION = "1.0.0"; +$VERSION = "1.0.1"; $PROTOCOL = stripos($_SERVER['SERVER_PROTOCOL'], 'https') ? 'https://' : 'http://'; $BASE_PATH = $PROTOCOL . $_SERVER['HTTP_HOST'] . $CONTEXT_ROOT; @@ -34,7 +34,13 @@ $LOG_LEVEL = Monolog\Logger::DEBUG; $CALLBACKS = [ array( 'url' => 'http://localhost:8087/grouper', - 'title' => 'Login to Grouper' + 'title' => 'Login to Grouper', + 'logo' => 'grouper.png' + ), + array( + 'url' => 'http://localhost/rap-ia2/', + 'title' => 'Account Management', + 'logo' => 'account-manager.png' ) ]; @@ -73,7 +79,12 @@ $AUTHENTICATION_METHODS = array( ); $GROUPER = array( - 'wsdlURL' => 'http://localhost:8087/grouper-ws/services/GrouperService_v2_3?wsdl', + 'wsURL' => 'http://localhost:8087/grouper-ws/', 'user' => 'GrouperSystem', 'password' => '***REMOVED***' ); +/*$GROUPER = array( + 'wsURL' => 'https://sso.ia2.inaf.it/grouper-ws/', + 'user' => 'GrouperSystem', + 'password' => '***REMOVED***321' +);*/ diff --git a/css/animation.css b/css/animation.css index ac5a956..be95362 100644 --- a/css/animation.css +++ b/css/animation.css @@ -1,85 +1,151 @@ +@charset "UTF-8"; /* 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-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); - } + 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); - } + 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); - } + 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); - } + 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); - } + 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); + } +} + +/*! + * animate.css -http://daneden.me/animate + * Version - 3.5.2 + * Licensed under the MIT license - http://opensource.org/licenses/MIT + * + * Copyright (c) 2017 Daniel Eden + */ +.animated { + animation-duration: 1s; + animation-fill-mode: both; +} + +.animated.infinite { + animation-iteration-count: infinite; } + +.animated.hinge { + animation-duration: 2s; +} + +.animated.flipOutX, +.animated.flipOutY, +.animated.bounceIn, +.animated.bounceOut { + animation-duration: .75s; +} + + +@keyframes bounceIn { + from, 20%, 40%, 60%, 80%, to { + animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + } + + 0% { + opacity: 0; + transform: scale3d(.3, .3, .3); + } + + 20% { + transform: scale3d(1.1, 1.1, 1.1); + } + + 40% { + transform: scale3d(.9, .9, .9); + } + + 60% { + opacity: 1; + transform: scale3d(1.03, 1.03, 1.03); + } + + 80% { + transform: scale3d(.97, .97, .97); + } + + to { + opacity: 1; + transform: scale3d(1, 1, 1); + } +} + +.bounceIn { + animation-name: bounceIn; +} \ No newline at end of file diff --git a/css/style.css b/css/style.css index cc7f30a..bdc99e9 100644 --- a/css/style.css +++ b/css/style.css @@ -27,7 +27,7 @@ body { vertical-align: middle; } -@keyframes pulse { +@keyframes home_pulse { from { transform: scale(1, 1); } @@ -64,7 +64,7 @@ body { .home-box .img-wrapper a:hover { animation-duration: 0.2s; animation-fill-mode: both; - animation-name: pulse; + animation-name: home_pulse; animation-timing-function: ease-in; } @@ -174,4 +174,15 @@ body { } .primary-identity-icon a:hover { color: #888; +} + +.services-list-wrapper { + font-size: 18px; +} +.services-list-wrapper .btn-link { + font-size: 17px; +} +.service-logo { + padding-right: 10px; + max-height: 50px; } \ No newline at end of file diff --git a/include/footer.php b/include/footer.php index 5d0b79f..39fdc44 100644 --- a/include/footer.php +++ b/include/footer.php @@ -1,3 +1,18 @@ +<br/> +<div class="row"> + <div class="col-sm-8 col-sm-offset-2"> + <div class="alert alert-info text-center"> + <div class="animated bounceIn hinge"> + <span class="glyphicon glyphicon-info-sign"></span> + <strong>Need help?</strong> Please read our <a href="https://sso.ia2.inaf.it/home/index.php?lang=en"><u>User guide</u></a> and <a href="https://sso.ia2.inaf.it/home/faq.php?lang=en"><u>FAQ</u></a>. + </div> + </div> + </div> +</div> +<div class="text-center"> + <a href="https://sso.ia2.inaf.it/home/privacy.php?lang=en" target="blank_">Privacy policy</a> +</div> + </div> <div class="waiting hide"> <span class="icon-wrapper"> diff --git a/include/front-controller.php b/include/front-controller.php index bab647c..5010fcd 100644 --- a/include/front-controller.php +++ b/include/front-controller.php @@ -20,8 +20,11 @@ function setCallback($callback) { Flight::route('/', function() { startSession(); $callback = setCallback(Flight::request()->data['callback']); - global $session, $callbackHandler, $AUTHENTICATION_METHODS; - if ($callback !== null && $session->user !== null) { + global $session, $callbackHandler, $BASE_PATH, $AUTHENTICATION_METHODS; + if ($callback === null && $session->user === null) { + Flight::render('services-list.php', array('title' => 'RAP', + 'action' => $BASE_PATH . '/')); + } else if ($callback !== null && $session->user !== null) { $redirectURL = $callbackHandler->getLoginWithTokenURL($session->user->id, $callback); Flight::redirect($redirectURL); } else { diff --git a/include/header.php b/include/header.php index 45b48d5..64d7268 100644 --- a/include/header.php +++ b/include/header.php @@ -7,8 +7,8 @@ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> - <link rel="stylesheet" href="css/style.css" /> - <link rel="stylesheet" href="css/animation.css" /> + <link rel="stylesheet" href="css/style.css?v=2" /> + <link rel="stylesheet" href="css/animation.css?v=2" /> <script src="js/script.js"></script> </head> <body> diff --git a/service-logos/account-manager.png b/service-logos/account-manager.png new file mode 100644 index 0000000000000000000000000000000000000000..23c914f1b7886d3451ad13be8ac3e5ef3ccd8d41 GIT binary patch literal 4686 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 literal 0 HcmV?d00001 diff --git a/service-logos/asiago.gif b/service-logos/asiago.gif new file mode 100644 index 0000000000000000000000000000000000000000..18dbb154e2cc4f13bcab57ad332d932995f6a17f GIT binary patch literal 2672 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 U>R*=^@NHe;?)z#I3k!oa0EGcab^rhX literal 0 HcmV?d00001 diff --git a/service-logos/grouper.png b/service-logos/grouper.png new file mode 100644 index 0000000000000000000000000000000000000000..b3ee45d31f45ba97614cdd6cbbc67243fe51f709 GIT binary patch literal 4787 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 D1=Bej literal 0 HcmV?d00001 diff --git a/service-logos/tng.png b/service-logos/tng.png new file mode 100644 index 0000000000000000000000000000000000000000..719dd541c971506e67d5ca26444ce98ad36c1f7d GIT binary patch literal 3996 zcmeAS@N?(olHy`uVBq!ia0y~yU@&B0U@+ofV_;zT%3-{Tfq{W7$=lt9;Xep2*t>i( z0|NtRfk$L90|U1(2s1Lwnj^u$z`$PO>Fdh=kX?|Ijk)`@^F0Oz2FViFh!W@g+}zZ> z5(ej@)Wnk16ovB4k_-iRPv3y>Mm}){27VS#7srr{dvj-1uSpG$J#N4Me$?+b#pi0z zES~%F#Fop`+GTYvBrz@GR9)Z_QqvNU!6Bq5(xcnYk~HB5Lyt?~|9~S?wrq8{$Z<@l z(W_E)LzWIBx2NOj)0vu=PoLRh{Jr#@W%c^6zkeRT_57aoW$Vk<<@e{@ss47i`t8=b z{`c>H|6Zrd9QQg~VgnaXW8?#i1rG1*7z+}_8zcGNMm~6P^6?58rJr>^EZ+s4_zkA? zEW9frEK?veAy3AgVJVxErJmvBzD?Etio~Y*Pp~Py&YG}NTAiWzfYgRdbB({9lTk{m z?dY%hp;q^4rf!9c>kHLHC;7`h3Kz4L?={QoS*+jrt#{As@AD78mA5}O{avi$DZ424 zCdD)scI9M?K1YuPW*4P%J7&*Wv?!&xrDwV6x}P_d_xy0(f9m%CCzJ2goR0rgeE#0? zC8j|FtIUig=Q$Pk?og5tQvUzzW&Wpo<+W2ZjGkOLI{ovU)rWSiy%N1C<nDJL1NPoG zQ4x-{XM*|HeY_?ef9US_d#%4!1(aT}*gWF%VB-l9ocrL+L(2=RpJm*d+@bZXA?-|b zLTCA%A2M|xE*$oVdHP}M?w>2?-{Un&$!fBU)ORxf8PxFJW<$$TDO2+#{l`59=Pe{_ zoXnIfm8!jG-kkBK%}sTgeBnh_UV}rf2Ui=dVQ+D;Wb)t@69~=<Tw{CcsJMgww1aL> zqxc^re><z5HO(;oXhvhh>`5OoSsvXyeOxG^L!Bo;P(Zs-Ca_8RU0X)yZK3L?<=K*o zLXv`!%ak7S9a`|DkG+K}rh&t<;r!xzMm^ncUjA>mzUSA=FHh=s6x>skR@&^b^vOiS zgpLgFX)$syP1zPW9SAIBaXjh3Y@|5-y={T(iVr#oq5%)}j-GN^@G8i7ftA8m-9Tw0 z?JKtq=W=q2P7pk~q9E#xyBkYogZbSLIk%qW#r@x<{j$|vfW_y-H<8U(^KMOCJhjmx zppKI%&f%D8V^ycB(Ie(5l_3Q_Vg|oFe0EqVF>4uS`MaDqVO)?_o|lp1)Mu=tEb;rK zS+l``+md_Y7JRIXvhT=lE08%q^Y3o9J&$$u)9yd;yZ8B-dg0a9@5O&luYdGX{Jdbq zlH-#jrnE=i-s&O4`@-CrLC3*fv)4?evq5CaXQ>&Ar&%6nbc$Y$5PN>;aer^I+U5PS zA3KVfCbKKZXfD4UD;qMOiFu7%)rS+0xZYR)pKG)0SIoWwf7d&oh4TL2xc=i{fB!_2 zhbk^f-)r7KsE}?Km*|hGiNB_C>f5{W0@qHK^&ZPCY$t?H*qUd=^=^iLL7DNU!!>Uv zbI*y{*L41Fss8Do0*jw4n0>aSuD!&q_nmb74VL)y+15%83se$13Ity2ctkYE2(IA1 zw6Za^>6^rIyZhEg-oKBs%Kf>hv-TRx+li(RBL%+8>MW|z-F5rdA1~FZ#dlmB^#qTw z9yJK#6gv4%)`7>%c3RJbi7}HI6We?qHU5_t+|e*6+h&TuC%r7zmv6S%-rq6(r<>rx zySrcB-uWkh?YpLx$d#3=*fX7+)Wjc}v7{A5#T@IHzPe|d_jZR5k#izmb$Gg~n=PN8 zZ@te&<oNaO13xV`MjV`TKq$ZRwtmsud^xsA#`$kATx?_sYUFTYwsKTi|2t}9lF9v! z=DBBF1s?IeSMySNT=O^k`{p^*9NRmlDyggyt69>2@xi2n!tcC(G9EXWKk4+`rQ6CY zMNZ3a%1f?3r0A`hZ!2hdVEVodUZ(}pJ6<KTe%r(Ug)5?~oYiaM755j@4;|g{C;!(4 zW5$%(j)@Y5v;6GVZd6K_J#tqtaFca0M{-uwH>R0(=OVIQ94@hZ<(llIaFp*s!^^@= zYbLE>;#5%PIPD=kBW-)JT;EHrsyl%$RS#L*m}V+mdSJ#7JVz=qh(n53@!y1PfAy5u z1?Mw+vdYx(r7%=7$Y}oD9M`<fy0>Uyp7^<KQU^}7mU&-RjAp&k+W2V3_Lz@XxGVmC z-GAUsfy;+oS9ovreLAneV?OiZc@@s*HchWGMZW$KSCrnG8ujnvji)VZl8?vK&pRA$ zBN>^#fNu+jFQ;kF@f%y>)bG@`tJcdd7r6e2(SLz&W4L(Jmmj}s`HTNEZ#R}Y+n^$I zSoDbW2UQ=xMRMgWo6=&B+RZPR6{oEgVWyy9$2@QMy49K;&fUfbYy@_6T+9#)Fw$PI zP+_`di{S~DpoK>7`h;$*i{*Y_ylCg#$yqs_HGGaqE067qIpic#sO=)aXr$)XtZ3JM zv81-5_qGqG{cHx~1D}>Ty?QR_r<xLa?(?zC?T<7AE-MvHX`Vhu<##iO<fj;Qo|Fr0 z>Pfo-B=TnIb}aIp?rr;_ifhfB@UVQNHC-nv+ZQtjwzRp<`+8>Yp6}=5&OSWdCLx(< zf6m5_sqjd;q6~9XLby7k?xHniPG^i3#EQQ>!8gfyxoEW6&KEIjRw^*1aI!r6aj$&( zj|1%g=f2llvyex@hHDqsLC$9`Qb(8#7%c;J-aGFx;#h9*?XgMhO}^#IxyLuK-o0dh z$uPcl4|8oa=e;QJ1;=kyi2pA=f4JvXY{;31+k%9w-On&dI)2J?$zCGW7`EfggLxkf zj!7!bWxwNmTxOY#%KXiT3%_f=y%D(7Sy>``28+s@L%NAyxGqlaTG04l;<4A4qAMJ3 z-3er6&c2wzk?Wq4+I+Bc{zUn@Yc~R>tWdiBKGXbej?W1TgCmm{%+s*A{^(hX^yKB& zwgd`Z=wM;|+7=h1^s2)pVb8gg&oeL9ol6OSyW&Tt!0YD^xdMe2b}(`<I#>1_aSkax zdRecQ%YWye%q6>2)t~?7mwA5T`+nzd!WP1HFQ@B2oh2T3wEEuzv18iy7ke{b@BR65 z=8AO9GB-70Zov<^hqkOQkGFJBXy{5zbeb*qs7qb;!7lT-<EP_3D(PA8nE%t#>Z^0) zY@Q#l_TGPVxxA*kzwSx!pWC+TKR$j;o)c4P*YaCnrtTr8V<CGgl5V^`bh4Zw^PQip zcYK4MlhrBh^|f;KfA^Jd`frqxq1b;iH*&@9z?C1Hve!Lfy&iM2H-GQ6@V&p--u>*~ z9WXEch;xrbcgdFuv5log{=(7a$7WC2CMle`v1W?&y)xPVKR%Xk`Y)usJjBU+j(|f9 zr=n1E(l#a)Jv)_}m#6DbpN{_))FaH%D4~3IiK9T#x!dPDWj9A0?{xH>^T53B@AIFZ z_g9F%<5h8Gp22#C>7-ByC#TysC6OK6(~J$b-Kn~LyYk*u_7h8#!d5RjwQc8Q>&s=| zeZo&x2}d2<)a&wcR#o}Jv&Sa$$DFvo=fCb0-v&V!fo=}33vw5fy}dWF@h*sZESV(G za^}w;Df9c^)V`fLH_7HP-^n==ht*EyOLtUHTj%EAtXjToRZsMbFN--3?YPp$vPxJ* zOMRMlUd8A2g&!vQZ0Ip;U;X$M%fw6J>?>*<Cj9&Li1XIXMaOCn7_Yl`Iy=5{MrypX z$pW4N{Y$odmL^AH+N?JhNxWtW*dBJxD%bPHR9hCtMU&UI-_*JP<Jk7fyRYk)2W0SG zeiScsd3Ro9P4M@9hMg;~ncDu3&acotF1986r*PUO+uPpKs?mqfhvZz={jbYe_};?5 zwLD|u$q0!LH#)m6dfeRm-f7cwqZ>12m;H{EIL}sUsQu+prvLsq$NSzcJZXC@F2X@@ zgSE5Qtx3my9dl00-S$k4KNGqA)E3D@+Sg{u8E+OZX?6`VidpJ0>GHKJ+pmQ$pDZr8 z<@Lnh#iGmQUSEF3Fw5*}=ewJ?@=h*Uet30xWkJ+pMd_eLCAat-PPHlaghiLVzqh&2 zG2~3GE#qmYCu?r()0<l+&v4qwi}T}|OyO5cwrzef;j;D{6RmygewRDFpHd~homFIc z*SS}(f+8bs3oY-z)H~-<Pt1)?XGLFzWJ#P!36Zs#^!eF`lhVxd&kCnnzwT+T)TzFl z)$!!3D@&k``5B(*Yi`}HY8+jWYGrd=t;%=&s?xJvxM{ZI<NlYeK1=p<c3LHTc(um7 z{6$Li)k8}6yOonznPp708>iV;w@#h<IN@lO(uCcGdzP@Z<wf^IR=g0|yxZ^6d(mF& zSIhPsD&SA|%+cI(*njc**NwqhtUEQzDjMJFu$WeDeE2F|_L=tl|2`9QtSoF}&ri(T z?=&x<^2eL~HPcSdH*z?karM`19%<f7kKI3>6}9$M`YAWZ)P=`r%dL`H2mVhy7n#K7 zJY9G>`mS?Nf5FMg!u5aL<yHD$97<dHrp2u3Hp_NV7qvAfxzzX~yG$mt7AuwuRJ{p# z7Ayac<@asLv{|NVd)+14HC+vZ+9!1eAKe_;^{HcVAy3Ps8&2H@$0QZGE-JqY>YCPA z;UaiNE2-m&Nq5$K{d>Pd^Y*@cw@CD&(Z}En{t44om`>AX3ib41b>c4Es$=0S@bGSZ zg|Pd+N|_`Eww5&cS-)jVv=08B>tfPfl{s(O?gN+3JUFwE(LK1=fZ6Pbaq8y)wT`q2 zV%H5X2pnd)JXxaa^@IaQ|J-|D*P(xBr%Q_b-iYZNHVgGRDqc`7NsTd4W@$Pju=qpy z_CMz4d;bTokV#NV*yw7Y)vG$^kdRg`V~@<KdF=t)rq68f>sYfOV|Sxc&>GbvljdC7 zJO3e9NQ&_$pMtyRPc89ZmNtcb&mYnE59Ytyu|C*Z;RVCzj-89PSnPCO%k`p}#qLA+ z|C3*@@8`eTJVRR8(nY##@v4a1Wm}vJoK6~=UWmD;I8p3{qL9_Cg#uN#=B^RYJyn(v z;N-|0+jC*{b5E-WS6(sZ{co?{&0CmSD6-?-t?vbYrSl&D`#n8EmfNv)#if(Fi~(Z) ztnc>y{{82a_x-cI`G13ZxDWC(B-?%Yen0Uj|D&WUhu_5t&Q%uTww~7DQ5o-|!L{gx zjHKeW+_SmcYua}2H#&5SOH_T)ma7t<Jv>BhXJ2TW^?0%Cv9}Yf-&akj-}gB2L3+mW zKd1DbPn-Sz;bHUpCym$H9Wd3e(VHGuHDRy#6`QIzBL9ECU0n08_<P}#_T!BmMUrm5 zua=zfugRJzyqa6$+}iDT4^FqQR#eM2nZ>!&zt5ZHweqDTC6@bV&G+qWFmTkf{&IWY zmK&35S!eSUmTU3%JofDAn(;g2nu1Zn+PLHu?Kh(Tb_8zj-gqwIqXmod63eFW6>B$5 zlRLUZEnT@yaGG+3YwY=Emo2XhXZEbf5-`m%@%|#!xjJC&hFvy_w*;n}Mn$^S@CPVY oiaSm-EDS2D+I+0w+K+l}nR#jkCs#`|FfcH9y85}Sb4q9e041qwZ2$lO literal 0 HcmV?d00001 diff --git a/views/index.php b/views/index.php index bd9a127..c667d11 100644 --- a/views/index.php +++ b/views/index.php @@ -6,7 +6,16 @@ include 'include/header.php'; <?php if ($session->user === null) { ?> <div class="row"> <div class="col-xs-12"> - <h1 class="text-center page-title"><?php echo $session->getCallbackTitle(); ?></h1> + <h1 class="text-center page-title"> + <?php + if ($session->getCallbackLogo() != null) { + ?> + <img class="service-logo" src="service-logos/<?php echo $session->getCallbackLogo(); ?>" alt="" /> + <?php + } + echo $session->getCallbackTitle(); + ?> + </h1> </div> </div> <div class="row" id="auth-panel"> diff --git a/views/services-list.php b/views/services-list.php new file mode 100644 index 0000000..800bff9 --- /dev/null +++ b/views/services-list.php @@ -0,0 +1,37 @@ +<?php +include 'include/header.php'; +?> +<div class="col-sm-offset-2 col-sm-10 services-list-wrapper"> + <p>Please choose the service where you want to login:</p> + <ul> + <li> + <form action="<?php echo $action; ?>" method="POST"> + <input name="callback" type="hidden" value="http://archives.ia2.inaf.it/tng/rest/login/rapinput" /> + <input type="submit" class="btn btn-link" value="Telescopio Nazionale Galileo (TNG) portal" /> + </form> + </li> + <li> + <form action="<?php echo $action; ?>" method="POST"> + <input name="callback" type="hidden" value="http://archives.ia2.inaf.it/aao/rest/login/rapinput" /> + <input type="submit" class="btn btn-link" value="Asiago Astrophysical Observatory portal" /> + </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> + </li> + <li> + <form action="<?php echo $action; ?>" method="POST"> + <input name="callback" type="hidden" value="https://sso.ia2.inaf.it/grouper" /> + <input type="submit" class="btn btn-link" value="Grouper (groups management)" /> + </form> + </li> + </ul> + <br/> +</div> + +<?php +include 'include/footer.php'; + -- GitLab