--- loncom/interface/lonpreferences.pm 2002/02/19 21:50:40 1.4
+++ loncom/interface/lonpreferences.pm 2007/05/13 22:04:06 1.104
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Preferences
#
-# $Id: lonpreferences.pm,v 1.4 2002/02/19 21:50:40 matthew Exp $
+# $Id: lonpreferences.pm,v 1.104 2007/05/13 22:04:06 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -25,18 +25,6 @@
#
# http://www.lon-capa.org/
#
-# (Internal Server Error Handler
-#
-# (Login Screen
-# 5/21/99,5/22,5/25,5/26,5/31,6/2,6/10,7/12,7/14,
-# 1/14/00,5/29,5/30,6/1,6/29,7/1,11/9 Gerd Kortemeyer)
-#
-# 3/1/1 Gerd Kortemeyer)
-#
-# 3/1 Gerd Kortemeyer
-#
-# 2/13/02 2/14 2/15 Matthew Hall
-#
# This package uses the "londes.js" javascript code.
#
# TODOs that have to be completed:
@@ -45,11 +33,16 @@
package Apache::lonpreferences;
use strict;
+use LONCAPA;
use Apache::Constants qw(:common);
use Apache::File;
use Crypt::DES;
use DynaLoader; # for Crypt::DES version
use Apache::loncommon();
+use Apache::lonhtmlcommon();
+use Apache::lonlocal;
+use Apache::lonnet;
+use LONCAPA();
#
# Write lonnet::passwd to do the call below.
@@ -61,7 +54,7 @@ use Apache::loncommon();
##################################################
sub des_keys {
# Make a new key for DES encryption.
- # Each key has two parts which are returned seperately.
+ # Each key has two parts which are returned separately.
# Please note: Each key must be passed through the &hex function
# before it is output to the web browser. The hex versions cannot
# be used to decrypt.
@@ -99,18 +92,940 @@ sub des_decrypt {
# Handler subroutines #
################################################################
+################################################################
+# Language Change Subroutines #
+################################################################
+
+sub wysiwygchanger {
+ my $r = shift;
+ my %userenv = &Apache::lonnet::get
+ ('environment',['wysiwygeditor']);
+ my $onselect='checked="checked"';
+ my $offselect='';
+ if ($userenv{'wysiwygeditor'} eq 'on') {
+ $onselect='';
+ $offselect='checked="checked"';
+ }
+ my $switchoff=&mt('Disable WYSIWYG editor');
+ my $switchon=&mt('Enable WYSIWYG editor');
+ $r->print(< '.&mt('Setting WYSIWYG editor to:').' '.&mt($newsetting).' TeX to HTML jsMath Convert to Images '.&mt('Some LON-CAPA users have a long list of '.$lc_role.'s. The Recent '.$role.'s Hotlist feature keeps track of the last N '.$lc_role.'s which have been visited and places a table of these at the top of the '.$lc_role.'s page. People with very few '.$lc_role.'s should leave this feature disabled.').'
+
+
+ENDFORM
+ $r->print(&server_form($logtoken,$caller,$mailtoken));
+ $r->print(&client_form($caller,\%hexkey,$currentpass,$defdom));
+
+ #
+ return;
+}
+sub jscript_send {
+ my ($caller) = @_;
+ my $output = qq|
-
-Change password for $user
-
-
+|;
+}
-
+
+
+ENDLSCREEN
+ $r->print('
');
+}
+
+
+sub verify_and_change_wysiwyg {
+ my $r = shift;
+ my $newsetting=$env{'form.wysiwyg'};
+ &Apache::lonnet::put('environment',{'wysiwygeditor' => $newsetting});
+ &Apache::lonnet::appenv('environment.wysiwygeditor' => $newsetting);
+ $r->print('
$pref: $selectionbox
+ENDLSCREEN
+ $r->print('
');
+}
+
+
+sub verify_and_change_languages {
+ my $r = shift;
+ my $user = $env{'user.name'};
+ my $domain = $env{'user.domain'};
+# Screenname
+ my $newlanguage = $env{'form.language'};
+ $newlanguage=~s/[^\-\w]//g;
+ my $message='';
+ if ($newlanguage) {
+ &Apache::lonnet::put('environment',{'languages' => $newlanguage});
+ &Apache::lonnet::appenv('environment.languages' => $newlanguage);
+ $message='Set new preferred languages to '.$newlanguage;
+ } else {
+ &Apache::lonnet::del('environment',['languages']);
+ &Apache::lonnet::delenv('environment\.languages');
+ $message='Reset preferred language';
+ }
+ $r->print(<
+
+
+$jsMath_start
+
+
+
+
+
+
+".&mt($role)."".
+ &Apache::loncommon::end_data_table_header_row().
+ "\n";
+ my $count;
+ foreach $role_key (@sorted_roles) {
+ my $checked = "";
+ my $value = $recent_roles{$role_key};
+ if ($frozen_roles{$role_key}) {
+ $checked = "checked=\"checked\"";
+ }
+ $count++;
+ $roles_check_list .=
+ &Apache::loncommon::start_data_table_row().
+ ' '.
+ " ".
+ "".
+ &Apache::loncommon::end_data_table_row(). "\n";
+ }
+ $roles_check_list .= "\n";
+ }
+
+ $r->print('
+
';
+ if ($hotlist_flag) {
+ &Apache::lonnet::put('environment',{'recentroles' => $hotlist_flag});
+ &Apache::lonnet::appenv('environment.recentroles' => $hotlist_flag);
+ $message=&mt('Recent '.$role.'s Hotlist is Enabled');
+ } else {
+ &Apache::lonnet::del('environment',['recentroles']);
+ &Apache::lonnet::delenv('environment\.recentroles');
+ $message=&mt('Recent '.$role.'s Hotlist is Disabled');
+ }
+ if ($hotlist_n) {
+ &Apache::lonnet::put('environment',{'recentrolesn' => $hotlist_n});
+ &Apache::lonnet::appenv('environment.recentrolesn' => $hotlist_n);
+ if ($hotlist_flag) {
+ $message.="
".
+ &mt('Display [_1] Most Recent '.$role.'s',$hotlist_n)."\n";
+ }
+ }
+
+# Get list of froze roles and list of recent roles
+ my @freeze_list = &Apache::loncommon::get_env_multiple('form.freezeroles');
+ my %freeze = ();
+ my %roletext = ();
+
+ foreach my $key (@freeze_list) {
+ $freeze{$key}='1';
+ }
+
+ my %recent_roles =
+ &Apache::lonhtmlcommon::get_recent('roles',$env{'environment.recentrolesn'});
+ my %frozen_roles =
+ &Apache::lonhtmlcommon::get_recent_frozen('roles',$env{'environment.recentrolesn'});
+ my %role_text = &rolespref_get_role_text([keys(%recent_roles)]);
+
+# Unset any roles that were previously frozen but aren't in list
+ foreach my $role_key (sort(keys(%recent_roles))) {
+ if (($frozen_roles{$role_key}) && (!exists($freeze{$role_key}))) {
+ $message .= "
".&mt('Unfreezing '.$role.': [_1]',$role_text{$role_key})."\n";
+ &Apache::lonhtmlcommon::store_recent('roles',$role_key,' ',0);
+ }
+ }
+
+# Freeze selected roles
+ foreach my $role_key (@freeze_list) {
+ if (!$frozen_roles{$role_key}) {
+ $message .= "
".&mt('Freezing '.$role.': [_1]',$role_text{$role_key})."\n";
+ &Apache::lonhtmlcommon::store_recent('roles',
+ $role_key,' ',1);
+ }
+ }
+ $message .= "
\n";
+
+ $r->print(<
New screenname (shown if you post anonymously):
+
+
New nickname (shown if you post non-anonymously):
+
+
+
+ENDSCREEN
+}
+
+sub verify_and_change_screenname {
+ my $r = shift;
+ my $user = $env{'user.name'};
+ my $domain = $env{'user.domain'};
+# Screenname
+ my $newscreen = $env{'form.screenname'};
+ $newscreen=~s/[^ \w]//g;
+ my $message='';
+ if ($newscreen) {
+ &Apache::lonnet::put('environment',{'screenname' => $newscreen});
+ &Apache::lonnet::appenv('environment.screenname' => $newscreen);
+ $message='Set new screenname to '.$newscreen;
+ } else {
+ &Apache::lonnet::del('environment',['screenname']);
+ &Apache::lonnet::delenv('environment\.screenname');
+ $message='Reset screenname';
+ }
+# Nickname
+ $message.='
';
+ $newscreen = $env{'form.nickname'};
+ $newscreen=~s/[^ \w]//g;
+ if ($newscreen) {
+ &Apache::lonnet::put('environment',{'nickname' => $newscreen});
+ &Apache::lonnet::appenv('environment.nickname' => $newscreen);
+ $message.='Set new nickname to '.$newscreen;
+ } else {
+ &Apache::lonnet::del('environment',['nickname']);
+ &Apache::lonnet::delenv('environment\.nickname');
+ $message.='Reset nickname';
+ }
+ &Apache::lonnet::devalidate_cache_new('namescache',$user.':'.$domain);
+ $r->print(<
+
+
+
+
+ENDSCREEN
+}
+
+sub verify_and_change_icons {
+ my $r = shift;
+ my $user = $env{'user.name'};
+ my $domain = $env{'user.domain'};
+ my $newicons = $env{'form.menumode'};
+
+ &Apache::lonnet::put('environment',{'icons' => $newicons});
+ &Apache::lonnet::appenv('environment.icons' => $newicons);
+ $r->print(&mt('Set menu mode to [_1].',$newicons));
+}
+
+################################################################
+# Message Forward #
+################################################################
+
+sub msgforwardchanger {
+ my ($r,$message) = @_;
+ my $user = $env{'user.name'};
+ my $domain = $env{'user.domain'};
+ my %userenv = &Apache::lonnet::get('environment',['msgforward','notification','critnotification','notifywithhtml']);
+ my $msgforward=$userenv{'msgforward'};
+ my %lt = &Apache::lonlocal::texthash(
+ all => 'All',
+ crit => 'Critical only',
+ reg => 'Non-critical only',
+ foad => 'Forwarding Address(es)',
+ mnot => 'Message Notification Email Address(es)',
+ chg => 'Change',
+ email => 'The e-mail address entered in row ',
+ notv => 'is not a valid e-mail address',
+ toen => "To enter multiple addresses, enter one address at a time, click 'Change' and then add the next one",
+ prme => 'Back to preferences menu',
+ );
+ my $forwardingHelp = Apache::loncommon::help_open_topic("Prefs_Forwarding",
+ "What are forwarding ".
+ "and notification ".
+ "addresses");
+ my $criticalMessageHelp = Apache::loncommon::help_open_topic("Course_Critical_Message",
+ "What are critical messages");
+ my @allow_html = split(/,/,$userenv{'notifywithhtml'});
+ my %allnot = &get_notifications(\%userenv);
+ my $validatescript = &Apache::lonhtmlcommon::javascript_valid_email();
+ my $jscript = qq|
+
+|;
+ $r->print(<
+$criticalMessageHelp
+$lt{'mnot'} (joe\@doe.com):
+ENDMSG
+ my @sortforwards = sort (keys(%allnot));
+ my $output = &Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_header_row().
+ ' '.
+ ''.&mt('Action').' '.
+ ''.&mt('Notification address').' '.
+ &mt('Types of message to forward to this address').' '.
+ &mt('Excerpt retains HTML tags in message').' '.
+ &Apache::loncommon::end_data_table_header_row();
+ my $num = 0;
+ my $counter = 1;
+ foreach my $item (@sortforwards) {
+ $output .= &Apache::loncommon::start_data_table_row().
+ ''.$counter.' '.
+ ' '.
+ ' '.
+ '';
+ my %chk;
+ if (defined($allnot{$item}{'crit'})) {
+ if (defined($allnot{$item}{'reg'})) {
+ $chk{'all'} = 'checked="checked" ';
+ } else {
+ $chk{'crit'} = 'checked="checked" ';
+ }
+ } else {
+ $chk{'reg'} = 'checked="checked" ';
+ }
+ foreach my $type ('all','crit','reg') {
+ $output .= ' ';
+ }
+ my $htmlon = '';
+ my $htmloff = '';
+ if (grep/^\Q$item\E/,@allow_html) {
+ $htmlon = 'checked="checked" ';
+ } else {
+ $htmloff = 'checked="checked" ';
+ }
+ $output .= ' '.
+ ' '.
+ &Apache::loncommon::end_data_table_row();
+ $num ++;
+ $counter ++;
+ }
+ my %defchk = (
+ all => 'checked="checked" ',
+ crit => '',
+ reg => '',
+ );
+ $output .= &Apache::loncommon::start_data_table_row().
+ ''.$counter.' '.
+ ''.
+ ' ';
+ foreach my $type ('all','crit','reg') {
+ $output .= ' ';
+ }
+ $output .= ' '.
+ ' '.
+ &Apache::loncommon::end_data_table_row().
+ &Apache::loncommon::end_data_table();
+ $num ++;
+ $r->print($output);
+ $r->print(qq|
+
+
+
+
+
+|);
+
+}
+
+sub get_notifications {
+ my ($userenv) = @_;
+ my %allnot;
+ my @critnot = split(/,/,$userenv->{'critnotification'});
+ my @regnot = split(/,/,$userenv->{'notification'});
+ foreach my $item (@critnot) {
+ $allnot{$item}{crit} = 1;
+ }
+ foreach my $item (@regnot) {
+ $allnot{$item}{reg} = 1;
+ }
+ return %allnot;
+}
+
+sub verify_and_change_msgforward {
+ my $r = shift;
+ my $user = $env{'user.name'};
+ my $domain = $env{'user.domain'};
+ my $newscreen = '';
+ my $message='';
+ foreach (split(/\,/,$env{'form.msgforward'})) {
+ my ($msuser,$msdomain)=split(/[\@\:]/,$_);
+ $msuser = &LONCAPA::clean_username($msuser);
+ $msdomain = &LONCAPA::clean_domain($msdomain);
+ if (($msuser) && ($msdomain)) {
+ if (&Apache::lonnet::homeserver($msuser,$msdomain) ne 'no_host') {
+ $newscreen.=$msuser.':'.$msdomain.',';
+ } else {
+ $message.= &mt('No such user: ').$msuser.':'.$msdomain.'
';
+ }
+ }
+ }
+ $newscreen=~s/\,$//;
+ if ($newscreen) {
+ &Apache::lonnet::put('environment',{'msgforward' => $newscreen});
+ &Apache::lonnet::appenv('environment.msgforward' => $newscreen);
+ $message .= &mt('Set message forwarding to: ').''.$newscreen.
+ '
';
+ } else {
+ &Apache::lonnet::del('environment',['msgforward']);
+ &Apache::lonnet::delenv('environment\.msgforward');
+ $message.= &mt("Set message forwarding to 'off'.").'
';
+ }
+ my $critnotification;
+ my $notification;
+ my $notify_with_html;
+ my $lastnotify = $env{'form.numnotify'}-1;
+ my $totaladdresses = 0;
+ for (my $i=0; $i<$env{'form.numnotify'}; $i++) {
+ if ((!defined($env{'form.del_notify_'.$i})) &&
+ ((($i==$lastnotify) && ($env{'form.add_notify_'.$lastnotify} == 1)) ||
+ ($i<$lastnotify))) {
+ if (defined($env{'form.address_'.$i})) {
+ if ($env{'form.notify_type_'.$i} eq 'all') {
+ $critnotification .= $env{'form.address_'.$i}.',';
+ $notification .= $env{'form.address_'.$i}.',';
+ } elsif ($env{'form.notify_type_'.$i} eq 'crit') {
+ $critnotification .= $env{'form.address_'.$i}.',';
+ } elsif ($env{'form.notify_type_'.$i} eq 'reg') {
+ $notification .= $env{'form.address_'.$i}.',';
+ }
+ if ($env{'form.html_'.$i} eq '1') {
+ $notify_with_html .= $env{'form.address_'.$i}.',';
+ }
+ $totaladdresses ++;
+ }
+ }
+ }
+ $critnotification =~ s/,$//;
+ $critnotification=~s/\s//gs;
+ $notification =~ s/,$//;
+ $notification=~s/\s//gs;
+ $notify_with_html =~ s/,$//;
+ $notify_with_html =~ s/\s//gs;
+ if ($notification) {
+ &Apache::lonnet::put('environment',{'notification' => $notification});
+ &Apache::lonnet::appenv('environment.notification' => $notification);
+ $message.=&mt('Set non-critical message notification address(es) to: ').''.$notification.'
';
+ } else {
+ &Apache::lonnet::del('environment',['notification']);
+ &Apache::lonnet::delenv('environment\.notification');
+ $message.=&mt("Non-critical message notification set to 'off'.").'
';
+ }
+ if ($critnotification) {
+ &Apache::lonnet::put('environment',{'critnotification' => $critnotification});
+ &Apache::lonnet::appenv('environment.critnotification' => $critnotification);
+ $message.=&mt('Set critical message notification address(es) to: ').''.$critnotification.'
';
+ } else {
+ &Apache::lonnet::del('environment',['critnotification']);
+ &Apache::lonnet::delenv('environment\.critnotification');
+ $message.=&mt("Critical message notification set to 'off'.").'
';
+ }
+ if ($critnotification || $notification) {
+ if ($notify_with_html) {
+ &Apache::lonnet::put('environment',{'notifywithhtml' => $notify_with_html});
+ &Apache::lonnet::appenv('environment.notifywithhtml' => $notify_with_html);
+ $message.=&mt('Set address(es) to receive excerpts with html retained: ').''.$notify_with_html.'';
+ } else {
+ &Apache::lonnet::del('environment',['notifywithhtml']);
+ &Apache::lonnet::delenv('environment\.notifywithhtml');
+ if ($totaladdresses == 1) {
+ $message.=&mt("Set notification address to receive excerpts with html stripped.");
+ } else {
+ $message.=&mt("Set all notification addresses to receive excerpts with html stripped.");
+ }
+ }
+ } else {
+ &Apache::lonnet::del('environment',['notifywithhtml']);
+ &Apache::lonnet::delenv('environment\.notifywithhtml');
+ }
+ if ($message) {
+ $message .= '
';
+ }
+ &msgforwardchanger($r,$message);
+}
+
+################################################################
+# Colors #
+################################################################
+
+sub colorschanger {
+ my $r = shift;
+# figure out colors
+ my $function=&Apache::loncommon::get_users_function();
+ my $domain=&Apache::loncommon::determinedomain();
+ my %colortypes=('pgbg' => 'Page Background',
+ 'tabbg' => 'Header Background',
+ 'sidebg'=> 'Header Border',
+ 'font' => 'Font',
+ 'link' => 'Un-Visited Link',
+ 'vlink' => 'Visited Link',
+ 'alink' => 'Active Link');
+ my $start_data_table = &Apache::loncommon::start_data_table();
+ my $chtable='';
+ foreach my $item (sort(keys(%colortypes))) {
+ my $curcol=&Apache::loncommon::designparm($function.'.'.$item,$domain);
+ $chtable.=&Apache::loncommon::start_data_table_row().
+ ''.$colortypes{$item}.' Select '.
+ &Apache::loncommon::end_data_table_row()."\n";
+ }
+ my $end_data_table = &Apache::loncommon::end_data_table();
+ my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition();
+ $r->print(<
';
+ } else {
+ &Apache::lonnet::del('environment',[$entry]);
+ &Apache::lonnet::delenv('environment\.'.$entry);
+ $message.='Reset '.$colortypes{$item}.'
';
+ }
+ }
+ my $now = time;
+ &Apache::lonnet::put('environment',{'color.timestamp' => $now});
+ &Apache::lonnet::appenv('environment.color.timestamp' => $now);
+
+ $r->print(<
');
+ return;
+ }
+ } else {
+ $r->print(&mt('Sorry, the URL generated when you requested reset of your password contained incomplete information.').'
');
+ return;
+ }
+ } else {
+ $r->print(&mt('Page requested in unexpected context').'
');
+ return;
+ }
my $currentauth=&Apache::lonnet::queryauthenticate($user,$domain);
# Check for authentication types that allow changing of the password.
return if ($currentauth !~ /^(unix|internal):/);
@@ -127,12 +1042,13 @@ sub passwordchanger {
.$ukey_npass2 . $lkey_npass2,
$lonhost);
# Hexify the keys for output as javascript variables
- $ukey_cpass = hex($ukey_cpass);
- $lkey_cpass = hex($lkey_cpass);
- $ukey_npass1= hex($ukey_npass1);
- $lkey_npass1= hex($lkey_npass1);
- $ukey_npass2= hex($ukey_npass2);
- $lkey_npass2= hex($lkey_npass2);
+ my %hexkey;
+ $hexkey{'ukey_cpass'} = hex($ukey_cpass);
+ $hexkey{'lkey_cpass'} = hex($lkey_cpass);
+ $hexkey{'ukey_npass1'} = hex($ukey_npass1);
+ $hexkey{'lkey_npass1'} = hex($lkey_npass1);
+ $hexkey{'ukey_npass2'} = hex($ukey_npass2);
+ $hexkey{'lkey_npass2'} = hex($lkey_npass2);
# Output javascript to deal with passwords
# Output DES javascript
{
@@ -140,10 +1056,25 @@ sub passwordchanger {
my $jsh=Apache::File->new($include."/londes.js");
$r->print(<$jsh>);
}
+ $r->print(&jscript_send($caller));
$r->print(<Preferences for $user
-$user is a member of domain $domain
-$errormessage
-
\n". + &mt("Invalid username and/or domain")."\n
", + $caller,$mailtoken); + return 1; + } + } else { + &passwordchanger($r,"\n". + &mt("Username and domain were blank")."\n
", + $caller,$mailtoken); + return 1; + } + } else { + $user = $env{'user.name'}; + $domain = $env{'user.domain'}; + $homeserver = $env{'user.home'}; + } my $currentauth=&Apache::lonnet::queryauthenticate($user,$domain); # Check for authentication types that allow changing of the password. - return if ($currentauth !~ /^(unix|internal):/); - # - $r->print(<\n". + &mt("Authentication type for this user can not be changed by this mechanism"). + "\n
", + $caller,$mailtoken); + return 1; + } else { + return; + } + } # - my $currentpass = $ENV{'form.currentpass'}; - my $newpass1 = $ENV{'form.newpass_1'}; - my $newpass2 = $ENV{'form.newpass_2'}; - my $logtoken = $ENV{'form.logtoken'}; + my $currentpass = $env{'form.currentpass'}; + my $newpass1 = $env{'form.newpass_1'}; + my $newpass2 = $env{'form.newpass_2'}; + my $logtoken = $env{'form.logtoken'}; # Check for empty data unless (defined($currentpass) && defined($newpass1) && defined($newpass2) ){ - &passwordchanger($r,"\nERROR". - "Password data was blank.\n
"); + &passwordchanger($r,"\n". + &mt("One or more password fields were blank"). + "\n
",$caller,$mailtoken); return; } # Get the keys @@ -246,34 +1254,48 @@ ENDHEADER my $tmpinfo = Apache::lonnet::reply('tmpget:'.$logtoken,$lonhost); if (($tmpinfo=~/^error/) || ($tmpinfo eq 'con_lost')) { # I do not a have a better idea about how to handle this + my $tryagain_text = &mt('Please log out and try again.'); + if ($caller eq 'reset_by_email') { + $tryagain_text = &mt('Please try again later.'); + } + my $unable=&mt("Unable to retrieve saved token for password decryption"); $r->print(<!"\#$%&\'()*+,-./0123456789:;<=>?\@ ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_\`abcdefghijklmnopqrstuvwxyz{|}~ -+ ENDERROR + &passwordchanger($r,$errormessage,$caller,$mailtoken); + return 1; } # # Change the password (finally) my $result = &Apache::lonnet::changepass - ($user,$domain,$currentpass,$newpass1,$homeserver); + ($user,$domain,$currentpass,$newpass1,$homeserver,$caller); # Inform the user the password has (not?) been changed if ($result =~ /^ok$/) { - $r->print(<<"ENDTEXT"); -
'.$helplink.' | '. + ''.$optiontext.' | '. + '