Skip to content

Commit

Permalink
MDL-74221 enrol_lti: db changes supporting draft registrations
Browse files Browse the repository at this point in the history
Summary:
- Allows nulls for a number of fields meaning largely empty drafts can
be stored.
- Adds 'uniqueid', an id unique to each issuer which is intended
to be used as a parameter in both the initiate login and dynamic
registration urls provided to platforms, as a means to identify specific
registrations for the issuer, in the absense of client_id (optional in
the 1.3 spec).
- Add 'status', used to denote draft or active registrations.
  • Loading branch information
snake committed Mar 24, 2022
1 parent 34ce146 commit 86f08a3
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 18 deletions.
28 changes: 11 additions & 17 deletions enrol/lti/db/install.xml
Expand Up @@ -194,20 +194,25 @@
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="Common name to identify this platform to users"/>
<FIELD NAME="platformid" TYPE="text" NOTNULL="true" SEQUENCE="false" COMMENT="The issuer URL"/>
<FIELD NAME="clientid" TYPE="char" LENGTH="1333" NOTNULL="true" SEQUENCE="false" COMMENT="The clientid string, generated by the platform when setting up the tool."/>
<FIELD NAME="platformclienthash" TYPE="char" LENGTH="64" NOTNULL="true" SEQUENCE="false" COMMENT="SHA256 hash of the platformid (issuer) and clientid, application generated"/>
<FIELD NAME="authenticationrequesturl" TYPE="text" NOTNULL="true" SEQUENCE="false" COMMENT="The authorisation endpoint of the platform"/>
<FIELD NAME="jwksurl" TYPE="text" NOTNULL="true" SEQUENCE="false" COMMENT="The JSON Web Key Set URL for the platform"/>
<FIELD NAME="accesstokenurl" TYPE="text" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="platformid" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="The issuer URL"/>
<FIELD NAME="clientid" TYPE="char" LENGTH="1333" NOTNULL="false" SEQUENCE="false" COMMENT="The clientid string, generated by the platform when setting up the tool."/>
<FIELD NAME="uniqueid" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="A unique local id, which can be used in the initiate login URI to provide {iss, clientid} uniqueness in the absence of the optional client_id claim."/>
<FIELD NAME="platformclienthash" TYPE="char" LENGTH="64" NOTNULL="false" SEQUENCE="false" COMMENT="SHA256 hash of the platformid (issuer) and clientid"/>
<FIELD NAME="platformuniqueidhash" TYPE="char" LENGTH="64" NOTNULL="false" SEQUENCE="false" COMMENT="SHA256 hash of the platformid (issuer) and uniqueid"/>
<FIELD NAME="authenticationrequesturl" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="The authorisation endpoint of the platform"/>
<FIELD NAME="jwksurl" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="The JSON Web Key Set URL for the platform"/>
<FIELD NAME="accesstokenurl" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="status" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Status of the registration, used to denote draft (incomplete) or active (complete)"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="uniqueid" TYPE="unique" FIELDS="uniqueid"/>
</KEYS>
<INDEXES>
<INDEX NAME="platformclienthash" UNIQUE="true" FIELDS="platformclienthash"/>
<INDEX NAME="platformuniqueidhash" UNIQUE="true" FIELDS="platformuniqueidhash"/>
</INDEXES>
</TABLE>
<TABLE NAME="enrol_lti_deployment" COMMENT="Each row represents a deployment of a tool within a platform.">
Expand Down Expand Up @@ -286,16 +291,5 @@
<INDEX NAME="ltiuserid-resourcelinkid" UNIQUE="true" FIELDS="ltiuserid, resourcelinkid"/>
</INDEXES>
</TABLE>
<TABLE NAME="enrol_lti_reg_token" COMMENT="Holds the value and lifespan of the token used to secure the dynamic registration initiation endpoint.">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="token" TYPE="char" LENGTH="60" NOTNULL="true" SEQUENCE="false" COMMENT="The value of the token."/>
<FIELD NAME="expirytime" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The time after which this token is deemed invalid and another must be generated."/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
</TABLES>
</XMLDB>
145 changes: 145 additions & 0 deletions enrol/lti/db/upgrade.php
Expand Up @@ -318,5 +318,150 @@ function xmldb_enrol_lti_upgrade($oldversion) {
upgrade_plugin_savepoint(true, 2021052514, 'enrol', 'lti');
}

