[LON-CAPA-cvs] cvs: rat(version_2_11_2_uiuc) /client parameter.html loncom/html/adm/helper newslot.helper loncom/interface loncommon.pm lonparmset.pm

raeburn raeburn at source.lon-capa.org
Sat Mar 2 11:25:57 EST 2019


raeburn		Sat Mar  2 16:25:57 2019 EDT

  Modified files:              (Branch: version_2_11_2_uiuc)
    /loncom/interface	lonparmset.pm loncommon.pm 
    /loncom/html/adm/helper	newslot.helper 
    /rat/client	parameter.html 
  Log:
  - For 2.11.2 (modified)
    Use 2.12 feature: deny from specified IPs/Hosts as well as existing allow
    from for (a) slots with IP access control, (b) Client IP/Name (acc) param.
  
    Domain's configuration must be set to prohibit hosting of sessions for
    for user's domains outside own domain, and modification must be in place
    on all nodes in domain.
  
    lonparmset.pm: 1.548 (part), 1.549 (part), 1.551, 1.589, 1.590, 1.591
    loncommon.pm: 1.1219 (part) 
    parameter.html: 1.73, 1.74, 1.75
    newslot.helper 1.34
  
  
-------------- next part --------------
Index: loncom/interface/lonparmset.pm
diff -u loncom/interface/lonparmset.pm:1.522.2.23.2.2 loncom/interface/lonparmset.pm:1.522.2.23.2.3
--- loncom/interface/lonparmset.pm:1.522.2.23.2.2	Mon Jun 19 19:04:51 2017
+++ loncom/interface/lonparmset.pm	Sat Mar  2 16:25:45 2019
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler to set parameters for assessments
 #
