[LON-CAPA-cvs] cvs: loncom(version_2_11_X) /interface lonuserutils.pm

raeburn raeburn at source.lon-capa.org
Thu Aug 22 15:31:21 EDT 2019


raeburn		Thu Aug 22 19:31:21 2019 EDT

  Modified files:              (Branch: version_2_11_X)
    /loncom/interface	lonuserutils.pm 
  Log:
  - For 2.11
    Backport 1.196, 1.197, 1.200
  
  
-------------- next part --------------
Index: loncom/interface/lonuserutils.pm
diff -u loncom/interface/lonuserutils.pm:1.184.4.3 loncom/interface/lonuserutils.pm:1.184.4.4
--- loncom/interface/lonuserutils.pm:1.184.4.3	Fri Jul 26 18:37:16 2019
+++ loncom/interface/lonuserutils.pm	Thu Aug 22 19:31:20 2019
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Utility functions for managing LON-CAPA user accounts
 #
-# $Id: lonuserutils.pm,v 1.184.4.3 2019/07/26 18:37:16 raeburn Exp $
+# $Id: lonuserutils.pm,v 1.184.4.4 2019/08/22 19:31:20 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -438,7 +438,7 @@
             } elsif ($context eq 'domain') {
                 $setsection_call = 'setCourse()';
                 $setsections_js = &dc_setcourse_js($param{'formname'},$mode,
-                                                   $context,$showcredits);
+                                                   $context,$showcredits,$domain);
             }
             $finish = "  var checkSec = $setsection_call\n".
                       "  if (checkSec == 'ok') {\n".
@@ -531,20 +531,24 @@
 /* regexp here to check for non \d \. in credits */
 END
     } else {
+        my ($numrules,$intargjs) =
+            &passwd_validation_js('vf.elements[current.argfield].value',$domain);
         $auth_checks .= (<<END);
     foundatype=1;
     if (current.argfield == null || current.argfield == '') {
+        // The login radiobutton checked does not have an associated textbox
+    } else if (vf.elements[current.argfield].value == '') {
         var alertmsg = '';
         switch (current.radiovalue) {
             case 'krb':
                 alertmsg = '$alert{'krb'}';
                 break;
             case 'loc':
-            case 'fsys':
+            case 'int':
                 alertmsg = '$alert{'ipass'}';
                 break;
             case 'fsys':
-                alertmsg = '';
+                alertmsg = '$alert{'ipass'}';
                 break;
             default:
                 alertmsg = '';
@@ -553,6 +557,10 @@
             alert(alertmsg);
             return;
         }
+    } else if (current.radiovalue == 'int') {
+        if ($numrules > 0) {
+$intargjs
+        }
     }
 END
     }
@@ -641,6 +649,136 @@
                  $section_checks.$authheader;
     return $result;
 }
