version 1.3, 2017/12/09 16:24:03
|
version 1.6, 2018/08/14 21:42:36
|
Line 29
|
Line 29
|
package Apache::ltipassback; |
package Apache::ltipassback; |
|
|
use strict; |
use strict; |
|
use URI::Escape; |
use Apache::Constants qw(:common :http); |
use Apache::Constants qw(:common :http); |
use Apache::lonnet; |
use Apache::lonnet; |
use Apache::loncommon; |
use Apache::loncommon; |
Line 38 use LONCAPA::ltiutils;
|
Line 39 use LONCAPA::ltiutils;
|
sub handler { |
sub handler { |
my $r = shift; |
my $r = shift; |
my %errors; |
my %errors; |
|
my $params = {}; |
|
my ($oauthtype,$authheader,$xmlbody); |
|
# |
|
# Retrieve content type from headers |
|
# |
|
my $content_type = $r->headers_in->get('Content-Type'); |
|
if ($content_type eq 'application/xml') { |
|
$oauthtype = 'consumer'; |
|
# |
|
# Retrieve OAuth data from Authorization header sent by LTI Provider |
|
# |
|
$authheader = $r->headers_in->get('Authorization'); |
|
my ($authtype,$valuestr) = ($authheader =~ /^(OAuth)\s+(.+)$/i); |
|
if (lc($authtype) eq 'oauth') { |
|
foreach my $pair (split(/\s*,\s*/,$valuestr)) { |
|
my ($key,$value) = split(/=/,$pair); |
|
$value =~ s /(^"|"$)//g; |
|
$params->{$key} = URI::Escape::uri_unescape($value); |
|
} |
|
} |
|
# |
|
# Retrieve message body |
|
# |
|
my $length = $r->headers_in->get('Content-length'); |
|
if ($length) { |
|
$r->read($xmlbody,$length,0); |
|
if ($xmlbody ne '') { |
|
my %grades = &LONCAPA::ltiutils::parse_grade_xml($xmlbody); |
|
foreach my $num (sort { $a <=> $b } (keys(%grades))) { |
|
if (ref($grades{$num}) eq 'HASH') { |
|
if (($grades{$num}{'sourcedid'} ne '') && ($grades{$num}{'score'} ne '')) { |
|
$params->{'sourcedid'} = $grades{$num}{'sourcedid'}; |
|
$params->{'result_resultscore_textstring'} = $grades{$num}{'score'}; |
|
$params->{'result_resultscore_language'} = $grades{$num}{'language'}; |
|
$params->{'result_resultvaluesourcedid'} = 'decimal'; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} else { |
|
$oauthtype = 'request token'; |
# |
# |
# Retrieve data POSTed by LTI Provider |
# Retrieve data POSTed by LTI Provider |
# |
# |
&Apache::lonacc::get_posted_cgi($r); |
&Apache::lonacc::get_posted_cgi($r); |
my $params = {}; |
foreach my $key (sort(keys(%env))) { |
foreach my $key (sort(keys(%env))) { |
if ($key =~ /^form\.(.+)$/) { |
if ($key =~ /^form\.(.+)$/) { |
$params->{$1} = $env{$key}; |
$params->{$1} = $env{$key}; |
} |
} |
} |
} |
} |
|
|
Line 119 sub handler {
|
Line 162 sub handler {
|
$marker,$symb,$cdom,$cnum, |
$marker,$symb,$cdom,$cnum, |
\%toolsettings,\%ltitools,\%errors); |
\%toolsettings,\%ltitools,\%errors); |
|
|
|
if (keys(%errors) > 0) { |
|
&invalid_request($r,$params,\%errors); |
|
return OK; |
|
} |
|
|
# |
# |
# Verify the signed request using the consumer_key and |
# Verify the signed request using the consumer_key and |
# secret for the specific LTI Provider. |
# secret for the specific LTI Provider. |
Line 128 sub handler {
|
Line 176 sub handler {
|
if ($ENV{'SERVER_PORT'} == 443) { |
if ($ENV{'SERVER_PORT'} == 443) { |
$protocol = 'https'; |
$protocol = 'https'; |
} |
} |
unless (LONCAPA::ltiutils::verify_request($params,$protocol,$r->hostname,$r->uri, |
|
$env{'request.method'},$consumer_secret, |
unless (LONCAPA::ltiutils::verify_request($oauthtype,$protocol,$r->hostname,$r->uri, |
\%errors)) { |
$r->method,$consumer_secret,$params, |
|
$authheader,\%errors)) { |
|
&invalid_request($r,$params,\%errors); |
|
return OK; |
|
} |
|
|
|
# |
|
# Verify XML in request body has not been tampered with |
|
# |
|
|
|
my $bodyhash = Digest::SHA::sha1_base64($xmlbody); |
|
while (length($bodyhash) % 4) { |
|
$bodyhash .= '='; |
|
} |
|
unless ($bodyhash eq $params->{oauth_body_hash}) { |
|
$errors{16} = 1; |
&invalid_request($r,$params,\%errors); |
&invalid_request($r,$params,\%errors); |
return OK; |
return OK; |
} |
} |
Line 138 sub handler {
|
Line 201 sub handler {
|
# |
# |
# Determine if nonce in POSTed data has expired. |
# Determine if nonce in POSTed data has expired. |
# If unexpired, confirm it has not already been used. |
# If unexpired, confirm it has not already been used. |
|
# |
|
|
unless (&LONCAPA::ltiutils::check_nonce($params->{'oauth_nonce'},$params->{'oauth_timestamp'}, |
unless (&LONCAPA::ltiutils::check_nonce($params->{'oauth_nonce'},$params->{'oauth_timestamp'}, |
$ltitools{'lifetime'},$cdom,$r->dir_config('lonLTIDir'))) { |
$ltitools{'lifetime'},$cdom,$r->dir_config('lonLTIDir'))) { |
$errors{16} = 1; |
$errors{17} = 1; |
&invalid_request($r,$params,\%errors); |
&invalid_request($r,$params,\%errors); |
return OK; |
return OK; |
} |
} |
Line 168 sub handler {
|
Line 232 sub handler {
|
%maproles = %{$ltitools{'roles'}}; |
%maproles = %{$ltitools{'roles'}}; |
} |
} |
unless (keys(%maproles)) { |
unless (keys(%maproles)) { |
$errors{21} = 1; |
$errors{22} = 1; |
&invalid_request($r,$params,\%errors); |
&invalid_request($r,$params,\%errors); |
return OK; |
return OK; |
} |
} |
Line 205 sub handler {
|
Line 269 sub handler {
|
} |
} |
} |
} |
unless ($hasrole) { |
unless ($hasrole) { |
$errors{22} = 1; |
$errors{23} = 1; |
&invalid_request($r,$params,\%errors); |
&invalid_request($r,$params,\%errors); |
return OK; |
return OK; |
} |
} |
} else { |
} else { |
$errors{23} = 1; |
$errors{24} = 1; |
&invalid_request($r,$params,\%errors); |
&invalid_request($r,$params,\%errors); |
return OK; |
return OK; |
} |
} |
Line 219 sub handler {
|
Line 283 sub handler {
|
# Store result if one was sent in a valid format. |
# Store result if one was sent in a valid format. |
# |
# |
|
|
|
|
my ($result,$resulttype,$lang,$pcf); |
my ($result,$resulttype,$lang,$pcf); |
if (exists($params->{'result_resultvaluesourcedid'})) { |
if (exists($params->{'result_resultvaluesourcedid'})) { |
$resulttype = $params->{'result_resultvaluesourcedid'}; |
$resulttype = $params->{'result_resultvaluesourcedid'}; |
$resulttype =~ s/(^\s+|\s+)$//g; |
$resulttype =~ s/(^\s+|\s+)$//g; |
} else { |
} else { |
$resulttype = 'decimal'; |
$resulttype = 'decimal'; |
} |
} |
$result = $params->{'result_resultscore_textstring'}; |
$result = $params->{'result_resultscore_textstring'}; |
$result =~ s/(^\s+|\s+)$//g; |
$result =~ s/(^\s+|\s+)$//g; |
my $posslang = $params->{'result_resultscore_language'}; |
my $posslang = $params->{'result_resultscore_language'}; |
Line 270 sub handler {
|
Line 333 sub handler {
|
my %newrecord=(); |
my %newrecord=(); |
my $reckey = 'resource.0.solved'; |
my $reckey = 'resource.0.solved'; |
my %record = &Apache::lonnet::restore($symb,$cdom.'_'.$cnum,$udom,$uname); |
my %record = &Apache::lonnet::restore($symb,$cdom.'_'.$cnum,$udom,$uname); |
|
my $tries = 0; |
|
if ($record{'resource.0.tries'} =~ /^\d$/) { |
|
$tries = $record{'resource.0.tries'}; |
|
} |
if ($record{'resource.0.awarded'} ne $pcf) { |
if ($record{'resource.0.awarded'} ne $pcf) { |
$newrecord{'resource.0.awarded'} = $pcf; |
$newrecord{'resource.0.awarded'} = $pcf; |
} |
} |
if ($pcf == 0) { |
if ($pcf == 0) { |
if ($record{$reckey} ne 'incorrect_by_override') { |
if ($record{$reckey} ne 'incorrect_by_passback') { |
$newrecord{$reckey} = 'incorrect_by_override'; |
$newrecord{$reckey} = 'incorrect_by_passback'; |
} |
} |
} else { |
} else { |
if ($record{$reckey} ne 'correct_by_override') { |
if ($record{$reckey} ne 'correct_by_passback') { |
$newrecord{$reckey} = 'correct_by_override'; |
$newrecord{$reckey} = 'correct_by_passback'; |
} |
} |
} |
} |
if (%newrecord) { |
if (%newrecord) { |
|
$newrecord{'resource.0.tries'} = 1 + $tries; |
|
$env{'request.course.id'} = $cdom.'_'.$cnum; |
my $result = &Apache::lonnet::cstore(\%newrecord,$symb,$cdom.'_'.$cnum, |
my $result = &Apache::lonnet::cstore(\%newrecord,$symb,$cdom.'_'.$cnum, |
$udom,$uname); |
$udom,$uname); |
|
delete($env{'request.course.id'}); |
if (($result eq 'ok') || ($result eq 'con_delayed')) { |
if (($result eq 'ok') || ($result eq 'con_delayed')) { |
&success($r,$params->{'sourcedid'},$resulttype,$result,$lang); |
&success($r,$params->{'sourcedid'},$resulttype,$result,$lang); |
} else { |
} else { |
$errors{25} = 1; |
$errors{25} = 1; |
&invalid_request($r,$params,\%errors); |
&invalid_request($r,$params,\%errors); |
} |
} |
|
} else { |
|
&success($r,$params->{'sourcedid'},$resulttype,$result,$lang); |
} |
} |
} else { |
} else { |
$errors{26} = 1; |
$errors{26} = 1; |