. /** * AJAX script for validating backpack connection. * * @package core * @subpackage badges * @copyright 2012 onwards Totara Learning Solutions Ltd {@link http://www.totaralms.com/} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @author Simon Coggins */ define('AJAX_SCRIPT', true); require_once(dirname(dirname(__FILE__)) . '/config.php'); require_once($CFG->dirroot . '/badges/lib/backpacklib.php'); require_once($CFG->libdir . '/filelib.php'); require_once($CFG->libdir . '/badgeslib.php'); require_sesskey(); require_login(); $PAGE->set_url('/badges/backpackconnect.php'); $PAGE->set_context(context_system::instance()); echo $OUTPUT->header(); // Use PHP input filtering as there is no PARAM type for // the type of cleaning that is required (ASCII chars 32-127 only). $assertion = filter_input( INPUT_POST, 'assertion', FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW|FILTER_FLAG_STRIP_HIGH ); // Audience is the site url scheme + host + port only. $wwwparts = parse_url($CFG->wwwroot); $audience = $wwwparts['scheme'] . '://' . $wwwparts['host']; $audience .= isset($wwwparts['port']) ? $wwwparts['port'] : ''; $params = 'assertion=' . urlencode($assertion) . '&audience=' . urlencode($audience); $curl = new curl(); $url = 'https://verifier.login.persona.org/verify'; $options = array( 'FRESH_CONNECT' => true, 'RETURNTRANSFER' => true, 'FORBID_REUSE' => true, 'SSL_VERIFYPEER' => true, 'SSL_VERIFYHOST' => 2, 'HEADER' => 0, 'HTTPHEADER' => array('Content-type: application/x-www-form-urlencoded'), 'CONNECTTIMEOUT' => 0, 'TIMEOUT' => 10, // Fail if data not returned within 10 seconds. ); $result = $curl->post($url, $params, $options); // Handle time-out and failed request. if ($curl->errno != 0) { if ($curl->errno == CURLE_OPERATION_TIMEOUTED) { $reason = get_string('error:requesttimeout', 'badges'); } else { $reason = get_string('error:requesterror', 'badges', $curl->errno); } badges_send_response('failure', $reason); } $data = json_decode($result); if (!isset($data->status) || $data->status != 'okay') { $reason = isset($data->reason) ? $data->reason : get_string('error:connectionunknownreason', 'badges'); badges_send_response('failure', $reason); } // Make sure email matches a backpack. $check = new stdClass(); $check->backpackurl = 'http://' . BADGE_BACKPACKURL; $check->email = $data->email; $bp = new OpenBadgesBackpackHandler($check); $request = $bp->curl_request('user'); if (isset($request->status) && $request->status == 'missing') { $reason = get_string('error:backpackemailnotfound', 'badges', $data->email); badges_send_response('failure', $reason); } else if (empty($request->userId)) { $reason = get_string('error:backpackdatainvalid', 'badges'); badges_send_response('failure', $reason); } else { $backpackuid = $request->userId; } // Insert record. $obj = new stdClass(); $obj->userid = $USER->id; $obj->email = $data->email; $obj->backpackurl = 'http://' . BADGE_BACKPACKURL; $obj->backpackuid = $backpackuid; $obj->autosync = 0; $obj->password = ''; $DB->insert_record('badge_backpack', $obj); // Return success indicator and email address. badges_send_response('success', $data->email); /** * Return a JSON response containing the response provided. * * @param string $status Status of the response, typically 'success' or 'failure'. * @param string $responsetext On success, the email address of the user, * otherwise a reason for the failure. * @return void Outputs the JSON and terminates the script. */ function badges_send_response($status, $responsetext) { $out = new stdClass(); $out->status = $status; if ($status == 'success') { $out->email = $responsetext; } else { $out->reason = $responsetext; send_header_404(); } echo json_encode($out); exit; }