--- loncom/interface/resetpw.pm 2013/07/19 16:17:07 1.33 +++ loncom/interface/resetpw.pm 2016/09/12 16:02:16 1.38 @@ -1,7 +1,7 @@ # The LearningOnline Network # Allow access to password changing via a token sent to user's e-mail. # -# $Id: resetpw.pm,v 1.33 2013/07/19 16:17:07 bisitz Exp $ +# $Id: resetpw.pm,v 1.38 2016/09/12 16:02:16 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -57,6 +57,7 @@ use Apache::lonnet; use Apache::loncommon; use Apache::lonlocal; use LONCAPA; +use HTML::Entities; sub handler { my $r = shift; @@ -87,8 +88,20 @@ sub handler { &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['token']); my @emailtypes = ('permanentemail','critnotification','notification'); - my $uname = &unescape($env{'form.uname'}); - my $udom = $env{'form.udom'}; + my $uname = $env{'form.uname'}; + $uname =~ s/^\s+|\s+$//g; + $uname = &LONCAPA::clean_username($uname); + my $udom = &LONCAPA::clean_domain($env{'form.udom'}); + my ($domdesc,$otherinst); + if ($udom) { + $domdesc = &Apache::lonnet::domain($udom,'description'); + if ($domdesc) { + my %servers = &Apache::lonnet::internet_dom_servers($udom); + unless (exists($servers{$server})) { + $otherinst = 1; + } + } + } my $token = $env{'form.token'}; my $brcrum = []; if ($token) { @@ -106,66 +119,152 @@ sub handler { } } my $args = {bread_crumbs => $brcrum}; - $r->print(&Apache::loncommon::start_page('Reset password','',$args)); - $r->print('

'.&mt('Reset forgotten LON-CAPA password').'

'); + my $js; + unless ($token || $otherinst || ($uname && $udom)) { + my (@intdoms,@instdoms); + my $internet_names = &Apache::lonnet::get_internet_names($server); + if (ref($internet_names) eq 'ARRAY') { + @intdoms = @{$internet_names}; + } + if (@intdoms) { + my %iphost = &Apache::lonnet::get_iphost(); + foreach my $ip (keys(%iphost)) { + if (ref($iphost{$ip}) eq 'ARRAY') { + foreach my $id (@{$iphost{$ip}}) { + my $location = &Apache::lonnet::internet_dom($id); + if ($location) { + if (grep(/^\Q$location\E$/,@intdoms)) { + my $dom = &Apache::lonnet::host_domain($id); + unless (grep(/^\Q$dom\E/,@instdoms)) { + push(@instdoms,$dom); + } + } + } + } + } + } + } + my $instdomstr; + if (@instdoms > 0) { + $instdomstr = "'".join("','",@instdoms)."'"; + } + my %js_lt = &Apache::lonlocal::texthash( + thdo => 'The domain you have selected is for another institution.', + yowi => 'You will be switched to the Forgot Password utility at that institution.', + unam => 'You must enter a username.', + mail => 'You must enter an e-mail address.' + ); + &js_escape(\%js_lt); + $js = <<"END"; + +END + } + my $header = &Apache::loncommon::start_page('Reset password',$js,$args). + '

'.&mt('Reset forgotten LON-CAPA password').'

'; my $output; if ($token) { $output = &reset_passwd($r,$token,$contact_name,$contact_email); - } elsif ($uname && $udom) { - my $domdesc = &Apache::lonnet::domain($udom,'description'); - my $authtype = &Apache::lonnet::queryauthenticate($uname,$udom); - if ($authtype =~ /^internal/) { - my $useremail = $env{'form.useremail'}; - if ($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) { - 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$/,@allemails)) { - push(@allemails,$item); + } elsif ($udom) { + if (!$domdesc) { + $output = &invalid_state('baddomain',$domdesc, + $contact_name,$contact_email); + } elsif ($otherinst) { + ($header,$output) = &homeserver_redirect($uname,$udom,$domdesc,$brcrum); + } elsif ($uname) { + my $authtype = &Apache::lonnet::queryauthenticate($uname,$udom); + if ($authtype =~ /^internal/) { + my $useremail = $env{'form.useremail'}; + my ($blocked,$blocktext) = + &Apache::loncommon::blocking_status('passwd',$uname,$udom); + if ($blocked) { + $output = '

'.$blocktext.'