+
+sub passwd_validation_js {
+    my ($currpasswdval,$domain) = @_;
+    my %passwdconf = &Apache::lonnet::get_passwdconf($domain);
+    my ($min,$max, at chars,$numrules,$intargjs,%alert);
+    $numrules = 0;
+    if (ref($passwdconf{'chars'}) eq 'ARRAY') {
+        if ($passwdconf{'min'} =~ /^\d+$/) {
+            $min = $passwdconf{'min'};
+            $numrules ++;
+        }
+        if ($passwdconf{'max'} =~ /^\d+$/) {
+            $max = $passwdconf{'max'};
+            $numrules ++;
+        }
+        @chars = @{$passwdconf{'chars'}};
+        if (@chars) {
+            $numrules ++;
+        }
+    } else {
+        $min = 7;
+        $numrules ++;
+    }
+    if (($min ne '') || ($max ne '') || (@chars > 0)) {
+        my $alertmsg = &mt('Initial password did not satisfy requirement(s):').'\n\n';
+        if ($min) {
+            $alert{'min'} = &mt('minimum [quant,_1,character]',$min).'\n';
+        }
+        if ($max) {
+            $alert{'max'} = &mt('maximum [quant,_1,character]',$max).'\n';
+        }
+        my (@charalerts, at charrules);
+        if (@chars) {
+            if (grep(/^uc$/, at chars)) {
+                push(@charalerts,&mt('contain at least one upper case letter'));
+                push(@charrules,'uc');
+            }
+            if (grep(/^lc$/, at chars)) {
+                push(@charalerts,&mt('contain at least one lower case letter'));
+                push(@charrules,'lc');
+            }
+            if (grep(/^num$/, at chars)) {
+                push(@charalerts,&mt('contain at least one number'));
+                push(@charrules,'num');
+            }
+            if (grep(/^spec$/, at chars)) {
+                push(@charalerts,&mt('contain at least one non-alphanumeric'));
+                push(@charrules,'spec');
+            }
+        }
+        $intargjs = qq|            var rulesmsg = '';\n|.
+                    qq|            var currpwval = $currpasswdval;\n|;
+            if ($min) {
+                $intargjs .= qq|
+            if (currpwval.length < $min) {
+                rulesmsg += ' - $alert{min}';
+            }
+|;
+            }
+            if ($max) {
+                $intargjs .= qq|
+            if (currpwval.length > $max) {
+                rulesmsg += ' - $alert{max}';
+            }
+|;
+            }
+            if (@chars > 0) {
+                my $charrulestr = '"'.join('","', at charrules).'"';
+                my $charalertstr = '"'.join('","', at charalerts).'"';
+                $intargjs .= qq|            var brokerules = new Array();\n|.
+                             qq|            var charrules = new Array($charrulestr);\n|.
+                             qq|            var charalerts = new Array($charalertstr);\n|;
+                my %rules;
+                map { $rules{$_} = 1; } @chars;
+                if ($rules{'uc'}) {
+                    $intargjs .= qq|
+            var ucRegExp = /[A-Z]/;
+            if (!ucRegExp.test(currpwval)) {
+                brokerules.push('uc');
+            }
+|;
+                }
+                if ($rules{'lc'}) {
+                    $intargjs .= qq|
+            var lcRegExp = /[a-z]/;
+            if (!lcRegExp.test(currpwval)) {
+                brokerules.push('lc');
+            }
+|;
+                }
+                if ($rules{'num'}) {
+                     $intargjs .= qq|
+            var numRegExp = /[0-9]/;
+            if (!numRegExp.test(currpwval)) {
+                brokerules.push('num');
+            }
+|;
+                }
+                if ($rules{'spec'}) {
+                     $intargjs .= q|
+            var specRegExp = /[!"#$%&'()*+,\-.\/:;<=>?@[\\^\]_`{\|}~]/;
+            if (!specRegExp.test(currpwval)) {
+                brokerules.push('spec');
+            }
+|;
+                }
+                $intargjs .= qq|
+            if (brokerules.length > 0) {
+                for (var i=0; i<brokerules.length; i++) {
+                    for (var j=0; j<charrules.length; j++) {
+                        if (brokerules[i] == charrules[j]) {
+                            rulesmsg += ' - '+charalerts[j]+'\\n';
+                            break;
+                        }
+                    }
+                }
+            }
+|;
+            }
+            $intargjs .= qq|
+            if (rulesmsg != '') {
+                rulesmsg = '$alertmsg'+rulesmsg;
+                alert(rulesmsg);
+                return false;
+            }
+|;
+    }
+    return ($numrules,$intargjs);
+}
+
 ###############################################################
 ###############################################################
 sub upload_manager_javascript_forward_associate {
@@ -4190,6 +4328,7 @@
     }
     my $amode  = '';
     my $genpwd = '';
+    my @genpwdfail;
     if ($env{'form.login'} eq 'krb') {
         $amode='krb';
         $amode.=$env{'form.krbver'};
@@ -4198,6 +4337,8 @@
         $amode='internal';
         if ((defined($env{'form.intarg'})) && ($env{'form.intarg'})) {
             $genpwd=$env{'form.intarg'};
+            @genpwdfail =
+                &Apache::loncommon::check_passwd_rules($domain,$genpwd);
         }
     } elsif ($env{'form.login'} eq 'loc') {
         $amode='localauth';
@@ -4276,7 +4417,6 @@
                                                   \@statuses,\@poss_roles);
                 &gather_userinfo($context,'view',\%userlist,$indexhash,\%info,
                              \%cstr_roles,$permission);
-
             }
         }
     }
@@ -4354,7 +4494,8 @@
         my $newuserdom = $env{'request.role.domain'};
         map { $cancreate{$_} = &can_create_user($newuserdom,$context,$_); } keys(%longtypes);
         # Get new users list
-        my (%existinguser,%userinfo,%disallow,%rulematch,%inst_results,%alerts,%checkuname);
+        my (%existinguser,%userinfo,%disallow,%rulematch,%inst_results,%alerts,%checkuname,
+            %showpasswdrules,$haspasswdmap);
         my $counter = -1;
         foreach my $line (@userdata) {
             $counter ++;
@@ -4482,12 +4623,44 @@
                         }
                     }
                     # determine user password
-                    my $password = $genpwd;
+                    my $password;
+                    my $passwdfromfile;
                     if (defined($fields{'ipwd'})) {
                         if ($entries{$fields{'ipwd'}}) {
                             $password=$entries{$fields{'ipwd'}};
+                            $passwdfromfile = 1;
+                            if ($env{'form.login'} eq 'int') {
+                                my $uhome=&Apache::lonnet::homeserver($username,$userdomain);
+                                if (($uhome eq 'no_host') || ($changeauth)) {
+                                    my @brokepwdrules =
+                                        &Apache::loncommon::check_passwd_rules($domain,$password);
+                                    if (@brokepwdrules) {
+                                        $disallow{$counter} = &mt('[_1]: Password included in file for this user did not meet requirements.',
+                                                                  '<b>'.$username.'</b>');
+                                        map { $showpasswdrules{$_} = 1; } @brokepwdrules;
+                                        next;
+                                    }
+                                }
+                            }
                         }
                     }
