Ottenere l'URL per il SSO in Moodle con WordPress

Lo scenario descritto in questo articolo è quello di un sito WordPress che utilizza Moodle per gestire corsi e lezioni. Vedremo ottenere l'URL per il SSO in Moodle usando le sue API grazie alle funzionalità HTTP di WordPress.

In Moodle occorre installare e attivare il plugin User key authentication. Dopo la configurazione iniziale del plugin, dobbiamo verificare che sia abilitato come servizio e generare un token per un utente abilitato ad usarlo.

Nel file functions.php del nostro tema, definiamo l'URL di base e il token di Moodle. Per impostazione predefinita, il plugin di autenticazione utilizza il solo campo email per il login temporaneo, quindi occorre specificarlo.

const HTTP_TIMEOUT = 15;
const MOODLE_BASE_URL = 'https://learn.example.com';
const MOODLE_SSO_TOKEN = 'token';
const MOODLE_MAPPING    = 'email';

Ora creiamo una funzione per gestire il logging durante le chiamate alle API:

function my_api_log( $message, $level = 'INFO' ) {
    
    $log_file = get_template_directory() . '/logs/api.log';


    $date = date('Y-m-d H:i:s');


    $entry = "[{$date}] [{$level}] {$message}\n";


    file_put_contents($log_file, $entry, FILE_APPEND | LOCK_EX);
}

A questo punto possiamo definire la nostra funzione principale:

function mfa_mdl_get_userkey_login_url($user, $wantsurl = '', $ip = '') {
    $endpoint = rtrim(MOODLE_BASE_URL, '/') . '/webservice/rest/server.php';

    
    $payload_user = [];
    if (MOODLE_MAPPING === 'email' && !empty($user['email'])) {
        $payload_user['email'] = $user['email'];
    } elseif (MOODLE_MAPPING === 'username' && !empty($user['username'])) {
        $payload_user['username'] = $user['username'];
    } elseif (MOODLE_MAPPING === 'idnumber' && !empty($user['idnumber'])) {
        $payload_user['idnumber'] = $user['idnumber'];
    } else {
        return '';
    }

    
    foreach (['firstname','lastname','username'] as $k) {
        if (!empty($user[$k])) $payload_user[$k] = $user[$k];
    }

    $body = [
        'wstoken'            => MOODLE_SSO_TOKEN,
        'wsfunction'         => 'auth_userkey_request_login_url',
        'moodlewsrestformat' => 'json',
        'user'               => $payload_user,
    ];

    if (!empty($wantsurl)) $body['wantsurl'] = $wantsurl;
    if (!empty($ip))       $body['ip']       = $ip;

    $resp = wp_remote_post($endpoint, [
        'timeout' => HTTP_TIMEOUT,
        'headers' => ['Content-Type' => 'application/x-www-form-urlencoded'],
        'body'    => $body,
    ]);

    if (is_wp_error($resp)) {
        mfa_log('WP HTTP error: '.$resp->get_error_message(), 'ERROR');
    }

    $code = wp_remote_retrieve_response_code($resp);
    $json = json_decode(wp_remote_retrieve_body($resp), true);

    if ($code >= 400) {
        mfa_log('Moodle HTTP '.$code.': '.wp_remote_retrieve_body($resp), 'ERROR');
        return '';
    }
    if (isset($json['exception'])) {
        mfa_log($json['errorcode'].': '.$json['message'].' | '.($json['debuginfo'] ?? ''), 'ERROR');
        return '';
    }
    if (empty($json['loginurl'])) {
        mfa_log('Nessun loginurl in risposta Moodle', 'ERROR');
        return '';
    }
    return $json['loginurl'];
}

La funzione restituisce l'URL di accesso per il SSO o una stringa vuota in caso di errore. Se nell'array associativo $user viene specificato il solo campo email, l'utente deve essere già presente in Moodle. Viceversa, se vengono specificati anche i campi firstname, lastname e username, ciò non è necessario se abbiamo abilitato il provisioning auto nel plugin.

$ip può essere usato per restringere l'IP di accesso se questa funzionalità è stata abilitata nella configurazione del plugin. $wantsurl è l'URL di destinazione post-login (può essere interno o esterno a Moodle).

Poichè la fase di testing potrebbe generare degli errori dovuti ad un formato non valido, la nostra funzione scrive nel file di log anche la proprietà debuginfo restituita da Moodle quando si attiva la modalità di debug negli strumenti di sviluppo.

Conclusione

Grazie alle funzionalità HTTP di WordPress è possibile effettuare un login SSO in Moodle usando le sue API. Si tratta di una soluzione che permette di accedere a Moodle senza aver creato prima un account.

Torna su