--- loncom/interface/loncreateuser.pm 2018/03/23 01:01:21 1.449 +++ loncom/interface/loncreateuser.pm 2022/11/17 19:07:21 1.464 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Create a user # -# $Id: loncreateuser.pm,v 1.449 2018/03/23 01:01:21 raeburn Exp $ +# $Id: loncreateuser.pm,v 1.464 2022/11/17 19:07:21 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -71,6 +71,7 @@ use Apache::longroup; use Apache::lonuserutils; use Apache::loncoursequeueadmin; use LONCAPA qw(:DEFAULT :match); +use HTML::Entities; my $loginscript; # piece of javascript used in two separate instances my $authformnop; @@ -246,6 +247,7 @@ sub build_tools_display { 'aboutme' => "Personal Information Page", 'webdav' => "WebDAV access to Authoring Spaces (if SSL and author/co-author)", 'portfolio' => "Personal User Portfolio", + 'timezone' => "Can set Time Zone", 'avai' => "Available", 'cusa' => "availability", 'chse' => "Change setting", @@ -259,6 +261,7 @@ sub build_tools_display { 'lti' => 'Can request creation of LTI courses', 'requestauthor' => 'Can request author space', ); + $isadv = &Apache::lonnet::is_advanced_user($ccdomain,$ccuname); if ($context eq 'requestcourses') { %userenv = &Apache::lonnet::userenvironment($ccdomain,$ccuname, 'requestcourses.official','requestcourses.unofficial', @@ -272,7 +275,6 @@ sub build_tools_display { $colspan = ' colspan="2"'; %domconfig = &Apache::lonnet::get_dom('configuration',['requestcourses'],$ccdomain); - $isadv = &Apache::lonnet::is_advanced_user($ccdomain,$ccuname); } elsif ($context eq 'requestauthor') { %userenv = &Apache::lonnet::userenvironment($ccdomain,$ccuname, 'requestauthor'); @@ -286,17 +288,18 @@ sub build_tools_display { } else { %userenv = &Apache::lonnet::userenvironment($ccdomain,$ccuname, 'tools.aboutme','tools.portfolio','tools.blog', - 'tools.webdav'); - @usertools = ('aboutme','blog','webdav','portfolio'); + 'tools.webdav','tools.timezone'); + @usertools = ('aboutme','blog','webdav','portfolio','timezone'); } foreach my $item (@usertools) { my ($custom_access,$curr_access,$cust_on,$cust_off,$tool_on,$tool_off, $currdisp,$custdisp,$custradio); $cust_off = 'checked="checked" '; $tool_on = 'checked="checked" '; - $curr_access = + $curr_access = &Apache::lonnet::usertools_access($ccuname,$ccdomain,$item,undef, - $context); + $context,\%userenv,'', + {'is_adv' => $isadv}); if ($context eq 'requestauthor') { if ($userenv{$context} ne '') { $cust_on = ' checked="checked" '; @@ -1484,17 +1487,21 @@ ENDAUTH $inst_results{$ccuname.':'.$ccdomain})); if ((&Apache::lonnet::allowed('ccc',$env{'request.role.domain'})) || (&Apache::lonnet::allowed('udp',$env{'request.role.domain'}))) { - $r->print('<br /><h3>'.&mt('User Can Request Creation of Courses/Communities in this Domain?').'</h3>'. - &Apache::loncommon::start_data_table()); - if ($env{'request.role.domain'} eq $ccdomain) { - $r->print(&build_tools_display($ccuname,$ccdomain,'requestcourses')); - } else { - if (&Apache::lonnet::will_trust('reqcrs',$ccdomain,$env{'request.role.domain'})) { + $r->print('<br /><h3>'.&mt('User Can Request Creation of Courses/Communities in this Domain?').'</h3>'."\n"); + if (($env{'request.role.domain'} eq $ccdomain) || + (&Apache::lonnet::will_trust('reqcrs',$ccdomain,$env{'request.role.domain'}))) { + $r->print(&Apache::loncommon::start_data_table()); + if ($env{'request.role.domain'} eq $ccdomain) { + $r->print(&build_tools_display($ccuname,$ccdomain,'requestcourses')); + } else { $r->print(&coursereq_externaluser($ccuname,$ccdomain, $env{'request.role.domain'})); } + $r->print(&Apache::loncommon::end_data_table()); + } else { + $r->print(&mt('Domain configuration for this domain prohibits course creation by users from domain: "[_1]"', + &Apache::lonnet::domain($ccdomain,'description'))); } - $r->print(&Apache::loncommon::end_data_table()); } $r->print('</div>'); my @order = ('auth','quota','tools','requestauthor'); @@ -1507,7 +1514,7 @@ ENDAUTH ($env{'request.role.domain'} eq $ccdomain)) { $user_text{'requestauthor'} = &domainrole_req($ccuname,$ccdomain); } - $user_text{'auth'} = &user_authentication($ccuname,$ccdomain,$formname); + $user_text{'auth'} = &user_authentication($ccuname,$ccdomain,$formname,$crstype,$permission); if ((&Apache::lonnet::allowed('mpq',$ccdomain)) || (&Apache::lonnet::allowed('mut',$ccdomain)) || (&Apache::lonnet::allowed('udp',$ccdomain))) { @@ -1612,7 +1619,7 @@ ENDNOTOOLSPRIV if ($newuser) { $r->print(' onclick="auth_check()" \>'."\n"); } else { - $r->print('onclick="this.form.submit()" \>'."\n"); + $r->print(' onclick="this.form.submit()" \>'."\n"); } } else { $r->print('</fieldset></div>'. @@ -2194,7 +2201,7 @@ sub new_domain_roles { } sub user_authentication { - my ($ccuname,$ccdomain,$formname) = @_; + my ($ccuname,$ccdomain,$formname,$crstype,$permission) = @_; my $currentauth=&Apache::lonnet::queryauthenticate($ccuname,$ccdomain); my $outcome; my %lt=&Apache::lonlocal::texthash( @@ -2267,6 +2274,43 @@ ENDBADAUTH } $outcome .= &Apache::loncommon::end_data_table(); } else { + if (($currentauth =~ /^internal:/) && + (&Apache::lonuserutils::can_change_internalpass($ccuname,$ccdomain,$crstype,$permission))) { + $outcome = <<"ENDJS"; +<script type="text/javascript"> +// <![CDATA[ +function togglePwd(form) { + if (form.newintpwd.length) { + if (document.getElementById('LC_ownersetpwd')) { + for (var i=0; i<form.newintpwd.length; i++) { + if (form.newintpwd[i].checked) { + if (form.newintpwd[i].value == 1) { + document.getElementById('LC_ownersetpwd').style.display = 'inline-block'; + } else { + document.getElementById('LC_ownersetpwd').style.display = 'none'; + } + } + } + } + } +} +// ]]> +</script> +ENDJS + + $outcome .= '<h3>'.$lt{'ld'}.'</h3>'. + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_row(). + '<td>'.&mt('Internally authenticated').'<br />'.&mt("Change user's password?"). + '<label><input type="radio" name="newintpwd" value="0" checked="checked" onclick="togglePwd(this.form);" />'. + &mt('No').'</label>'.(' 'x2). + '<label><input type="radio" name="newintpwd" value="1" onclick="togglePwd(this.form);" />'.&mt('Yes').'</label>'. + '<div id="LC_ownersetpwd" style="display:none">'. + ' '.&mt('Password').' <input type="password" size="15" name="intarg" value="" />'. + '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.intarg.type='."'text'".' } else { this.form.intarg.type='."'password'".' }" />'.&mt('Visible input').'</label></div></td>'. + &Apache::loncommon::end_data_table_row(). + &Apache::loncommon::end_data_table(); + } if (&Apache::lonnet::allowed('udp',$ccdomain)) { # Current user has rights to view domain preferences for user's domain my $result; @@ -2285,7 +2329,7 @@ ENDBADAUTH } elsif ($currentauth =~ /^unix:/) { $result = &mt('Currently Filesystem Authenticated.'); } elsif ($currentauth =~ /^lti:/) { - $result = &mt('Currently LTi authenticated.'); + $result = &mt('Currently LTI authenticated.'); } $outcome = '<h3>'.$lt{'ld'}.'</h3>'. &Apache::loncommon::start_data_table(). @@ -2400,8 +2444,8 @@ sub modify_login_block { } sub personal_data_display { - my ($ccuname,$ccdomain,$newuser,$context,$inst_results,$rolesarray, - $now,$captchaform,$emailusername,$usertype,$usernameset,$condition,$excluded) = @_; + my ($ccuname,$ccdomain,$newuser,$context,$inst_results,$rolesarray,$now, + $captchaform,$emailusername,$usertype,$usernameset,$condition,$excluded,$showsubmit) = @_; my ($output,%userenv,%canmodify,%canmodify_status); my @userinfo = ('firstname','middlename','lastname','generation', 'permanentemail','id'); @@ -2511,8 +2555,8 @@ sub personal_data_display { } $rowcount ++; $output .= &Apache::lonhtmlcommon::row_closure(1); - my $upassone = '<input type="password" name="upass'.$now.'" size="20" autocomplete="off" />'; - my $upasstwo = '<input type="password" name="upasscheck'.$now.'" size="20" autocomplete="off" />'; + my $upassone = '<input type="password" name="upass'.$now.'" size="20" autocomplete="new-password" />'; + my $upasstwo = '<input type="password" name="upasscheck'.$now.'" size="20" autocomplete="new-password" />'; $output .= &Apache::lonhtmlcommon::row_title(&mt('Password').'<b>*</b>', 'LC_pick_box_title', 'LC_oddrow_value')."\n". @@ -2526,10 +2570,11 @@ sub personal_data_display { if ($usernameset eq 'free') { my $onclick = "toggleUsernameDisp(this,'selfcreateusername');"; $output .= &Apache::lonhtmlcommon::row_title($lt{'username'},undef,'LC_oddrow_value')."\n". - &mt('Use e-mail address: '). - '<label><input type="radio" name="emailused" value="1" checked="checked" onclick="'.$onclick.'" />'.&mt('Yes').'</label>'."\n". - (' 'x2). - '<label><input type="radio" name="emailused" value="0" onclick="'.$onclick.'" />'.&mt('No').'</label>'."\n". + '<span class="LC_nobreak">'.&mt('Use e-mail address: '). + '<label><input type="radio" name="emailused" value="1" checked="checked" onclick="'.$onclick.'" />'. + &mt('Yes').'</label>'.(' 'x2). + '<label><input type="radio" name="emailused" value="0" onclick="'.$onclick.'" />'. + &mt('No').'</label></span>'."\n". '<div id="selfcreateusername" style="display: none; font-size: smaller">'. '<br /><span class="LC_nobreak">'.&mt('Preferred username'). ' <input type="text" name="username" value="" size="20" autocomplete="off"/>'. @@ -2637,12 +2682,17 @@ sub personal_data_display { &Apache::lonhtmlcommon::row_closure(1); $rowcount ++; } - my $submit_text = &mt('Create account'); - $output .= &Apache::lonhtmlcommon::row_title()."\n". - '<br /><input type="submit" name="createaccount" value="'. - $submit_text.'" />'. - '<input type="hidden" name="type" value="'.$usertype.'" />'. - &Apache::lonhtmlcommon::row_closure(1); + if ($showsubmit) { + my $submit_text = &mt('Create account'); + $output .= &Apache::lonhtmlcommon::row_title()."\n". + '<br /><input type="submit" name="createaccount" value="'. + $submit_text.'" />'; + if ($usertype ne '') { + $output .= '<input type="hidden" name="type" value="'. + &HTML::Entities::encode($usertype,'\'<>"&').'" />'; + } + $output .= &Apache::lonhtmlcommon::row_closure(1); + } } $output .= &Apache::lonhtmlcommon::end_pick_box(); if (wantarray) { @@ -2726,7 +2776,7 @@ sub get_inststatuses { # ================================================================= Phase Three sub update_user_data { - my ($r,$context,$crstype,$brcrum,$showcredits) = @_; + my ($r,$context,$crstype,$brcrum,$showcredits,$permission) = @_; my $uhome=&Apache::lonnet::homeserver($env{'form.ccuname'}, $env{'form.ccdomain'}); # Error messages @@ -2865,7 +2915,7 @@ sub update_user_data { my (%alerts,%rulematch,%inst_results,%curr_rules); my @userinfo = ('firstname','middlename','lastname','generation','permanentemail','id'); - my @usertools = ('aboutme','blog','webdav','portfolio'); + my @usertools = ('aboutme','blog','webdav','portfolio','timezone'); my @requestcourses = ('official','unofficial','community','textbook','placement','lti'); my @requestauthor = ('requestauthor'); my ($othertitle,$usertypes,$types) = @@ -2995,7 +3045,7 @@ sub update_user_data { $env{'form.ccdomain'},$env{'form.ccuname'}); } } - $r->print('<br />'.&mt('Home server').': '.$uhome.' '. + $r->print('<br />'.&mt('Home Server').': '.$uhome.' '. &Apache::lonnet::hostname($uhome)); } elsif (($env{'form.login'} ne 'nochange') && ($env{'form.login'} ne '' )) { @@ -3010,12 +3060,19 @@ sub update_user_data { &Apache::lonnet::modifyuserauth( $env{'form.ccdomain'},$env{'form.ccuname'}, $amode,$genpwd)); - $r->print('<br />'.&mt('Home server').': '.&Apache::lonnet::homeserver + $r->print('<br />'.&mt('Home Server').': '.&Apache::lonnet::homeserver ($env{'form.ccuname'},$env{'form.ccdomain'})); } else { # Okay, this is a non-fatal error. - $r->print($error.&mt('You do not have the authority to modify this users authentication information.').$end); + $r->print($error.&mt('You do not have privileges to modify the authentication configuration for this user.').$end); } + } elsif (($env{'form.intarg'} ne '') && + (&Apache::lonnet::queryauthenticate($env{'form.ccuname'},$env{'form.ccdomain'}) =~ /^internal:/) && + (&Apache::lonuserutils::can_change_internalpass($env{'form.ccuname'},$env{'form.ccdomain'},$crstype,$permission))) { + $r->print('Modifying authentication: '. + &Apache::lonnet::modifyuserauth( + $env{'form.ccdomain'},$env{'form.ccuname'}, + 'internal',$env{'form.intarg'})); } $r->rflush(); # Finish display of header before time consuming actions start &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state); @@ -3034,12 +3091,14 @@ sub update_user_data { my %userenv = &Apache::lonnet::get ('environment',['firstname','middlename','lastname','generation', 'id','permanentemail','portfolioquota','authorquota','inststatus', - 'tools.aboutme','tools.blog','tools.webdav','tools.portfolio', + 'tools.aboutme','tools.blog','tools.webdav', + 'tools.portfolio','tools.timezone', 'requestcourses.official','requestcourses.unofficial', 'requestcourses.community','requestcourses.textbook', + 'requestcourses.lti','requestauthor', 'reqcrsotherdom.official','reqcrsotherdom.unofficial', 'reqcrsotherdom.community','reqcrsotherdom.textbook', - 'reqcrsotherdom.placement','requestauthor'], + 'reqcrsotherdom.placement'], $env{'form.ccdomain'},$env{'form.ccuname'}); my ($tmp) = keys(%userenv); if ($tmp =~ /^(con_lost|error)/i) { @@ -3069,7 +3128,7 @@ sub update_user_data { } } elsif ($context eq 'author') { if ($rolenum eq $auname && $roledom eq $audom) { - if (!grep(/^\Q$role\E$/,@userroles)) { + if (!grep(/^\Q$role\E$/,@userroles)) { push(@userroles,$role); } } @@ -3368,6 +3427,10 @@ sub update_user_data { &Apache::lonnet::appenv(\%newenvhash); } } + if ($changed{'aboutme'}) { + &Apache::loncommon::devalidate_aboutme_cache($env{'form.ccuname'}, + $env{'form.ccdomain'}); + } } } if (keys(%namechanged) > 0) { @@ -3537,6 +3600,7 @@ sub display_userinfo { 'webdav' => 'WebDAV Availability', 'aboutme' => 'Personal Information Page Availability', 'portfolio' => 'Portfolio Availability', + 'timezone' => 'Can set own Time Zone', 'official' => 'Can Request Official Courses', 'unofficial' => 'Can Request Unofficial Courses', 'community' => 'Can Request Communities', @@ -4044,9 +4108,9 @@ sub update_roles { my $result=&Apache::lonnet::assignrole($env{'form.ccdomain'}, $env{'form.ccuname'},$url,$role,0,$now,'','', $context); - $output = &Apache::lonhtmlcommon::confirm_success(&mt('Re-enabling [_1] in [_2]', - &Apache::lonnet::plaintext($role), - &Apache::loncommon::show_role_extent($url,$context,$role)),$result ne "ok").'<br />'; + $output = &Apache::lonhtmlcommon::confirm_success(&mt('Re-enabling [_1] in [_2]', + &Apache::lonnet::plaintext($role), + &Apache::loncommon::show_role_extent($url,$context,$role)),$result ne "ok").'<br />'; if ($result ne "ok") { $output .= &mt('Error: [_1]',$result).'<br />'; } @@ -4091,7 +4155,7 @@ sub update_roles { # split multiple sections my %sections = (); - my $num_sections = &build_roles($env{'form.sec_'.$full},\%sections,$5); + my $num_sections = &build_roles($env{'form.sec_'.$full},\%sections,$five); if ($num_sections == 0) { $r->print(&Apache::loncommon::commit_customrole($udom,$uname,$url,$three,$four,$five,$start,$end,$context)); } else { @@ -4114,10 +4178,10 @@ sub update_roles { # Activate roles for sections with 3 id numbers # set start, end times, and the url for the class my ($one,$two,$three)=($1,$2,$3); - my $start = ( $env{'form.start_'.$one.'_'.$two.'_'.$three} ? - $env{'form.start_'.$one.'_'.$two.'_'.$three} : + my $start = ( $env{'form.start_'.$one.'_'.$two.'_'.$three} ? + $env{'form.start_'.$one.'_'.$two.'_'.$three} : $now ); - my $end = ( $env{'form.end_'.$one.'_'.$two.'_'.$three} ? + my $end = ( $env{'form.end_'.$one.'_'.$two.'_'.$three} ? $env{'form.end_'.$one.'_'.$two.'_'.$three} : 0 ); my $url='/'.$one.'/'.$two; @@ -4127,7 +4191,7 @@ sub update_roles { my $num_sections = &build_roles($env{'form.sec_'.$one.'_'.$two.'_'.$three},\%sections,$three); my $credits; if ($three eq 'st') { - if ($showcredits) { + if ($showcredits) { my $defaultcredits = &Apache::lonuserutils::get_defaultcredits($one,$two); $credits = $env{'form.credits_'.$one.'_'.$two.'_'.$three}; @@ -4167,10 +4231,10 @@ sub update_roles { } elsif ($key=~/^form\.act\_([^\_]+)\_([^\_]+)$/) { # Activate roles for sections with two id numbers # set start, end times, and the url for the class - my $start = ( $env{'form.start_'.$1.'_'.$2} ? - $env{'form.start_'.$1.'_'.$2} : + my $start = ( $env{'form.start_'.$1.'_'.$2} ? + $env{'form.start_'.$1.'_'.$2} : $now ); - my $end = ( $env{'form.end_'.$1.'_'.$2} ? + my $end = ( $env{'form.end_'.$1.'_'.$2} ? $env{'form.end_'.$1.'_'.$2} : 0 ); my $one = $1; @@ -4924,7 +4988,7 @@ sub handler { &print_useraccesslogs_display($r,$ccuname,$ccdomain,$permission,$brcrum); } } elsif ($env{'form.phase'} eq 'update_user_data') { - &update_user_data($r,$context,$crstype,$brcrum,$showcredits); + &update_user_data($r,$context,$crstype,$brcrum,$showcredits,$permission); } else { &print_username_entry_form($r,$context,undef,$srch,undef,$crstype, $brcrum,$permission); @@ -5302,7 +5366,8 @@ sub handler { '<span class="LC_error">'.&mt('You do not have permission to view change logs').'</span>'); } } elsif ($env{'form.action'} eq 'helpdesk') { - if (($permission->{'owner'}) || ($permission->{'co-owner'})) { + if (($permission->{'owner'} || $permission->{'co-owner'}) && + ($permission->{'cusr'} || $permission->{'view'})) { if ($env{'form.state'} eq 'process') { if ($permission->{'owner'}) { &update_helpdeskaccess($r,$permission,$brcrum); @@ -5732,7 +5797,8 @@ sub print_main_menu { icon => 'helpdesk-access.png', #help => 'Course_Helpdesk_Access', url => '/adm/createuser?action=helpdesk', - permission => ($permission->{'owner'} || $permission->{'co-owner'}), + permission => (($permission->{'owner'} || $permission->{'co-owner'}) && + ($permission->{'view'} || $permission->{'cusr'})), linktitle => 'Helpdesk access options', }, { @@ -7099,9 +7165,10 @@ ENDSCRIPT my ($nav_script,$nav_links); # table header - my $tableheader = '<h3>'. + my $heading = '<h3>'. &mt('User access logs for: [_1]', - &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$udom),$uname,$udom)).'</h3>' + &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$udom),$uname,$udom)).'</h3>'; + my $tableheader = $heading .&Apache::loncommon::start_data_table_header_row() .'<th> </th>' .'<th>'.&mt('When').'</th>' @@ -7219,7 +7286,7 @@ ENDSCRIPT $r->print(&Apache::loncommon::end_data_table(). &userlogdisplay_navlinks(\%curr,$more_records)); } else { # No content displayed above - $r->print('<p class="LC_info">' + $r->print($heading.'<p class="LC_info">' .&mt('There are no records to display.') .'</p>'); } @@ -7408,12 +7475,12 @@ sub role_display_filter { &mt('Context:').'</b><br /><select name="chgcontext">'; my @posscontexts; if ($context eq 'course') { - @posscontexts = ('any','automated','updatenow','createcourse','course','domain','selfenroll','requestcourses'); + @posscontexts = ('any','automated','updatenow','createcourse','course','domain','selfenroll','requestcourses','chgtype'); } elsif ($context eq 'domain') { @posscontexts = ('any','domain','requestauthor','domconfig','server'); } else { @posscontexts = ('any','author','domain'); - } + } foreach my $chgtype (@posscontexts) { my $selstr = ''; if ($curr->{'chgcontext'} eq $chgtype) { @@ -7457,6 +7524,7 @@ sub rolechg_contexts { %lt = &Apache::lonlocal::texthash ( any => 'Any', automated => 'Automated Enrollment', + chgtype => 'Enrollment Type/Lock Change', updatenow => 'Roster Update', createcourse => 'Course Creation', course => 'User Management in course',