WeBWorK Main Forum

LTIAdvanced grade passback to Canvas error

LTIAdvanced grade passback to Canvas error

by Sarunas Burdulis -
Number of replies: 6

Hi,

We just started using Canvas to Webwork LTIAdvanced. Testing went fine with both student account management and grade passback. Now with the real course we started getting errors on grade passback:

Can't use string ("{"errors":[{"message":"Duplicate"...) as a HASH ref while "strict refs" in use at /opt/webwork/webwork2/lib/WeBWorK/Authen/LTIAdva
nced/SubmitGrade.pm line 193.
* in WeBWorK::Authen::LTIAdvanced::SubmitGrade::local_escape_html called at line 339 of /opt/webwork/webwork2/lib/WeBWorK/Authen/LTIAdvanced/SubmitGrade.pm\n * in WeBWorK::Authen::LTIAdvanced::SubmitGrade::submit_grade called at line 182 of /opt /webwork/webwork2/lib/WeBWorK/Authen/LTIAdvanced/SubmitGrade.pm
* in WeBWorK::Authen::LTIAdvanced::SubmitGrade::submit_set_grade called at line 294 of /opt/webwork/webwork2/lib/WeBWorK/ContentGenerator/ProblemUtil/ProblemUtil.pm
* in WeBWorK::ContentGenerator::ProblemUtil: :ProblemUtil::process_and_log_answer called at line 794 of /opt/webwork/webwork2/lib/WeBWorK/ContentGenerator/Problem.pm
* in WeBWorK::ContentGenerator::Problem::pre_header_initialize called at line 214 of /opt/webwork/webwork2/lib/WeBWorK/ContentGenerator.pm
* in WeBWorK: :ContentGenerator::go called at line 386 of /opt/webwork/webwork2/lib/WeBWorK.pm

Webwork software didn't change after testing with no problems. Using 2.15 on Ubuntu 18.04, plenty of system resources. LTI configuration is per course. Below are LTI related parameters from course.conf. Would anyone have a suggestion what to check?

include("conf/authen_LTI.conf");
$debug_lti_parameters = 0;  
$LTIBasicConsumerSecret = "****";
$NonceLifeTime=180; # in seconds
$preferred_source_of_username = "lis_person_sourcedid";
$permissionLevels{change_email} = "professor";
$LTIGradeMode = "homework";
$LTIAccountCreationCutoff = "professor";
$authen{user_module} = [  
       {  "*" => "WeBWorK::Authen::LTIAdvanced", }, #preferred authorization method
       {  "*" => "WeBWorK::Authen::Basic_TheLastOption",}  #fallback authorization method
];

In reply to Sarunas Burdulis

Re: LTIAdvanced grade passback to Canvas error

by Larry Riddle -

We had a similar issue with grade passback to Canvas. See my report at https://webwork.maa.org/moodle/mod/forum/discuss.php?d=4770. In our case the problem was that our WeBWorK server was posting times that were more than 1 minute ahead of the timestamp Canvas had and thus causing a "duplicate nonce detected" error. Apparently Canvas only allows for 1 minute ahead and 5 minutes behind.

In reply to Larry Riddle

Re: LTIAdvanced grade passback to Canvas error

by Nathan Wallach -
This seems to be a recurring problem, and the error message about "duplicate nonce" does not really provide much help in discovering the problem.

It might help to add code to SubmitGrade.pm to specifically watch for "duplicate nonce detected" error messages, and then report that this is sometimes caused by an incorrect time on the WW server.
In reply to Nathan Wallach

Re: LTIAdvanced grade passback to Canvas error

by Sarunas Burdulis -
For now I have just added warn() statements duplicating those of debug() in submit_grade code, failure clauses. Now that PERL doesn't croak on erroneous “Can't use string...” it's easy to not notice the difference between “Your score was successfully sent to the LMS” and “Your score was not successfully sent to the LMS” on homework web page.
In reply to Larry Riddle

Re: LTIAdvanced grade passback to Canvas error

by Sarunas Burdulis -
Thanks! I could have searched this forum better…

After fixing SubmitGrade.pm line 339 (local_escape_html() to $self->local_escape_html()), the error "Duplicate nonce detected" can be properly seen in debug mode.

I'm not sure about the cause or solution. Our WeBWorK server's time was always synchronized to a pool of campus NTP servers. As a test I changed it to use Ubuntu NTP pool. We are still getting intermittent "Duplicate nonce detected" responses to grade passback from WeBWorK to Canvas.
In reply to Sarunas Burdulis

Re: LTIAdvanced grade passback to Canvas error

by Nathan Wallach -

Larry Riddle's LTI problem was not intermittent, and happened continuously until the "time error" issue was discovered. In that case - the "duplicate nonce" error message was hiding the real reason Canvas was rejecting the LTI grade submissions.

If you have an intermittent problem - it is quite possible that the problem is really nonce reuse.

WeBWorK's current generation/handling of the nonces is pretty simple and just generates a random nonce whenever one is needed and makes no effort to avoid reuse or to track what nonces were used "recently". The assumption of the people who wrote the code is that the probability of randomly reusing a nonce is sufficiently small to disregard it.

Canvas keeps track of the nonces used (to enforce non-reuse in the time window they set) until they "expire" so there is some "small" possibility that the nonce is truly a duplicate nonce. 

Having WeBWorK track and expire nonces for grade-passback would require quite some effort (and DB tracking / cleanup), so it is unlikely to be implemented anytime soon, unless someone find the issue annoying enough to work on it.

In the discussion thread at https://webwork.maa.org/moodle/mod/forum/discuss.php?d=4770 I posted a version of SubmitGrade.pm which has a different (and more complex) version of the nonce generation code.  Since the issue there was not really related to duplicate nonces - the code was not advanced further. The proposed code (at the expense of more CPU time) is hopefully far less likely to hit such cases. You are welcome to try it out, but should merge the code changes carefully into a current version of SubmitGrade.pm.

In reply to Nathan Wallach

Re: LTIAdvanced grade passback to Canvas error

by Sarunas Burdulis -
Thanks, Nathan. Yes, I'm aware of the other thread and your version of SubmitGrade.pm.

For now we were using $LTIGradeOnSubmit = 0 and relied on mass update.

Today I went back to testing grade passback on submit with the intention to use your improved nonce generation. I started with the original method and tried to submit some answers in a test course as a student. Everything worked as expected, no "Duplicate nonce detected" errors, grades appeared instantly on Canvas. Tried to submit about 130 times and no errors. I have also tried SubmitGrade.pm with the change to nonce generated by your method, the diff:

35c35
<  
---
> use UUID::Tiny  ':std';
285a286,293
>  
>   # Generate a better nonce, first a portion unique for the sourcedid
>   # which should be dependent on the student + the assignment if a
>   # "homework" level sourcedid.
>   my $uuid_p1 = create_uuid_as_string(UUID_SHA1, UUID_NS_URL, $sourcedid);
>   # Next create a time dependent portion
>   my $uuid_p2 = create_uuid_as_string(UUID_TIME);
>  
292c300
<                 nonce => int(rand( 2**32)),
---
>                 nonce => "${uuid_p1}__${uuid_p2}",

Grade passback worked normally as well, submitted about 100 times.

There were no changes on our server since our first initial and successful LTI/Canvas testing in August.

That is, for now, grade passback works perfectly again without any change on WeBWorK side...