Diff for /loncom/interface/resetpw.pm between versions 1.43 and 1.44

version 1.43, 2019/02/08 19:57:29 version 1.44, 2019/04/24 01:44:30
Line 55  use Apache::Constants qw(:common); Line 55  use Apache::Constants qw(:common);
 use Apache::lonacc;  use Apache::lonacc;
 use Apache::lonnet;  use Apache::lonnet;
 use Apache::loncommon;  use Apache::loncommon;
   use Apache::lonpreferences;
 use Apache::lonlocal;  use Apache::lonlocal;
 use LONCAPA;  use LONCAPA;
 use HTML::Entities;  use HTML::Entities;
Line 92  sub handler { Line 93  sub handler {
     $uname =~ s/^\s+|\s+$//g;      $uname =~ s/^\s+|\s+$//g;
     $uname = &LONCAPA::clean_username($uname);      $uname = &LONCAPA::clean_username($uname);
     my $udom = &LONCAPA::clean_domain($env{'form.udom'});      my $udom = &LONCAPA::clean_domain($env{'form.udom'});
     my ($domdesc,$otherinst);      my ($domdesc,$otherinst,$lookup);
     if ($udom) {      if ($udom) {
         $domdesc = &Apache::lonnet::domain($udom,'description');          $domdesc = &Apache::lonnet::domain($udom,'description');
         if ($domdesc) {          if ($domdesc) {
             $otherinst = 1;              $otherinst = 1;
             my @ids=&Apache::lonnet::current_machine_ids();              my @ids=&Apache::lonnet::current_machine_ids();
             my %servers = &Apache::lonnet::internet_dom_servers($udom);              my %servers = &Apache::lonnet::internet_dom_servers($udom);
             foreach my $server (keys(%servers)) {              foreach my $hostid (keys(%servers)) {
                 if (grep(/^\Q$server\E$/,@ids)) {                  if (grep(/^\Q$hostid\E$/,@ids)) {
                     $otherinst = 0;                      $otherinst = 0;
                     last;                      last;
                 }                  }
             }              }
         }          }
     }      }
       my $dom_in_effect = $defdom;
       if (($udom ne '') && ($domdesc ne '')) {
           unless ($otherinst) {
               $dom_in_effect = $udom;
           }
       }
       my %passwdconf = &Apache::lonnet::get_passwdconf($dom_in_effect);
     my $token = $env{'form.token'};      my $token = $env{'form.token'};
       my $useremail = $env{'form.useremail'};
       if (($udom ne '') && (!$otherinst) && (!$token)) {
           if ($uname ne '') {
               my $uhome = &Apache::lonnet::homeserver($uname,$udom);
               if ($uhome eq 'no_host') {
                   my %srch = (srchby     => 'uname_ci',
                               srchdomain => $udom,
                               srchterm   => $uname,
                               srchtype   => 'exact');
                   my %srch_results = &Apache::lonnet::usersearch(\%srch);
                   if (keys(%srch_results) > 1) {
                       $lookup = 'nonunique';
                       if ($useremail =~ /^[^\@]+\@[^\@]+\.[^\@\.]+$/) {
                           foreach my $key (keys(%srch_results)) {
                               if (ref($srch_results{$key}) eq 'HASH') {
                                   if ($srch_results{$key}{permanentemail} =~ /^\Q$useremail\E$/i) {
                                       ($uname) = split(/:/,$key);
                                       undef($lookup);
                                       last;
                                   }
                               }
                           }
                       }
                   } elsif (keys(%srch_results) == 1) {
                       my $match = (keys(%srch_results))[0];
                       ($uname) = split(/:/,$match);
                   } else {
                       $lookup = 'nomatch';
                   }
               }
           }
           if (($lookup eq 'nomatch') || ($uname eq '')) {
               if (($useremail =~ /^[^\@]+\@[^\@]+\.[^\@\.]+$/) &&
                   ($passwdconf{'resetprelink'} eq 'either')) {
                   my %srch = (srchby     => 'email',
                               srchdomain => $udom,
                               srchterm   => $useremail,
                               srchtype   => 'exact');
                   my %srch_results = &Apache::lonnet::usersearch(\%srch);
                   if (keys(%srch_results) > 1) {
                       $lookup = 'nonunique';
                   } elsif (keys(%srch_results) == 1) {
                       my $match = (keys(%srch_results))[0];
                       ($uname) = split(/:/,$match);
                       undef($lookup);
                   } else {
                       $lookup = 'nomatch';
                   }
               }
           }
       }
     my $brcrum = [];      my $brcrum = [];
     if ($token) {      if ($token) {
         push (@{$brcrum},          push (@{$brcrum},
Line 157  sub handler { Line 216  sub handler {
             thdo  => 'The domain you have selected is for another institution.',              thdo  => 'The domain you have selected is for another institution.',
             yowi  => 'You will be switched to the Forgot Password utility at that institution.',              yowi  => 'You will be switched to the Forgot Password utility at that institution.',
             unam  => 'You must enter a username.',              unam  => 'You must enter a username.',
             mail  => 'You must enter an e-mail address.'              mail  => 'You must enter an e-mail address.',
               eith  => 'Enter a username and/or an e-mail address.',
         );          );
         &js_escape(\%js_lt);          &js_escape(\%js_lt);
         $js = <<"END";          $js = <<"END";
 <script type="text/javascript">  
 // <![CDATA[  
 function verifyDomain(caller,form) {  function verifyDomain(caller,form) {
     var redirect = 1;       var redirect = 1; 
     var instdoms = new Array($instdomstr);      var instdoms = new Array($instdomstr);
Line 174  function verifyDomain(caller,form) { Line 232  function verifyDomain(caller,form) {
             }              }
         }          }
     }      }
       if (redirect == 0) {
           if (caller.options[caller.selectedIndex].value != '$dom_in_effect') {
               document.forgotpw.uname.value = '';
               document.forgotpw.useremail.value = '';
               form.submit();
           }
       }
     if (redirect == 1) {      if (redirect == 1) {
         if (confirm('$js_lt{thdo}\\n$js_lt{yowi}')) {          if (confirm('$js_lt{thdo}\\n$js_lt{yowi}')) {
             form.submit();              form.submit();
           } else {
               for (var i=0; i<caller.options.length; i++) { 
                   if (caller.option[i].value == '$dom_in_effect') {
                       caller.selectedIndex = i;
                       break;
                   }
               }
         }          }
     }      }
     return;      return;
 }  }
   
   END
           if ($passwdconf{resetprelink} eq 'either') {
               $js .= <<"END";
   function validInfo() {
       if ((document.forgotpw.uname.value == '') &&
           (document.forgotpw.useremail.value == '')) {
           alert("$js_lt{'eith'}");
           return false;
       }
       return true;
   }
   END
           } else {
               $js .= <<"END";
   
 function validInfo() {  function validInfo() {
     if (document.forgotpw.uname.value == '') {      if (document.forgotpw.uname.value == '') {
         alert("$js_lt{'unam'}");          alert("$js_lt{'unam'}");
Line 193  function validInfo() { Line 280  function validInfo() {
     }      }
     return true;      return true;
 }  }
 // ]]>  
 </script>  
 END  END
           }
       }
       $js = &Apache::lonhtmlcommon::scripttag($js);
       if (($passwdconf{'captcha'} eq 'recaptcha') && ($passwdconf{'recaptchaversion'} >=2)) {
           $js.= "\n".'<script src="https://www.google.com/recaptcha/api.js"></script>'."\n";
     }      }
     my $header = &Apache::loncommon::start_page('Reset password',$js,$args).      my $header = &Apache::loncommon::start_page('Reset password',$js,$args).
                  '<h2>'.&mt('Reset forgotten LON-CAPA password').'</h2>';                   '<h2>'.&mt('Reset forgotten LON-CAPA password').'</h2>';
     my $output;      my $output;
     if ($token) {      if ($token) {
         $r->print($header);          $r->print($header);
         &reset_passwd($r,$token,$contact_name,$contact_email);          &reset_passwd($r,$token,$contact_name,$contact_email,\%passwdconf);
         $r->print(&Apache::loncommon::end_page());          $r->print(&Apache::loncommon::end_page());
         return OK;          return OK;
     } elsif ($udom) {      } elsif ($udom) {
Line 211  END Line 301  END
                                      $contact_name,$contact_email);                                        $contact_name,$contact_email); 
         } elsif ($otherinst) {          } elsif ($otherinst) {
             ($header,$output) = &homeserver_redirect($uname,$udom,$domdesc,$brcrum);              ($header,$output) = &homeserver_redirect($uname,$udom,$domdesc,$brcrum);
         } elsif ($uname) {          } elsif (($uname) || ($useremail)) {
             my $authtype = &Apache::lonnet::queryauthenticate($uname,$udom);              my $earlyout;
             if ($authtype =~ /^internal/) {              unless ($passwdconf{'captcha'} eq 'unused') {
                 my $useremail = $env{'form.useremail'};                  my ($captcha_chk,$captcha_error) =
                 my ($blocked,$blocktext) =                      &Apache::loncommon::captcha_response('passwords',$server);
                     &Apache::loncommon::blocking_status('passwd',$uname,$udom);                  if ($captcha_chk != 1) {
                 if ($blocked) {                      my $error = 'captcha'; 
                     $output = '<p class="LC_warning">'.$blocktext.'</p>'                      if ($passwdconf{'captcha'} eq 'recaptcha') {
                               .&display_actions($contact_email,$domdesc);                          $error = 'recaptcha';
                 } elsif ($useremail !~ /^[^\@]+\@[^\@]+\.[^\@\.]+$/) {                      }
                     $output = &invalid_state('baduseremail',$domdesc,                      $output = &invalid_state($error,$domdesc,
                                              $contact_name,$contact_email);                                               $contact_name,$contact_email);
                 } else {                      $earlyout = 1;
                     my %userinfo =                   }
                 &Apache::lonnet::get('environment',\@emailtypes,              }
      $udom,$uname);              unless ($earlyout) {
                     my @allemails;                  if ($lookup) {
                     foreach my $type (@emailtypes) {                      $output = &invalid_state($lookup,$domdesc,
                         my $email = $userinfo{$type};                                               $contact_name,$contact_email);
                         my @items;                      $earlyout = 1;
                         if ($email =~ /,/) {                  }
                             @items = split(',',$userinfo{$type});              }
                         } else {              unless ($earlyout) {
                             @items = ($email);                  my $authtype = &Apache::lonnet::queryauthenticate($uname,$udom);
                         }                  if ($authtype =~ /^internal/) {
                         foreach my $item (@items) {                      my ($blocked,$blocktext) =
                             if ($item =~ /^[^\@]+\@[^\@]+\.[^\@\.]+$/) {                          &Apache::loncommon::blocking_status('passwd',$uname,$udom);
                                 unless(grep(/^\Q$item\E$/,@allemails)) {                       if ($blocked) {
                                     push(@allemails,$item);                          $output = '<p class="LC_warning">'.$blocktext.'</p>'
                                     .&display_actions($contact_email,$domdesc);
                       } elsif (($passwdconf{'resetprelink'} ne 'either') && 
                                ($useremail !~ /^[^\@]+\@[^\@]+\.[^\@\.]+$/)) {
                           $output = &invalid_state('baduseremail',$domdesc,
                                                    $contact_name,$contact_email);
                       } else {
                           my %userinfo = 
                       &Apache::lonnet::get('environment',\@emailtypes,
            $udom,$uname);
                           my @allemails;
                           foreach my $type (@emailtypes) {
                               if (ref($passwdconf{resetemail}) eq 'ARRAY') {
                                   if ($type eq 'permanentemail') {
                                       next unless (grep(/^permanent$/,@{$passwdconf{resetemail}}));
                                   } elsif ($type eq 'critnotification') {
                                       next unless (grep(/^critical$/,@{$passwdconf{resetemail}}));
                                   } elsif ($type eq 'notification') {
                                       next unless (grep(/^notify$/,@{$passwdconf{resetemail}}));
                                   }
                               }
                               my $email = $userinfo{$type};
                               my @items;
                               if ($email =~ /,/) {
                                   @items = split(',',$userinfo{$type});
                               } else {
                                   @items = ($email);
                               }
                               foreach my $item (@items) {
                                   if ($item =~ /^[^\@]+\@[^\@]+\.[^\@\.]+$/) {
                                       unless (grep(/^\Q$item\E$/i,@allemails)) { 
                                           push(@allemails,$item);
                                       }
                                 }                                  }
                             }                              }
                         }                          }
                     }                          if (@allemails > 0) {
                     if (@allemails > 0) {                              my ($sendto,$warning,$timelimit);
                         if (grep(/^\Q$useremail\E$/,@allemails)) {                              my $timelimit = 2;
                             $output = &send_token($uname,$udom,$useremail,$server,                              if ($passwdconf{'resetlink'} =~ /^\d+(|\.\d*)$/) {
                                                   $domdesc,$contact_name,                                  $timelimit = $passwdconf{'resetlink'};
                                                   $contact_email);                              }
                               if ($passwdconf{'resetprelink'} eq 'either') {
                                   if ($useremail ne '') {
                                       if (grep(/^\Q$useremail\E$/i,@allemails)) {
                                           $sendto = $useremail;
                                       } else {
                                           $warning = &mt('The e-mail address you entered did not match the expected e-mail address.');
                                       }
                                   } elsif (@allemails > 1) {
                                       $warning = &mt('More than one e-mail address is associated with your username, and one has been selected to receive the message sent by LON-CAPA.');
                                   }
                                   unless ($sendto) {
                                       $sendto = $allemails[0];
                                   }
                               } else {
                                   if (grep(/^\Q$useremail\E$/i,@allemails)) {
                                       $sendto = $useremail;
                                   } else {
                                       $output = &invalid_state('mismatch',$domdesc,
                                                                $contact_name,
                                                                $contact_email);
                                   }
                               }
                               if ($sendto) {
                                   $output = &send_token($uname,$udom,$sendto,$server,
                                                         $domdesc,$contact_name,
                                                         $contact_email,$timelimit,$warning);
                               }
                         } else {                          } else {
                             $output = &invalid_state('mismatch',$domdesc,                              $output = &invalid_state('missing',$domdesc,
                                                      $contact_name,                                                       $contact_name,$contact_email);
                                                      $contact_email);  
                         }                          }
                     } else {  
                         $output = &invalid_state('missing',$domdesc,  
                                                  $contact_name,$contact_email);  
                     }                      }
                 }                  } elsif ($authtype =~ /^(krb|unix|local)/) {
             } elsif ($authtype =~ /^(krb|unix|local)/) {                       $output = &invalid_state('authentication',$domdesc,
                 $output = &invalid_state('authentication',$domdesc,  
                                          $contact_name,$contact_email);  
             } else {  
                 $output = &invalid_state('invalid',$domdesc,  
                                          $contact_name,$contact_email);                                           $contact_name,$contact_email);
                   } else {
                       $output = &invalid_state('invalid',$domdesc,
                                                $contact_name,$contact_email);
                   }
             }              }
         } else {          } else {
             $output = &get_uname($defdom);              $output = &get_uname($server,$dom_in_effect,\%passwdconf);
         }          }
     } else {      } else {
         $output = &get_uname($defdom);          $output = &get_uname($server,$defdom,\%passwdconf);
     }      }
     $r->print($header.$output);      $r->print($header.$output);
     $r->print(&Apache::loncommon::end_page());      $r->print(&Apache::loncommon::end_page());
