--- loncom/interface/londocs.pm 2020/01/16 18:51:30 1.484.2.85.2.1
+++ loncom/interface/londocs.pm 2023/01/20 16:30:43 1.484.2.93.2.8
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Documents
#
-# $Id: londocs.pm,v 1.484.2.85.2.1 2020/01/16 18:51:30 raeburn Exp $
+# $Id: londocs.pm,v 1.484.2.93.2.8 2023/01/20 16:30:43 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -178,6 +178,45 @@ sub default_folderpath {
}
}
+sub validate_folderpath {
+ my ($supplementalflag) = @_;
+ if ($env{'form.folderpath'} ne '') {
+ my @items = split(/\&/,$env{'form.folderpath'});
+ my $badpath;
+ for (my $i=0; $i<@items; $i++) {
+ my $odd = $i%2;
+ if (($odd) && (!$supplementalflag) && ($items[$i] !~ /^[^:]*:(|\d+):(|1):(|1):(|1):(|1)$/)) {
+ $badpath = 1;
+ } elsif ((!$odd) && ($items[$i] !~ /^(default|supplemental)(|_\d+)$/)) {
+ $badpath = 1;
+ }
+ last if ($badpath);
+ }
+ if ($badpath) {
+ delete($env{'form.folderpath'});
+ }
+ }
+ return;
+}
+
+sub validate_suppath {
+ if ($env{'form.supppath'} ne '') {
+ my @items = split(/\&/,$env{'form.supppath'});
+ my $badpath;
+ for (my $i=0; $i<@items; $i++) {
+ my $odd = $i%2;
+ if ((!$odd) && ($items[$i] !~ /^supplemental(|_\d+)$/)) {
+ $badpath = 1;
+ }
+ last if ($badpath);
+ }
+ if ($badpath) {
+ delete($env{'form.supppath'});
+ }
+ }
+ return;
+}
+
sub dumpcourse {
my ($r) = @_;
my $crstype = &Apache::loncommon::course_type();
@@ -657,7 +696,7 @@ sub group_import {
my $marker = $2;
my $info = $3;
my ($toolid,%toolhash,%toolsettings);
- my @extras = ('linktext','explanation','crslabel','crstitle');
+ my @extras = ('linktext','explanation','crslabel','crstitle','crsappend');
my @toolinfo = split(/:/,$info);
if ($residx) {
%toolsettings=&Apache::lonnet::dump('exttool_'.$marker,$coursedom,$coursenum);
@@ -668,7 +707,7 @@ sub group_import {
$toolid =~ s/\D//g;
($toolhash{'target'},$toolhash{'width'},$toolhash{'height'},
$toolhash{'linktext'},$toolhash{'explanation'},
- $toolhash{'crslabel'},$toolhash{'crstitle'}) = @toolinfo;
+ $toolhash{'crslabel'},$toolhash{'crstitle'},$toolhash{'crsappend'}) = @toolinfo;
foreach my $item (@extras) {
$toolhash{$item} = &unescape($toolhash{$item});
}
@@ -754,6 +793,8 @@ sub group_import {
if (@deleted) {
&Apache::lonnet::del('exttool_'.$marker,\@deleted,$coursedom,$coursenum);
}
+ } else {
+ return (&mt('Failed to save update to external tool.'),1);
}
}
}
@@ -783,26 +824,27 @@ sub group_import {
}
my $ext = 'false';
if ($url=~m{^http://} || $url=~m{^https://}) { $ext = 'true'; }
- $name = &LONCAPA::map::qtunescape($name);
- if ($name eq '') {
- $name = &LONCAPA::map::qtunescape(&mt('Web Page'));
- }
if ($url =~ m{^/uploaded/$coursedom/$coursenum/((?:docs|supplemental)/(?:default|\d+))/new\.html$}) {
my $filepath = $1;
- my $fname = $name;
- if ($fname =~ /^\W+$/) {
+ my $fname;
+ if ($name eq '') {
+ $name = &mt('Web Page');
$fname = 'web';
} else {
- $fname =~ s/\W/_/g;
- }
- if (length($fname) > 15) {
- $fname = substr($fname,0,14);
+ $fname = $name;
+ $fname=&Apache::lonnet::clean_filename($fname);
+ if ($fname eq '') {
+ $fname = 'web';
+ } elsif (length($fname) > 15) {
+ $fname = substr($fname,0,14);
+ }
}
+ my $title = &Apache::loncommon::cleanup_html($name);
my $initialtext = &mt('Replace with your own content.');
my $newhtml = < '.&mt('Created [quant,_1,URL]',$numnew).'');
+ my ($title,$url) = split(/\:/,$docslog{$id}{'logentry'}{'parameter_res'},3);
+ if ($title eq '') {
+ ($title) = ($url =~ m{/([^/]+)$});
+ }
+ $r->print(&LONCAPA::map::qtescape($title).':
');
foreach my $parameter ('randompick','hiddenresource','encrypturl','randomorder') {
if ($docslog{$id}{'logentry'}{'parameter_action_'.$parameter}) {
# FIXME: internationalization seems wrong here
@@ -1166,13 +1213,19 @@ sub update_paste_buffer {
# Construct identifiers for current contents of user's paste buffer
if (@currpaste) {
foreach my $suffix (@currpaste) {
- my $cid = $env{'docs.markedcopy_crs_'.$suffix};
- my $url = $env{'docs.markedcopy_url_'.$suffix};
- my $mapidx = $env{'docs.markedcopy_map_'.$suffix};
- if (($cid =~ /^$match_domain(?:_)$match_courseid$/) &&
- ($url ne '')) {
- $pasteurls{$cid.'_'.$url.'_'.$mapidx} = 1;
- }
+ my $cid = $env{'docs.markedcopy_crs_'.$suffix};
+ my $url = $env{'docs.markedcopy_url_'.$suffix};
+ my $mapidx = $env{'docs.markedcopy_map_'.$suffix};
+ if (($cid =~ /^$match_domain(?:_)$match_courseid$/) &&
+ ($url ne '')) {
+ if ($url eq '/res/lib/templates/simpleproblem.problem') {
+ $pasteurls{$cid.'_'.$mapidx} = 1;
+ } elsif ($url =~ m{^/res/$match_domain/$match_username/}) {
+ $pasteurls{$url} = 1;
+ } else {
+ $pasteurls{$cid.'_'.$url} = 1;
+ }
+ }
}
}
@@ -1181,7 +1234,7 @@ sub update_paste_buffer {
my @pathitems = split(/\&/,$env{'form.folderpath'});
my @folderconf = split(/\:/,$pathitems[-1]);
- my $ispage = $folderconf[4];
+ my $ispage = $folderconf[5];
foreach my $item (@possibles) {
my ($orderidx,$cmd) = split(/:/,$item);
@@ -1194,7 +1247,13 @@ sub update_paste_buffer {
$env{'form.folderpath'},\%curr_groups);
next if ($denied{'copy'});
$url=~s{http(:|:)//https(:|:)//}{https$2//};
- next if (exists($pasteurls{$coursedom.'_'.$coursenum.'_'.$mapidx}));
+ if ($url eq '/res/lib/templates/simpleproblem.problem') {
+ next if (exists($pasteurls{$coursedom.'_'.$coursenum.'_'.$mapidx}));
+ } elsif ($url =~ m{^/res/$match_domain/$match_username/}) {
+ next if (exists($pasteurls{$url}));
+ } else {
+ next if (exists($pasteurls{$coursedom.'_'.$coursenum.'_'.$url}));
+ }
my ($suffix,$errortxt,$locknotfreed) =
&new_timebased_suffix($env{'user.domain'},$env{'user.name'},'paste');
if ($suffix ne '') {
@@ -1391,7 +1450,7 @@ sub print_paste_buffer {
}
$pasteitems .= '';
if ($nopaste) {
- $pasteitems .= $nopaste;
+ $pasteitems .= ' '.$nopaste.'';
} else {
if ($othercrs) {
$pasteitems .= $othercrs;
@@ -2661,6 +2720,15 @@ sub apply_fixups {
$storefn =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir{$key}/;
}
my $mapcontent = &Apache::lonnet::getfile($key);
+ if (($mapcontent eq '-1') && ($before{'map'} eq 'supplemental') &&
+ ($after{'map'} eq 'default') &&
+ ($key =~ m{^/uploaded/$match_domain/$match_courseid/supplemental_\d+\.sequence$})) {
+ $mapcontent = '';
+ }
if ($mapcontent eq '-1') {
if (ref($errors) eq 'HASH') {
$errors->{$key} = 1;
@@ -2943,7 +3011,7 @@ sub update_parameter {
my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]);
$name=&LONCAPA::map::qtescape($name);
$url=&LONCAPA::map::qtescape($url);
- next unless ($name && $url);
+ next unless $url;
my $is_map;
if ($url =~ m{/uploaded/.+\.(page|sequence)$}) {
$is_map = 1;
@@ -3813,7 +3881,7 @@ sub entryline {
my $line=&Apache::loncommon::start_data_table_row();
my ($form_start,$form_end,$form_common,$form_param);
# Edit commands
- my ($esc_path, $path, $symb);
+ my ($esc_path, $path, $symb, $shownsymb);
if ($env{'form.folderpath'}) {
$esc_path=&escape($env{'form.folderpath'});
$path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
@@ -4038,11 +4106,19 @@ END
my ($editlink,$extresform,$anchor,$hiddenres,$nomodal);
my $orig_url = $url;
$orig_url=~s{http(:|:)//https(:|:)//}{https$2//};
- $url=~s{^http(|s)(:|:)//}{/adm/wrapper/ext/};
+ if ($container eq 'page') {
+ $url=~s{^http(|s)(:|:)//}{/ext/};
+ } else {
+ $url=~s{^http(|s)(:|:)//}{/adm/wrapper/ext/};
+ }
if (!$supplementalflag && $residx && $symb) {
if ((!$isfolder) && (!$ispage)) {
(undef,undef,$url)=&Apache::lonnet::decode_symb($symb);
- $url=&Apache::lonnet::clutter($url);
+ if (($url =~ m{^ext/}) && ($container eq 'page')) {
+ $url=&Apache::lonnet::clutter_with_no_wrapper($url);
+ } else {
+ $url=&Apache::lonnet::clutter($url);
+ }
if ($url=~/^\/*uploaded\//) {
$url=~/\.(\w+)$/;
my $embstyle=&Apache::loncommon::fileembstyle($1);
@@ -4056,7 +4132,7 @@ END
} elsif ($url=~m{^(|/adm/wrapper)/ext/([^#]+)}) {
my $wrapped = $1;
my $exturl = $2;
- if ($wrapped eq '') {
+ if (($wrapped eq '') && ($container ne 'page')) {
$url='/adm/wrapper'.$url;
}
if (($ENV{'SERVER_PORT'} == 443) && ($exturl !~ /^https:/)) {
@@ -4067,38 +4143,16 @@ END
} elsif ($url eq "/public/$coursedom/$coursenum/syllabus") {
if (($ENV{'SERVER_PORT'} == 443) &&
($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) {
- unless (&Apache::lonnet::uses_sts()) {
+ unless ((&Apache::lonnet::uses_sts()) || (&Apache::lonnet::waf_allssl($hostname))) {
$url .= '?usehttp=1';
}
$nomodal = 1;
}
}
- if (&Apache::lonnet::symbverify($symb,$url)) {
- my $shownsymb = $symb;
- if ($isexternal) {
- if ($url =~ /^([^#]+)#([^#]+)$/) {
- $url = $1;
- $anchor = $2;
- my $escan = &escape('#');
- $shownsymb =~ s/^([^\#]+)#([^\#]+)$/$1$escan$2/;
- }
- }
- unless ($env{'request.role.adv'}) {
- if ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) {
- $url = '';
- }
- if (&Apache::lonnet::EXT('resource.0.hiddenresource',$symb) =~ /^yes$/i) {
- $url = '';
- $hiddenres = 1;
- }
- }
- if ($url ne '') {
- $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($shownsymb);
- }
- } elsif (!$env{'request.role.adv'}) {
- my $checkencrypt;
+ my ($checkencrypt,$shownurl);
+ if (!$env{'request.role.adv'}) {
if (((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i) ||
- $isencrypted || (&Apache::lonnet::EXT('resource.0.encrypturl',$symb) =~ /^yes$/i)) {
+ ($isencrypted) || (&Apache::lonnet::EXT('resource.0.encrypturl',$symb) =~ /^yes$/i)) {
$checkencrypt = 1;
} elsif (ref($navmapref)) {
unless (ref($$navmapref)) {
@@ -4110,22 +4164,39 @@ END
}
}
}
- if ($checkencrypt) {
- my $shownsymb = &Apache::lonenc::encrypted($symb);
- my $shownurl = &Apache::lonenc::encrypted($url);
- if (&Apache::lonnet::symbverify($shownsymb,$shownurl)) {
- $url = $shownurl.(($shownurl=~/\?/)?'&':'?').'symb='.&escape($shownsymb);
- if ($env{'request.enc'} ne '') {
- delete($env{'request.enc'});
- }
- } else {
- $url='';
- }
+ }
+ if ($checkencrypt) {
+ my $currenc = $env{'request.enc'};
+ $env{'request.enc'} = 1;
+ $shownsymb = &Apache::lonenc::encrypted($symb);
+ $shownurl = &Apache::lonenc::encrypted($url);
+ if (&Apache::lonnet::symbverify($symb,$url)) {
+ $url = $shownurl;
} else {
- $url='';
+ $url = '';
+ }
+ $env{'request.enc'} = $currenc;
+ } elsif (&Apache::lonnet::symbverify($symb,$url)) {
+ $shownsymb = $symb;
+ if ($isexternal) {
+ $url =~ s/\#[^#]+$//;
+ if ($container eq 'page') {
+ $url = &Apache::lonnet::clutter($url);
+ }
+ }
+ $shownurl = $url;
+ }
+ unless ($env{'request.role.adv'}) {
+ if ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) {
+ $url = '';
+ }
+ if (&Apache::lonnet::EXT('resource.0.hiddenresource',$symb) =~ /^yes$/i) {
+ $url = '';
+ $hiddenres = 1;
}
- } else {
- $url='';
+ }
+ if ($url ne '') {
+ $url = $shownurl.(($shownurl=~/\?/)?'&':'?').'symb='.&escape($shownsymb);
}
}
} elsif ($supplementalflag) {
@@ -4134,7 +4205,7 @@ END
$url = $1;
$anchor = $2;
if (($url =~ m{^(|/adm/wrapper)/ext/(?!https:)}) && ($ENV{'SERVER_PORT'} == 443)) {
- unless (&Apache::lonnet::uses_sts()) {
+ unless ((&Apache::lonnet::uses_sts()) || (&Apache::lonnet::waf_allssl($hostname))) {
if ($hostname ne '') {
$url = 'http://'.$hostname.$url;
}
@@ -4146,7 +4217,7 @@ END
} elsif ($url =~ m{^\Q/public/$coursedom/$coursenum/syllabus\E}) {
if (($ENV{'SERVER_PORT'} == 443) &&
($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) {
- unless (&Apache::lonnet::uses_sts()) {
+ unless ((&Apache::lonnet::uses_sts()) || (&Apache::lonnet::waf_allssl($hostname))) {
if ($hostname ne '') {
$url = 'http://'.$hostname.$url;
}
@@ -4285,7 +4356,7 @@ $form_end;
&Apache::lonhtmlcommon::jump_to_editres($cfile,$home,
$switchserver,
$forceedit,
- undef,$symb,
+ undef,$symb,$shownsymb,
&escape($env{'form.folderpath'}),
$renametitle,$hostname,
'','',1,$suppanchor);
@@ -4720,7 +4791,7 @@ sub short_urls {
$r->rflush();
my $readonly;
if ($canedit) {
- my ($numnew,$errors) = &Apache::loncommon::make_short_symbs($cdom,$cnum,$navmap);
+ my ($numnew,$errors) = &Apache::loncommon::get_requested_shorturls($cdom,$cnum,$navmap);
if ($numnew) {
$r->print('
'. - ''. + ''. ''. '
'); $r->print(&endContentScreen()); @@ -5214,11 +5285,11 @@ sub handler { # # --------------------------------------------- Initialize help topics for this foreach my $topic ('Adding_Course_Doc','Main_Course_Documents', - 'Adding_External_Resource','Adding_External_Tool', + 'Adding_External_Resource','Adding_External_Tool', 'Navigate_Content','Adding_Folders','Docs_Overview', - 'Load_Map','Supplemental','Score_Upload_Form', - 'Adding_Pages','Importing_LON-CAPA_Resource', - 'Importing_IMS_Course','Uploading_From_Harddrive', + 'Load_Map','Supplemental','Score_Upload_Form', + 'Adding_Pages','Importing_LON-CAPA_Resource', + 'Importing_IMS_Course','Uploading_From_Harddrive', 'Course_Roster','Web_Page','Dropbox','Simple_Problem') { $help{$topic}=&Apache::loncommon::help_open_topic('Docs_'.$topic); } @@ -5346,35 +5417,11 @@ sub handler { if ($env{'form.tools'}) { $toolsflag=1; } if ($env{'form.folderpath'} ne '') { - my @items = split(/\&/,$env{'form.folderpath'}); - my $badpath; - for (my $i=0; $i<@items; $i++) { - my $odd = $i%2; - if (($odd) && (!$supplementalflag) && ($items[$i] !~ /^[^:]*:(|\d+):(|1):(|1):(|1):(|1)$/)) { - $badpath = 1; - } elsif ((!$odd) && ($items[$i] !~ /^(default|supplemental)(|_\d+)$/)) { - $badpath = 1; - } - last if ($badpath); - } - if ($badpath) { - delete($env{'form.folderpath'}); - } + &validate_folderpath($supplementalflag); } if ($env{'form.supppath'} ne '') { - my @items = split(/\&/,$env{'form.supppath'}); - my $badpath; - for (my $i=0; $i<@items; $i++) { - my $odd = $i%2; - if ((!$odd) && ($items[$i] !~ /^supplemental(|_\d+)$/)) { - $badpath = 1; - } - last if ($badpath); - } - if ($badpath) { - delete($env{'form.supppath'}); - } + &validate_suppath(); } my $script=''; @@ -5433,6 +5480,9 @@ sub handler { } else { undef($env{'form.folderpath'}); } + if ($env{'form.folderpath'} ne '') { + &validate_folderpath($supplementalflag); + } } # If we are not allowed to make changes, all we can see are supplemental docs @@ -5457,7 +5507,7 @@ sub handler { undef($env{'form.folderpath'}); } else { $folderurl = "uploaded/$coursedom/$coursenum/$folder"; - if ((split(/\:/,$pathitems[-1]))[4]) { + if ((split(/\:/,$pathitems[-1]))[5]) { $folderurl .= '.page'; } else { $folderurl .= '.sequence'; @@ -5561,7 +5611,7 @@ sub handler { } } my $tabidstr = join("','",@tabids); - %ltitools = &Apache::lonnet::get_domain_ltitools($coursedom); + %ltitools = &Apache::lonnet::get_domain_lti($coursedom,'consumer'); my $posslti = keys(%ltitools); my $hostname = $r->hostname(); $script .= &editing_js($udom,$uname,$supplementalflag,$coursedom,$coursenum,$posslti, @@ -5706,7 +5756,7 @@ sub handler { 'lnks' => 'Import from Stored Links', 'impm' => 'Import from Assembled Map', 'extr' => 'External Resource', - 'extt' => 'External Tool', + 'extt' => 'External Tool', 'selm' => 'Select Map', 'load' => 'Load Map', 'newf' => 'New Folder', @@ -5927,6 +5977,7 @@ HIDDENFORM # my $savefolderpath; + my $hostname = $r->hostname(); if ($allowed) { my $folder=$env{'form.folder'}; @@ -6118,13 +6169,19 @@ NSYLFORM $help{'Group Portfolio'} NGFFORM - @specialdocumentsforma=( + if ($container eq 'page') { + @specialdocumentsforma=( + {''.$error.'
'); } @@ -6818,7 +6876,7 @@ sub editing_js { if ($backtourl =~ m{^\Q/public/$coursedom/$coursenum/syllabus\E}) { if (($ENV{'SERVER_PORT'} == 443) && ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) { - unless (&Apache::lonnet::uses_sts()) { + unless ((&Apache::lonnet::uses_sts()) || (&Apache::lonnet::waf_allssl($hostname))) { if ($hostname ne '') { $backtourl = 'http://'.$hostname.$backtourl; } @@ -6827,7 +6885,7 @@ sub editing_js { } } elsif ($backtourl =~ m{^/adm/wrapper/ext/(?!https:)}) { if (($ENV{'SERVER_PORT'} == 443) && ($hostname ne '')) { - unless (&Apache::lonnet::uses_sts()) { + unless ((&Apache::lonnet::uses_sts()) || (&Apache::lonnet::waf_allssl($hostname))) { if ($hostname ne '') { $backtourl = 'http://'.$hostname.$backtourl; } @@ -6871,7 +6929,7 @@ sub editing_js { function makenewfolder(targetform,folderseq) { var foldername=prompt('$js_lt{"p_mnf"}','$js_lt{"t_mnf"}'); if (foldername) { - targetform.importdetail.value=escape(foldername)+"="+folderseq; + targetform.importdetail.value=encodeURIComponent(foldername)+"="+folderseq; targetform.submit(); } } @@ -6879,7 +6937,7 @@ function makenewfolder(targetform,folder function makenewpage(targetform,folderseq) { var pagename=prompt('$js_lt{"p_mnp"}','$js_lt{"t_mnp"}'); if (pagename) { - targetform.importdetail.value=escape(pagename)+"="+folderseq; + targetform.importdetail.value=encodeURIComponent(pagename)+"="+folderseq; targetform.submit(); } } @@ -6888,7 +6946,7 @@ function makeexamupload() { var title=prompt('$js_lt{"p_mxu"}'); if (title) { this.document.forms.newexamupload.importdetail.value= - escape(title)+'=/res/lib/templates/examupload.problem'; + encodeURIComponent(title)+'=/res/lib/templates/examupload.problem'; this.document.forms.newexamupload.submit(); } } @@ -6897,7 +6955,7 @@ function makesmppage() { var title=prompt('$js_lt{"p_msp"}'); if (title) { this.document.forms.newsmppg.importdetail.value= - escape(title)+'=/adm/$udom/$uname/new/smppg'; + encodeURIComponent(title)+'=/adm/$udom/$uname/new/smppg'; this.document.forms.newsmppg.submit(); } } @@ -6912,7 +6970,7 @@ function makewebpage(type) { } if (title) { var webpage = formname.importdetail.value; - formname.importdetail.value = escape(title)+'='+webpage; + formname.importdetail.value = encodeURIComponent(title)+'='+webpage; formname.submit(); } } @@ -6921,7 +6979,7 @@ function makesmpproblem() { var title=prompt('$js_lt{"p_msb"}'); if (title) { this.document.forms.newsmpproblem.importdetail.value= - escape(title)+'=/res/lib/templates/simpleproblem.problem'; + encodeURIComponent(title)+'=/res/lib/templates/simpleproblem.problem'; this.document.forms.newsmpproblem.submit(); } } @@ -6930,7 +6988,7 @@ function makedropbox() { var title=prompt('$js_lt{"p_mdb"}'); if (title) { this.document.forms.newdropbox.importdetail.value= - escape(title)+'=/res/lib/templates/DropBox.problem'; + encodeURIComponent(title)+'=/res/lib/templates/DropBox.problem'; this.document.forms.newdropbox.submit(); } } @@ -6939,7 +6997,7 @@ function makebulboard() { var title=prompt('$js_lt{"p_mbb"}'); if (title) { this.document.forms.newbul.importdetail.value= - escape(title)+'=/adm/$udom/$uname/new/bulletinboard'; + encodeURIComponent(title)+'=/adm/$udom/$uname/new/bulletinboard'; this.document.forms.newbul.submit(); } }