' + .&display_actions($contact_email,$domdesc); + } elsif ($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) { + 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$/,@allemails)) { + push(@allemails,$item); + } } } } - } - if (@allemails > 0) { - if (grep(/^\Q$useremail\E$/,@allemails)) { - $output = &send_token($uname,$udom,$useremail,$server, - $domdesc,$contact_name, - $contact_email); + if (@allemails > 0) { + if (grep(/^\Q$useremail\E$/,@allemails)) { + $output = &send_token($uname,$udom,$useremail,$server, + $domdesc,$contact_name, + $contact_email); + } else { + $output = &invalid_state('mismatch',$domdesc, + $contact_name, + $contact_email); + } } else { - $output = &invalid_state('mismatch',$domdesc, - $contact_name, - $contact_email); + $output = &invalid_state('missing',$domdesc, + $contact_name,$contact_email); } - } else { - $output = &invalid_state('missing',$domdesc, - $contact_name,$contact_email); } + } elsif ($authtype =~ /^(krb|unix|local)/) { + $output = &invalid_state('authentication',$domdesc, + $contact_name,$contact_email); + } else { + $output = &invalid_state('invalid',$domdesc, + $contact_name,$contact_email); } - } elsif ($authtype =~ /^(krb|unix|local)/) { - $output = &invalid_state('authentication',$domdesc, - $contact_name,$contact_email); } else { - $output = &invalid_state('invalid',$domdesc, - $contact_name,$contact_email); + $output = &get_uname($defdom); } } else { $output = &get_uname($defdom); } - $r->print($output); + $r->print($header.$output); $r->print(&Apache::loncommon::end_page()); return OK; } @@ -184,16 +283,23 @@ sub get_uname { .'
  • '.&mt('You must be able to access e-mail sent to that address.').'
  • ' .'
  • '.&mt('Your LON-CAPA account must be of a type for which LON-CAPA can reset a password.') .''; - $msg .= '
    '. + 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);'; + $msg .= ''. &Apache::lonhtmlcommon::start_pick_box(). &Apache::lonhtmlcommon::row_title($lt{'unam'}). - ''. + ''. &Apache::lonhtmlcommon::row_closure(1). &Apache::lonhtmlcommon::row_title($lt{'udom'}). - &Apache::loncommon::select_dom_form($defdom,'udom'). + &Apache::loncommon::select_dom_form($defdom,'udom',undef,undef,$onchange). &Apache::lonhtmlcommon::row_closure(1). &Apache::lonhtmlcommon::row_title($lt{'uemail'}). - ''. + ''. &Apache::lonhtmlcommon::end_pick_box(). '

    '; return $msg; @@ -225,7 +331,10 @@ sub send_token { my $result = &send_mail($domdesc,$email,$mailmsg,$contact_name, $contact_email); if ($result eq 'ok') { - $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.

    The link included in the message will be valid for the next two hours."); + $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('The link included in the message will be valid for the next [_1]two[_2] hours.','',''); } else { $msg .= '

    ' @@ -233,7 +342,6 @@ sub send_token { .' associated with your LON-CAPA account.') .'

    ' .&display_actions($contact_email,$domdesc); - } } else { $msg .= @@ -285,6 +393,8 @@ sub invalid_state { $msg = &mt('A valid e-mail address was not located in the LON-CAPA system for the username and domain you provided.'); } elsif ($error eq 'authentication') { $msg = &mt('The username you provided uses an authentication type which can not be reset directly via LON-CAPA.'); + } elsif ($error eq 'baddomain') { + $msg = &mt('The domain you provided was not verified as a valid domain in the LON-CAPA system.'); } $msg = '

    '.$msg.'

    ' .&display_actions($contact_email,$domdesc); @@ -292,6 +402,25 @@ sub invalid_state { return $msg; } +sub homeserver_redirect { + my ($uname,$udom,$domdesc,$brcrum) = @_; + my $uhome = &Apache::lonnet::homeserver(); + if ($uhome eq 'no_host') { + $uhome = &Apache::lonnet::domain($udom,'primary'); + } + my $protocol = $Apache::lonnet::protocol{$uhome}; + $protocol = 'http' if ($protocol ne 'https'); + my $url = $protocol.'://'.&Apache::lonnet::hostname($uhome).'/adm/resetpw'; + # Breadcrumbs + my $start_page = &Apache::loncommon::start_page('Switching Server',undef, + {'redirect' => [0,$url], + 'bread_crumbs' => $brcrum,}); + my $output = '

    '.&mt('This LON-CAPA server belongs to a different domain.').' '. + &mt('You are being switched to your domain ([_1]), to use the "Forgot Password" tool.',$domdesc). + '

    '; + return ($start_page,$output); +} + sub reset_passwd { my ($r,$token,$contact_name,$contact_email) = @_; my $msg; @@ -308,7 +437,12 @@ sub reset_passwd { ($data{'email'} =~ /^[^\@]+\@[^\@]+\.[^\@\.]+$/) && ($data{'temppasswd'} =~/^\w+$/)) { my $reqtime = &Apache::lonlocal::locallocaltime($data{'time'}); - if ($now - $data{'time'} < 7200) { + my ($blocked,$blocktext) = + &Apache::loncommon::blocking_status('passwd',$data{'username'},$data{'domain'}); + if ($blocked) { + $msg = '

    '.$blocktext.'

    '; + return $msg; + } elsif ($now - $data{'time'} < 7200) { if ($env{'form.action'} eq 'verify_and_change_pass') { unless (($env{'form.uname'} eq $data{'username'}) && ($env{'form.udom'} eq $data{'domain'}) && ($env{'form.email'} eq $data{'email'})) { $msg = &generic_failure_msg($contact_name,$contact_email); @@ -395,7 +529,7 @@ sub generic_failure_msg { '

    ' .&mt('A problem occurred when attempting to reset the password for your account.') .'
    ' - .&mt('Please contact the [_1] - ([_2]) for assistance.', + .&mt('Please contact the [_1] ([_2]) for assistance.', $contact_name,''.$contact_email.'') .'

    '; }