From c10f3c7b75c0b1c85ec8e1e6ab651b21de3da472 Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Sat, 10 Feb 2024 15:25:43 -0600 Subject: [PATCH] Fix an issue that can cause LTI 1.3 grade passback to fail when called from the job queue. The `get_access_token` method calls `$c->url_for` (on line 141 of `WeBWorK::Authen::LTIAdvantage::SubmitGrade`. This is only called if the access token is not saved in the database or if the access token that is saved is expired. When this is called from the minion job queue, `$c` is not a `Mojolicious::Controller`. Instead it is an unblessed hash reference that has the keys `ce`, `db`, and `app` defined. Clearly that unblessed hash reference will not have the `url_for` method. As such, the job will fail if a new access token is needed. So as is done on line 249 in the `submit_grade` method, the `$c` object needs to be switched to the passed in `$c->{app}` object, which does have the `url_for` method. Note that with the current code this method will still succeed if the database has an unexpired access token stored. Also, this method will succeed if called with a `Mojolicious::Controller` object (for instance when called in the case that a student initially logs in via LTI 1.3 authentication or in the case that a student submits an answer to a problem or grades a test). This could be considered for a hotfix. --- lib/WeBWorK/Authen/LTIAdvantage/SubmitGrade.pm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/WeBWorK/Authen/LTIAdvantage/SubmitGrade.pm b/lib/WeBWorK/Authen/LTIAdvantage/SubmitGrade.pm index b5f89e5a90..b08399956f 100644 --- a/lib/WeBWorK/Authen/LTIAdvantage/SubmitGrade.pm +++ b/lib/WeBWorK/Authen/LTIAdvantage/SubmitGrade.pm @@ -117,16 +117,17 @@ async sub get_access_token ($self) { my $c = $self->{c}; my $ce = $c->{ce}; my $db = $c->{db}; + $c = $c->{app} if $self->{post_processing_mode}; my $current_token = decode_json($db->getSettingValue('LTIAdvantageAccessToken') // '{}'); - # If the token is still valid (and not about to expire) then it can still be used. + # If the token has not expired and is not about to expire, then it can still be used. if (%$current_token && $current_token->{timestamp} + $current_token->{expires_in} > time + 60) { $self->warning('Using current access token from database.'); return $current_token; } - # The token is about to expire, so get a new one. + # The token is expired or about to, so get a new one. my ($private_key, $err) = get_site_key($ce, 1); if (!$private_key) { @@ -150,7 +151,7 @@ async sub get_access_token ($self) { ); }; if ($@) { - $self->warning("Error encoding JWT: $@") if $@; + $self->warning("Error encoding JWT: $@"); return; }