chamilo/chamilo-lms

View on GitHub
public/plugin/azure_active_directory/src/callback.php

Summary

Maintainability
A
0 mins
Test Coverage
<?php
/* For license terms, see /license.txt */
/**
 * Callback script for Azure. The URL of this file is sent to Azure as a
 * point of contact to send particular signals.
 */
require __DIR__.'/../../../main/inc/global.inc.php';

$plugin = AzureActiveDirectory::create();

$provider = $plugin->getProvider();

if (!isset($_GET['code'])) {
    // If we don't have an authorization code then get one by redirecting
    // users to Azure (with the callback URL information)
    $authUrl = $provider->getAuthorizationUrl();

    ChamiloSession::write('oauth2state', $provider->getState());

    header('Location: '.$authUrl);
    exit;
}

// Check given state against previously stored one to mitigate CSRF attack
if (empty($_GET['state']) || ($_GET['state'] !== ChamiloSession::read('oauth2state'))) {
    ChamiloSession::erase('oauth2state');

    exit;
}

// Try to get an access token (using the authorization code grant)
$token = $provider->getAccessToken('authorization_code', [
    'code' => $_GET['code'],
    'resource' => 'https://graph.windows.net',
]);

$me = null;

try {
    $me = $provider->get('me', $token);

    if (empty($me)) {
        throw new Exception('Token not found.');
    }

    // We use the e-mail to authenticate the user, so check that at least one
    // e-mail source exists
    if (empty($me['mail']) || empty($me['mailNickname'])) {
        throw new Exception('Mail empty');
    }

    $extraFieldValue = new ExtraFieldValue('user');
    $organisationValue = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
        AzureActiveDirectory::EXTRA_FIELD_ORGANISATION_EMAIL,
        $me['mail']
    );
    $azureValue = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
        AzureActiveDirectory::EXTRA_FIELD_AZURE_ID,
        $me['mailNickname']
    );

    $userId = null;
    // Get the user ID (if any) from the EXTRA_FIELD_ORGANISATION_EMAIL extra
    // field
    if (!empty($organisationValue) && isset($organisationValue['item_id'])) {
        $userId = $organisationValue['item_id'];
    }

    if (empty($userId)) {
        // If the previous step didn't work, get the user ID from
        // EXTRA_FIELD_AZURE_ID
        if (!empty($azureValue) && isset($azureValue['item_id'])) {
            $userId = $azureValue['item_id'];
        }
    }

    if (empty($userId)) {
        // If we didn't find the user
        if ('true' === $plugin->get(AzureActiveDirectory::SETTING_PROVISION_USERS)) {
            // If the option is set to create users, create it
            $userId = UserManager::create_user(
                $me['givenName'],
                $me['surname'],
                STUDENT,
                $me['mail'],
                $me['mailNickname'],
                '',
                null,
                null,
                $me['telephoneNumber'],
                null,
                'azure',
                null,
                ($me['accountEnabled'] ? 1 : 0),
                null,
                [
                    'extra_'.AzureActiveDirectory::EXTRA_FIELD_ORGANISATION_EMAIL => $me['mail'],
                    'extra_'.AzureActiveDirectory::EXTRA_FIELD_AZURE_ID => $me['mailNickname'],
                ]
            );
            if (!$userId) {
                throw new Exception(get_lang('UserNotAdded').' '.$me['mailNickname']);
            }
        } else {
            throw new Exception('User not found when checking the extra fields from '.$me['mail'].' or '.$me['mailNickname'].'.');
        }
    }

    $userInfo = api_get_user_info($userId);

    if (empty($userInfo)) {
        throw new Exception('User '.$userId.' not found.');
    }

    if ('1' != $userInfo['active']) {
        throw new Exception(get_lang('AccountInactive'));
    }
} catch (Exception $exception) {
    $message = Display::return_message($exception->getMessage(), 'error');
    Display::addFlash($message);
    header('Location: '.api_get_path(WEB_PATH));
    exit;
}

$_user['user_id'] = $userInfo['user_id'];
$_user['uidReset'] = true;

ChamiloSession::write('_user', $_user);
ChamiloSession::write('_user_auth_source', 'azure_active_directory');
Event::eventLogin($userInfo['user_id']);
Redirect::session_request_uri(true, $userInfo['user_id']);