--- loncom/interface/lonpreferences.pm 2012/12/18 14:25:59 1.201 +++ loncom/interface/lonpreferences.pm 2016/02/17 19:15:48 1.219 @@ -1,7 +1,7 @@ # The LearningOnline Network # Preferences # -# $Id: lonpreferences.pm,v 1.201 2012/12/18 14:25:59 raeburn Exp $ +# $Id: lonpreferences.pm,v 1.219 2016/02/17 19:15:48 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -36,8 +36,6 @@ 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; @@ -45,50 +43,6 @@ use Apache::lonnet; use LONCAPA::lonauthcgi(); use LONCAPA(); -# -# Write lonnet::passwd to do the call below. -# Use: -# my $answer=reply("encrypt:passwd:$udom:$uname:$upass",$tryserver); -# -################################################## -# password associated functions # -################################################## -sub des_keys { - # Make a new key for DES encryption. - # 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. - my @hexstr=('0','1','2','3','4','5','6','7', - '8','9','a','b','c','d','e','f'); - my $lkey=''; - for (0..7) { - $lkey.=$hexstr[rand(15)]; - } - my $ukey=''; - for (0..7) { - $ukey.=$hexstr[rand(15)]; - } - return ($lkey,$ukey); -} - -sub des_decrypt { - my ($key,$cyphertext) = @_; - my $keybin=pack("H16",$key); - my $cypher; - if ($Crypt::DES::VERSION>=2.03) { - $cypher=new Crypt::DES $keybin; - } else { - $cypher=new DES $keybin; - } - my $plaintext= - $cypher->decrypt(unpack("a8",pack("H16",substr($cyphertext,0,16)))); - $plaintext.= - $cypher->decrypt(unpack("a8",pack("H16",substr($cyphertext,16,16)))); - $plaintext=substr($plaintext,1,ord(substr($plaintext,0,1)) ); - return $plaintext; -} - ################################################################ # Handler subroutines # ################################################################ @@ -152,32 +106,16 @@ sub languagechanger { text => 'Change Language'}); $r->print(Apache::loncommon::start_page('Content Display Settings')); $r->print(Apache::lonhtmlcommon::breadcrumbs('Change Language')); - my $user = $env{'user.name'}; - my $domain = $env{'user.domain'}; - my %userenv = &Apache::lonnet::get - ('environment',['languages']); + my %userenv = &Apache::lonnet::get('environment',['languages']); my $language=$userenv{'languages'}; - my $pref=&mt('Preferred language'); - my %langchoices=('' => 'No language preference'); - foreach (&Apache::loncommon::languageids()) { - if (&Apache::loncommon::supportedlanguagecode($_)) { - $langchoices{&Apache::loncommon::supportedlanguagecode($_)} - = &Apache::loncommon::plainlanguagedescription($_); - } - } - %langchoices = &Apache::lonlocal::texthash(%langchoices); - my $selectionbox= - &Apache::loncommon::select_form( - $language, - 'language', - \%langchoices); - $r->print(<<ENDLSCREEN); -<form name="prefs" action="/adm/preferences" method="post"> -<input type="hidden" name="action" value="verify_and_change_languages" /> -<br />$pref: $selectionbox -ENDLSCREEN - $r->print('<br /><input type="submit" value="'.&mt('Save').'" />'); + $r->print( + '<form name="prefs" action="/adm/preferences" method="post">'."\n". + '<input type="hidden" name="action" value="verify_and_change_languages" />'. + '<br /><span class="LC_nobreak">'.&mt('Preferred language').': '. + &Apache::loncommon::select_language('language',$language,1).'</span>'."\n". + '<br /><input type="submit" value="'.&mt('Save').'" /></form>' + ); } @@ -245,6 +183,7 @@ sub texenginechanger { 'change' => 'Save', 'exmpl' => 'Examples', 'mathjax' => 'MathJax:', + 'mathjaxinfo' => 'MathJax provides rendered equations whose source code can be extracted in TeX and MathML formats by right clicking the equation.', 'jsmath' => 'jsMath:', 'tth' => 'tth (TeX to HTML):', 'mimetex' => 'mimetex (Convert to Images):', @@ -281,10 +220,10 @@ $lt{'exmpl'} <h3>$lt{'mathjax'}</h3> </script> -<iframe src="/res/adm/pages/math_example.tex?inhibitmenu=yes&texengine=MathJax" width="400" height="120"></iframe> +<iframe src="/res/adm/pages/math_example.tex?inhibitmenu=yes&texengine=MathJax" width="400" height="150"></iframe> </p> <p> -MathJax provides rendered equations whose source code can be extracted in TeX and MathML formats by right clicking the equation. +$lt{'mathjaxinfo'} </p> <h3>$lt{'jsmath'}</h3> @@ -296,17 +235,17 @@ if (jsMath.nofonts == 1) { } </script> -<iframe src="/res/adm/pages/math_example.tex?inhibitmenu=yes&texengine=jsMath" width="400" height="120"></iframe> +<iframe src="/res/adm/pages/math_example.tex?inhibitmenu=yes&texengine=jsMath" width="400" height="150"></iframe> </p> <h3>$lt{'mimetex'}</h3> <p> -<iframe src="/res/adm/pages/math_example.tex?inhibitmenu=yes&texengine=mimetex" width="400" height="100"></iframe> +<iframe src="/res/adm/pages/math_example.tex?inhibitmenu=yes&texengine=mimetex" width="400" height="150"></iframe> </p> <h3>$lt{'tth'}</h3> <p> -<iframe src="/res/adm/pages/math_example.tex?inhibitmenu=yes&texengine=tth" width="400" height="220"></iframe> +<iframe src="/res/adm/pages/math_example.tex?inhibitmenu=yes&texengine=tth" width="400" height="150"></iframe> </p> ENDLSCREEN if ($env{'environment.texengine'} ne 'jsMath') { @@ -463,7 +402,7 @@ $options.' </div>'); } else { $r->print('<br clear="all" />'. - &mt('Once the Hotlist contains recently visited '.$lc_role.'s, you can return to this page to also set frozen roles.')); + &mt('Once the Hotlist contains recently visited '.$lc_role.'s you can return to this page to also set frozen roles.')); } $r->print(' <br clear="all" /> @@ -774,16 +713,51 @@ sub verify_and_change_clicker { my $r = shift; my $user = $env{'user.name'}; my $domain = $env{'user.domain'}; + my $uhome = $env{'user.home'}; my $newclickers = $env{'form.clickers'}; + my $message; $newclickers=~s/[^\w\:\-]+/\,/gs; $newclickers=~tr/a-z/A-Z/; $newclickers=~s/[\:\-]+/\-/g; $newclickers=~s/\,+/\,/g; $newclickers=~s/^\,//; $newclickers=~s/\,$//; - &Apache::lonnet::put('environment',{'clickers' => $newclickers}); - &Apache::lonnet::appenv({'environment.clickers' => $newclickers}); - my $message=&Apache::lonhtmlcommon::confirm_success(&mt('Registering clickers: [_1]',$newclickers)); + my @oldclickers = split(/,/,$env{'environment.clickers'}); + my @newclickers = split(/,/,$newclickers); + my %newuniq; + map { $newuniq{$_} = 1; } @newclickers; + @newclickers = sort(keys(%newuniq)); + my @differences = &Apache::loncommon::compare_arrays(\@oldclickers,\@newclickers); + if (@differences) { + my $putres = &Apache::lonnet::put('environment',{'clickers' => $newclickers}); + if ($putres eq 'ok') { + my @adds = (); + my @dels = (); + foreach my $item (@differences) { + if (grep(/^\Q$item\E$/,@newclickers)) { + push(@adds,$item); + } else { + push(@dels,$item); + } + } + if (@dels) { + my %delclicker; + map { $delclicker{$_} = $user; } @dels; + my $putresult = &Apache::lonnet::iddel($domain,\%delclicker,$uhome,'clickers'); + } + if (@adds) { + my %addclicker; + map { $addclicker{$_} = $user; } @adds; + my $putresult = &Apache::lonnet::updateclickers($domain,'add',\%addclicker,$uhome,1); + } + &Apache::lonnet::appenv({'environment.clickers' => $newclickers}); + $message=&Apache::lonhtmlcommon::confirm_success(&mt('Registering clickers: [_1]',$newclickers)); + } else { + $message=&Apache::lonhtmlcommon::confirm_success(&mt('Error saving clicker ID').1); + } + } else { + $message='<span class="LC_info">'.&mt('Clicker information unchanged').'</span>'; + } $message=&Apache::loncommon::confirmwrapper($message); &print_main_menu($r, $message); } @@ -807,8 +781,8 @@ sub domcoordchanger { if ($userenv{'domcoord.author'} eq 'blocked') { $constchecked=' checked="checked"'; } - my $text=&mt('By default, the Domain Coordinator can enter your construction space.'); - my $construction=&mt('Block access to construction space'); + my $text=&mt('By default, the Domain Coordinator can enter your Authoring Space.'); + my $construction=&mt('Block access to Authoring Space'); my $change=&mt('Save'); $r->print(<<ENDSCREEN); <form name="prefs" action="/adm/preferences" method="post"> @@ -834,7 +808,7 @@ sub verify_and_change_domcoord { } else { $status=&mt('off'); } - my $message=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]','<i>'.&mt('Block access to construction space').'</i>','<tt>'.$status.'</tt>')); + my $message=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]','<i>'.&mt('Block access to Authoring Space').'</i>','<tt>'.$status.'</tt>')); $message=&Apache::loncommon::confirmwrapper($message); &print_main_menu($r,$message); } @@ -850,7 +824,7 @@ sub lockwarning { my $textbottom=&mt('Changing roles or logging out may result in data corruption.'); my ($num,%which)=&Apache::lonnet::get_locks(); my $which=''; - foreach my $id (keys %which) { + foreach my $id (keys(%which)) { $which.='<li>'.$which{$id}.'</li>'; } my $change=&mt('Override'); @@ -892,15 +866,15 @@ sub msgforwardchanger { foad => 'Forward to account(s)', fwdm => 'Forward messages to other account(s) in LON-CAPA', noti => 'E-mail notification of LON-CAPA messages', - foad_exmpl => 'e.g. <tt>userA:domain1,userB:domain2,...</tt>', mnot => 'E-mail address(es) which should be notified about new LON-CAPA messages', - mnot_exmpl => 'e.g. <tt>joe@doe.com</tt>', chg => 'Save', 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', ); + $lt{'foad_exmpl'} = &mt('e.g. [_1]userA:domain1,userB:domain2,...[_2]','<tt>','</tt>'); + $lt{'mnot_exmpl'} = &mt('e.g. [_1]joe@doe.com[_2]','<tt>','</tt>'); Apache::lonhtmlcommon::add_breadcrumb( { href => '/adm/preferences?action=changemsgforward', text => 'Messages & Notifications'}); @@ -1004,7 +978,7 @@ ENDMSG '" onclick="javscript:delete_address('."'$num'".')" />'. &mt('Delete').'</label></span></td>'. '<td><input type="text" value="'.$item.'" name="address_'. - $num.'" onFocus="javascript:address_changes('."'$num'". + $num.'" onfocus="javascript:address_changes('."'$num'". ')" /></td><td>'; my %chk; if (defined($allnot{$item}{'crit'})) { @@ -1053,7 +1027,7 @@ ENDMSG '<input type="checkbox" name="add_notify_'.$num. '" value="1" />'.&mt('Add new address').'</label></span></td>'. '<td><input type="text" value="" name="address_'.$num. - '" onFocus="javascript:new_address('."'$num'".')" /></td><td>'; + '" onfocus="javascript:new_address('."'$num'".')" /></td><td>'; foreach my $type ('all','crit','reg') { $output .= '<span class="LC_nobreak"><label>'. '<input type="radio" name="notify_type_'.$num. @@ -1238,13 +1212,13 @@ sub colorschanger { my $resetbutton = &mt('Reset All'); my $resetbuttondesc = &mt('Reset All Colors to Default'); my $colorchooser=&Apache::lonhtmlcommon::color_picker(); - $r-print('<script type="text/javascript" language="JavaScript"> + $r->print('<script type="text/javascript" language="JavaScript"> ' . $colorchooser . ' </script> '); $r->print(<<ENDCOL); -<form name="parmform"> +<form name="parmform" action=""> <input type="hidden" name="pres_marker" /> <input type="hidden" name="pres_type" /> <input type="hidden" name="pres_value" /> @@ -1280,7 +1254,7 @@ sub verify_and_change_colors { ); my $message=''; - foreach my $item (keys %colortypes) { + foreach my $item (keys(%colortypes)) { my $color=$env{'form.'.$item}; if (!($color =~ /^#/)) { $color = '#' . $color; @@ -1323,6 +1297,12 @@ sub passwordchanger { $r->print(Apache::loncommon::start_page('Personal Data')); $r->print(Apache::lonhtmlcommon::breadcrumbs('Change Password')); } + my ($blocked,$blocktext) = + &Apache::loncommon::blocking_status('passwd'); + if ($blocked) { + $r->print('<p class="LC_warning">'.$blocktext.'</p>'); + return; + } if ((!defined($caller)) || ($caller eq 'preferences')) { $user = $env{'user.name'}; $domain = $env{'user.domain'}; @@ -1379,9 +1359,9 @@ sub passwordchanger { return if ($currentauth !~ /^(unix|internal):/); # # Generate keys - my ($lkey_cpass ,$ukey_cpass ) = &des_keys(); - my ($lkey_npass1,$ukey_npass1) = &des_keys(); - my ($lkey_npass2,$ukey_npass2) = &des_keys(); + my ($lkey_cpass ,$ukey_cpass ) = &Apache::loncommon::des_keys(); + my ($lkey_npass1,$ukey_npass1) = &Apache::loncommon::des_keys(); + my ($lkey_npass2,$ukey_npass2) = &Apache::loncommon::des_keys(); # Store the keys in the log files my $lonhost = $r->dir_config('lonHostID'); my $logtoken=Apache::lonnet::reply('tmpput:' @@ -1429,21 +1409,18 @@ sub jscript_send { uextkey=this.document.client.elements.ukey_cpass.value; lextkey=this.document.client.elements.lkey_cpass.value; initkeys(); - - this.document.pserver.elements.currentpass.value - =crypted(this.document.client.elements.currentpass.value); - + this.document.pserver.elements.currentpass.value = + getCrypted(this.document.client.elements.currentpass.value); uextkey=this.document.client.elements.ukey_npass1.value; lextkey=this.document.client.elements.lkey_npass1.value; initkeys(); this.document.pserver.elements.newpass_1.value - =crypted(this.document.client.elements.newpass_1.value); - + =getCrypted(this.document.client.elements.newpass_1.value); uextkey=this.document.client.elements.ukey_npass2.value; lextkey=this.document.client.elements.lkey_npass2.value; initkeys(); this.document.pserver.elements.newpass_2.value - =crypted(this.document.client.elements.newpass_2.value); + =getCrypted(this.document.client.elements.newpass_2.value); |; if ($caller eq 'reset_by_email') { $output .= qq| @@ -1458,6 +1435,7 @@ sub jscript_send { $ output .= qq| this.document.pserver.submit(); } + </script> |; } @@ -1474,7 +1452,7 @@ sub client_form { 'changepass' => 'Save', ); - my $output = '<form name="client">' + my $output = '<form name="client" action="">' .&Apache::lonhtmlcommon::start_pick_box(); if ($caller eq 'reset_by_email') { $output .= &Apache::lonhtmlcommon::row_title( @@ -1483,7 +1461,7 @@ sub client_form { .&Apache::lonhtmlcommon::row_closure() .&Apache::lonhtmlcommon::row_title( '<label for="uname">'.$lt{'username'}.'</label>') - .'<input type="text" name="uname" size="15" />' + .'<input type="text" name="uname" size="20" />' .'<input type="hidden" name="currentpass" value="'.$currentpass.'" />' .&Apache::lonhtmlcommon::row_closure() .&Apache::lonhtmlcommon::row_title( @@ -1493,19 +1471,19 @@ sub client_form { } else { $output .= &Apache::lonhtmlcommon::row_title( '<label for="currentpass">'.$lt{'currentpass'}.'</label>') - .'<input type="password" name="currentpass" size="10"/>' + .'<input type="password" name="currentpass" size="20"/>' .&Apache::lonhtmlcommon::row_closure(); } $output .= &Apache::lonhtmlcommon::row_title( '<label for="newpass_1">'.$lt{'newpass'}.'</label>') - .'<input type="password" name="newpass_1" size="10" />' + .'<input type="password" name="newpass_1" size="20" />' .&Apache::lonhtmlcommon::row_closure() .&Apache::lonhtmlcommon::row_title( '<label for="newpass_2">'.$lt{'confirmpass'}.'</label>') - .'<input type="password" name="newpass_2" size="10" />' + .'<input type="password" name="newpass_2" size="20" />' .&Apache::lonhtmlcommon::row_closure(1) .&Apache::lonhtmlcommon::end_pick_box(); - $output .= '<p><input type="button" value="'.$lt{'changepass'}.'" onClick="send();" /></p>' + $output .= '<p><input type="button" value="'.$lt{'changepass'}.'" onclick="send();" /></p>' .qq| <input type="hidden" name="ukey_cpass" value="$hexkey->{'ukey_cpass'}" /> <input type="hidden" name="lkey_cpass" value="$hexkey->{'lkey_cpass'}" /> @@ -1551,6 +1529,12 @@ sub server_form { sub verify_and_change_password { my ($r,$caller,$mailtoken) = @_; my ($user,$domain,$homeserver); + my ($blocked,$blocktext) = + &Apache::loncommon::blocking_status('passwd'); + if ($blocked) { + $r->print('<p class="LC_warning">'.$blocktext.'</p>'); + return; + } if ($caller eq 'reset_by_email') { $user = $env{'form.uname'}; $domain = $env{'form.udom'}; @@ -1619,10 +1603,10 @@ ENDERROR return 1; } my ($ckey,$n1key,$n2key)=split(/&/,$tmpinfo); - # - $currentpass = &des_decrypt($ckey ,$currentpass); - $newpass1 = &des_decrypt($n1key,$newpass1); - $newpass2 = &des_decrypt($n2key,$newpass2); + # + $currentpass = &Apache::loncommon::des_decrypt($ckey ,$currentpass); + $newpass1 = &Apache::loncommon::des_decrypt($n1key,$newpass1); + $newpass2 = &Apache::loncommon::des_decrypt($n2key,$newpass2); # if ($caller eq 'reset_by_email') { my %data = &Apache::lonnet::tmpget($mailtoken); @@ -1835,7 +1819,7 @@ sub verify_and_change_discussion { if (defined($env{'form.discmark'}) ) { my $newmark = $env{'form.newmark'}; if ($newmark eq 'ondisp') { - $message.=&Apache::lonhtmlcommon::confirm_success(&mt('In discussions: new posts will be cease to be identified as "NEW" after display.')).'<br />'; + $message.=&Apache::lonhtmlcommon::confirm_success(&mt('In discussions: new posts will cease to be identified as "NEW" after display.')).'<br />'; &Apache::lonnet::put('environment',{'discmarkread' => $newmark}); &Apache::lonnet::appenv({'environment.discmarkread' => $newmark}); } else { @@ -1937,6 +1921,58 @@ sub verify_and_change_coursepage { &print_main_menu($r,$message); } +sub author_space_settings { + my $r = shift; + &Apache::lonhtmlcommon::add_breadcrumb( + { href => '/adm/preferences?action=authorsettings', + text => 'Authoring Space Settings'}); + my $user = $env{'user.name'}; + my $domain = $env{'user.domain'}; + my %author_roles = &Apache::lonnet::get_my_roles($user,$domain,'userroles','',['au','ca','aa']); + if (keys(%author_roles) > 0) { + $r->print(Apache::loncommon::start_page('Authoring Space Settings')); + $r->print(Apache::lonhtmlcommon::breadcrumbs('Authoring Space Settings')); + my %userenv = &Apache::lonnet::get('environment',['nocodemirror']); + my $constchecked=''; + if ($env{'environment.nocodemirror'}) { + $constchecked=' checked="checked"'; + } + my $text=&mt('By default, CodeMirror an editor with advanced functionality for editing code is activated for authors.'); + my $cmoff=&mt('Deactivate CodeMirror. This can improve performance on slow computers and accessibility.'); + my $change=&mt('Save'); + $r->print(<<ENDSCREEN); + <form name="prefs" action="/adm/preferences" method="post"> + <input type="hidden" name="action" value="change_authoring_settings" /> + $text<br /> + <label><input type="checkbox" name="cmoff"$constchecked />$cmoff</label><br /> + <input type="submit" value="$change" /> + </form> +ENDSCREEN + } +} + +sub change_authoring_settings { + my $r = shift; + my $user = $env{'user.name'}; + my $domain = $env{'user.domain'}; + my %author_roles = &Apache::lonnet::get_my_roles($user,$domain,'userroles','',['au','ca','aa']); + if (keys(%author_roles) > 0) { + my %ausettings=('environment.nocodemirror' => ''); + if ($env{'form.cmoff'}) { $ausettings{'environment.nocodemirror'}='yes'; } + &Apache::lonnet::put('environment',\%ausettings); + &Apache::lonnet::appenv({'environment.nocodemirror' => $ausettings{'environment.nocodemirror'}}); + my $status=''; + if ($ausettings{'environment.nocodemirror'} eq 'yes') { + $status=&mt('on'); + } else { + $status=&mt('off'); + } + my $message=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]','<i>'.&mt('Deactivate CodeMirror in Authoring Space').'</i>','<tt>'.$status.'</tt>')); + $message=&Apache::loncommon::confirmwrapper($message); + &print_main_menu($r,$message); + } +} + sub lockednameschanger { my $r = shift; &Apache::lonhtmlcommon::add_breadcrumb( @@ -2178,6 +2214,18 @@ push(@{ $menu[4]->{items} }, { }); } + + my %author_roles = &Apache::lonnet::get_my_roles($user,$domain,'userroles','',['au','ca','aa']); + if (keys(%author_roles) > 0) { + push(@{ $menu[4]->{items} }, { + linktext => 'Authoring Space Configuration', + url => '/adm/preferences?action=authorsettings', + permission => 'F', + icon => 'course_ini.png', + linktitle => 'Settings for your authoring space.', + }); + } + if (&can_toggle_debug()) { push(@{ $menu[4]->{items} }, { linktext => 'Toggle Debug Messages (Currently '.($env{'user.debug'} ? 'on)' : 'off)'), @@ -2233,7 +2281,7 @@ sub handler { }elsif($env{'form.action'} eq 'changepass'){ &passwordchanger($r); }elsif($env{'form.action'} eq 'verify_and_change_pass'){ - &verify_and_change_password($r); + &verify_and_change_password($r,'preferences'); }elsif($env{'form.action'} eq 'changescreenname'){ &screennamechanger($r); }elsif($env{'form.action'} eq 'verify_and_change_screenname'){ @@ -2286,6 +2334,10 @@ sub handler { &coursedisplaychanger($r); }elsif($env{'form.action'} eq 'verify_and_change_coursepage'){ &verify_and_change_coursepage($r); + }elsif($env{'form.action'} eq 'authorsettings'){ + &author_space_settings($r); + }elsif($env{'form.action'} eq 'change_authoring_settings'){ + &change_authoring_settings($r); }elsif($env{'form.action'} eq 'debugtoggle'){ if (&can_toggle_debug()) { &toggle_debug();