From 4e0c3d3a8787c4751e50167519444fb70ca68534 Mon Sep 17 00:00:00 2001 From: Sonia Zorba <zorba@oats.inaf.it> Date: Mon, 21 May 2018 15:59:21 +0200 Subject: [PATCH] Changes for being compliant with new GDPR law --- auth/oauth2/facebook_token.php | 5 +- auth/oauth2/google_token.php | 5 +- auth/oauth2/linkedin_token.php | 5 +- auth/saml2/aai.php | 5 +- auth/x509/certlogin.php | 90 ++++++++++++---------------------- classes/SessionData.php | 4 ++ classes/X509Data.php | 19 +++++++ include/front-controller.php | 50 +++++++++++++++++-- js/tou.js | 7 +++ sql/setup-database.sql | 1 + views/tou-check.php | 44 +++++++++++++++++ 11 files changed, 169 insertions(+), 66 deletions(-) create mode 100644 js/tou.js create mode 100644 views/tou-check.php diff --git a/auth/oauth2/facebook_token.php b/auth/oauth2/facebook_token.php index d438314..52f66a0 100755 --- a/auth/oauth2/facebook_token.php +++ b/auth/oauth2/facebook_token.php @@ -98,7 +98,10 @@ if ($user === null) { $user->addIdentity($identity); - $userHandler->saveUser($user); + $session->userToLogin = $user; + $session->save(); + header('Location: ' . $BASE_PATH . '/tou-check'); + die(); } $auditLog->info("LOGIN,Facebook," . $user->id); diff --git a/auth/oauth2/google_token.php b/auth/oauth2/google_token.php index c5a5bd4..16831cc 100644 --- a/auth/oauth2/google_token.php +++ b/auth/oauth2/google_token.php @@ -92,7 +92,10 @@ if ($client->getAccessToken()) { $user->addIdentity($identity); - $userHandler->saveUser($user); + $session->userToLogin = $user; + $session->save(); + header('Location: ' . $BASE_PATH . '/tou-check'); + die(); } $auditLog->info("LOGIN,Google," . $user->id); diff --git a/auth/oauth2/linkedin_token.php b/auth/oauth2/linkedin_token.php index fde3cb8..64a5647 100644 --- a/auth/oauth2/linkedin_token.php +++ b/auth/oauth2/linkedin_token.php @@ -118,7 +118,10 @@ if ($info2['http_code'] === 200) { $user->addIdentity($identity); - $userHandler->saveUser($user); + $session->userToLogin = $user; + $session->save(); + header('Location: ' . $BASE_PATH . '/tou-check'); + die(); } $auditLog->info("LOGIN,LinkedIn," . $user->id); diff --git a/auth/saml2/aai.php b/auth/saml2/aai.php index cd89610..0b82779 100644 --- a/auth/saml2/aai.php +++ b/auth/saml2/aai.php @@ -57,7 +57,10 @@ if (isset($_SERVER['Shib-Session-ID'])) { $user->addIdentity($identity); - $userHandler->saveUser($user); + $session->userToLogin = $user; + $session->save(); + header('Location: ' . $BASE_PATH . '/tou-check'); + die(); } $auditLog->info("LOGIN,eduGAIN," . $user->id); diff --git a/auth/x509/certlogin.php b/auth/x509/certlogin.php index 61085fe..c811cd8 100644 --- a/auth/x509/certlogin.php +++ b/auth/x509/certlogin.php @@ -32,66 +32,38 @@ include '../../include/init.php'; startSession(); -function saveUserFromX509Data($x509Data) { - - global $session, $userHandler; - - $user = new RAP\User(); - - $identity = new RAP\Identity(RAP\Identity::X509); - $identity->email = $x509Data->email; - $identity->name = $x509Data->name; - $identity->surname = $x509Data->surname; - $identity->typedId = $x509Data->serialNumber; - $identity->institution = $x509Data->institution; - - $user->addIdentity($identity); - - $userHandler->saveUser($user); - - $session->x509DataToRegister = null; - $session->save(); - - return $user; -} - -/** - * 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 ($session->x509DataToRegister !== null && $session->x509DataToRegister->name !== null) { - - $user = saveUserFromX509Data($session->x509DataToRegister); -} else { - - 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) { - - if ($x509Data->name === null) { - $session->x509DataToRegister = $x509Data; - $session->save(); - header('Location: ' . $BASE_PATH . '/x509-name-surname'); - die(); - } else { - $user = saveUserFromX509Data($x509Data); - } +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 { - http_response_code(500); - die("Unable to verify client certificate"); + $auditLog->info("LOGIN,X.509," . $user->id); + $callbackHandler->manageLoginRedirect($user, $session); } +} else { + http_response_code(500); + die("Unable to verify client certificate"); } - -$auditLog->info("LOGIN,X.509," . $user->id); -$callbackHandler->manageLoginRedirect($user, $session); diff --git a/classes/SessionData.php b/classes/SessionData.php index 294e934..ef5c8a8 100644 --- a/classes/SessionData.php +++ b/classes/SessionData.php @@ -37,6 +37,10 @@ class 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; /** * @todo: move DAO away from here diff --git a/classes/X509Data.php b/classes/X509Data.php index bede4cd..ddfb402 100644 --- a/classes/X509Data.php +++ b/classes/X509Data.php @@ -88,6 +88,9 @@ class X509Data { $this->email = $AyAlt[1]; } } + if ($this->email === null && isset($parsedX509["subject"]) && isset($parsedX509["subject"]["emailAddress"])) { + $this->email = $parsedX509["subject"]["emailAddress"]; + } $this->serialNumber = $parsedX509["serialNumber"]; @@ -200,4 +203,20 @@ class X509Data { return $parsedData; } + public function toUser() { + + $user = new User(); + + $identity = new Identity(Identity::X509); + $identity->email = $this->email; + $identity->name = $this->name; + $identity->surname = $this->surname; + $identity->typedId = $this->serialNumber; + $identity->institution = $this->institution; + + $user->addIdentity($identity); + + return $user; + } + } diff --git a/include/front-controller.php b/include/front-controller.php index 2d1c405..1fbabb7 100644 --- a/include/front-controller.php +++ b/include/front-controller.php @@ -159,6 +159,7 @@ Flight::route('GET /x509-name-surname', function() { } else { // Redirect to index header("Location: " . $BASE_PATH); + die(); } }); @@ -169,12 +170,55 @@ Flight::route('GET /x509-name-surname', function() { Flight::route('POST /submit-x509-name', function() { $selectedNameIndex = Flight::request()->data['selected-name']; - + + error_log('index=' . $selectedNameIndex); + startSession(); global $session, $BASE_PATH; - + if ($session->x509DataToRegister !== null) { $session->x509DataToRegister->selectCandidateName($selectedNameIndex); - header("Location: " . $BASE_PATH . '/x509'); + $session->userToLogin = $session->x509DataToRegister->toUser(); + $session->x509DataToRegister = null; + $session->save(); + header("Location: " . $BASE_PATH . '/tou-check'); + die(); + } else { + die('X.509 data not returned'); + } +}); + +Flight::route('GET /tou-check', function() { + + startSession(); + global $session, $BASE_PATH, $VERSION; + + if ($session->userToLogin === null) { + die("User data not retrieved."); + } else { + Flight::render('tou-check.php', array('title' => 'Terms of Use acceptance', + 'user' => $session->userToLogin, + 'version' => $VERSION, + 'registration_url' => $BASE_PATH . '/register')); + } +}); + +Flight::route('GET /register', function() { + + startSession(); + global $session, $userHandler, $auditLog, $callbackHandler; + + if ($session->userToLogin === null) { + die("User data not retrieved."); + } else { + + $user = $session->userToLogin; + $userHandler->saveUser($user); + + $session->userToLogin = null; + $session->save(); + + $auditLog->info("LOGIN," . $user->identities[0]->type . "," . $user->id); + $callbackHandler->manageLoginRedirect($user, $session); } }); diff --git a/js/tou.js b/js/tou.js new file mode 100644 index 0000000..a3f42bd --- /dev/null +++ b/js/tou.js @@ -0,0 +1,7 @@ +$('#tou-ck').on('change', function () { + if ($(this).is(':checked')) { + $('#tou-submit').removeClass('hide'); + } else { + $('#tou-submit').addClass('hide'); + } +}); diff --git a/sql/setup-database.sql b/sql/setup-database.sql index 8bb38e0..d5b4328 100644 --- a/sql/setup-database.sql +++ b/sql/setup-database.sql @@ -14,6 +14,7 @@ CREATE TABLE `identity` ( `surname` varchar(255) DEFAULT NULL, `institution` varchar(255) DEFAULT NULL, `eppn` varchar(255) DEFAULT NULL, + `tou_accepted` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/views/tou-check.php b/views/tou-check.php new file mode 100644 index 0000000..a72f88a --- /dev/null +++ b/views/tou-check.php @@ -0,0 +1,44 @@ +<?php +include 'include/header.php'; +?> + +<br/> +<div class="text-center"> + <p>If you proceed, following data will be stored into IA2 user database:</p> +</div> + +<div class="row"> + <div class="col-xs-12 col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3"> + <div class="panel"> + <div class="panel-body"> + <?php + $readOnly = true; + include 'include/user-data.php'; + ?> + </div> + </div> + </div> +</div> + +<div class="row text-center"> + <strong> + <span class="glyphicon glyphicon-info-sign"></span> + For using IA2 services you need to accept our <a href="https://sso.ia2.inaf.it/home/privacy.php?lang=en" target="blank_">privacy policy</a>. + </strong> + <div class="checkbox"> + <label> + <input type="checkbox" id="tou-ck" /> + I accept IA2 services Terms of Use. + </label> + </div> + <form method="GET" action="<?php echo $registration_url; ?>"> + <input type="submit" class="btn btn-primary hide" id="tou-submit" value="Submit" /> + </form> +</div> + +<script src="js/tou.js"></script> + +<br/> + +<?php +include 'include/footer.php'; -- GitLab