Merge branch 'MDL-57429-32' of https://github.com/snake/moodle into MOODLE_32_STABLE
This commit is contained in:
+40
-25
@@ -46,23 +46,6 @@ class edit_backpack_form extends moodleform {
|
||||
$mform->addElement('header', 'backpackheader', get_string('backpackconnection', 'badges'));
|
||||
$mform->addHelpButton('backpackheader', 'backpackconnection', 'badges');
|
||||
$mform->addElement('static', 'url', get_string('url'), BADGE_BACKPACKURL);
|
||||
$status = html_writer::tag('span', get_string('notconnected', 'badges'),
|
||||
array('class' => 'notconnected', 'id' => 'connection-status'));
|
||||
$mform->addElement('static', 'status', get_string('status'), $status);
|
||||
|
||||
$nojs = html_writer::tag('noscript', get_string('error:personaneedsjs', 'badges'),
|
||||
array('class' => 'notconnected'));
|
||||
$personadiv = $OUTPUT->container($nojs, null, 'persona-container');
|
||||
|
||||
$mform->addElement('static', 'persona', '', $personadiv);
|
||||
$mform->addHelpButton('persona', 'personaconnection', 'badges');
|
||||
|
||||
$PAGE->requires->js(new moodle_url('https://login.persona.org/include.js'));
|
||||
$PAGE->requires->js('/badges/backpack.js');
|
||||
$PAGE->requires->js_init_call('badges_init_persona_login_button', null, false);
|
||||
$PAGE->requires->strings_for_js(array('error:backpackloginfailed', 'signinwithyouremail',
|
||||
'error:noassertion', 'error:connectionunknownreason', 'error:badjson', 'connecting',
|
||||
'notconnected'), 'badges');
|
||||
|
||||
$mform->addElement('hidden', 'userid', $USER->id);
|
||||
$mform->setType('userid', PARAM_INT);
|
||||
@@ -70,23 +53,55 @@ class edit_backpack_form extends moodleform {
|
||||
$mform->addElement('hidden', 'backpackurl', BADGE_BACKPACKURL);
|
||||
$mform->setType('backpackurl', PARAM_URL);
|
||||
|
||||
if (isset($this->_customdata['email'])) {
|
||||
// Email will be passed in when we're in the process of verifying the user's email address,
|
||||
// so set the connection status, lock the email field, and provide options to resend the verification
|
||||
// email or cancel the verification process entirely and start over.
|
||||
$status = html_writer::tag('span', get_string('backpackemailverificationpending', 'badges'),
|
||||
array('class' => 'notconnected', 'id' => 'connection-status'));
|
||||
$mform->addElement('static', 'status', get_string('status'), $status);
|
||||
$mform->addElement('hidden', 'email', $this->_customdata['email']);
|
||||
$mform->setType('email', PARAM_RAW_TRIMMED);
|
||||
$mform->hardFreeze(['email']);
|
||||
$status = html_writer::tag('span', $this->_customdata['email'], []);
|
||||
$mform->addElement('static', 'emailverify', get_string('email'), $status);
|
||||
$buttonarray = [];
|
||||
$buttonarray[] = &$mform->createElement('submit', 'submitbutton',
|
||||
get_string('backpackconnectionresendemail', 'badges'));
|
||||
$buttonarray[] = &$mform->createElement('submit', 'revertbutton',
|
||||
get_string('backpackconnectioncancelattempt', 'badges'));
|
||||
$mform->addGroup($buttonarray, 'buttonar', '', [''], false);
|
||||
$mform->closeHeaderBefore('buttonar');
|
||||
} else {
|
||||
// Email isn't present, so provide an input element to get it and a button to start the verification process.
|
||||
$status = html_writer::tag('span', get_string('notconnected', 'badges'),
|
||||
array('class' => 'notconnected', 'id' => 'connection-status'));
|
||||
$mform->addElement('static', 'status', get_string('status'), $status);
|
||||
$mform->addElement('text', 'email', get_string('email'), 'maxlength="100" size="30"');
|
||||
$mform->addHelpButton('email', 'backpackemail', 'badges');
|
||||
$mform->addRule('email', get_string('required'), 'required', null, 'client');
|
||||
$mform->setType('email', PARAM_RAW_TRIMMED);
|
||||
$this->add_action_buttons(false, get_string('backpackconnectionconnect', 'badges'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates form data
|
||||
*/
|
||||
public function validation($data, $files) {
|
||||
global $DB;
|
||||
$errors = parent::validation($data, $files);
|
||||
|
||||
$check = new stdClass();
|
||||
$check->backpackurl = $data['backpackurl'];
|
||||
$check->email = $data['email'];
|
||||
// We don't need to verify the email address if we're clearing a pending email verification attempt.
|
||||
if (!isset($data['revertbutton'])) {
|
||||
$check = new stdClass();
|
||||
$check->backpackurl = $data['backpackurl'];
|
||||
$check->email = $data['email'];
|
||||
|
||||
$bp = new OpenBadgesBackpackHandler($check);
|
||||
$request = $bp->curl_request('user');
|
||||
if (isset($request->status) && $request->status == 'missing') {
|
||||
$errors['email'] = get_string('error:nosuchuser', 'badges');
|
||||
$bp = new OpenBadgesBackpackHandler($check);
|
||||
$request = $bp->curl_request('user');
|
||||
if (isset($request->status) && $request->status == 'missing') {
|
||||
$errors['email'] = get_string('error:nosuchuser', 'badges');
|
||||
}
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Endpoint for the verification email link.
|
||||
*
|
||||
* @package core
|
||||
* @subpackage badges
|
||||
* @copyright 2016 Jake Dallimore <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
require_once(__DIR__ . '/../config.php');
|
||||
require_once($CFG->libdir . '/badgeslib.php');
|
||||
require_once(__DIR__ . '/lib/backpacklib.php');
|
||||
|
||||
$data = optional_param('data', '', PARAM_RAW);
|
||||
require_login();
|
||||
$PAGE->set_url('/badges/openbackpackemailverify.php');
|
||||
$PAGE->set_context(context_user::instance($USER->id));
|
||||
$redirect = '/badges/mybackpack.php';
|
||||
|
||||
// Confirm the secret and create the backpack connection.
|
||||
$storedsecret = get_user_preferences('badges_email_verify_secret');
|
||||
if (!is_null($storedsecret)) {
|
||||
if ($data === $storedsecret) {
|
||||
$storedemail = get_user_preferences('badges_email_verify_address');
|
||||
|
||||
$data = new stdClass();
|
||||
$data->backpackurl = BADGE_BACKPACKURL;
|
||||
$data->email = $storedemail;
|
||||
$bp = new OpenBadgesBackpackHandler($data);
|
||||
|
||||
$obj = new stdClass();
|
||||
$obj->userid = $USER->id;
|
||||
$obj->email = $data->email;
|
||||
$obj->backpackurl = $data->backpackurl;
|
||||
$obj->backpackuid = $bp->curl_request('user')->userId;
|
||||
$obj->autosync = 0;
|
||||
$obj->password = '';
|
||||
$DB->insert_record('badge_backpack', $obj);
|
||||
|
||||
// Remove the verification vars and redirect to the mypackpack page.
|
||||
unset_user_preference('badges_email_verify_secret');
|
||||
unset_user_preference('badges_email_verify_address');
|
||||
redirect(new moodle_url($redirect), get_string('backpackemailverifysuccess', 'badges'),
|
||||
null, \core\output\notification::NOTIFY_SUCCESS);
|
||||
} else {
|
||||
// Stored secret doesn't match the supplied secret. Take user back to the mybackpack page and present a warning message.
|
||||
redirect(new moodle_url($redirect), get_string('backpackemailverifytokenmismatch', 'badges'),
|
||||
null, \core\output\notification::NOTIFY_ERROR);
|
||||
}
|
||||
} else {
|
||||
// Stored secret is null. Either the email address has already been verified, or there is no record of a verification attempt
|
||||
// for the current user. Either way, just redirect to the mybackpack page.
|
||||
redirect(new moodle_url($redirect));
|
||||
}
|
||||
@@ -117,3 +117,45 @@ class OpenBadgesBackpackHandler {
|
||||
return $this->backpack;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and send a verification email to the email address supplied.
|
||||
*
|
||||
* Since we're not sending this email to a user, email_to_user can't be used
|
||||
* but this function borrows largely the code from that process.
|
||||
*
|
||||
* @param string $email the email address to send the verification email to.
|
||||
* @return true if the email was sent successfully, false otherwise.
|
||||
*/
|
||||
function send_verification_email($email) {
|
||||
global $DB, $USER;
|
||||
|
||||
// Store a user secret (badges_email_verify_secret) and the address (badges_email_verify_address) as users prefs.
|
||||
// The address will be used by edit_backpack_form for display during verification and to facilitate the resending
|
||||
// of verification emails to said address.
|
||||
$secret = random_string(15);
|
||||
set_user_preference('badges_email_verify_secret', $secret);
|
||||
set_user_preference('badges_email_verify_address', $email);
|
||||
|
||||
// To, from.
|
||||
$tempuser = $DB->get_record('user', array('id' => $USER->id), '*', MUST_EXIST);
|
||||
$tempuser->email = $email;
|
||||
$noreplyuser = core_user::get_noreply_user();
|
||||
|
||||
// Generate the verification email body.
|
||||
$verificationurl = '/badges/backpackemailverify.php';
|
||||
$verificationurl = new moodle_url($verificationurl);
|
||||
$verificationpath = $verificationurl->out(false);
|
||||
|
||||
$site = get_site();
|
||||
$args = new stdClass();
|
||||
$args->link = $verificationpath . '?data='. $secret;
|
||||
$args->sitename = $site->fullname;
|
||||
$args->admin = generate_email_signoff();
|
||||
|
||||
$messagesubject = get_string('backpackemailverifyemailsubject', 'badges', $site->fullname);
|
||||
$messagetext = get_string('backpackemailverifyemailbody', 'badges', $args);
|
||||
$messagehtml = text_to_html($messagetext, false, false, true);
|
||||
|
||||
return email_to_user($tempuser, $noreplyuser, $messagesubject, $messagetext, $messagehtml);
|
||||
}
|
||||
|
||||
+29
-13
@@ -110,23 +110,39 @@ if ($backpack) {
|
||||
}
|
||||
} else {
|
||||
// If backpack is not connected, need to connect first.
|
||||
$form = new edit_backpack_form();
|
||||
// To create a new connection to the backpack, first we need to verify the user's email address:
|
||||
// 1. User enters email and clicks 'Connect to backpack'.
|
||||
// 2. After cross-checking the email address against the backpack provider, an email is sent to the specified address,
|
||||
// and the email and secret are stored in user preferences. These will be cleared upon successful verification.
|
||||
// 3. User clicks verification link in the email to confirm the backpack connection.
|
||||
// 4. User redirected to the mybackpack page.
|
||||
// While the verification process is pending, the edit_backpack_form form will present the user with options to resend the
|
||||
// verification email, and to cancel the current verification attempt and start over.
|
||||
|
||||
// To pass through the current state of the verification attempt to the form.
|
||||
$params['email'] = get_user_preferences('badges_email_verify_address');
|
||||
|
||||
$form = new edit_backpack_form(new moodle_url('/badges/mybackpack.php'), $params);
|
||||
if ($form->is_cancelled()) {
|
||||
redirect(new moodle_url('/badges/mybadges.php'));
|
||||
} else if ($data = $form->get_data()) {
|
||||
$bp = new OpenBadgesBackpackHandler($data);
|
||||
|
||||
$obj = new stdClass();
|
||||
$obj->userid = $data->userid;
|
||||
$obj->email = $data->email;
|
||||
$obj->backpackurl = $data->backpackurl;
|
||||
$obj->backpackuid = $bp->curl_request('user')->userId;
|
||||
$obj->autosync = 0;
|
||||
$obj->password = '';
|
||||
$DB->insert_record('badge_backpack', $obj);
|
||||
|
||||
redirect(new moodle_url('/badges/mybackpack.php'));
|
||||
// The form may have been submitted under one of the following circumstances:
|
||||
// 1. After clicking 'Connect to backpack'. We'll have $data->email.
|
||||
// 2. After clicking 'Resend verification email'. We'll have $data->email.
|
||||
// 3. After clicking 'Connect using a different email' to cancel the verification process. We'll have $data->revertbutton.
|
||||
if (isset($data->revertbutton)) {
|
||||
unset_user_preference('badges_email_verify_secret');
|
||||
unset_user_preference('badges_email_verify_address');
|
||||
redirect(new moodle_url('/badges/mybackpack.php'));
|
||||
} else if (isset($data->email)) {
|
||||
if (send_verification_email($data->email)) {
|
||||
redirect(new moodle_url('/badges/mybackpack.php'),
|
||||
get_string('backpackemailverifypending', 'badges', $data->email),
|
||||
null, \core\output\notification::NOTIFY_INFO);
|
||||
} else {
|
||||
print_error ('backpackcannotsendverification', 'badges');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ You should fix this issue on any production site where you are planning to issue
|
||||
|
||||
The only URL required for verification is [your-site-url]/badges/assertion.php so if you are able to modify your firewall to allow external access to that file, badge verification will still work.';
|
||||
$string['backpackbadges'] = 'You have {$a->totalbadges} badge(s) displayed from {$a->totalcollections} collection(s). <a href="mybackpack.php">Change backpack settings</a>.';
|
||||
$string['backpackcannotsendverification'] = 'Cannot send verification email';
|
||||
$string['backpackconnection'] = 'Backpack connection';
|
||||
$string['backpackconnection_help'] = 'This page allows you to set up connection to an external backpack provider. Connecting to a backpack lets you display external badges within this site and push badges earned here to your backpack.
|
||||
|
||||
@@ -90,6 +91,26 @@ $string['personaconnection'] = 'Sign in with your email';
|
||||
$string['personaconnection_help'] = 'Persona is a system for identifying yourself across the web, using an email address that you own. The Open Badges backpack uses Persona as a login system, so to be able to connect to a backpack you will need a Persona account.
|
||||
|
||||
For more information about Persona visit <a href="https://login.persona.org/about">https://login.persona.org/about</a>.';
|
||||
$string['backpackconnectioncancelattempt'] = 'Connect using a different email address';
|
||||
$string['backpackconnectionconnect'] = 'Connect to Backpack';
|
||||
$string['backpackconnectionresendemail'] = 'Resend verification email';
|
||||
$string['backpackemailverificationpending'] = 'Verification pending';
|
||||
$string['backpackemailverifyemailbody'] = 'Hi,
|
||||
|
||||
A new connection to your OpenBadges backpack has been requested from \'{$a->sitename}\' using your email address.
|
||||
|
||||
To confirm and activate the connection to your backpack, please click the link below.
|
||||
|
||||
{$a->link}
|
||||
|
||||
In most mail programs, this should appear as a blue link which you can just click on. If that doesn\'t work, then cut and paste the address into the address line at the top of your web browser.
|
||||
|
||||
If you need help, please contact the site administrator,
|
||||
{$a->admin}';
|
||||
$string['backpackemailverifyemailsubject'] = '{$a}: OpenBadges Backpack email verification';
|
||||
$string['backpackemailverifypending'] = 'A verification email has been sent to <strong>{$a}</strong>. Click on the verification link in the email to activate your Backpack connection.';
|
||||
$string['backpackemailverifysuccess'] = 'Thanks for verifying your email address. You are now connected to your Backpack.';
|
||||
$string['backpackemailverifytokenmismatch'] = 'The token in the link you clicked does not match the stored token. Make sure you clicked the link in most recent email you received.';
|
||||
$string['backpackimport'] = 'Badge import settings';
|
||||
$string['backpackimport_help'] = 'After the backpack connection is successfully established, badges from your backpack can be displayed on your badges page and your profile page.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user