+                    unless ($passwdfromfile) {
+                        if ($env{'form.login'} eq 'int') {
+                            if (@genpwdfail) {
+                                my $uhome=&Apache::lonnet::homeserver($username,$userdomain);
+                                if (($uhome eq 'no_host') || ($changeauth)) {
+                                    $disallow{$counter} = &mt('[_1]: No specific password in file for this user; default password did not meet requirements',
+                                                              '<b>'.$username.'</b>');
+                                    unless ($haspasswdmap) {
+                                        map { $showpasswdrules{$_} = 1; } @genpwdfail;
+                                        $haspasswdmap = 1;
+                                    }
+                                }
+                                next;
+                            }
+                        }
+                        $password = $genpwd;
+                    }
                     # determine user role
                     my $role = '';
                     if (defined($fields{'role'})) {
@@ -4849,6 +5022,7 @@
                           $counts{'auth'})."</p>\n");
         }
         $r->print(&print_namespacing_alerts($domain,\%alerts,\%curr_rules));
+        $r->print(&passwdrule_alerts($domain,\%showpasswdrules));
         #####################################
         # Display list of students to drop  #
         #####################################
@@ -4918,6 +5092,38 @@
     }
 }
 
+sub passwdrule_alerts {
+    my ($domain,$passwdrules) = @_;
+    my $warning;
+    if (ref($passwdrules) eq 'HASH') {
+        my %showrules = %{$passwdrules};
+        if (keys(%showrules)) {
+            my %passwdconf = &Apache::lonnet::get_passwdconf($domain);
+            $warning = '<b>'.&mt('Password requirement(s) unmet for one or more users:').'</b><ul>';
+            if ($showrules{'min'}) {
+                $warning .= '<li>'.&mt('minimum [quant,_1,character]',$passwdconf{'min'}).'</li>';
+            }
+            if ($showrules{'max'}) {
+                $warning .= '<li>'.&mt('maximum [quant,_1,character]',$passwdconf{'max'}).'</li>';
+            }
+            if ($showrules{'uc'}) {
+                $warning .= '<li>'.&mt('contain at least one upper case letter').'</li>';
+            }
+            if ($showrules{'lc'}) {
+                $warning .= '<li>'.&mt('contain at least one lower case letter').'</li>';
+            }
+            if ($showrules{'num'}) {
+                $warning .= '<li>'.&mt('contain at least one number').'</li>';
+            }
+            if ($showrules{'spec'}) {
+                $warning .= '<li>'.&mt('contain at least one non-alphanumeric').'</li>';
+            }
+            $warning .= '</ul>';
+        }
+    }
+    return $warning;
+}
+
 sub user_change_result {
     my ($r,$userresult,$authresult,$roleresult,$idresult,$counts,$flushc,
         $username,$userdomain,$userchg) = @_;
@@ -5999,7 +6205,7 @@
 }
 
 sub dc_setcourse_js {
-    my ($formname,$mode,$context,$showcredits) = @_;
+    my ($formname,$mode,$context,$showcredits,$domain) = @_;
     my ($dc_setcourse_code,$authen_check);
     my $cctext = &Apache::lonnet::plaintext('cc');
     my $cotext = &Apache::lonnet::plaintext('co');
@@ -6008,7 +6214,7 @@
     if ($mode eq 'upload') {
         $role = 'courserole';
     } else {
-        $authen_check = &verify_authen($formname,$context);
+        $authen_check = &verify_authen($formname,$context,$domain);
     }
     $dc_setcourse_code = (<<"SCRIPTTOP");
 $authen_check
@@ -6152,12 +6358,14 @@
 }
 
 sub verify_authen {
-    my ($formname,$context) = @_;
+    my ($formname,$context,$domain) = @_;
     my %alerts = &authcheck_alerts();
     my $finish = "return 'ok';";
     if ($context eq 'author') {
         $finish = "document.$formname.submit();";
     }
+    my ($numrules,$intargjs) =
+        &passwd_validation_js('argpicked',$domain);
     my $outcome = <<"ENDSCRIPT";
 
 function auth_check() {
@@ -6191,6 +6399,7 @@
                 break;
             case 'int':
                 alertmsg = '$alerts{'ipass'}';
+                break;
             case 'fsys':
                 alertmsg = '$alerts{'ipass'}';
                 break;
@@ -6204,6 +6413,11 @@
             alert(alertmsg);
             return;
         }
+    } else if (logintype == 'int') {
+        var numrules = $numrules;
+        if (numrules > 0) {
+$intargjs
+        }
     }
     $finish
 }


More information about the LON-CAPA-cvs mailing list