Skip to content

Commit

Permalink
MDL-65959 badges: Allow cross domain/protocol functionality - obv2
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter Dias committed Oct 26, 2020
1 parent d3af959 commit ef447fc
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 93 deletions.
153 changes: 84 additions & 69 deletions badges/backpack-add.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@
require_once(__DIR__ . '/../config.php');
require_once($CFG->libdir . '/badgeslib.php');

if (badges_open_badges_backpack_api() != OPEN_BADGES_V2) {
require_login();

$userbackpack = badges_get_user_backpack();
if (badges_open_badges_backpack_api($userbackpack->id) != OPEN_BADGES_V2) {
throw new coding_exception('No backpacks support Open Badges V2.');
}

require_login();

$id = required_param('hash', PARAM_ALPHANUM);

$PAGE->set_url('/badges/backpack-add.php', array('hash' => $id));
Expand All @@ -44,82 +45,97 @@
// * Create badge
// * Create assertion (Award the badge!)

// With the introduction OBv2.1 and MDL-65959 to allow cross region Badgr imports the above (old) procedure will
// only be completely performed if both the site and user backpacks conform to the same apiversion.
// Else we will attempt at pushing the assertion to the user's backpack. In this case, the id set against the assertion
// has to be a publicly accessible resource.

// Get the backpack.
$badgeid = $issuedbadge->badgeid;
$badge = new badge($badgeid);
$backpack = $DB->get_record('badge_backpack', array('userid' => $USER->id));
$sitebackpack = badges_get_site_primary_backpack();
$userbackpack = badges_get_site_backpack($backpack->externalbackpackid, $USER->id);
$assertion = new core_badges_assertion($id, $sitebackpack->apiversion);
$api = new \core_badges\backpack_api($sitebackpack);
$api->authenticate();

// Create issuer.
$issuer = $assertion->get_issuer();
if (!($issuerentityid = badges_external_get_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_ISSUER, $issuer['email']))) {
$response = $api->put_issuer($issuer);
if (!$response) {
throw new moodle_exception('invalidrequest', 'error');
}
$issuerentityid = $response->id;
badges_external_create_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_ISSUER, $issuer['email'],
$issuerentityid, $response->openBadgeId);
}
// Create badge.
$badge = $assertion->get_badge_class(false);
$badgeid = $assertion->get_badge_id();
if (!($badgeentityid = badges_external_get_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_BADGE, $badgeid))) {
$response = $api->put_badgeclass($issuerentityid, $badge);
if (!$response) {
throw new moodle_exception('invalidrequest', 'error');
}
$badgeentityid = $response->id;
badges_external_create_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_BADGE, $badgeid,
$badgeentityid, $response->hostedUrl);
}

// Create assertion (Award the badge!).
$assertion = new core_badges_assertion($id, OPEN_BADGES_V2);
$assertiondata = $assertion->get_badge_assertion(false, false);

$assertionid = $assertion->get_assertion_hash();
$assertionentityid = badges_external_get_mapping(
$sitebackpack->id,
OPEN_BADGES_V2_TYPE_ASSERTION,
$assertionid
);
$assertionentityid = $assertiondata['id'];
$badgeadded = false;
if (badges_open_badges_backpack_api() == OPEN_BADGES_V2) {
$sitebackpack = badges_get_site_primary_backpack();
$api = new \core_badges\backpack_api($sitebackpack);
$response = $api->authenticate();

if ($assertionentityid && strpos($sitebackpack->backpackapiurl, 'badgr')) {
$assertionentityid = badges_generate_badgr_open_url(
$sitebackpack,
OPEN_BADGES_V2_TYPE_ASSERTION,
$assertionentityid
);
}
// A numeric response indicates a valid successful authentication. Else an error object will be returned.
if (is_numeric($response)) {
// Create issuer.
$issuer = $assertion->get_issuer();
if (!($issuerentityid = badges_external_get_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_ISSUER, $issuer['email']))) {
$response = $api->put_issuer($issuer);
if (!$response) {
throw new moodle_exception('invalidrequest', 'error');
}
$issuerentityid = $response->id;
badges_external_create_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_ISSUER, $issuer['email'],
$issuerentityid);
}
// Create badge.
$badge = $assertion->get_badge_class(false);
$badgeid = $assertion->get_badge_id();
if (!($badgeentityid = badges_external_get_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_BADGE, $badgeid))) {
$response = $api->put_badgeclass($issuerentityid, $badge);
if (!$response) {
throw new moodle_exception('invalidrequest', 'error');
}
$badgeentityid = $response->id;
badges_external_create_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_BADGE, $badgeid,
$badgeentityid);
}

