From 5e53354db849d3a1aca1a46ff43a01459ad8aa68 Mon Sep 17 00:00:00 2001 From: Dimitris Efstathiou Date: Thu, 3 Nov 2016 14:19:33 +0200 Subject: [PATCH] Login process added to the code. --- OrcidProfilePlugin.inc.php | 33 ++++++++++++ locale/en_US/locale.xml | 1 + orcidLogin.tpl | 25 ++++++++++ orcidProfile.tpl | 2 +- pages/OrcidHandler.inc.php | 100 ++++++++++++++++++++++++++++++++++++- 5 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 orcidLogin.tpl diff --git a/OrcidProfilePlugin.inc.php b/OrcidProfilePlugin.inc.php index b8ab80e0..f1d11fb2 100644 --- a/OrcidProfilePlugin.inc.php +++ b/OrcidProfilePlugin.inc.php @@ -99,6 +99,9 @@ function handleTemplateDisplay($hookName, $args) { case 'author/submit/step3.tpl': $templateMgr->register_outputfilter(array(&$this, 'submitFilter')); break; + case 'user/login.tpl': + $templateMgr->register_outputfilter(array(&$this, 'loginFilter')); + break; } return false; } @@ -117,6 +120,36 @@ function getOauthPath() { } } + /** + * Output filter adds ORCiD interaction to login form. + * @param $output string + * @param $templateMgr TemplateManager + * @return $string + */ + function loginFilter($output, &$templateMgr) { + $sessionManager = SessionManager::getManager(); + $userSession = $sessionManager->getUserSession(); + + if (preg_match('/
]+>/', $output, $matches, PREG_OFFSET_CAPTURE)) { + $match = $matches[0][0]; + $offset = $matches[0][1]; + $journal = Request::getJournal(); + + $templateMgr->assign(array( + 'targetOp' => 'login', + 'orcidProfileOauthPath' => $this->getOauthPath(), + 'orcidClientId' => $this->getSetting($journal->getId(), 'orcidClientId'), + )); + + $newOutput = substr($output, 0, $offset); + $newOutput .= $templateMgr->fetch($this->getTemplatePath() . 'orcidLogin.tpl'); + $newOutput .= substr($output, $offset); + $output = $newOutput; + } + $templateMgr->unregister_outputfilter('loginFilter'); + return $output; + } + /** * Output filter adds ORCiD interaction to registration form. * @param $output string diff --git a/locale/en_US/locale.xml b/locale/en_US/locale.xml index a0bcdb31..c15a47ae 100644 --- a/locale/en_US/locale.xml +++ b/locale/en_US/locale.xml @@ -20,6 +20,7 @@ Couldn\'t find any data from ORCID. Email address or ORCID iD: Submit + Create or Connect your ORCID iD ORCID Profile Settings Configure the ORCID API for use in pulling ORCID profile information into the user profile. ORCID API diff --git a/orcidLogin.tpl b/orcidLogin.tpl new file mode 100644 index 00000000..0d7adf4e --- /dev/null +++ b/orcidLogin.tpl @@ -0,0 +1,25 @@ +{** + * plugins/generic/orcidProfile/orcidProfile.tpl + * + * Copyright (c) 2015-2016 University of Pittsburgh + * Copyright (c) 2014-2016 Simon Fraser University Library + * Copyright (c) 2003-2016 John Willinsky + * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING. + * + * ORCID Profile authorization form + * + *} + +{literal} + +{/literal} + \ No newline at end of file diff --git a/orcidProfile.tpl b/orcidProfile.tpl index 6b060417..1a3c24a0 100644 --- a/orcidProfile.tpl +++ b/orcidProfile.tpl @@ -19,4 +19,4 @@ function openORCID() {ldelim} -
+
\ No newline at end of file diff --git a/pages/OrcidHandler.inc.php b/pages/OrcidHandler.inc.php index 56bd2210..f68ba2a7 100644 --- a/pages/OrcidHandler.inc.php +++ b/pages/OrcidHandler.inc.php @@ -29,19 +29,24 @@ function orcidAuthorize($args, &$request) { // fetch the access token $curl = curl_init(); + //curl_setopt($curl, CURLOPT_URL, $plugin->getSetting($journal->getId(), 'orcidProfileAPIPath').OAUTH_TOKEN_URL); curl_setopt_array($curl, array( CURLOPT_URL => $plugin->getSetting($journal->getId(), 'orcidProfileAPIPath').OAUTH_TOKEN_URL, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => array('Accept: application/json'), CURLOPT_POST => true, CURLOPT_POSTFIELDS => http_build_query(array( - 'code' => Request::getUserVar('code'), + 'code' => $request->getUserVar('code'), 'grant_type' => 'authorization_code', 'client_id' => $plugin->getSetting($journal->getId(), 'orcidClientId'), 'client_secret' => $plugin->getSetting($journal->getId(), 'orcidClientSecret') )) )); + $result = curl_exec($curl); + $error = curl_error($curl); + + $response = json_decode($result, true); curl_setopt_array($curl, array( @@ -56,6 +61,8 @@ function orcidAuthorize($args, &$request) { $json = json_decode($result, true); } + // TODO defstat: Check the $json parameter - Not always full because of error code not always 200. + switch (Request::getUserVar('targetOp')) { case 'register': echo ''; + break; + case 'login': + if (!is_null($json)) { + // The user that will be logged in + $loggedInUser = null; + + // Check if there is any user that has autoassigned orcidauth parameter on the UserSettings. + $userSettingsDao = DAORegistry::getDAO('UserSettingsDAO'); + $userDao = DAORegistry::getDAO('UserDAO'); + $users = $userSettingsDao->getUsersBySetting('orcidauth', 'http://orcid.org/' . $response['orcid']); + + if (is_null($users) || $users->count == 0) { // If no user exists + // Then we should look for someone that has his orcid field filled. + $users = $userSettingsDao->getUsersBySetting('orcid', 'http://orcid.org/' . $response['orcid']); + + if (is_null($users) || $users->count == 0) { // If no user exists + // Then we can look if there is any user with the email assigned to any email from ORCID profile + + // get all emails + $emails = $json['orcid-profile']['orcid-bio']['contact-details']['email']; + if (!is_null($emails)) { // No emails retrieved from api. Email field may not be public + foreach($emails as $email) { + $user->$userDao->getUserByEmail($email, false); + + if (!is_null($user)) { + $loggedInUser = $user; + break; + } + } + } + } else { // we have at least one user with his orcid field filled + if (count($users) != 1) { // There are more than one users with that orcidauth. Nothing we can do. Loggin fails + $loggedInUser = false; + Validation::redirectLogin('plugins.generic.oauth.message.oauthTooManyMatches'); + } else { // only one user has the current orcidauth. We can log him in. + $loggedInUser = $users->next(); + } + } + + } else { // There is at least one user with its orcidauth assigned to the current value + if ($users->count != 1) { // There are more than one users with that orcidauth. Nothing we can do. Loggin fails + $loggedInUser = false; + Validation::redirectLogin('plugins.generic.oauth.message.oauthTooManyMatches'); + } else { // only one user has the current orcidauth. We can log him in. + $loggedInUser = $users->next(); + } + + } + + if ($loggedInUser) { + $userDao =& DAORegistry::getDAO('UserDAO'); + + $reason = null; + // The user is valid, mark user as logged in in current session + $sessionManager =& SessionManager::getManager(); + + // Regenerate session ID first + $sessionManager->regenerateSessionId(); + + $session =& $sessionManager->getUserSession(); + $session->setSessionVar('userId', $loggedInUser->getId()); + $session->setUserId($loggedInUser->getId()); + $session->setSessionVar('username', $loggedInUser->getUsername()); + //$session->setRemember($remember); + + $loggedInUser->setDateLastLogin(Core::getCurrentDate()); + $userDao->updateObject($loggedInUser); + + Validation::redirectLogin(); + } else { // OAuth successful, but not linked to a user account (yet) + $sessionManager = SessionManager::getManager(); + $userSession = $sessionManager->getUserSession(); + $user = $userSession->getUser(); + + if (isset($user)) { + // If the user is authenticated, link this user account + $userSettingsDao->updateSetting($user->getId(), 'orcidauth', 'http://orcid.org/' . $response['orcid'], 'string'); + $userSettingsDao->updateSetting($user->getId(), 'orcid', 'http://orcid.org/' . $response['orcid'], 'string'); + } else { + // Otherwise, send the user to the login screen (keep track of the oauthUniqueId to link upon login!) + $userSession->setSessionVar('orcidauth', 'http://orcid.org/' . $response['orcid']); + } + } + + Validation::redirectLogin('plugins.generic.oauth.message.oauthLoginError'); + } + + Validation::redirectLogin('plugins.generic.oauth.message.oauthTooManyMatches'); + break; default: assert(false); } @@ -150,6 +246,8 @@ function orcidVerify($args, $request) { )); $templateMgr->display('common/message.tpl'); } + + } ?>