[LON-CAPA-cvs] cvs: loncom /interface lonwishlist.pm

wenzelju wenzelju@source.lon-capa.org
Mon, 16 Aug 2010 13:37:42 -0000


This is a MIME encoded message

--wenzelju1281965862
Content-Type: text/plain

wenzelju		Mon Aug 16 13:37:42 2010 EDT

  Modified files:              
    /loncom/interface	lonwishlist.pm 
  Log:
  - Only allow links to LON-CAPA-resources from resource-pool (paths starts with /res/...) or to external websites. Uses same filter for external websites as it is used in lonwrapper to display external resources. That means that only paths (not starting with /res/...) which does not contain a .problem, .quiz, .exam etc. are allowed. This is good for most cases but crashes as soon as a real external website contains one of this pattern in its URL. So maybe there's a better way to find out wether a given URL belongs to a LON-CAPA-server or not...?  
  - Allow users to edit the path of a link regarding the restriction from above.
  
  
--wenzelju1281965862
Content-Type: text/plain
Content-Disposition: attachment; filename="wenzelju-20100816133742.txt"

Index: loncom/interface/lonwishlist.pm
diff -u loncom/interface/lonwishlist.pm:1.2 loncom/interface/lonwishlist.pm:1.3
--- loncom/interface/lonwishlist.pm:1.2	Mon Aug 16 08:58:39 2010
+++ loncom/interface/lonwishlist.pm	Mon Aug 16 13:37:41 2010
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Routines to control the wishlist
 #
-# $Id: lonwishlist.pm,v 1.2 2010/08/16 08:58:39 wenzelju Exp $
+# $Id: lonwishlist.pm,v 1.3 2010/08/16 13:37:41 wenzelju Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -189,6 +189,20 @@
 }
 
 
+# Set a new path for an entry
+sub setNewPath {
+    my ($nodeindex, $newPath) = @_;
+    &getNodesToArray(\@childrenRt);
+    my $found = &Tree::getNodeByIndex($nodeindex, \@allNodes);
+    if ($found->value()->path()) {
+        $found->value()->path($newPath); 
+        return 1;
+    }
+    @allNodes = ();
+    return 0;
+}
+
+
 # Set a new note for an entry
 sub setNewNote {
     my ($nodeindex, $newNote) = @_;
@@ -352,6 +366,17 @@
     $inPageNewLink =~ s/\n//g;
     $inPageNewFolder =~ s/\n//g;
 
+    # it is checked, wether a path links to a LON-CAPA-resource or an external website. links to course-contents are not allowed
+    # because they probably will return a kind of 'no access' (unless the user is already in the course, the path links to).
+    # also importing these kind of links into a course does not make much sense.
+    # to find out if a path (not starting with /res/...) links to course-contents, the same filter as in lonwrapper is used,
+    # that means that it is checked wether a path contains .problem, .quiz, .exam etc.
+    # this is good for most cases but crashes as soon as a real external website contains one of this pattern in its URL.
+    # so maybe there's a better way to find out wether a given URL belongs to a LON-CAPA-server or not ...?
+    my $warningLinkNotAllowed1 = &mt('You can only insert links to LON-CAPA resources from the resource-pool '.
+                                    'or to external websites. Paths to LON-CAPA resources must be of the form /res/dom/usr... . '.
+                                    'Paths to external websites must contain the network protocol (e.g. http://...).');
+    my $warningLinkNotAllowed2 = &mt('The following link is not allowed: ');
     my $warningLink = &mt('You must insert a title and a path!');
     my $warningFolder = &mt('You must insert a title!');
     my $warningDelete = &mt('Are you sure you want to delete the selected entries? Deleting a folder also deletes all entries within this folder!');
@@ -370,6 +395,15 @@
                               +'if (!path || !title) {'
                               +'alert("$warningLink");'
                               +'return false;}'
+                              +'var linkOK = (path.match(/^http:(\\\\/\\\\/)/) || path.match(/^https:(\\\\/\\\\/)/))'
+                              +'&& !(path.match(/\\.problem/) || path.match(/\\.exam/)'
+                              +'|| path.match(/\\.quiz/) || path.match(/\\.assess/)'
+                              +'|| path.match(/\\.survey/) || path.match(/\\.form/)'
+                              +'|| path.match(/\\.library/) || path.match(/\\.page/)'
+                              +'|| path.match(/\\.sequence/));'
+                              +'if (!path.match(/^(\\\\/res\\\\/)/) && !linkOK) {'
+                              +'alert("$warningLinkNotAllowed1");'
+                              +'return false;}'
                               +'else {'
                               +'window.close();'
                               +'return true;}}'
@@ -409,9 +443,15 @@
             if (d) {
                 if (!confirm('$warningSave')) {
                     setAction('noSave');
+                    r = true;
+                }
+                else {
+                    r = linksOK();
                 }
             }
-            r = true;
+        }
+        else if (action == 'saveOK') {
+            r = linksOK();
         }
         document.getElementsByName('list')[0].setAttribute("action", "/adm/wishlist?mode="+mode); 
         if (r) {
@@ -433,6 +473,15 @@
                 return true;
             }
         }
