mirror of
https://github.com/moodle/moodle.git
synced 2025-01-29 11:46:19 +01:00
MDL-65959 core_badges: Allow ability to upload badges cross domain.
This commit is contained in:
parent
1c4620bce6
commit
b6435e0934
@ -48,7 +48,8 @@ if (!empty($issuedbadge->recipient->id)) {
|
||||
$badgeid = $issuedbadge->badgeid;
|
||||
$badge = new badge($badgeid);
|
||||
$backpack = $DB->get_record('badge_backpack', array('userid' => $USER->id));
|
||||
$sitebackpack = badges_get_site_backpack($backpack->externalbackpackid);
|
||||
$sitebackpack = badges_get_site_primary_backpack();
|
||||
$userbackpack = badges_get_site_backpack($backpack->externalbackpackid);
|
||||
$assertion = new core_badges_assertion($id, $sitebackpack->apiversion);
|
||||
$api = new \core_badges\backpack_api($sitebackpack);
|
||||
$api->authenticate();
|
||||
@ -61,7 +62,8 @@ if (!empty($issuedbadge->recipient->id)) {
|
||||
throw new moodle_exception('invalidrequest', 'error');
|
||||
}
|
||||
$issuerentityid = $response->id;
|
||||
badges_external_create_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_ISSUER, $issuer['email'], $issuerentityid);
|
||||
badges_external_create_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_ISSUER, $issuer['email'],
|
||||
$issuerentityid, $response->openBadgeId);
|
||||
}
|
||||
// Create badge.
|
||||
$badge = $assertion->get_badge_class(false);
|
||||
@ -72,25 +74,55 @@ if (!empty($issuedbadge->recipient->id)) {
|
||||
throw new moodle_exception('invalidrequest', 'error');
|
||||
}
|
||||
$badgeentityid = $response->id;
|
||||
badges_external_create_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_BADGE, $badgeid, $badgeentityid);
|
||||
badges_external_create_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_BADGE, $badgeid,
|
||||
$badgeentityid, $response->hostedUrl);
|
||||
}
|
||||
|
||||
// Create assertion (Award the badge!).
|
||||
$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
|
||||
);
|
||||
|
||||
if (!($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);
|
||||
badges_external_create_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_ASSERTION, $assertionid,
|
||||
$response->id);
|
||||
}
|
||||
|
||||
// Now award/upload the badge to the user's account.
|
||||
if ($assertionentityid && !badges_external_get_mapping($userbackpack->id, OPEN_BADGES_V2_TYPE_ASSERTION, $assertionid)) {
|
||||
$userapi = new \core_badges\backpack_api($userbackpack, $backpack);
|
||||
$userapi->authenticate();
|
||||
$response = $userapi->import_badge_assertion($assertionentityid);
|
||||
if (!$response) {
|
||||
throw new moodle_exception('invalidrequest', 'error');
|
||||
}
|
||||
$assertionentityid = $response->id;
|
||||
badges_external_create_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_ASSERTION, $assertionid, $assertionentityid);
|
||||
badges_external_create_mapping($userbackpack->id, OPEN_BADGES_V2_TYPE_ASSERTION, $assertionid,
|
||||
$assertionentityid);
|
||||
$response = ['success' => 'addedtobackpack'];
|
||||
} else {
|
||||
$response = ['warning' => 'existsinbackpack'];
|
||||
}
|
||||
|
||||
redirect(new moodle_url('/badges/mybadges.php', $response));
|
||||
} else {
|
||||
redirect(new moodle_url('/badges/mybadges.php'));
|
||||
|
@ -87,7 +87,6 @@ class backpack_api {
|
||||
global $CFG;
|
||||
$admin = get_admin();
|
||||
|
||||
$this->backpackapiurl = $sitebackpack->backpackapiurl;
|
||||
$this->backpackapiurl = $sitebackpack->backpackapiurl;
|
||||
$this->backpackapiversion = $sitebackpack->apiversion;
|
||||
$this->password = $sitebackpack->password;
|
||||
@ -152,6 +151,21 @@ class backpack_api {
|
||||
true, // JSON Encoded.
|
||||
true // Auth required.
|
||||
];
|
||||
$mapping[] = [
|
||||
'importbadge', // Action.
|
||||
// Badgr.io does not return the public information about a badge
|
||||
// if the issuer is associated with another user. We need to pass
|
||||
// the expand parameters which are not in any specification to get
|
||||
// additional information about the assertion in a single request.
|
||||
'[URL]/backpack/import',
|
||||
['url' => '[PARAM]'], // Post params.
|
||||
'', // Request exporter.
|
||||
'core_badges\external\assertion_exporter', // Response exporter.
|
||||
false, // Multiple.
|
||||
'post', // Method.
|
||||
true, // JSON Encoded.
|
||||
true // Auth required.
|
||||
];
|
||||
$mapping[] = [
|
||||
'badges', // Action.
|
||||
'[URL]/backpack/collections/[PARAM1]', // URL
|
||||
@ -408,6 +422,22 @@ class backpack_api {
|
||||
return $this->curl_request('assertions', null, $entityid, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a badge assertion into a backpack. This is used to handle cross domain backpacks.
|
||||
*
|
||||
* @param string $data The structure of the badge class assertion.
|
||||
* @return mixed
|
||||
* @throws coding_exception
|
||||
*/
|
||||
public function import_badge_assertion(string $data) {
|
||||
// V2 Only.
|
||||
if ($this->backpackapiversion == OPEN_BADGES_V1) {
|
||||
throw new coding_exception('Not supported in this backpack API');
|
||||
}
|
||||
|
||||
return $this->curl_request('importbadge', null, null, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select collections from a backpack.
|
||||
*
|
||||
@ -570,7 +600,6 @@ class backpack_api {
|
||||
*
|
||||
* @param integer $userid The user in Moodle
|
||||
* @param integer $backpackid The backpack to disconnect
|
||||
* @param integer $externalbackupid The external backpack to disconnect
|
||||
* @return boolean
|
||||
*/
|
||||
public function disconnect_backpack($userid, $backpackid, $externalbackupid) {
|
||||
|
@ -209,6 +209,8 @@ class backpack_api_mapping {
|
||||
} else if ($value == '[PASSWORD]') {
|
||||
$value = $password;
|
||||
$request[$key] = $value;
|
||||
} else if ($value == '[PARAM]') {
|
||||
$request[$key] = is_array($param) ? $param[0] : $param;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -312,6 +314,7 @@ class backpack_api_mapping {
|
||||
return array(
|
||||
'FRESH_CONNECT' => true,
|
||||
'RETURNTRANSFER' => true,
|
||||
'FOLLOWLOCATION' => true,
|
||||
'FORBID_REUSE' => true,
|
||||
'HEADER' => 0,
|
||||
'CONNECTTIMEOUT' => 3,
|
||||
|
@ -650,10 +650,6 @@ class core_badges_renderer extends plugin_renderer_base {
|
||||
$externalhtml .= html_writer::start_tag('div', array('class' => 'generalbox'));
|
||||
$externalhtml .= $this->output->heading_with_help(get_string('externalbadges', 'badges'), 'externalbadges', 'badges');
|
||||
if (!is_null($backpack)) {
|
||||
if ($backpack->backpackid != $CFG->badges_site_backpack) {
|
||||
$externalhtml .= $this->output->notification(get_string('backpackneedsupdate', 'badges'), 'warning');
|
||||
|
||||
}
|
||||
if ($backpack->totalcollections == 0) {
|
||||
$externalhtml .= get_string('nobackpackcollectionssummary', 'badges', $backpack);
|
||||
} else {
|
||||
|
@ -1,6 +1,22 @@
|
||||
This files describes API changes in /badges/*,
|
||||
information provided here is intended especially for developers.
|
||||
|
||||
=== 3.10 ===
|
||||
* Users can now specify a backpack that differs from the site backpack. In order to do this, connection details need to
|
||||
be set in 'Manage backpacks' with OR without auth details.
|
||||
* Introduced new functions in backpack_api
|
||||
** 'import_badge_assertion' to facilitate cross domain badge imports.
|
||||
** 'update_assertion' updates a previously defined/created assertion.
|
||||
* New badge lib functions introduced
|
||||
** badges_save_external_backpack() - This method handles inserts/updates to the site wide backpacks' configuration details.
|
||||
** badges_save_backpack_credentials() - This method handles inserts/updates any authentication details to connect to the backpacks created. This can either be site OR user backpack authentication details
|
||||
** badges_get_user_backpack() - Gets a specific user's backpack. Defaults to current user's backpack if none provided.
|
||||
** badges_get_site_primary_backpack() - Get the primary backpack set for the site as defined in $CFG->badges_site_backpack
|
||||
* badges_open_badges_backpack_api() - Now accepts a backpackid(badge_external_backpack id) to check whether the version of the provided backpack.
|
||||
This was introduced because now there is a difference between a site and user backpack. If null, defaults to site_backpack.
|
||||
* badges_get_site_backpack() - Accepts an additional $userid param if we want to get a specific user's backpack. Defaults to 0 if we are trying to get the site/admin level backpack
|
||||
* badges_external_get_mapping() - Accepts an additional argument to indicate which value it wants returned. Defaults to 'externalid' which contains the OBv2 badge URL
|
||||
|
||||
=== 3.9 ===
|
||||
* BADGE_BACKPACKAPIURL and BADGE_BACKPACKWEBURL are deprecated and should not be used.
|
||||
* OBv2 has been set to the default value when the obversion is not defined.
|
||||
|
@ -936,6 +936,17 @@ function badges_get_site_backpack($id) {
|
||||
return $DB->get_record('badge_external_backpack', ['id' => $id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the primary backpack for the site
|
||||
*
|
||||
* @return array(stdClass)
|
||||
*/
|
||||
function badges_get_site_primary_backpack() {
|
||||
global $CFG;
|
||||
|
||||
return badges_get_site_backpack($CFG->badges_site_backpack);
|
||||
}
|
||||
|
||||
/**
|
||||
* List the backpacks at site level.
|
||||
*
|
||||
@ -1026,9 +1037,10 @@ function badges_disconnect_user_backpack($userid) {
|
||||
* @param integer $sitebackpackid The site backpack to connect to.
|
||||
* @param string $type The type of this remote object.
|
||||
* @param string $internalid The id for this object on the Moodle site.
|
||||
* @param string $param The param we need to return. Defaults to the externalid.
|
||||
* @return mixed The id or false if it doesn't exist.
|
||||
*/
|
||||
function badges_external_get_mapping($sitebackpackid, $type, $internalid) {
|
||||
function badges_external_get_mapping($sitebackpackid, $type, $internalid, $param = 'externalid') {
|
||||
global $DB;
|
||||
// Return externalid if it exists.
|
||||
$params = [
|
||||
@ -1037,9 +1049,9 @@ function badges_external_get_mapping($sitebackpackid, $type, $internalid) {
|
||||
'internalid' => $internalid
|
||||
];
|
||||
|
||||
$record = $DB->get_record('badge_external_identifier', $params, 'externalid', IGNORE_MISSING);
|
||||
$record = $DB->get_record('badge_external_identifier', $params, $param, IGNORE_MISSING);
|
||||
if ($record) {
|
||||
return $record->externalid;
|
||||
return $record->$param;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -1320,3 +1332,26 @@ function badges_get_oauth2_service_options() {
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a public badgr URL that conforms to OBv2. This is done because badgr responses do not currently conform to
|
||||
* the spec.
|
||||
*
|
||||
* WARNING: This is an extremely hacky way of implementing this and should be removed once the standards are conformed to.
|
||||
*
|
||||
* @param stdClass $backpack The Badgr backpack we are pushing to
|
||||
* @param string $type The type of object we are dealing with either Issuer, Assertion OR Badge.
|
||||
* @param string $externalid The externalid as provided by the backpack
|
||||
* @return string The public URL to access Badgr objects
|
||||
*/
|
||||
function badges_generate_badgr_open_url($backpack, $type, $externalid) {
|
||||
if (badges_open_badges_backpack_api($backpack->id) == OPEN_BADGES_V2) {
|
||||
$entity = strtolower($type);
|
||||
if ($type == OPEN_BADGES_V2_TYPE_BADGE) {
|
||||
$entity = "badge";
|
||||
}
|
||||
$url = new moodle_url($backpack->backpackapiurl);
|
||||
return "{$url->get_scheme()}://{$url->get_host()}/public/{$entity}s/$externalid";
|
||||
|
||||
}
|
||||
}
|
@ -2868,9 +2868,6 @@ function xmldb_main_upgrade($oldversion) {
|
||||
if (!$dbman->field_exists($table, $field)) {
|
||||
$dbman->add_field($table, $field);
|
||||
}
|
||||
$table->deleteKey('backpackapiurlkey');
|
||||
$table->deleteKey('backpackweburlkey');
|
||||
$table->add_key('backpackapiurlkey', XMLDB_KEY_UNIQUE, ['backpackapiurl', 'backpackemail']);
|
||||
|
||||
// Main savepoint reached.
|
||||
upgrade_main_savepoint(true, 2021052500.32);
|
||||
|
Loading…
x
Reference in New Issue
Block a user