Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions admin/processltiqueue.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ function debuglog($str) {
'platformid' => $platformid,
'grade' => max(0, $row['grade']),
'isstu' => $row['isstu'],
'addedon' => $row['addedon']
'addedon' => $row['addedon'],
'keyseturl' => $row['keyseturl'],
),
null, //no special callback
array( //user-data; will get passed to response
Expand All @@ -149,7 +150,8 @@ function debuglog($str) {
'ver' => 'LTI1.3',
'action' => 'gettoken',
'platformid' => $platformid,
'platforminfo' => $platforminfo
'platforminfo' => $platforminfo,
'keyseturl' => $row['keyseturl'],
),
null, //no special callback
array( //user-data; will get passed to response
Expand Down Expand Up @@ -276,7 +278,7 @@ function LTIqueuePostdataCallback($data) {
if ($updater1p3->have_token($data['platformid']) &&
$updater1p3->token_valid($data['platformid'])
) { // double check we have a valid token
$token = $updater1p3->get_access_token($data['platformid']);
$token = $updater1p3->get_access_token($data['platformid'], '', '', '', $data['keyseturl']);
return $updater1p3->get_update_body($token, $data['grade'], $data['ltiuserid'], $data['isstu'], $data['addedon']);
} else {
return false;
Expand Down
10 changes: 6 additions & 4 deletions includes/ltioutcomes.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ function addToLTIQueue($sourcedid, $key, $grade, $sendnow=false, $isstu=true) {
global $DBH, $CFG;

$LTIdelay = 60*(isset($CFG['LTI']['queuedelay'])?$CFG['LTI']['queuedelay']:5);
$keyseturl = $GLOBALS['basesiteurl'] . '/lti/jwks.php';

$query = 'INSERT INTO imas_ltiqueue (hash, sourcedid, grade, failures, sendon, isstu, addedon) ';
$query .= 'VALUES (:hash, :sourcedid, :grade, 0, :sendon, :isstu, :addedon) ON DUPLICATE KEY UPDATE ';
$query .= 'grade=VALUES(grade),sendon=VALUES(sendon),sourcedid=VALUES(sourcedid),failures=0,isstu=GREATEST(isstu,VALUES(isstu)) ';
$query = 'INSERT INTO imas_ltiqueue (hash, sourcedid, grade, failures, sendon, isstu, addedon, keyseturl) ';
$query .= 'VALUES (:hash, :sourcedid, :grade, 0, :sendon, :isstu, :addedon, :keyseturl) ON DUPLICATE KEY UPDATE ';
$query .= 'grade=VALUES(grade),sendon=VALUES(sendon),sourcedid=VALUES(sourcedid),failures=0,isstu=GREATEST(isstu,VALUES(isstu)),keyseturl=VALUES(keyseturl) ';

$stm = $DBH->prepare($query);
$stm->execute(array(
Expand All @@ -31,7 +32,8 @@ function addToLTIQueue($sourcedid, $key, $grade, $sendnow=false, $isstu=true) {
':grade' => $grade,
':sendon' => (time() + ($sendnow?0:$LTIdelay)),
':isstu' => $isstu ? 1 : 0,
':addedon' => time()
':addedon' => time(),
':keyseturl' => $keyseturl,
));

return ($stm->rowCount()>0);
Expand Down
29 changes: 19 additions & 10 deletions lti/LTI_Grade_Update.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
class LTI_Grade_Update {
private $dbh;
private $access_tokens = [];
private $private_key = '';
private $private_key = [];
private $failures = [];
private $debug = false;

Expand Down Expand Up @@ -210,9 +210,12 @@ public function get_update_body(string $token, float $score, string $ltiuserid,
* @param string $client_id optional if known - the client_id
* @param string $token_server optional if known - the token_server_url
* @param string $auth_server optional if known - the aud for token request
* @param string|null $keyseturl optional if known - the keyset url
* @return false|string access token, or false on failure
*/
public function get_access_token(int $platform_id, string $client_id='', string $token_server='', string $auth_server='') {
public function get_access_token(int $platform_id, string $client_id='', string $token_server='', string $auth_server='',
?string $keyseturl = null
) {
// see if we already have the token in our private variable cache
if (isset($this->access_tokens[$platform_id]) &&
$this->access_tokens[$platform_id]['expires'] < time()
Expand Down Expand Up @@ -248,7 +251,7 @@ public function get_access_token(int $platform_id, string $client_id='', string
list($client_id, $token_server, $auth_server) = $stm->fetch(PDO::FETCH_NUM);
}
$this->debuglog('requesting a token from '.$platform_id);
$request_post = $this->get_token_request_post($platform_id, $client_id, $token_server, $auth_server);
$request_post = $this->get_token_request_post($platform_id, $client_id, $token_server, $auth_server, $keyseturl);
// Make request to get auth token
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $token_server);
Expand Down Expand Up @@ -306,11 +309,16 @@ public function store_access_token(int $platform_id, array $token_data): void {
* @param string $client_id
* @param string $token_server
* @param string $auth_server
* @param string|null $keyseturl
* @return string output of http_build_query
*/
public function get_token_request_post(int $platform_id, string $client_id,
string $token_server, string $auth_server
string $token_server, string $auth_server, ?string $keyseturl = null
): string {
if (empty($keyseturl)) {
$keyseturl = TOOL_HOST . '/lti/jwks.php';
}

// Build up JWT to exchange for an auth token
$jwt_claim = [
"iss" => $client_id,
Expand All @@ -322,10 +330,10 @@ public function get_token_request_post(int $platform_id, string $client_id,
];

// Get tool private key from our JWKS
$private_key = $this->get_tool_private_key();
$private_key[$keyseturl] = $this->get_tool_private_key($keyseturl);

// Sign the JWT with our private key (given by the platform on registration)
$jwt = JWT::encode($jwt_claim, $private_key['privatekey'], 'RS256', $private_key['kid']);
$jwt = JWT::encode($jwt_claim, $private_key[$keyseturl]['privatekey'], 'RS256', $private_key[$keyseturl]['kid']);

// Build auth token request headers
$auth_request = [
Expand Down Expand Up @@ -390,14 +398,15 @@ public function update_sendon(string $hash, int $platform_id): void {

/**
* Get tool's private key
* @param string $keyseturl
* @return array
*/
private function get_tool_private_key(): array {
if (!empty($this->private_key)) {
return $this->private_key;
private function get_tool_private_key(string $keyseturl): array {
if (!empty($this->private_key[$keyseturl])) {
return $this->private_key[$keyseturl];
}
$stm = $this->dbh->prepare('SELECT * FROM imas_lti_keys WHERE key_set_url=? AND privatekey != "" ORDER BY created_at DESC LIMIT 1');
$stm->execute(array(TOOL_HOST.'/lti/jwks.php'));
$stm->execute(array($keyseturl));
$row = $stm->fetch(PDO::FETCH_ASSOC);
$this->private_key = $row;
return $row;
Expand Down
22 changes: 22 additions & 0 deletions migrations/20230321_add_keyseturl_to_ltiqueue.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

// Add a keyseturl column to imas_ltiqueue to record the hostname
// a user used when queueing a grade return for an LMS.
$DBH->beginTransaction();

$query = "ALTER TABLE `imas_ltiqueue`
ADD COLUMN `keyseturl` VARCHAR(256) NULL,
ALGORITHM=INPLACE,
LOCK=NONE;";
$res = $DBH->query($query);
if ($res===false) {
echo "<p>Query failed: ($query) : ".print_r($DBH->errorInfo(),true)."</p>";
$DBH->rollBack();
return false;
}


$DBH->commit();
echo '<p>Add keyseturl columnn to imas_ltiqueue.</p>';

return true;