+        var newpath = document.getElementsByName('newpath');
+        var i = 0;
+        for (i=0;i<newpath.length;i++) {
+            var newp = newpath[i].value;
+            var oldp = newpath[i].alt;
+            if (newp != oldp) {
+                return true;
+            }
+        }
         var newnote = document.getElementsByName('newnote');
         var i = 0;
         for (i=0;i<newnote.length;i++) {
@@ -445,6 +494,25 @@
         return false;
     }
 
+    function linksOK() {
+        var newpath = document.getElementsByName('newpath');
+        var i = 0;
+        for (i=0;i<newpath.length;i++) {
+            var path = newpath[i].value;
+            var linkOK = (path.match(/^http:\\/\\//) || path.match(/^https:\\/\\//))
+                         && !(path.match(/\\.problem/) || path.match(/\\.exam/)
+                         || path.match(/\\.quiz/) || path.match(/\\.assess/)
+                         || path.match(/\\.survey/) || path.match(/\\.form/)
+                         || path.match(/\\.library/) || path.match(/\\.page/)
+                         || path.match(/\\.sequence/));
+            if (!path.match(/^(\\/res\\/)/) && !linkOK) {
+                alert("$warningLinkNotAllowed1 $warningLinkNotAllowed2"+path);
+                return false;
+            }
+         }
+        return true;
+    }
+
     function onLoadAction(mode) {
         window.name = 'wishlist';
         if (mode == "edit") {
@@ -801,7 +869,13 @@
     }
 
     function preview(url) {
-       var newWin = window.open(url+'?inhibitmenu=yes','preview','width=560,height=350,scrollbars=yes');
+       var newWin;
+       if (!(url.match(/^http:\\/\\//) || url.match(/^https:\\/\\//))) {
+           newWin = window.open(url+'?inhibitmenu=yes','preview','width=560,height=350,scrollbars=yes');
+       }
+       else {
+           newWin = window.open(url,'preview','width=560,height=350,scrollbars=yes');
+       }
        newWin.focus();
     }
 
@@ -945,7 +1019,9 @@
                                  '<td id="padd'.$index.'" style="padding-left:'.(($indent-$indentConst)<0?0:($indent-$indentConst)).'px;">'.
                                  '<a href="javascript:;" onclick="folderAction('."'row".$index."'".')" style="vertical-align:top" >'.
                                  '<img src="/adm/lonIcons/arrow.closed.gif" id="img'.$index.'" alt = ""  class="LC_icon"/>'.
-                                 '<img src="/adm/lonIcons/navmap.folder.closed.gif" id="imgFolder'.$index.'" alt="folder"/></a>';
+                                 '<img src="/adm/lonIcons/navmap.folder.closed.gif" id="imgFolder'.$index.'" alt="folder"/></a>'.
+                                 '<input type="text" name="newtitle" value="'.$n->value()->title().'" alt = "'.$n->value()->title().'"/>'.
+                                 '</td><td></td>';
 
         }
         # entry is a link
@@ -953,12 +1029,11 @@
             $wishlistHTMLedit .= '<td><select class="LC_hidden" name="sel" id="sel'.$index.'" onchange="submitSelect();">'.
                                  $options.'</select></td>'.
                                  '<td id="padd'.$index.'" style="padding-left:'.(($indent-$indentConst)<=0?$indentConst:$indent).'px;">'.
-                                 '<img src="/res/adm/pages/wishlist-link.png" id="img'.$index.'" alt="link"/>';
+                                 '<img src="/res/adm/pages/wishlist-link.png" id="img'.$index.'" alt="link"/>'.
+                                 '<input type="text" name="newtitle" value="'.$n->value()->title().'" alt = "'.$n->value()->title().'"/></td>'.
+                                 '<td><input type="text" name="newpath" value="'.$n->value()->path().'" alt = "'.$n->value()->path().'"/></td>';
         }
-
-        # input-field for title
-        $wishlistHTMLedit .= '<input type="text" name="newtitle" value="'.$n->value()->title().'" alt = "'.$n->value()->title().'"/></td>';
-
+        
         # note-icon, different icons for an entries with note and those without
         my $noteIMG = 'anot.png';
 
@@ -974,7 +1049,7 @@
 
         # start row containing the textarea for the note
         $wishlistHTMLedit .= &Apache::loncommon::continue_data_table_row('LC_hidden','note'.$index).
-                             '<td></td><td></td><td>'.
+                             '<td></td><td></td><td colspan="2">'.
                              '<textarea id="noteText'.$index.'" cols="25" rows="3" style="width:100%" '.
                              'name="newnote">'.
                              $n->value()->note().'</textarea></td><td></td>';
@@ -1192,7 +1267,7 @@
     # icon for edit-mode, display when in view-mode
     if ($mode eq 'view') {
         $functions .= &Apache::lonhtmlcommon::add_item_funclist('<a href="javascript:;" '.
-                          'onclick="setFormAction('."'save','edit'".'); list.submit();" class="LC_menubuttons_link">'.
+                          'onclick="setFormAction('."'save','edit'".');" class="LC_menubuttons_link">'.
                           '<img src="/res/adm/pages/edit-mode-22x22.png" alt="'.$lt{'ed'}.'" '.
                           'title="'.$lt{'ed'}.'" class="LC_icon"/> '.
                           '<span class="LC_menubuttons_inline_text">'.$lt{'ed'}.'</span></a>');
@@ -1200,7 +1275,7 @@
     # icon for view-mode, display when in edit-mode
     else {
         $functions .= &Apache::lonhtmlcommon::add_item_funclist('<a href="javascript:;" '.
-                          'onclick="setFormAction('."'save','view'".'); list.submit();" class="LC_menubuttons_link">'.
+                          'onclick="setFormAction('."'save','view'".');" class="LC_menubuttons_link">'.
                           '<img src="/res/adm/pages/view-mode-22x22.png" alt="'.$lt{'vw'}.'" '.
                           'title="'.$lt{'vw'}.'" class="LC_icon"/> '.
                           '<span class="LC_menubuttons_inline_text">'.$lt{'vw'}.'</span></a>');
@@ -1236,7 +1311,7 @@
 
     # icon for saving changes
     $functions .= &Apache::lonhtmlcommon::add_item_funclist('<a href="javascript:;" '.
-                      'onclick="setFormAction('."'','".$mode."'".'); " class="LC_menubuttons_link">'.
+                      'onclick="setFormAction('."'saveOK','".$mode."'".'); " class="LC_menubuttons_link">'.
                       '<img src="/res/adm/pages/save-22x22.png" alt="'.$lt{'sv'}.'" '.
                       'title="'.$lt{'sv'}.'" class="LC_icon" />'.
                       '<span class="LC_menubuttons_inline_text">'.$lt{'sv'}.'</span></a>');
@@ -1479,9 +1554,12 @@
         # only save, if user wants to save changes
         # do not save, when current action is 'delete' or 'sort' or 'move' 
         my @newTitles = ();
+        my @newPaths = ();
         my @newNotes = ();
-        if ((defined $env{'form.newtitle'} || defined $env{'form.newnote'}) && ($env{'form.action'} ne 'noSave') && ($env{'form.action'} ne 'delete') && !$changeOrder) {
+        if ((defined $env{'form.newtitle'} || defined $env{'form.newpath'} || defined $env{'form.newnote'})
+            && ($env{'form.action'} ne 'noSave') && ($env{'form.action'} ne 'delete') && !$changeOrder) {
             @newTitles = &Apache::loncommon::get_env_multiple('form.newtitle');
+            @newPaths = &Apache::loncommon::get_env_multiple('form.newpath');
             @newNotes = &Apache::loncommon::get_env_multiple('form.newnote');
             my $node = 0;
             foreach my $t (@newTitles) {
@@ -1489,6 +1567,14 @@
                $node++;
             }
             $node = 0;
+            my $path = 0;
+            for (my $i = 0; $i < ($#newTitles+1); $i++ ) {
+               if (&setNewPath($node, $newPaths[$path])) {
+                     $path++;
+               }
+               $node++;
+            }
+            $node = 0;
             foreach my $n (@newNotes) {
                &setNewNote($node, $n);
                $node++;

--wenzelju1281965862--