Line 278  END Line 423  END
 }  }
   
 sub get_uname {  sub get_uname {
     my ($defdom) = @_;      my ($server,$defdom,$passwdconf) = @_;
       return unless (ref($passwdconf) eq 'HASH');
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
                                          unam => 'LON-CAPA username',              unam => 'LON-CAPA username',
                                          udom => 'LON-CAPA domain',              udom => 'LON-CAPA domain',
                                          uemail => 'E-mail address in LON-CAPA',              uemail => 'E-mail address in LON-CAPA',
                                          proc => 'Proceed');              vali   => 'Validation',
               proc => 'Proceed');
     my $msg = &mt('If you use the same account for other campus services besides LON-CAPA, (e.g., e-mail, course registration, etc.), a separate centrally managed mechanism likely exists to reset a password. However, if your account is used for just LON-CAPA access you will probably be able to reset a password from this page.');      my $msg;
     $msg .= '<br /><br />'.&mt('Three conditions must be met:')      unless ($passwdconf->{'resetremove'}) {
           $msg = '<p>'.&mt('If you use the same account for other campus services besides LON-CAPA, (e.g., e-mail, course registration, etc.), a separate centrally managed mechanism likely exists to reset a password. However, if your account is used for just LON-CAPA access you will probably be able to reset a password from this page.').'</p>';
       }
       if ($passwdconf->{'resetcustom'} eq "/res/$defdom/$defdom-domainconfig/customtext/resetpw/resetpw.html") {
           my $contents = &Apache::lonnet::getfile(&Apache::lonnet::filelocation('',$passwdconf->{'resetcustom'}));
           unless ($contents eq '-1') {
               $msg .= $contents;
           }
       }
       $msg .= '<p>'.&mt('Three conditions must be met:')
            .'<ul><li>'.&mt('An e-mail address must have previously been associated with your LON-CAPA username.').'</li>'             .'<ul><li>'.&mt('An e-mail address must have previously been associated with your LON-CAPA username.').'</li>'
            .'<li>'.&mt('You must be able to access e-mail sent to that address.').'</li>'             .'<li>'.&mt('You must be able to access e-mail sent to that address.').'</li>'
            .'<li>'.&mt('Your LON-CAPA account must be of a type for which LON-CAPA can reset a password.')             .'<li>'.&mt('Your LON-CAPA account must be of a type for which LON-CAPA can reset a password.')
            .'</ul>';             .'</ul></p>';
     my $mobileargs;  
     (undef,undef,undef,undef,undef,undef,my $clientmobile) =  
         &Apache::loncommon::decode_user_agent();  
     if ($clientmobile) {  
         $mobileargs = 'autocapitalize="off" autocorrect="off" ';  
     }  
     my $onchange = 'javascript:verifyDomain(this,this.form);';      my $onchange = 'javascript:verifyDomain(this,this.form);';
     $msg .= '<form name="forgotpw" method="post" action="/adm/resetpw" onsubmit="return validInfo();">'.      $msg .= '<form name="forgotpw" method="post" action="/adm/resetpw" onsubmit="return validInfo();">'.
             &Apache::lonhtmlcommon::start_pick_box().               &Apache::lonhtmlcommon::start_pick_box().
             &Apache::lonhtmlcommon::row_title($lt{'unam'}).  
             '<input type="text" name="uname" size="20" '.$mobileargs.'/>'.  
             &Apache::lonhtmlcommon::row_closure(1).  
             &Apache::lonhtmlcommon::row_title($lt{'udom'}).              &Apache::lonhtmlcommon::row_title($lt{'udom'}).
             &Apache::loncommon::select_dom_form($defdom,'udom',undef,undef,$onchange).              &Apache::loncommon::select_dom_form($defdom,'udom',undef,undef,$onchange).
             &Apache::lonhtmlcommon::row_closure(1).              &Apache::lonhtmlcommon::row_closure(1).
               &Apache::lonhtmlcommon::row_title($lt{'unam'}).
               '<input type="text" name="uname" size="20" autocapitalize="off" autocorrect="off" />'.
               &Apache::lonhtmlcommon::row_closure(1).
             &Apache::lonhtmlcommon::row_title($lt{'uemail'}).              &Apache::lonhtmlcommon::row_title($lt{'uemail'}).
             '<input type="text" name="useremail" size="30" '.$mobileargs.'/>'.              '<input type="text" name="useremail" size="30" autocapitalize="off" autocorrect="off" />'.
             &Apache::lonhtmlcommon::end_pick_box().              &Apache::lonhtmlcommon::row_closure(1);
       unless ($passwdconf->{'captcha'} eq 'notused') {
           my ($captcha_form,$captcha_error,$captcha,$recaptcha_version) =
               &Apache::loncommon::captcha_display('passwords',$server,$defdom);
           if ($captcha_form) {
               $msg .= &Apache::lonhtmlcommon::row_title($lt{'vali'}).
                       $captcha_form."\n".
                       &Apache::lonhtmlcommon::row_closure(1);
           }
       }
       $msg .= &Apache::lonhtmlcommon::end_pick_box().
             '<br /><br /><input type="submit" name="resetter" value="'.$lt{'proc'}.'" /></form>';              '<br /><br /><input type="submit" name="resetter" value="'.$lt{'proc'}.'" /></form>';
     return $msg;      return $msg;
 }  }
   
 sub send_token {  sub send_token {
     my ($uname,$udom,$email,$server,$domdesc,$contact_name,      my ($uname,$udom,$email,$server,$domdesc,$contact_name,
         $contact_email) = @_;          $contact_email,$timelimit,$warning) = @_;
     my $msg =      my $msg =
         '<p class="LC_info">'          '<p class="LC_info">'
        .&mt('Thank you for your request to reset the password for your LON-CAPA account.')         .&mt('Thank you for your request to reset the password for your LON-CAPA account.')
Line 342  sub send_token { Line 501  sub send_token {
             $msg .=              $msg .=
                 &mt('An e-mail sent to the e-mail address associated with your LON-CAPA account includes the web address for the link you should use to complete the reset process.')                  &mt('An e-mail sent to the e-mail address associated with your LON-CAPA account includes the web address for the link you should use to complete the reset process.')
                .'<br /><br />'                 .'<br /><br />'
                .&mt('The link included in the message will be valid for the next [_1]two[_2] hours.','<b>','</b>');                 .&mt('The link included in the message will be valid for the next [_1][quant,_2,hour][_3].','<b>',$timelimit,'</b>');
         } else {          } else {
             $msg .=              $msg .=
                 '<p class="LC_error">'                  '<p class="LC_error">'
Line 393  sub invalid_state { Line 552  sub invalid_state {
               .'</p>';                .'</p>';
         $msg .= &display_actions($contact_email,$domdesc);          $msg .= &display_actions($contact_email,$domdesc);
     } else {      } else {
         if ($error eq 'baduseremail') {          if ($error eq 'captcha') {
               $msg = &mt('Validation of the code you entered failed');
           } elsif ($error eq 'recaptcha') {
               $msg = &mt('Validation of human, not robot, failed'); 
           } elsif ($error eq 'nonunique') {
               $msg = &mt('More than one username was identified from the information you provided; try providing both a username and e-mail address');
           } elsif ($error eq 'nomatch') {
               $msg = &mt('A valid user could not be identified from the username and/or e-mail address you provided');
           } elsif ($error eq 'baduseremail') {
             $msg = &mt('The e-mail address you provided does not appear to be a valid address.');              $msg = &mt('The e-mail address you provided does not appear to be a valid address.');
         } elsif ($error eq 'mismatch') {          } elsif ($error eq 'mismatch') {
             $msg = &mt('The e-mail address you provided does not match the address recorded in the LON-CAPA system for the username and domain you provided.');                $msg = &mt('The e-mail address you provided does not match the address recorded in the LON-CAPA system for the username and domain you provided.');  
Line 434  sub homeserver_redirect { Line 601  sub homeserver_redirect {
 }  }
   
 sub reset_passwd {  sub reset_passwd {
     my ($r,$token,$contact_name,$contact_email) = @_;      my ($r,$token,$contact_name,$contact_email,$passwdconf) = @_;
       return unless (ref($passwdconf) eq 'HASH');
     my %data = &Apache::lonnet::tmpget($token);      my %data = &Apache::lonnet::tmpget($token);
     my $now = time;      my $now = time;
     if (keys(%data) == 0) {      if (keys(%data) == 0) {
Line 448  sub reset_passwd { Line 616  sub reset_passwd {
         ($data{'domain'} ne '') &&           ($data{'domain'} ne '') && 
         ($data{'email'}  =~ /^[^\@]+\@[^\@]+\.[^\@\.]+$/) &&           ($data{'email'}  =~ /^[^\@]+\@[^\@]+\.[^\@\.]+$/) && 
         ($data{'temppasswd'} =~/^\w+$/)) {          ($data{'temppasswd'} =~/^\w+$/)) {
           my $timelimit = 7200;
           if ($passwdconf->{resetlink} =~ /^\d+(|\.\d*)$/) {
               $timelimit = 3600 * $passwdconf->{resetlink};
           }
         my $reqtime = &Apache::lonlocal::locallocaltime($data{'time'});          my $reqtime = &Apache::lonlocal::locallocaltime($data{'time'});
         my ($blocked,$blocktext) =          my ($blocked,$blocktext) =
             &Apache::loncommon::blocking_status('passwd',$data{'username'},$data{'domain'});              &Apache::loncommon::blocking_status('passwd',$data{'username'},$data{'domain'});
         if ($blocked) {          if ($blocked) {
             $r->print('<p class="LC_warning">'.$blocktext.'</p>');              $r->print('<p class="LC_warning">'.$blocktext.'</p>');
             return;              return;
         } elsif ($now - $data{'time'} < 7200) {          } elsif ($now - $data{'time'} < $timelimit) {
               my ($needscase,%formfields) = &reset_requires($data{'username'},$data{'domain'},
                                                             $passwdconf);
             if ($env{'form.action'} eq 'verify_and_change_pass') {              if ($env{'form.action'} eq 'verify_and_change_pass') {
                 $env{'form.uname'} =~ s/^\s+|\s+$//g;                  my $invalidinfo;
                 $env{'form.udom'} =~ s/^\s+|\s+$//g;                  if ($formfields{'username'}) {
                 $env{'form.email'} =~ s/^\s+|\s+$//g;                      $env{'form.uname'} =~ s/^\s+|\s+$//g;
                 unless (($env{'form.uname'} eq $data{'username'}) && ($env{'form.udom'} eq $data{'domain'}) && ($env{'form.email'} eq $data{'email'})) {                      $env{'form.udom'} =~ s/^\s+|\s+$//g;
                     &Apache::lonnet::logthis("Forgot Password -- token data: ||$data{'username'}|| ||$data{'domain'}|| ||$data{'email'}|| differs from form: ||$env{'form.uname'}|| ||$env{'form.udom'}|| ||$env{'form.email'}||");                      if ($needscase) {
                           unless (($env{'form.uname'} eq $data{'username'}) && ($env{'form.udom'} eq $data{'domain'})) {
                               $invalidinfo = "||$env{'form.uname'}|| ||$env{'form.udom'}|| ";
                           }
                       } else {
                           unless ((lc($env{'form.uname'}) eq lc($data{'username'})) && (lc($env{'form.udom'}) eq lc($data{'domain'}))) {
                               $invalidinfo = "||$env{'form.uname'}|| ||$env{'form.udom'}|| ";
                           }
                       }
                   } else {
                       $env{'form.uname'} = $data{'username'};
                       $env{'form.udom'} = $data{'domain'};
                   }
                   if ($formfields{'email'}) {
                       $env{'form.email'} =~ s/^\s+|\s+$//g;
                       if ($needscase) {
                           unless ($env{'form.email'} eq $data{'email'}) {
                               $invalidinfo .= "||$env{'form.email'}||";
                           }
                       } else {
                           unless (lc($env{'form.email'}) eq lc($data{'email'})) {
                               $invalidinfo = "||$env{'form.email'}||";
                           }
                       }
                   }
                   if ($invalidinfo) {
                       &Apache::lonnet::logthis("Forgot Password -- token data: ||$data{'username'}|| ||$data{'domain'}|| ||$data{'email'}|| differs from form: $invalidinfo");
                     $r->print(&generic_failure_msg($contact_name,$contact_email));                      $r->print(&generic_failure_msg($contact_name,$contact_email));
                       unless ($formfields{'username'}) {
                           delete($env{'form.uname'});
                           delete($env{'form.udom'});
                       }
                     return;                      return;
                 }                  }
                 my $change_failed =                   my $change_failed =
     &Apache::lonpreferences::verify_and_change_password($r,'reset_by_email',$token);      &Apache::lonpreferences::verify_and_change_password($r,'reset_by_email',$token);
                 if (!$change_failed) {                  if (!$change_failed) {
                     my $delete = &Apache::lonnet::tmpdel($token);                      my $delete = &Apache::lonnet::tmpdel($token);
Line 519  sub reset_passwd { Line 723  sub reset_passwd {
                 } else {                  } else {
                     $r->print(&generic_failure_msg($contact_name,$contact_email));                      $r->print(&generic_failure_msg($contact_name,$contact_email));
                 }                  }
                   unless ($formfields{'username'}) {
                       delete($env{'form.uname'});
                       delete($env{'form.udom'});
                   }
             } else {              } else {
                 $r->print(&mt('The token included in an e-mail sent to you [_1] has been verified, so you may now proceed to reset the password for your LON-CAPA account.',$reqtime).'<br /><br />');                  $r->print(&mt('The token included in an e-mail sent to you [_1] has been verified, so you may now proceed to reset the password for your LON-CAPA account.',$reqtime).'<br /><br />');
                 $r->print(&mt('Please enter the username and domain of the LON-CAPA account, and the associated e-mail address, for which you are setting a password. The new password must contain at least 7 characters.').' '.&mt('Your new password will be sent to the LON-CAPA server in an encrypted form.').'<br />');                  if (keys(%formfields)) {
                 &Apache::lonpreferences::passwordchanger($r,'','reset_by_email',$token);                      if (($formfields{'username'}) && ($formfields{'email'})) {
                           $r->print(&mt('Please enter the username and domain of the LON-CAPA account, and the associated e-mail address, for which you are setting a password.'));
                       } elsif ($formfields{'username'}) {
                           $r->print(&mt('Please enter the username and domain of the LON-CAPA account for which you are setting a password.'));
                       } elsif ($formfields{'email'}) {
                           $r->print(&mt('Please enter the e-mail address associated with the LON-CAPA account for which you are setting a password.'));
                       }
                       if ($needscase) {
                           $r->print(' '.&mt('User data entered must match LON-CAPA account information (including case).'));
                       }
                       $r->print(' ');
                   }
                   if (ref($passwdconf->{chars}) eq 'ARRAY') {
                       my %rules;
                       map { $rules{$_} = 1; } @{$passwdconf->{chars}};
                       my %rulenames = &Apache::lonlocal::texthash(
                                                        uc => 'At least one upper case letter',
                                                        lc => 'At least one lower case letter',
                                                        num => 'At least one number',
                                                        spec => 'At least one non-alphanumeric',
                                                      );
                       $r->print(&mt('The new password must satisfy the following:').'<ul>');
                       foreach my $poss ('uc','lc','num','spec') {
                           if ($rules{$poss}) {
                               $r->print('<li>'.$rulenames{$poss}.'</li>');
                           }
                       }
                       $r->print('</ul>');
                   } else {
                       $r->print(&mt('The new password must contain at least 7 characters.').' ');
                   }
                   $r->print(&mt('Your new password will be sent to the LON-CAPA server in an encrypted form.').'<br />');
                   &Apache::lonpreferences::passwordchanger($r,'','reset_by_email',$token,$timelimit,\%formfields);
             }              }
         } else {          } else {
             $r->print(              $r->print(
Line 593  sub display_actions { Line 833  sub display_actions {
                 '<i>'.$domdesc.'</i>')                  '<i>'.$domdesc.'</i>')
            .'</p>';             .'</p>';
     }      }
   
     return &Apache::lonhtmlcommon::actionbox(\@msg).$msg2;      return &Apache::lonhtmlcommon::actionbox(\@msg).$msg2;
   }
   
   sub reset_requires {
       my ($username,$domain,$passwdconf) = @_;
       my (%fields,$needscase);
       return ($needscase,%fields) unless (ref($passwdconf) eq 'HASH');
       my (%postlink,%resetcase);
       if (ref($passwdconf->{resetpostlink}) eq 'HASH') {
           %postlink = %{$passwdconf->{resetpostlink}};
       }
       if (ref($passwdconf->{resetcase}) eq 'ARRAY') {
           map { $resetcase{$_} = 1; } (@{$passwdconf->{resetcase}});
       } else {
           $needscase = 1;
       }
       my %userenv =
           &Apache::lonnet::get('environment',['inststatus'],$domain,$username);
       my @inststatuses;
       if ($userenv{'inststatus'} ne '') {
           @inststatuses = split(/:/,$userenv{'inststatus'});
       } else {
           @inststatuses = ('default');
       }
       foreach my $status (@inststatuses) {
           if (ref($postlink{$status}) eq 'ARRAY') {
               map { $fields{$_} = 1; } (@{$postlink{$status}});
           } else {
               map { $fields{$_} = 1; } ('username','email');
           }
           if ($resetcase{$status}) {
               $needscase = 1;
           }
       }
       return ($needscase,%fields);
 }  }
   
 1;  1;

Removed from v.1.43  
changed lines
  Added in v.1.44


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>