Commit 0fd902eb authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Added ORCID login

parent 48517d29
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@ Requirements:

On Ubuntu:

    sudo apt install apache2 mariadb-server libapache2-mod-php mariadb-server php7.2-xml php7.2-mbstring php-mysql
    sudo apt install apache2 mariadb-server libapache2-mod-php mariadb-server php7.2-xml php7.2-mbstring php-mysql php-curl

### PHP

+3 −3
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ class FacebookLogin extends LoginHandler {
        parent::__construct($locator, Identity::FACEBOOK);
    }

    public function login() {
    public function login(): string {

        // Retrieve Facebook configuration
        $Facebook = $this->locator->config->authenticationMethods->Facebook;
@@ -25,10 +25,10 @@ class FacebookLogin extends LoginHandler {

        $loginUrl = $helper->getLoginUrl($Facebook->callback, $permissions);

        header("Location: $loginUrl");
        return $loginUrl;
    }

    public function retrieveToken() {
    public function retrieveToken(): string {
        // Retrieve Facebook configuration
        $Facebook = $this->locator->config->authenticationMethods->Facebook;

+7 −7
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ class LinkedInLogin extends LoginHandler {
        parent::__construct($locator, Identity::FACEBOOK);
    }

    public function login() {
    public function login(): string {
        // Retrieve LinkedIn configuration
        $LinkedIn = $this->locator->config->authenticationMethods->LinkedIn;

@@ -18,10 +18,10 @@ class LinkedInLogin extends LoginHandler {
        $url .= "&state=789654123";
        $url .= "&scope=r_basicprofile r_emailaddress";

        header("Location: $url");
        return $url;
    }

    public function retrieveToken() {
    public function retrieveToken(): string {
        // Retrieve LinkedIn configuration
        $LinkedIn = $this->locator->config->authenticationMethods->LinkedIn;

+127 −0
Original line number Diff line number Diff line
<?php

namespace RAP;

class OrcidLogin extends LoginHandler {

    public function __construct(Locator $locator) {
        parent::__construct($locator, Identity::ORCID);
    }

    public function login(): string {

        $ORCID = $this->locator->config->authenticationMethods->OrcID;

        $url = "https://orcid.org/oauth/authorize";
        $url = $url . "?client_id=" . $ORCID->id;
        $url = $url . "&response_type=code";
        $url = $url . "&scope=/authenticate";
        $url = $url . "&redirect_uri=" . $this->locator->getBasePath() . $ORCID->callback;

        return $url;
    }

    public function retrieveToken($code) {

        if ($code === null) {
            throw new BadRequestException("Unable to get ORCID client code");
        }

        $token = $this->getAccessTokenFromCode($code);

        $access_token = $token['access_token'];
        $expires_in = $token['expires_in'];
        $orcid_id = $username = $token['orcid'];

        $orcid_data = $this->getOrcidDataUsingAccessToken($orcid_id, $access_token);

        if (!isset($orcid_data['person']['emails']['email'][0]['email'])) {
            throw new \Exception("ORCID didn't return the email");
        }

        return $this->onIdentityDataReceived($orcid_id, function($identity) use($orcid_data) {
                    $identity->email = $email = $orcid_data['person']['emails']['email'][0]['email'];
                    $identity->name = $orcid_data['person']['name']['given-names']['value'];
                    $identity->surname = $orcid_data['person']['name']['family-name']['value'];
                    $employmentSummary = $orcid_data['activities-summary']['employments']['employment-summary'];
                    if (count($employmentSummary) > 0) {
                        $identity->institution = $employmentSummary[0]['organization']['name'];
                    }
                });
    }

    private function getAccessTokenFromCode($code): array {

        $ORCID = $this->locator->config->authenticationMethods->OrcID;

        //create array of data to be posted to get AccessToken
        $post_data = array(
            'grant_type' => "authorization_code",
            'code' => $code,
            'redirect_uri' => $this->locator->getBasePath() . $ORCID->callback,
            'client_id' => $ORCID->id,
            'client_secret' => $ORCID->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
        $conn = curl_init('https://orcid.org/oauth/token');

        //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);

        //set data to be posted
        curl_setopt($conn, CURLOPT_POSTFIELDS, $post_string);

        //perform our request
        $result = curl_exec($conn);

        if ($result) {
            $token = json_decode($result, TRUE);
            curl_close($conn);
            return $token;
        } else {
            //show information regarding the error
            $errorMessage = curl_errno($conn) . "-";
            $errorMessage = $errorMessage . curl_error($conn);
            curl_close($conn);
            throw new \Exception($errorMessage);
        }
    }

    private function getOrcidDataUsingAccessToken(string $orcid_id, string $access_token) {

        // API call
        $orcid_url = "https://pub.orcid.org/v2.1/" . $orcid_id . "/record";
        $conn = curl_init();
        curl_setopt($conn, CURLOPT_URL, $orcid_url);
        curl_setopt($conn, CURLOPT_HTTPHEADER, array(
            'Authorization: Bearer ' . $access_token,
            'Accept: application/json'));

        curl_setopt($conn, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($conn);

        if ($result) {
            $orcid_data = json_decode($result, TRUE);
            curl_close($conn);
            return $orcid_data;
        } else {
            $errorMessage = curl_errno($conn) . "-";
            $errorMessage = $errorMessage . curl_error($conn);
            curl_close($conn);
            throw new \Exception($errorMessage);
        }
    }

}
+1 −1
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ class AuthPageModel {
        $this->eduGAIN = isset($config->authenticationMethods->eduGAIN) &&
                in_array(AuthenticationMethods::EDU_GAIN, $client->authMethods);

        $this->orcid = isset($config->authenticationMethods->Orcid) &&
        $this->orcid = isset($config->authenticationMethods->OrcID) &&
                in_array(AuthenticationMethods::ORCID, $client->authMethods);

        $this->x509 = isset($config->authenticationMethods->X509) &&
Loading