-# $Id: lonparmset.pm,v 1.522.2.23.2.2 2017/06/19 19:04:51 raeburn Exp $
+# $Id: lonparmset.pm,v 1.522.2.23.2.3 2019/03/02 16:25:45 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -833,8 +833,12 @@
     my ($type,$dis,$value,$marker,$return,$call)=@_;
     my $winvalue=$value;
     unless ($winvalue) {
-    if (&isdateparm($type)) {
+        if ((&isdateparm($type)) || (&is_specialstring($type))) {
             $winvalue=$env{'form.recent_'.$type};
+        } elsif ($type eq 'string_yesno') {
+            if ($env{'form.recent_string'} =~ /^(yes|no)$/i) {
+                $winvalue=$env{'form.recent_string'};
+            }
         } else {
             $winvalue=$env{'form.recent_'.(split(/\_/,$type))[0]};
         }
@@ -867,12 +871,14 @@
     $pjump_def
 
     function psub() {
+        var specstring = /^string_!(yesno|any)/i;
         if (document.parmform.pres_marker.value!='') {
             document.parmform.action+='#'+document.parmform.pres_marker.value;
             var typedef=new Array();
             typedef=document.parmform.pres_type.value.split('_');
            if (document.parmform.pres_type.value!='') {
-            if (typedef[0]=='date') {
+            if ((typedef[0]=='date') ||
+                (specstring.test(document.parmform.pres_type.value))) {
                 eval('document.parmform.recent_'+
                      document.parmform.pres_type.value+
              '.value=document.parmform.pres_value.value;');
@@ -922,6 +928,72 @@
 COURSECONTENTSCRIPT
 }
 
+sub validateparms_js {
+    return <<'ENDSCRIPT';
+
+function validateParms() {
+    var ipallowRegExp = /^setipallow_/;
+    var ipdenyRegExp = /^setipdeny_/;
+    var patternIP = /[\[\]\*\.a-zA-Z\d\-]+/;
+    if ((document.parmform.elements.length != 'undefined')  && (document.parmform.elements.length) != 'null') {
+        if (document.parmform.elements.length) {
+            for (i=0; i<document.parmform.elements.length; i++) {
+                var name=document.parmform.elements[i].name;
+                if (ipallowRegExp.test(name)) {
+                    var identifier = name.replace(ipallowRegExp,'');
+                    var possallow = document.parmform.elements[i].value;
+                    possallow = possallow.replace(/^\s+|\s+$/g,'');
+                    if (patternIP.test(possallow)) {
+                        if (document.parmform.elements['set_'+identifier].value) {
+                            possallow = ','+possallow;
+                        }
+                        document.parmform.elements['set_'+identifier].value += possallow;
+                    }
+                } else if (ipdenyRegExp.test(name)) {
+                    var identifier = name.replace(ipdenyRegExp,'');
+                    var possdeny = document.parmform.elements[i].value;
+                    possdeny = possdeny.replace(/^\s+|\s+$/g,'');
+                    if (patternIP.test(possdeny)) {
+                        possdeny = '!'+possdeny;
+                        if (document.parmform.elements['set_'+identifier].value) {
+                            possdeny = ','+possdeny;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return true;
+}
+
+ENDSCRIPT
+}
+
+# Javascript initialization, for overview mode
+sub ipacc_boxes_js  {
+    my $remove = &mt('Remove');
+    return <<"END";
+\$(document).ready(function() {
+    var wrapper         = \$(".LC_string_ipacc_wrap");
+    var add_button      = \$(".LC_add_ipacc_button");
+    var ipaccRegExp     = /^LC_string_ipacc_/;
+
+    \$(add_button).click(function(e){
+        e.preventDefault();
+        var identifier = \$(this).closest("div").attr("id");
+        identifier = identifier.replace(ipaccRegExp,'');
+        \$(this).closest('div').find('.LC_string_ipacc_inner').append('<div><input type="text" name="setip'+identifier+'" /><a href="#" class="LC_remove_ipacc">$remove</a></div>');
+    });
+
+    \$(wrapper).delegate(".LC_remove_ipacc","click", function(e){
+        e.preventDefault(); \$(this).closest("div").remove();
+    })
+});
+
+
+END
+}
+
 sub done_proctor_js {
     return <<"END";
 function toggleSecret(form,radio,key) {
@@ -1315,6 +1387,14 @@
     return (($type=~/^date/) && (!($type eq 'date_interval')));
 }
 
+# Determine if parameter type is specialized string type (i.e.,
+# not just string or string_yesno.
+
+sub is_specialstring {
+    my $type=shift;
+    return (($type=~/^string_/) && (($type ne 'string_yesno')));
+}
+
 #
 # parmmenu displays a list of the selected parameters.
 # It also offers a link to show/hide the complete parameter list
@@ -2194,7 +2274,6 @@
         my ($got_chostname,$chostname,$cmajor,$cminor);
         my $totalstored = 0;
         my $now = time;
-
         for (my $i=0;$i<=$#markers;$i++) {
             my ($needsrelease,$needsnewer,$name);
             if ($markers[$i] =~ /^[\d.]+\&0_availablestudent\&(1|2|3)$/) {
@@ -2286,11 +2365,14 @@
 
     &startpage($r,$pssymb);
 
-    foreach ('tolerance','date_default','date_start','date_end',
-        'date_interval','int','float','string') {
+    foreach my $item ('tolerance','date_default','date_start','date_end',
+                      'date_interval','int','float','string','string_lenient',
+                      'string_examcode','string_deeplink','string_discussvote',
+                      'string_useslots','string_problemstatus','string_ip',
+                      'string_questiontype') {
         $r->print('<input type="hidden" value="'.
-          &HTML::Entities::encode($env{'form.recent_'.$_},'"&<>').
-          '" name="recent_'.$_.'" />');
+          &HTML::Entities::encode($env{'form.recent_'.$item},'"&<>').
+          '" name="recent_'.$item.'" />');
     }
 
     # ----- Start Parameter Selection
@@ -2902,6 +2984,7 @@
     if ($key =~ /^form\.([a-z]+)\_(.+)$/) {
         my $cmd=$1;
         my $thiskey=$2;
+        next if ($cmd eq 'setipallow' || $cmd eq 'setipdeny');
         my ($tuname,$tudom)=&extractuser($thiskey);
         my $tkey=$thiskey;
             if ($tuname) {
@@ -3314,6 +3397,68 @@
     return '<input type="text" name="set_'.$thiskey.'" value="'.$showval.'"'.$disabled.' />';
 }
 
+sub string_ip_selector {
+    my ($thiskey, $showval, $readonly) = @_;
+    my %access = (
+                   allow => [],
+                   deny  => [],
+                 );
+    if ($showval ne '') {
+        my @current;
+        if ($showval =~ /,/) {
+            @current = split(/,/,$showval);
+        } else {
+            @current = ($showval);
+        }
+        foreach my $item (@current) {
+            if ($item =~ /^\!([\[\]a-zA-Z\.\d\*\-]+)$/) {
+                push(@{$access{'deny'}},$1);
+            } elsif ($item =~ /^([\[\]a-zA-Z\.\d\*\-]+)$/) {
+                push(@{$access{'allow'}},$item);
+            }
+        }
+    }
+    if (!@{$access{'allow'}}) {
+        @{$access{'allow'}} = ('');
+    }
+    if (!@{$access{'deny'}}) {
+        @{$access{'deny'}} = ('');
+    }
+    my ($disabled,$addmore);
+    if ($readonly) {
+        $disabled=' disabled="disabled"';
+    } else {
+        $addmore = "\n".'<button class="LC_add_ipacc_button">'.&mt('Add more').'</button>';
+    }
+    my $output = '<input type="hidden" name="set_'.$thiskey.'" />
+<table><tr><th>'.&mt('Allow from').'</th><th>'.&mt('Deny from').'</th></tr><tr>';
+    foreach my $acctype ('allow','deny') {
+        $output .= '
+<td valign="top">
+<div class="LC_string_ipacc_wrap" id="LC_string_ipacc_'.$acctype.'_'.$thiskey.'">
+  <div class="LC_string_ipacc_inner">'."\n";
+        my $num = 0;
+        foreach my $curr (@{$access{$acctype}}) {
+            $output .= '<div><input type="text" name="setip'.$acctype.'_'.$thiskey.'" value="'.$curr.'"'.$disabled.' />';
+            if ($num > 0) {
+                $output .= '<a href="#" class="LC_remove_ipacc">'.&mt('Remove').'</a>';
+            }
+            $output .= '</div>'."\n";
+            $num ++;
+        }
+        $output .= '
+  </div>'.$addmore.'
+</div>
+</td>';
+   }
+   $output .= '
+</tr>
+</table>'."\n";
+    return $output;
+}
+
+{
+
 my %strings =
     (
      'string_yesno'
@@ -3341,7 +3486,10 @@
              => [['yes','Yes'],
                  ['notended','Yes, unless discussion ended'],
                  ['no','No']],
-     );
+     'string_ip'
+             => [['_allowfrom_','Hostname(s), or IP(s) from which access is allowed'],
+                 ['_denyfrom_','Hostname(s) or IP(s) from which access is disallowed']],
+    );
 
 sub standard_string_options {
     my ($string_type) = @_;
@@ -3382,6 +3530,10 @@
         }
     }
  
+    if ($thistype eq 'string_ip') {
+        return &string_ip_selector($thiskey,$showval,$readonly);
+    }
+
     my ($result,$disabled);
 
     if ($readonly) {
@@ -3435,6 +3587,55 @@
     return $result;
 }
 
+sub oldversion_warning {
+    my ($name,$value,$chostname,$cmajor,$cminor,$needsrelease) = @_;
+    my $desc;
+    my %stringtypes = (
+                        type         => 'string_questiontype',
+                        lenient      => 'string_lenient',
+                        retrypartial => 'string_yesno',
+                        discussvote  => 'string_discussvote',
+                        examcode     => 'string_examcode',
+                      );
+    if (exists($stringtypes{$name})) {
+        if ($name eq 'examcode') {
+            $desc = $value;
+        } elsif (ref($strings{$stringtypes{$name}}) eq 'ARRAY') {
+            foreach my $possibilities (@{ $strings{$stringtypes{$name}} }) {
+                next unless (ref($possibilities) eq 'ARRAY');
+                my ($parmval, $description) = @{ $possibilities };
+                if ($parmval eq $value) {
+                    $desc = $description;
+                    last;
+                }
+            }
+        }
+    } elsif (($name eq 'printstartdate') || ($name eq 'printenddate')) {
+        my $now = time;
+        if ($value =~ /^\d+$/) {
+            if ($name eq 'printstartdate') {
+                if ($value > $now) {
+                    $desc = &Apache::lonlocal::locallocaltime($value);
+                }
+            } elsif ($name eq 'printenddate') {
+                if ($value < $now) {
+                    $desc = &Apache::lonlocal::locallocaltime($value);
+                }
+            }
+        }
+    }
+    my $standard_name = &standard_parameter_names($name);
+    return '<p class="LC_warning">'.
+           &mt('[_1] was [_2]not[_3] set to [_4].',
+               $standard_name,'<b>','</b>','"'.$desc.'"').'<br />'.
+           &mt('LON-CAPA version ([_1]) installed on home server ([_2]) does not meet version requirements ([_3] or newer).',
+           $cmajor.'.'.$cminor,$chostname,
+           $needsrelease).
+           '</p>';
+}
+
+}
+
 #
 # Shift all start and end dates by $shift
 #
@@ -4907,53 +5108,6 @@
     return $needsnewer;
 }
 
-sub oldversion_warning {
-    my ($name,$value,$chostname,$cmajor,$cminor,$needsrelease) = @_;
-    my $desc;
-    my %stringtypes = (
-                        type         => 'string_questiontype',
-                        lenient      => 'string_lenient',
-                        retrypartial => 'string_yesno',
-                        discussvote  => 'string_discussvote',
-                        examcode     => 'string_examcode',
-                      );
-    if (exists($stringtypes{$name})) {
-        if ($name eq 'examcode') {
-            $desc = $value;
-        } elsif (ref($strings{$stringtypes{$name}}) eq 'ARRAY') {
-            foreach my $possibilities (@{ $strings{$stringtypes{$name}} }) {
-                next unless (ref($possibilities) eq 'ARRAY');
-                my ($parmval, $description) = @{ $possibilities };
-                if ($parmval eq $value) {
-                    $desc = $description;
-                    last;
-                }
-            }
-        }
-    } elsif (($name eq 'printstartdate') || ($name eq 'printenddate')) {
-        my $now = time;
-        if ($value =~ /^\d+$/) {
-            if ($name eq 'printstartdate') {
-                if ($value > $now) {
-                    $desc = &Apache::lonlocal::locallocaltime($value);
-                }
-            } elsif ($name eq 'printenddate') {
-                if ($value < $now) {
-                    $desc = &Apache::lonlocal::locallocaltime($value);
-                }
-            }
-        }
-    }
-    my $standard_name = &standard_parameter_names($name);
-    return '<p class="LC_warning">'.
-           &mt('[_1] was [_2]not[_3] set to [_4].',
-               $standard_name,'<b>','</b>','"'.$desc.'"').'<br />'.
-           &mt('LON-CAPA version ([_1]) installed on home server ([_2]) does not meet version requirements ([_3] or newer).',
-           $cmajor.'.'.$cminor,$chostname,
-           $needsrelease).
-           '</p>';
-}
-
 sub get_permission {
     my %permission;
     my $allowed = 0;
Index: loncom/interface/loncommon.pm
diff -u loncom/interface/loncommon.pm:1.1075.2.127 loncom/interface/loncommon.pm:1.1075.2.127.6.1
--- loncom/interface/loncommon.pm:1.1075.2.127	Sun Apr  2 03:09:27 2017
+++ loncom/interface/loncommon.pm	Sat Mar  2 16:25:45 2019
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common routines
 #
-# $Id: loncommon.pm,v 1.1075.2.127 2017/04/02 03:09:27 raeburn Exp $
+# $Id: loncommon.pm,v 1.1075.2.127.6.1 2019/03/02 16:25:45 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -4946,17 +4946,38 @@
     if (!defined($acc) || $acc =~ /^\s*$/ || $acc =~/^\s*no\s*$/i) {
         return 1;
     }
-    my $allowed=0;
+    my $allowed;
     my $ip=$ENV{'REMOTE_ADDR'} || $clientip || $env{'request.host'};
 
     my $name;
-    foreach my $pattern (split(',',$acc)) {
-        $pattern =~ s/^\s*//;
-        $pattern =~ s/\s*$//;
+    my %access = (
+                     allowfrom => 1,
+                     denyfrom  => 0,
+                 );
+    my @allows;
+    my @denies;
+    foreach my $item (split(',',$acc)) {
+        $item =~ s/^\s*//;
+        $item =~ s/\s*$//;
+        if ($item =~ /^\!(.+)$/) {
+            push(@denies,$1);
+        } else {
+            push(@allows,$item);
+        }
+    }
+    my $numdenies = scalar(@denies);
+    my $numallows = scalar(@allows);
+    my $count = 0;
+    foreach my $pattern (@denies, at allows) {
+        $count ++;
+        my $acctype = 'allowfrom';
+        if ($count <= $numdenies) {
+            $acctype = 'denyfrom';
+        }
         if ($pattern =~ /\*$/) {
             #35.8.*
             $pattern=~s/\*//;
-            if ($ip =~ /^\Q$pattern\E/) { $allowed=1; }
+            if ($ip =~ /^\Q$pattern\E/) { $allowed=$access{$acctype}; }
         } elsif ($pattern =~ /(\d+\.\d+\.\d+)\.\[(\d+)-(\d+)\]$/) {
             #35.8.3.[34-56]
             my $low=$2;
@@ -4964,7 +4985,7 @@
             $pattern=$1;
             if ($ip =~ /^\Q$pattern\E/) {
                 my $last=(split(/\./,$ip))[3];
-                if ($last <=$high && $last >=$low) { $allowed=1; }
+                if ($last <=$high && $last >=$low) { $allowed=$access{$acctype}; }
             }
         } elsif ($pattern =~ /^\*/) {
             #*.msu.edu
@@ -4974,10 +4995,10 @@
                 my $netaddr=inet_aton($ip);
                 ($name)=gethostbyaddr($netaddr,AF_INET);
             }
-            if ($name =~ /\Q$pattern\E$/i) { $allowed=1; }
+            if ($name =~ /\Q$pattern\E$/i) { $allowed=$access{$acctype}; }
         } elsif ($pattern =~ /\d+\.\d+\.\d+\.\d+/) {
             #127.0.0.1
-            if ($ip =~ /^\Q$pattern\E/) { $allowed=1; }
+            if ($ip =~ /^\Q$pattern\E/) { $allowed=$access{$acctype}; }
         } else {
             #some.name.com
             if (!defined($name)) {
@@ -4985,9 +5006,16 @@
                 my $netaddr=inet_aton($ip);
                 ($name)=gethostbyaddr($netaddr,AF_INET);
             }
-            if ($name =~ /\Q$pattern\E$/i) { $allowed=1; }
+            if ($name =~ /\Q$pattern\E$/i) { $allowed=$access{$acctype}; }
+        }
+        if ($allowed =~ /^(0|1)$/) { last; }
+    }
+    if ($allowed eq '') {
+        if ($numdenies && !$numallows) {
+            $allowed = 1;
+        } else {
+            $allowed = 0;
         }
-        if ($allowed) { last; }
     }
     return $allowed;
 }
Index: loncom/html/adm/helper/newslot.helper
diff -u loncom/html/adm/helper/newslot.helper:1.30 loncom/html/adm/helper/newslot.helper:1.30.6.1
--- loncom/html/adm/helper/newslot.helper:1.30	Wed Jul 24 18:21:46 2013
+++ loncom/html/adm/helper/newslot.helper	Sat Mar  2 16:25:52 2019
@@ -26,8 +26,32 @@
 	  my $name=$helper->{VARS}{'origname'};
 	  my %slot=&Apache::lonnet::get('slots', [$name], $cdom, $cnum);
 	  if (!ref($slot{$name})) { return $default; }
-	  if (!exists($slot{$name}{$which})) { return $default; }
-	  return $slot{$name}{$which};
+          if (($which eq 'ipdeny') || ($which eq 'ipallow')) {
+              if (!exists($slot{$name}{'ip'})) { return $default; }
+          } else {
+              if (!exists($slot{$name}{$which})) { return $default; }
+          }
+          if (($which eq 'ipdeny') || ($which eq 'ipallow')) {
+              my @allows;
+              my @denies;
+              foreach my $item (split(',',$slot{$name}{'ip'})) {
+                  $item =~ s/^\s*//;
+                  $item =~ s/\s*$//;
+                  if ($item =~ /^\!(.+)$/) {
+                      push(@denies,$1);
+                  } else {
+                      push(@allows,$item);
+                  }
+              }
+              if ($which eq 'ipdeny') {
+                  return join(',', at denies);
+              }
+              if ($which eq 'ipallow') {
+                  return join(',', at allows);
+              }
+          } else {
+              return $slot{$name}{$which};
+          }
       }
     </exec>
     <message>
@@ -229,14 +253,28 @@
     </choices>
     
     <message>
-	</p><p>IP restrictions:<br />         
+	</p><p>IP restrictions -- allow from all except:<br />         
     </message>
-    <string variable="ip" size="30">
+
+    <string variable="ipdeny" size="30">
       <validator>
           return undef;
       </validator>
       <defaultvalue>
-        return &{$helper->{DATA}{origslot}}('ip');
+        return &{$helper->{DATA}{origslot}}('ipdeny');
+      </defaultvalue>
+    </string>
+
+    <message>
+        </p><p>IP restrictions -- deny from all except: <br />   
+    </message>
+
+    <string variable="ipallow" size="30">
+      <validator>
+          return undef;
+      </validator>
+      <defaultvalue>
+        return &{$helper->{DATA}{origslot}}('ipallow');
       </defaultvalue>
     </string>
     <message>  </p>  </message>
@@ -326,12 +364,32 @@
 	    $slot{$which} = $helper->{'VARS'}{$which};
 	}
 
-	foreach my $which ('ip','description','maxspace','secret','symb') {
+	foreach my $which ('description','maxspace','secret','symb') {
 	    if ( $helper->{'VARS'}{$which} =~/\S/ ) {
 		$slot{$which} = $helper->{'VARS'}{$which};
 	    }
 	}
 
+        if ($helper->{'VARS'}{'ipdeny'} =~/\S/ ) {
+            foreach my $item (split(',',$helper->{'VARS'}{'ipdeny'})) {
+                $item =~ s/^\s*//;
+                $item =~ s/\s*$//;
+                $slot{'ip'} .= '!'.$item.',';
+            }
+        }
+
+        if ($helper->{'VARS'}{'ipallow'} =~/\S/ ) {
+            foreach my $item (split(',',$helper->{'VARS'}{'ipallow'})) {
+                $item =~ s/^\s*//;
+                $item =~ s/\s*$//;
+                $slot{'ip'} .= $item.',';
+            }
+        }
+
+        if ($slot{'ip'} ne '') {
+            $slot{'ip'} =~s /,$//;
+        }
+
         if ($helper->{'VARS'}{'type'} eq 'schedulable_student') {
             if (($helper->{'VARS'}{'reservationmsg'} eq 'only_student') ||
                ($helper->{'VARS'}{'reservationmsg'} eq 'student_and_user_notes_screen')) {
Index: rat/client/parameter.html
diff -u rat/client/parameter.html:1.71.2.1 rat/client/parameter.html:1.71.2.2
--- rat/client/parameter.html:1.71.2.1	Tue Jun 13 15:49:36 2017
+++ rat/client/parameter.html	Sat Mar  2 16:25:56 2019
@@ -5,7 +5,7 @@
 The LearningOnline Network with CAPA
 Parameter Input Window
 //
-// $Id: parameter.html,v 1.71.2.1 2017/06/13 15:49:36 raeburn Exp $
+// $Id: parameter.html,v 1.71.2.2 2019/03/02 16:25:56 raeburn Exp $
 //
 // Copyright Michigan State University Board of Trustees
 //
@@ -440,6 +440,61 @@
    draw();
 }
 
+function ipstringeval() {
+    var patternIp = /^([\[\]a-zA-Z\.\d\*\-]+)$/;
+    var acctypes = new Array;
+    acctypes = ['allow','deny'];
+    svalue = '';
+    for (var i=0; i<acctypes.length; i++) {
+        var items = choices.document.getElementsByName('setip'+acctypes[i]);
+        if (items.length > 0) {
+            for (var j=0; j<items.length; j++) {
+                if (items[j].type == "text") {
+                    var possip = items[j].value;
+                    possip = possip.replace(/^\s+|\s+$/g,'');
+                    if (patternIp.test(possip)) {
+                        if (acctypes[i] == 'deny') {
+                            possip = '!'+possip;
+                        }
+                        if (svalue == '') {
+                            svalue = possip;
+                        } else {
+                            svalue += ','+possip;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+function addIpRule(iptype) {
+    var frame = window.frames["choices"];
+    if (frame.document.getElementById('LC_string_ipacc_inner_'+iptype)) {
+        var innerDiv = frame.document.getElementById('LC_string_ipacc_inner_'+iptype);
+        var count = innerDiv.childNodes.length
+        var ipDiv = frame.document.createElement('div');
+        ipDiv.innerHTML = '<input type="text" size="10" name="setip'+iptype+'" onblur="parent.ipstringeval();" />'+
+                          '<a href="#" onclick="parent.removeIpRule(\''+iptype+'\',\''+count+'\')">Remove</a>';
+        frame.document.getElementById('LC_string_ipacc_inner_'+iptype).appendChild(ipDiv);
+    }
+    return false;
+}
+
+function removeIpRule(iptype,num) {
+    var frame = window.frames["choices"];
+    if (frame.document.getElementById('LC_string_ipacc_inner_'+iptype)) {
+        var innerDiv = frame.document.getElementById('LC_string_ipacc_inner_'+iptype);
+        for (var i=0; i<innerDiv.childNodes.length; i++) {
+            if (i==num) {
+                innerDiv.removeChild(innerDiv.childNodes[i]);
+                ipstringeval();
+                break;
+            }
+        }
+    }
+}
+
 function radiostringeval(newval) {
    svalue=newval;
    draw();
@@ -490,7 +545,11 @@
       choicewrite(' action="javascript:floateval();"');
    }
    if (ptype=='string') {
-      choicewrite(' action="javascript:stringeval();"');
+      if (pscat == 'ip') {
+          choicewrite(' action="javascript:ipstringeval();"');
+      } else {
+          choicewrite(' action="javascript:stringeval();"');
+      }
    }
    if (ptype != 'int' && ptype != 'float' && ptype != 'string') {
        choicewrite(' action=""');
@@ -841,10 +900,51 @@
            choicewrite(' /> No</label><br />');
         }
         if (pscat=='ip') {
-           tablestart('IP Number/Name');
-	   choicewrite('<tr><td>Value:</td><td colspan="2">');
-           choicewrite('<input name="stringval" size="20" value="'+escapeHTML(svalue)+
-                    '" onchange="parent.stringeval()" />');
+            var currallow = new Array;
+            var currdeny = new Array;
+            if ((svalue != '') && (svalue != null)) {
+                var patternComma = /,/;
+                var patternAllow = /^([\[\]a-zA-Z\.\d\*\-]+)$/;
+                var patternDeny = /^\!([\[\]a-zA-Z\.\d\*\-]+)$/;
+                var current = new Array;
+                if (patternComma.test(svalue)) { 
+                    current = svalue.split(',');
+                } else {
+                    current = [svalue];
+                }
+                for (var i=0; i<current.length; i++) {
+                    if (patternDeny.test(current[i])) {
+                        var denied = current[i].replace(/^!/,'');
+                        currdeny.push(denied);
+                    } else {
+                        if (patternAllow.test(current[i])) {
+                            currallow.push(current[i]);
+                        }
+                    }
+                }
+            }
+            if (currdeny.length == 0) {
+                currdeny = ('');
+            }
+            if (currallow.length == 0) {
+                currallow = ('');
+            }
+            var curripaccess = [currallow,currdeny];
+            tablestart('IP Number/Name');
+            choicewrite('<tr><th>Allow from</th><th>Deny from</th></tr><tr>');
+            var acctypes = ['allow','deny'];
+            for (var i=0; i<acctypes.length; i++) {
+                choicewrite('<td valign="top">'+
+                            '<div class="LC_string_ipacc_wrap" id="LC_string_ipacc_'+acctypes[i]+'">'+
+                            '<div class="LC_string_ipacc_inner" id="LC_string_ipacc_inner_'+acctypes[i]+'">');
+                for (var j=0; j<curripaccess[i].length; j++) {
+                    choicewrite('<div><input type="text" size="10" name="setip'+acctypes[i]+'" value="'+curripaccess[i][j]+'" onblur="parent.ipstringeval();" />');
+                    choicewrite('<a href="#" onclick="parent.removeIpRule(\''+acctypes[i]+'\',\''+j+'\')">Remove</a>');
+                    choicewrite('</div>');
+                }
+                choicewrite('</div><button onclick="parent.addIpRule(\''+acctypes[i]+'\');">Add item</button>');
+            }
+            choicewrite('</div></td></tr></table>');
         }
         if (pscat=='fileext') {
             tablestart('Allowed File Extensions');


More information about the LON-CAPA-cvs mailing list