if ($oldversion < 2022031400) {
// Changing the default of field platformid on table enrol_lti_app_registration to null.
$table = new xmldb_table('enrol_lti_app_registration');
$field = new xmldb_field('platformid', XMLDB_TYPE_TEXT, null, null, null, null, null, 'name');

// Launch change of nullability for field platformid.
$dbman->change_field_notnull($table, $field);

// Changing the default of field clientid on table enrol_lti_app_registration to null.
$field = new xmldb_field('clientid', XMLDB_TYPE_CHAR, '1333', null, null, null, null, 'platformid');

// Launch change of nullability for field clientid.
$dbman->change_field_notnull($table, $field);

// Drop the platformclienthash index, so the field can be modified.
$index = new xmldb_index('platformclienthash', XMLDB_INDEX_UNIQUE, ['platformclienthash']);

// Conditionally launch drop index platformclienthash.
if ($dbman->index_exists($table, $index)) {
$dbman->drop_index($table, $index);
}

// Changing the default of field platformclienthash on table enrol_lti_app_registration to null.
$field = new xmldb_field('platformclienthash', XMLDB_TYPE_CHAR, '64', null, null, null, null, 'clientid');

// Launch change of nullability for field platformclienthash.
$dbman->change_field_notnull($table, $field);

// Recreate the platformclienthash index.
if (!$dbman->index_exists($table, $index)) {
$dbman->add_index($table, $index);
}

// Changing the default of field authenticationrequesturl on table enrol_lti_app_registration to null.
$field = new xmldb_field('authenticationrequesturl', XMLDB_TYPE_TEXT, null, null, null, null, null, 'platformclienthash');

// Launch change of nullability for field authenticationrequesturl.
$dbman->change_field_notnull($table, $field);

// Changing the default of field jwksurl on table enrol_lti_app_registration to null.
$field = new xmldb_field('jwksurl', XMLDB_TYPE_TEXT, null, null, null, null, null, 'authenticationrequesturl');

// Launch change of nullability for field jwksurl.
$dbman->change_field_notnull($table, $field);

// Changing the default of field accesstokenurl on table enrol_lti_app_registration to null.
$field = new xmldb_field('accesstokenurl', XMLDB_TYPE_TEXT, null, null, null, null, null, 'jwksurl');

// Launch change of nullability for field accesstokenurl.
$dbman->change_field_notnull($table, $field);

// Lti savepoint reached.
upgrade_plugin_savepoint(true, 2022031400, 'enrol', 'lti');
}

if ($oldversion < 2022031401) {
// Define field uniqueid to be added to enrol_lti_app_registration (defined as null so it can be set for existing rows).
$table = new xmldb_table('enrol_lti_app_registration');
$field = new xmldb_field('uniqueid', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'accesstokenurl');

// Conditionally launch add field uniqueid.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);

// Set existing values to use a suitable unique id.
$recordset = $DB->get_recordset('enrol_lti_app_registration');
foreach ($recordset as $record) {
// Create a unique id for the registration. This will be used by:
// a) The initiate_login endpoint (enrol/lti/login.php), as a stand in for client_id, when that's not provided.
// b) The dynamic registration endpoint, where it'll be used to identify the incomplete registration to update
// with the platform details.
do {
$bytes = random_bytes(30);
$record->uniqueid = bin2hex($bytes);
} while ($DB->record_exists('enrol_lti_app_registration', ['uniqueid' => $record->uniqueid]));

$DB->update_record('enrol_lti_app_registration', $record);
}
$recordset->close();

// Now make the field notnull.
$field = new xmldb_field('uniqueid', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'accesstokenurl');
$dbman->change_field_notnull($table, $field);
}

// Launch add unique key uniqueid.
$key = new xmldb_key('uniqueid', XMLDB_KEY_UNIQUE, ['uniqueid']);
$dbman->add_key($table, $key);

// Define field status to be added to enrol_lti_app_registration (defined as null to allow data migration).
$field = new xmldb_field('status', XMLDB_TYPE_INTEGER, '1', null, null, null, null, 'uniqueid');

// Conditionally launch add field status.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);

$recordset = $DB->get_recordset('enrol_lti_app_registration');
foreach ($recordset as $record) {
$record->status = 1;
$DB->update_record('enrol_lti_app_registration', $record);
}
$recordset->close();

// Now make the field notnull.
$field = new xmldb_field('status', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null, 'uniqueid');
$dbman->change_field_notnull($table, $field);
}

// Define field platformuniqueidhash to be added to enrol_lti_app_registration.
$field = new xmldb_field('platformuniqueidhash', XMLDB_TYPE_CHAR, '64', null, null, null, null, 'status');
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);

$recordset = $DB->get_recordset('enrol_lti_app_registration');
foreach ($recordset as $record) {
$record->platformuniqueidhash = hash('sha256', $record->platformid . ':' . $record->uniqueid);
$DB->update_record('enrol_lti_app_registration', $record);
}
$recordset->close();
}

// Add index platformuniqueidhash to enrol_lti_app_registration.
$index = new xmldb_index('platformuniqueidhash', XMLDB_INDEX_UNIQUE, ['platformuniqueidhash']);

if (!$dbman->index_exists($table, $index)) {
$dbman->add_index($table, $index);
}

// Lti savepoint reached.
upgrade_plugin_savepoint(true, 2022031401, 'enrol', 'lti');
}

if ($oldversion < 2022031402) {
// Define table enrol_lti_reg_token to be dropped.
$table = new xmldb_table('enrol_lti_reg_token');

// Conditionally launch drop table for enrol_lti_reg_token.
if ($dbman->table_exists($table)) {
$dbman->drop_table($table);
}

// Lti savepoint reached.
upgrade_plugin_savepoint(true, 2022031402, 'enrol', 'lti');
}

return true;
}
2 changes: 1 addition & 1 deletion enrol/lti/version.php
Expand Up @@ -24,7 +24,7 @@

defined('MOODLE_INTERNAL') || die();

$plugin->version = 2021052517; // The current plugin version (Date: YYYYMMDDXX).
$plugin->version = 2022031402; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2021052500; // Requires this Moodle version.
$plugin->component = 'enrol_lti'; // Full name of the plugin (used for diagnostics).
$plugin->dependencies = [
Expand Down

0 comments on commit 86f08a3

Please sign in to comment.