// Create an assertion for the recipient in the issuer's account.
if (!$assertionentityid) {
$response = $api->put_badgeclass_assertion($badgeentityid, $assertiondata);
if (!$response) {
throw new moodle_exception('invalidrequest', 'error');
}
$assertionentityid = badges_generate_badgr_open_url($sitebackpack, OPEN_BADGES_V2_TYPE_ASSERTION, $response->id);
badges_external_create_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_ASSERTION, $assertionid,
$response->id);
} else {
// An assertion already exists. Make sure it's up to date.
$internalid = badges_external_get_mapping(
$sitebackpack->id,
OPEN_BADGES_V2_TYPE_ASSERTION,
$assertionid,
'externalid'
);
$response = $api->update_assertion($internalid, $assertiondata);
if (!$response) {
throw new moodle_exception('invalidrequest', 'error');
// Create assertion (Award the badge!).
$assertionentityid = badges_external_get_mapping(
$sitebackpack->id,
OPEN_BADGES_V2_TYPE_ASSERTION,
$assertionid
);

if ($assertionentityid && strpos($sitebackpack->backpackapiurl, 'badgr')) {
$assertionentityid = badges_generate_badgr_open_url(
$sitebackpack,
OPEN_BADGES_V2_TYPE_ASSERTION,
$assertionentityid
);
}

// Create an assertion for the recipient in the issuer's account.
if (!$assertionentityid) {
$response = $api->put_badgeclass_assertion($badgeentityid, $assertiondata);
if (!$response) {
throw new moodle_exception('invalidrequest', 'error');
}
$assertionentityid = badges_generate_badgr_open_url($sitebackpack, OPEN_BADGES_V2_TYPE_ASSERTION, $response->id);
$badgeadded = true;
badges_external_create_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_ASSERTION, $assertionid,
$response->id);
} else {
// An assertion already exists. Make sure it's up to date.
$internalid = badges_external_get_mapping(
$sitebackpack->id,
OPEN_BADGES_V2_TYPE_ASSERTION,
$assertionid,
'externalid'
);
$response = $api->update_assertion($internalid, $assertiondata);
if (!$response) {
throw new moodle_exception('invalidrequest', 'error');
}
}
}
}

// Now award/upload the badge to the user's account.
// - If a user and site backpack have the same provider we can skip this as Badgr automatically maps recipients
// based on email address.
// - This is only needed when the backpacks are from different regions.
if ($assertionentityid && !badges_external_get_mapping($userbackpack->id, OPEN_BADGES_V2_TYPE_ASSERTION, $assertionid)) {
$userapi = new \core_badges\backpack_api($userbackpack, $backpack);
$userapi->authenticate();
Expand All @@ -128,13 +144,12 @@
throw new moodle_exception('invalidrequest', 'error');
}
$assertionentityid = $response->id;
$badgeadded = true;
badges_external_create_mapping($userbackpack->id, OPEN_BADGES_V2_TYPE_ASSERTION, $assertionid,
$assertionentityid);
$response = ['success' => 'addedtobackpack'];
} else {
$response = ['warning' => 'existsinbackpack'];
}

$response = $badgeadded ? ['success' => 'addedtobackpack'] : ['warning' => 'existsinbackpack'];
redirect(new moodle_url('/badges/mybadges.php', $response));
} else {
redirect(new moodle_url('/badges/mybadges.php'));
Expand Down
50 changes: 26 additions & 24 deletions badges/mybackpack.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@

if ($disconnect && $backpack) {
require_sesskey();
$sitebackpack = badges_get_site_backpack($backpack->externalbackpackid);
$sitebackpack = badges_get_user_backpack();
if ($sitebackpack->apiversion == OPEN_BADGES_V2P1) {
$bp = new \core_badges\backpack_api2p1($sitebackpack);
$bp->disconnect_backpack($backpack);
Expand All @@ -71,7 +71,7 @@
$warning = '';
if ($backpack) {

$sitebackpack = badges_get_site_backpack($backpack->externalbackpackid);
$sitebackpack = badges_get_user_backpack();

// If backpack is connected, need to select collections.
$bp = new \core_badges\backpack_api($sitebackpack, $backpack);
Expand Down Expand Up @@ -123,28 +123,30 @@
$data = $form->get_submitted_data();
if ($form->is_cancelled()) {
redirect(new moodle_url('/badges/mybadges.php'));
} else if (badges_open_badges_backpack_api($data->externalbackpackid) == OPEN_BADGES_V2P1) {
// If backpack is version 2.1 to redirect on the backpack site to login.
// User input username/email/password on the backpack site
// After confirm the scopes.
redirect(new moodle_url('/badges/backpack-connect.php', ['backpackid' => $data->externalbackpackid]));
} else if ($data = $form->get_data()) {
// 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)) {
badges_disconnect_user_backpack($USER->id);
redirect(new moodle_url('/badges/mybackpack.php'));
} else if (isset($data->backpackemail)) {
if (badges_send_verification_email($data->backpackemail, $data->externalbackpackid, $data->password)) {
$a = get_user_preferences('badges_email_verify_backpackid');
redirect(new moodle_url('/badges/mybackpack.php'),
get_string('backpackemailverifypending', 'badges', $data->backpackemail),
null, \core\output\notification::NOTIFY_INFO);
} else {
print_error ('backpackcannotsendverification', 'badges');
} else if ($form->is_submitted()) {
if (badges_open_badges_backpack_api($data->externalbackpackid) == OPEN_BADGES_V2P1) {
// If backpack is version 2.1 to redirect on the backpack site to login.
// User input username/email/password on the backpack site
// After confirm the scopes.
redirect(new moodle_url('/badges/backpack-connect.php', ['backpackid' => $data->externalbackpackid]));
} else if ($data = $form->get_data()) {
// 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)) {
badges_disconnect_user_backpack($USER->id);
redirect(new moodle_url('/badges/mybackpack.php'));
} else if (isset($data->backpackemail)) {
if (badges_send_verification_email($data->backpackemail, $data->externalbackpackid, $data->password)) {
$a = get_user_preferences('badges_email_verify_backpackid');
redirect(new moodle_url('/badges/mybackpack.php'),
get_string('backpackemailverifypending', 'badges', $data->backpackemail),
null, \core\output\notification::NOTIFY_INFO);
} else {
print_error ('backpackcannotsendverification', 'badges');
}
}
}
}
Expand Down

0 comments on commit ef447fc

Please sign in to comment.