--- loncom/interface/londocs.pm 2020/01/20 20:16:28 1.484.2.85.2.2 +++ loncom/interface/londocs.pm 2022/01/05 00:48:06 1.484.2.93.2.2 @@ -1,7 +1,7 @@ # The LearningOnline Network # Documents # -# $Id: londocs.pm,v 1.484.2.85.2.2 2020/01/20 20:16:28 raeburn Exp $ +# $Id: londocs.pm,v 1.484.2.93.2.2 2022/01/05 00:48:06 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 = < -$name +$title $initialtext @@ -824,6 +866,7 @@ END return (&mt('Failed to save new web page.'),1); } } + $name = &LONCAPA::map::qtunescape($name); $url = &LONCAPA::map::qtunescape($url); $LONCAPA::map::resources[$residx] = join(':', ($name, $url, $ext, 'normal', 'res')); @@ -1166,13 +1209,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 +1230,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 +1243,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 '') { @@ -4038,11 +4093,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 +4119,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,7 +4130,7 @@ 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; @@ -4076,11 +4139,9 @@ END 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/; + $url =~ s/\#[^#]+$//; + if ($container eq 'page') { + $url = &Apache::lonnet::clutter($url); } } unless ($env{'request.role.adv'}) { @@ -4134,7 +4195,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 +4207,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; } @@ -4720,7 +4781,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('

'.&mt('Created [quant,_1,URL]',$numnew).'

'); } @@ -4755,7 +4816,7 @@ sub contentverifyform { &mt('No').''.(' 'x2). '

'. - ''. + ''. ''. '

'); $r->print(&endContentScreen()); @@ -5214,11 +5275,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 +5407,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 +5470,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 +5497,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 +5601,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 +5746,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', @@ -6119,13 +6159,19 @@ NSYLFORM $help{'Group Portfolio'} NGFFORM - @specialdocumentsforma=( + if ($container eq 'page') { + @specialdocumentsforma=( + {''.$lt{webp}.''=>$newwebpageform}, + ); + } else { + @specialdocumentsforma=( {''.$lt{newp}.''=>$newpageform}, {''.$lt{syll}.''=>$newsylform}, {''.$lt{navc}.''=>$newnavform}, {''.$lt{sipa}.''=>$newsmppageform}, {''.$lt{webp}.''=>$newwebpageform}, - ); + ); + } $specialdocumentsform = &create_form_ul(&create_list_elements(@specialdocumentsforma)); @@ -6168,11 +6214,11 @@ my %orderhash = ( 'aa' => ['Upload',$fileuploadform], 'bb' => ['Import',$importpubform], 'cc' => ['Grading',$gradingform], + 'ee' => ['Other',$specialdocumentsform], ); unless ($container eq 'page') { $orderhash{'00'} = ['Newfolder',$newfolderform]; $orderhash{'dd'} = ['Collaboration',$communityform]; - $orderhash{'ee'} = ['Other',$specialdocumentsform]; } $hadchanges=0; @@ -6819,7 +6865,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; } @@ -6828,7 +6874,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; } @@ -6872,7 +6918,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(); } } @@ -6880,7 +6926,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(); } } @@ -6889,7 +6935,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(); } } @@ -6898,7 +6944,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(); } } @@ -6913,7 +6959,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(); } } @@ -6922,7 +6968,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(); } } @@ -6931,7 +6977,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(); } } @@ -6940,7 +6986,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(); } }