--- loncom/interface/loncreateuser.pm 2001/03/17 15:06:57 1.7 +++ loncom/interface/loncreateuser.pm 2007/12/08 19:19:03 1.205 @@ -1,72 +1,310 @@ -# The LearningOnline Network +# The LearningOnline Network with CAPA # Create a user # -# (Create a course -# (My Desk +# $Id: loncreateuser.pm,v 1.205 2007/12/08 19:19:03 raeburn Exp $ # -# (Internal Server Error Handler +# Copyright Michigan State University Board of Trustees # -# (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) +# This file is part of the LearningOnline Network with CAPA (LON-CAPA). # -# 3/1/1 Gerd Kortemeyer) +# LON-CAPA is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. # -# 3/1 Gerd Kortemeyer) +# LON-CAPA is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # -# 2/14 Gerd Kortemeyer) +# You should have received a copy of the GNU General Public License +# along with LON-CAPA; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# 2/14,2/17,2/19,2/20,2/21,2/22,2/23,3/2,3/17 Gerd Kortemeyer +# /home/httpd/html/adm/gpl.txt # +# http://www.lon-capa.org/ +# +### + package Apache::loncreateuser; +=pod + +=head1 NAME + +Apache::loncreateuser - handler to create users and custom roles + +=head1 SYNOPSIS + +Apache::loncreateuser provides an Apache handler for creating users, + editing their login parameters, roles, and removing roles, and + also creating and assigning custom roles. + +=head1 OVERVIEW + +=head2 Custom Roles + +In LON-CAPA, roles are actually collections of privileges. "Teaching +Assistant", "Course Coordinator", and other such roles are really just +collection of privileges that are useful in many circumstances. + +Creating custom roles can be done by the Domain Coordinator through +the Create User functionality. That screen will show all privileges +that can be assigned to users. For a complete list of privileges, +please see C. + +Custom role definitions are stored in the C file of the role +author. + +=cut + use strict; use Apache::Constants qw(:common :http); use Apache::lonnet; +use Apache::loncommon; +use Apache::lonlocal; +use Apache::longroup; +use Apache::lonuserutils; +use LONCAPA qw(:DEFAULT :match); + +my $loginscript; # piece of javascript used in two separate instances +my $authformnop; +my $authformkrb; +my $authformint; +my $authformfsys; +my $authformloc; + +sub initialize_authen_forms { + my ($dom,$curr_authtype,$mode) = @_; + my ($krbdefdom)=( $ENV{'SERVER_NAME'}=~/(\w+\.\w+)$/); + $krbdefdom= uc($krbdefdom); + my %param = ( formname => 'document.cu', + kerb_def_dom => $krbdefdom, + domain => $dom, + ); + my %abv_auth = &auth_abbrev(); + if ($curr_authtype =~ /^(krb4|krb5|internal|localauth|unix):$/) { + my $long_auth = $1; + my %abv_auth = &auth_abbrev(); + $param{'curr_authtype'} = $abv_auth{$long_auth}; + if ($long_auth =~ /^krb(4|5)$/) { + $param{'curr_kerb_ver'} = $1; + } + if ($mode eq 'modifyuser') { + $param{'mode'} = $mode; + } + } +# no longer static due to configurable kerberos defaults +# $loginscript = &Apache::loncommon::authform_header(%param); + $authformnop = &Apache::loncommon::authform_nochange(%param); +# no longer static due to configurable kerberos defaults +# $authformkrb = &Apache::loncommon::authform_kerberos(%param); + $authformint = &Apache::loncommon::authform_internal(%param); + $authformfsys = &Apache::loncommon::authform_filesystem(%param); + $authformloc = &Apache::loncommon::authform_local(%param); +} + +sub auth_abbrev { + my %abv_auth = ( + krb4 => 'krb', + internal => 'int', + localuth => 'loc', + unix => 'fsys', + ); + return %abv_auth; +} + +# ==================================================== Figure out author access + +sub authorpriv { + my ($auname,$audom)=@_; + unless ((&Apache::lonnet::allowed('cca',$audom.'/'.$auname)) + || (&Apache::lonnet::allowed('caa',$audom.'/'.$auname))) { return ''; } + return 1; +} + +# ==================================================== + +sub portfolio_quota { + my ($ccuname,$ccdomain) = @_; + my %lt = &Apache::lonlocal::texthash( + 'disk' => "Disk space allocated to user's portfolio files", + 'cuqu' => "Current quota", + 'cust' => "Custom quota", + 'defa' => "Default", + 'chqu' => "Change quota", + ); + my ($currquota,$quotatype,$inststatus,$defquota) = + &Apache::loncommon::get_user_quota($ccuname,$ccdomain); + my ($usertypes,$order) = &Apache::lonnet::retrieve_inst_usertypes($ccdomain); + my ($longinsttype,$showquota,$custom_on,$custom_off,$defaultinfo); + if ($inststatus ne '') { + if ($usertypes->{$inststatus} ne '') { + $longinsttype = $usertypes->{$inststatus}; + } + } + $custom_on = ' '; + $custom_off = ' checked="checked" '; + my $quota_javascript = <<"END_SCRIPT"; + +END_SCRIPT + if ($quotatype eq 'custom') { + $custom_on = $custom_off; + $custom_off = ' '; + $showquota = $currquota; + if ($longinsttype eq '') { + $defaultinfo = &mt('For this user, the default quota would be [_1] + Mb.',$defquota); + } else { + $defaultinfo = &mt("For this user, the default quota would be [_1] + Mb, as determined by the user's institutional + affiliation ([_2]).",$defquota,$longinsttype); + } + } else { + if ($longinsttype eq '') { + $defaultinfo = &mt('For this user, the default quota is [_1] + Mb.',$defquota); + } else { + $defaultinfo = &mt("For this user, the default quota of [_1] + Mb, is determined by the user's institutional + affiliation ([_2]).",$defquota,$longinsttype); + } + } + my $output = $quota_javascript. + '

'.$lt{'disk'}.'

'. + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_row(). + ''.$lt{'cuqu'}.': '.$currquota.' Mb.  '. + $defaultinfo.''. + &Apache::loncommon::end_data_table_row(). + &Apache::loncommon::start_data_table_row(). + ''.$lt{'chqu'}. + ':  '. + '  '. + ' Mb'. + &Apache::loncommon::end_data_table_row(). + &Apache::loncommon::end_data_table(); + return $output; +} # =================================================================== Phase one -sub phase_one { - my $r=shift; - my $defdom=$ENV{'user.domain'}; - $r->print(< - -The LearningOnline Network with CAPA - - -

Create User, Change User Privileges

-
- -Username:
-Domain:

- +sub print_username_entry_form { + my ($r,$response,$srch,$forcenewuser) = @_; + my $defdom=$env{'request.role.domain'}; + my $formtoset = 'crtuser'; + if (exists($env{'form.startrolename'})) { + $formtoset = 'docustom'; + $env{'form.rolename'} = $env{'form.startrolename'}; + } + + my ($jsback,$elements) = &crumb_utilities(); + + my $jscript = &Apache::loncommon::studentbrowser_javascript()."\n". + ''."\n"; + + my %loaditems = ( + 'onload' => "javascript:setFormElements(document.$formtoset)", + ); + my $start_page = + &Apache::loncommon::start_page('User Management', + $jscript,{'add_entries' => \%loaditems,}); + if ($env{'form.action'} eq 'singleuser') { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:backPage(document.crtuser)", + text=>"Single user search", + faq=>282,bug=>'Instructor Interface',}); + } elsif ($env{'form.action'} eq 'custom') { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:backPage(document.crtuser)", + text=>"Pick custom role",}); + } + my $crumbs = &Apache::lonhtmlcommon::breadcrumbs('User Management'); + my %existingroles=&Apache::lonuserutils::my_custom_roles(); + my $choice=&Apache::loncommon::select_form('make new role','rolename', + ('make new role' => 'Generate new role ...',%existingroles)); + my %lt=&Apache::lonlocal::texthash( + 'srch' => "User Search", + or => "or", + 'usr' => "Username", + 'dom' => "Domain", + 'ecrp' => "Edit Custom Role Privileges", + 'nr' => "Name of Role", + 'cre' => "Custom Role Editor", + 'mod' => "to add/modify roles", + ); + my $help = &Apache::loncommon::help_open_menu(undef,undef,282,'Instructor Interface'); + my $helpsiur=&Apache::loncommon::help_open_topic('Course_Change_Privileges'); + my $helpecpr=&Apache::loncommon::help_open_topic('Course_Editing_Custom_Roles'); + my $sellink=&Apache::loncommon::selectstudent_link('crtuser','srchterm','srchdomain'); + if ($sellink) { + $sellink = "$lt{'or'} ".$sellink; + } + $r->print($start_page."\n".$crumbs); + if ($env{'form.action'} eq 'singleuser') { + $r->print(" +

$lt{'srch'} $sellink $lt{'mod'}$helpsiur

+$response"); + $r->print(&entry_form($defdom,$srch,$forcenewuser)); + } elsif ($env{'form.action'} eq 'custom') { + if (&Apache::lonnet::allowed('mcr','/')) { + $r->print(< + + +

$lt{'ecrp'}$helpecpr

+$lt{'nr'}: $choice
+ + +ENDCUSTOM + } + } + $r->print(&Apache::loncommon::end_page()); +} + +sub entry_form { + my ($dom,$srch,$forcenewuser) = @_; + my $userpicker = + &Apache::loncommon::user_picker($dom,$srch,$forcenewuser, + 'document.crtuser'); + my $srchbutton = &mt('Search'); + my $output = <<"ENDDOCUMENT"; +
+ + +$userpicker +
- - ENDDOCUMENT + return $output; } -# =================================================================== Phase two - -sub phase_two { - my $r=shift; - my $ccuname=$ENV{'form.ccuname'}; - my $ccdomain=$ENV{'form.ccdomain'}; - - $ENV{'SERVER_NAME'}=~/(\w+\.\w+)$/; - my $krbdefdom=$1; - $krbdefdom=~tr/a-z/A-Z/; - - my $defdom=$ENV{'user.domain'}; - - $ccuname=~s/\W//g; - $ccdomain=~s/\W//g; - $r->print(< - -The LearningOnline Network with CAPA - +END +} + +# =================================================================== Phase two +sub print_user_selection_page { + my ($r,$response,$srch,$srch_results,$operation,$srcharray) = @_; + my @fields = ('username','domain','lastname','firstname','permanentemail'); + my $sortby = $env{'form.sortby'}; + + if (!grep(/^\Q$sortby\E$/,@fields)) { + $sortby = 'lastname'; + } + + my ($jsback,$elements) = &crumb_utilities(); + + my $jscript = (< +function pickuser(uname,udom) { + document.usersrchform.seluname.value=uname; + document.usersrchform.seludom.value=udom; + document.usersrchform.phase.value="userpicked"; + document.usersrchform.submit(); +} + +$jsback - - - -

Create User, Change User Privileges

-
- - - - - - - - +ENDSCRIPT -ENDENHEAD + my %lt=&Apache::lonlocal::texthash( + 'usrch' => "User Search to add/modify roles", + 'stusrch' => "User Search to enroll student", + 'usel' => "Select a user to add/modify roles", + 'stusel' => "Select a user to enroll as a student", + 'username' => "username", + 'domain' => "domain", + 'lastname' => "last name", + 'firstname' => "first name", + 'permanentemail' => "permanent e-mail", + ); + if ($operation eq 'createuser') { + $r->print(&Apache::loncommon::start_page('User Management',$jscript)); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:backPage(document.usersrchform,'','')", + text=>"Create/modify user", + faq=>282,bug=>'Instructor Interface',}, + {href=>"javascript:backPage(document.usersrchform,'get_user_info','select')", + text=>"Select User", + faq=>282,bug=>'Instructor Interface',}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management')); + $r->print("$lt{'usrch'}
"); + $r->print(&entry_form($srch->{'srchdomain'},$srch)); + $r->print('

'.$lt{'usel'}.'

'); + } else { + $r->print($jscript."$lt{'stusrch'}
"); + $r->print(&Apache::londropadd::single_user_entry_form($srch->{'srchdomain'},$srch)); + $r->print('

'.$lt{'stusel'}.'

'); + } + $r->print('
'. + &Apache::loncommon::start_data_table()."\n". + &Apache::loncommon::start_data_table_header_row()."\n". + ' '."\n"); + foreach my $field (@fields) { + $r->print(' '. + $lt{$field}.''."\n"); + } + $r->print(&Apache::loncommon::end_data_table_header_row()); + + my @sorted_users = sort { + lc($srch_results->{$a}->{$sortby}) cmp lc($srch_results->{$b}->{$sortby}) + || + lc($srch_results->{$a}->{lastname}) cmp lc($srch_results->{$b}->{lastname}) + || + lc($srch_results->{$a}->{firstname}) cmp lc($srch_results->{$b}->{firstname}) + || + lc($a) cmp lc($b) + } (keys(%$srch_results)); + + foreach my $user (@sorted_users) { + my ($uname,$udom) = split(/:/,$user); + $r->print(&Apache::loncommon::start_data_table_row(). + ''. + ''.$uname.''. + ''.$udom.''); + foreach my $field ('lastname','firstname','permanentemail') { + $r->print(''.$srch_results->{$user}->{$field}.''); + } + $r->print(&Apache::loncommon::end_data_table_row()); + } + $r->print(&Apache::loncommon::end_data_table().'

'); + if (ref($srcharray) eq 'ARRAY') { + foreach my $item (@{$srcharray}) { + $r->print(''."\n"); + } + } + $r->print(' '."\n". + ' '."\n". + ' '."\n". + ' '."\n". + ' '."\n". + ' '."\n"); + $r->print($response); + if ($operation eq 'createuser') { + $r->print('
'.&Apache::loncommon::end_page()); + } else { + $r->print(''."\n". + ''."\n"); + } +} + +sub print_user_query_page { + my ($r,$caller) = @_; +# FIXME - this is for a network-wide name search (similar to catalog search) +# To use frames with similar behavior to catalog/portfolio search. +# To be implemented. + return; +} + +sub print_user_modification_page { + my ($r,$ccuname,$ccdomain,$srch,$response,$context) = @_; + if (($ccuname eq '') || ($ccdomain eq '')) { + my $usermsg = &mt('No username and/or domain provided.'); + &print_username_entry_form($r,$usermsg); + return; + } + my %abv_auth = &auth_abbrev(); + my ($curr_authtype,%rulematch,%inst_results,$curr_kerb_ver,$newuser, + %alerts,%curr_rules,%got_rules); my $uhome=&Apache::lonnet::homeserver($ccuname,$ccdomain); - my %incdomains; + if ($uhome eq 'no_host') { + $newuser = 1; + my $checkhash; + my $checks = { 'username' => 1 }; + $checkhash->{$ccuname.':'.$ccdomain} = { 'newuser' => $newuser }; + &Apache::loncommon::user_rule_check($checkhash,$checks, + \%alerts,\%rulematch,\%inst_results,\%curr_rules,\%got_rules); + if (ref($alerts{'username'}) eq 'HASH') { + if (ref($alerts{'username'}{$ccdomain}) eq 'HASH') { + my $domdesc = + &Apache::lonnet::domain($ccdomain,'description'); + if ($alerts{'username'}{$ccdomain}{$ccuname}) { + my $userchkmsg; + if (ref($curr_rules{$ccdomain}) eq 'HASH') { + $userchkmsg = + &Apache::loncommon::instrule_disallow_msg('username', + $domdesc,1). + &Apache::loncommon::user_rule_formats($ccdomain, + $domdesc,$curr_rules{$ccdomain}{'username'}, + 'username'); + } + &print_username_entry_form($r,$userchkmsg); + return; + } + } + } + } else { + $newuser = 0; + my $currentauth = + &Apache::lonnet::queryauthenticate($ccuname,$ccdomain); + if ($currentauth =~ /^(krb4|krb5|unix|internal|localauth):/) { + $curr_authtype = $abv_auth{$1}; + if ($currentauth =~ /^krb(4|5)/) { + $curr_kerb_ver = $1; + } + } + } + if ($response) { + $response = '
'.$response + } + my $defdom=$env{'request.role.domain'}; + + my ($krbdef,$krbdefdom) = + &Apache::loncommon::get_kerberos_defaults($defdom); + + my %param = ( formname => 'document.cu', + kerb_def_dom => $krbdefdom, + kerb_def_auth => $krbdef, + curr_authtype => $curr_authtype, + curr_kerb_ver => $curr_kerb_ver, + domain => $ccdomain, + ); + $loginscript = &Apache::loncommon::authform_header(%param); + $authformkrb = &Apache::loncommon::authform_kerberos(%param); + + my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition(); + my $dc_setcourse_code = ''; + my $nondc_setsection_code = ''; + + my %loaditem; + + my $groupslist; + my %curr_groups = &Apache::longroup::coursegroups(); + if (%curr_groups) { + $groupslist = join('","',sort(keys(%curr_groups))); + $groupslist = '"'.$groupslist.'"'; + } + + if ($env{'request.role'} =~ m-^dc\./($match_domain)/$-) { + my $dcdom = $1; + $loaditem{'onload'} = "document.cu.coursedesc.value='';"; + my @rolevals = ('st','ta','ep','in','cc'); + my (@crsroles,@grproles); + for (my $i=0; $i<@rolevals; $i++) { + $crsroles[$i]=&Apache::lonnet::plaintext($rolevals[$i],'Course'); + $grproles[$i]=&Apache::lonnet::plaintext($rolevals[$i],'Group'); + } + my $rolevalslist = join('","',@rolevals); + my $crsrolenameslist = join('","',@crsroles); + my $grprolenameslist = join('","',@grproles); + my $pickcrsfirst = '<--'.&mt('Pick course first'); + my $pickgrpfirst = '<--'.&mt('Pick group first'); + $dc_setcourse_code = <<"ENDSCRIPT"; + function setCourse() { + var course = document.cu.dccourse.value; + if (course != "") { + if (document.cu.dcdomain.value != document.cu.origdom.value) { + alert("You must select a course in the current domain"); + return; + } + var userrole = document.cu.role.options[document.cu.role.selectedIndex].value + var section=""; + var numsections = 0; + var newsecs = new Array(); + for (var i=0; i 1)) { + alert("In each course, each user may only have one student role at a time. You had selected "+numsections+" sections.\\nPlease modify your selections so they include no more than one section.") + return; + } + for (var j=0; j 0)) { + alert("Section designations do not apply to Course Coordinator roles.\\nA course coordinator role will be added with access to all sections."); + section = ""; + } + var coursename = "_$dcdom"+"_"+course+"_"+userrole + var numcourse = getIndex(document.cu.dccourse); + if (numcourse == "-1") { + alert("There was a problem with your course selection"); + return + } + else { + document.cu.elements[numcourse].name = "act"+coursename; + var numnewsec = getIndex(document.cu.newsec); + if (numnewsec != "-1") { + document.cu.elements[numnewsec].name = "sec"+coursename; + document.cu.elements[numnewsec].value = section; + } + var numstart = getIndex(document.cu.start); + if (numstart != "-1") { + document.cu.elements[numstart].name = "start"+coursename; + } + var numend = getIndex(document.cu.end); + if (numend != "-1") { + document.cu.elements[numend].name = "end"+coursename + } + } + } + document.cu.submit(); + } + + function getIndex(caller) { + for (var i=0;i'."\n".$jsback."\n". + $javascript_validations.''; + my $start_page = + &Apache::loncommon::start_page('User Management', + $js,{'add_entries' => \%loaditem,}); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:backPage(document.cu)", + text=>"Create/modify user", + faq=>282,bug=>'Instructor Interface',}); + + if ($env{'form.phase'} eq 'userpicked') { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:backPage(document.cu,'get_user_info','select')", + text=>"Select a user", + faq=>282,bug=>'Instructor Interface',}); + } + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:backPage(document.cu,'$env{'form.phase'}','modify')", + text=>"Set user role", + faq=>282,bug=>'Instructor Interface',}); + my $crumbs = &Apache::lonhtmlcommon::breadcrumbs('User Management'); + + my $forminfo =<<"ENDFORMINFO"; +
+ + + + + + +ENDFORMINFO my %inccourses; - $incdomains{$ENV{'user.domain'}}=1; - map { - if ($_=~/^user\.priv\.cm\.\/(\w+)\/(\w+)/) { + foreach my $key (keys(%env)) { + if ($key=~/^user\.priv\.cm\.\/($match_domain)\/($match_username)/) { $inccourses{$1.'_'.$2}=1; } - } %ENV; + } if ($uhome eq 'no_host') { - $r->print(<New user $ccuname at $ccdomain - + +

$lt{'cnu'} "$ccuname" $lt{'ind'} $ccdomain

+ENDTITLE + $r->print('
'. + &personal_data_display($ccuname,$ccdomain,$newuser, + %inst_results)); + my ($home_server_pick,$numlib) = + &Apache::loncommon::home_server_form_item($ccdomain,'hserver', + 'default','hide'); + if ($numlib > 1) { + $r->print(" +
+$lt{'hs'}: $home_server_pick +
"); + } else { + $r->print($home_server_pick); + } + $r->print('
'."\n".'

'. + $lt{'lg'}.'

'); + my ($fixedauth,$varauth,$authmsg); + if (ref($rulematch{$ccuname.':'.$ccdomain}) eq 'HASH') { + my $matchedrule = $rulematch{$ccuname.':'.$ccdomain}{'username'}; + my ($rules,$ruleorder) = + &Apache::lonnet::inst_userrules($ccdomain,'username'); + if (ref($rules) eq 'HASH') { + if (ref($rules->{$matchedrule}) eq 'HASH') { + my $authtype = $rules->{$matchedrule}{'authtype'}; + if ($authtype !~ /^(krb4|krb5|int|fsys|loc)$/) { + $r->print(&Apache::lonuserutils::set_login($ccdomain,$authformkrb,$authformint,$authformloc)); + } else { + my $authparm = $rules->{$matchedrule}{'authparm'}; + if ($authtype =~ /^krb(4|5)$/) { + my $ver = $1; + if ($authparm ne '') { + $fixedauth = <<"KERB"; + + + +KERB + $authmsg = $rules->{$matchedrule}{'authmsg'}; + } + } else { + $fixedauth = +''."\n"; + if ($rules->{$matchedrule}{'authparmfixed'}) { + $fixedauth .= +''."\n"; + } else { + $varauth = +''."\n"; + } + } + } + } else { + $r->print(&Apache::lonuserutils::set_login($ccdomain,$authformkrb,$authformint,$authformloc)); + } + } + if ($authmsg) { + $r->print(<print(&Apache::lonuserutils::set_login($ccdomain,$authformkrb,$authformint,$authformloc)); + } + $r->print(< +ENDPORT + } else { # user already exists + my %lt=&Apache::lonlocal::texthash( + 'cup' => "Modify existing user: ", + 'id' => "in domain", + ); + $r->print(<$lt{'cup'} "$ccuname" $lt{'id'} "$ccdomain" +ENDCHANGEUSER + $r->print('
'. + &personal_data_display($ccuname,$ccdomain,$newuser, + %inst_results)); + if ($context eq 'domain') { + $r->print(&Apache::lonuserutils::forceid_change($context)); + } + $r->print('
'); + my $user_auth_text = + &user_authentication($ccuname,$ccdomain,$krbdefdom,\%abv_auth); + my $user_quota_text; + if (&Apache::lonnet::allowed('mpq',$ccdomain)) { + # Current user has quota modification privileges + $user_quota_text = &portfolio_quota($ccuname,$ccdomain); + } elsif (&Apache::lonnet::allowed('mpq',$env{'request.role.domain'})) { + # Get the user's portfolio information + my %portq = &Apache::lonnet::get('environment',['portfolioquota'], + $ccdomain,$ccuname); + + my %lt=&Apache::lonlocal::texthash( + 'dska' => "Disk space allocated to user's portfolio files", + 'youd' => "You do not have privileges to modify the portfolio quota for this user.", + 'ichr' => "If a change is required, contact a domain coordinator for the domain", + ); + $user_quota_text = <$lt{'dska'} +$lt{'youd'} $lt{'ichr'}: $ccdomain +ENDNOPORTPRIV + } + if ($user_auth_text ne '') { + $r->print('
'.$user_auth_text); + if ($user_quota_text ne '') { + $r->print($user_quota_text); + } + $r->print('
'); -function clickint(vf) { - vf.krbdom.value=''; + } elsif ($user_quota_text ne '') { + $r->print('
'.$user_quota_text.'
'); + } + $r->print(''); + my %rolesdump=&Apache::lonnet::dump('roles',$ccdomain,$ccuname); + # Build up table of user roles to allow revocation of a role. + my ($tmp) = keys(%rolesdump); + unless ($tmp =~ /^(con_lost|error)/i) { + my $now=time; + my %lt=&Apache::lonlocal::texthash( + 'rer' => "Existing Roles", + 'rev' => "Revoke", + 'del' => "Delete", + 'ren' => "Re-Enable", + 'rol' => "Role", + 'ext' => "Extent", + 'sta' => "Start", + 'end' => "End" + ); + my (%roletext,%sortrole,%roleclass,%rolepriv); + foreach my $area (sort { my $a1=join('_',(split('_',$a))[1,0]); + my $b1=join('_',(split('_',$b))[1,0]); + return $a1 cmp $b1; + } keys(%rolesdump)) { + next if ($area =~ /^rolesdef/); + my $envkey=$area; + my $role = $rolesdump{$area}; + my $thisrole=$area; + $area =~ s/\_\w\w$//; + my ($role_code,$role_end_time,$role_start_time) = + split(/_/,$role); +# Is this a custom role? Get role owner and title. + my ($croleudom,$croleuname,$croletitle)= + ($role_code=~m{^cr/($match_domain)/($match_username)/(\w+)$}); + my $allowed=0; + my $delallowed=0; + my $sortkey=$role_code; + my $class='Unknown'; + if ($area =~ m{^/($match_domain)/($match_courseid)} ) { + $class='Course'; + my ($coursedom,$coursedir) = ($1,$2); + $sortkey.="\0$coursedom"; + # $1.'_'.$2 is the course id (eg. 103_12345abcef103l3). + my %coursedata= + &Apache::lonnet::coursedescription($1.'_'.$2); + my $carea; + if (defined($coursedata{'description'})) { + $carea=$coursedata{'description'}. + '
'.&mt('Domain').': '.$coursedom.(' 'x8). + &Apache::loncommon::syllabuswrapper('Syllabus',$coursedir,$coursedom); + $sortkey.="\0".$coursedata{'description'}; + $class=$coursedata{'type'}; + } else { + $carea=&mt('Unavailable course').': '.$area; + $sortkey.="\0".&mt('Unavailable course').': '.$area; + } + $sortkey.="\0$coursedir"; + $inccourses{$1.'_'.$2}=1; + if ((&Apache::lonnet::allowed('c'.$role_code,$1.'/'.$2)) || + (&Apache::lonnet::allowed('c'.$role_code,$ccdomain))) { + $allowed=1; + } + if ((&Apache::lonnet::allowed('dro',$1)) || + (&Apache::lonnet::allowed('dro',$ccdomain))) { + $delallowed=1; + } +# - custom role. Needs more info, too + if ($croletitle) { + if (&Apache::lonnet::allowed('ccr',$1.'/'.$2)) { + $allowed=1; + $thisrole.='.'.$role_code; + } + } + # Compute the background color based on $area + if ($area=~m{^/($match_domain)/($match_courseid)/(\w+)}) { + $carea.='
Section: '.$3; + $sortkey.="\0$3"; + } + $area=$carea; + } else { + $sortkey.="\0".$area; + # Determine if current user is able to revoke privileges + if ($area=~m{^/($match_domain)/}) { + if ((&Apache::lonnet::allowed('c'.$role_code,$1)) || + (&Apache::lonnet::allowed('c'.$role_code,$ccdomain))) { + $allowed=1; + } + if (((&Apache::lonnet::allowed('dro',$1)) || + (&Apache::lonnet::allowed('dro',$ccdomain))) && + ($role_code ne 'dc')) { + $delallowed=1; + } + } else { + if (&Apache::lonnet::allowed('c'.$role_code,'/')) { + $allowed=1; + } + } + if ($role_code eq 'ca' || $role_code eq 'au') { + $class='Construction Space'; + } elsif ($role_code eq 'su') { + $class='System'; + } else { + $class='Domain'; + } + } + if (($role_code eq 'ca') || ($role_code eq 'aa')) { + $area=~m{/($match_domain)/($match_username)}; + if (&authorpriv($2,$1)) { + $allowed=1; + } else { + $allowed=0; + } + } + my $row = ''; + $row.= ''; + my $active=1; + $active=0 if (($role_end_time) && ($now>$role_end_time)); + if (($active) && ($allowed)) { + $row.= ''; + } else { + if ($active) { + $row.=' '; + } else { + $row.=&mt('expired or revoked'); + } + } + $row.=''; + if ($allowed && !$active) { + $row.= ''; + } else { + $row.=' '; + } + $row.=''; + if ($delallowed) { + $row.= ''; + } else { + $row.=' '; + } + my $plaintext=''; + if (!$croletitle) { + $plaintext=&Apache::lonnet::plaintext($role_code,$class) + } else { + $plaintext= + "Customrole '$croletitle'
defined by $croleuname\@$croleudom"; + } + $row.= ''.$plaintext. + ''.$area. + ''.($role_start_time?localtime($role_start_time) + : ' ' ). + ''.($role_end_time ?localtime($role_end_time) + : ' ' ) + .""; + $sortrole{$sortkey}=$envkey; + $roletext{$envkey}=$row; + $roleclass{$envkey}=$class; + $rolepriv{$envkey}=$allowed; + #$r->print($row); + } # end of foreach (table building loop) + my $rolesdisplay = 0; + my %output = (); + foreach my $type ('Construction Space','Course','Group','Domain','System','Unknown') { + $output{$type} = ''; + foreach my $which (sort {uc($a) cmp uc($b)} (keys(%sortrole))) { + if ( ($roleclass{$sortrole{$which}} =~ /^\Q$type\E/ ) && ($rolepriv{$sortrole{$which}}) ) { + $output{$type}.= + &Apache::loncommon::start_data_table_row(). + $roletext{$sortrole{$which}}. + &Apache::loncommon::end_data_table_row(); + } + } + unless($output{$type} eq '') { + $output{$type} = ''. + "".&mt($type)."". + $output{$type}; + $rolesdisplay = 1; + } + } + if ($rolesdisplay == 1) { + $r->print(' +

'.$lt{'rer'}.'

'. +&Apache::loncommon::start_data_table("LC_createuser"). +&Apache::loncommon::start_data_table_header_row(). +''.$lt{'rev'}.''.$lt{'ren'}.''.$lt{'del'}. +''.$lt{'rol'}.''.$lt{'ext'}. +''.$lt{'sta'}.''.$lt{'end'}.''. +&Apache::loncommon::end_data_table_header_row()); + foreach my $type ('Construction Space','Course','Group','Domain','System','Unknown') { + if ($output{$type}) { + $r->print($output{$type}."\n"); + } + } + $r->print(&Apache::loncommon::end_data_table()); + } + } # End of unless + } ## End of new user/old user logic + my $addrolesdisplay = 0; + $r->print('

'.&mt('Add Roles').'

'); +# +# Co-Author +# + if (&authorpriv($env{'user.name'},$env{'request.role.domain'}) && + ($env{'user.name'} ne $ccuname || $env{'user.domain'} ne $ccdomain)) { + # No sense in assigning co-author role to yourself + $addrolesdisplay = 1; + my $cuname=$env{'user.name'}; + my $cudom=$env{'request.role.domain'}; + my %lt=&Apache::lonlocal::texthash( + 'cs' => "Construction Space", + 'act' => "Activate", + 'rol' => "Role", + 'ext' => "Extent", + 'sta' => "Start", + 'end' => "End", + 'cau' => "Co-Author", + 'caa' => "Assistant Co-Author", + 'ssd' => "Set Start Date", + 'sed' => "Set End Date" + ); + $r->print('

'.$lt{'cs'}.'

'."\n". + &Apache::loncommon::start_data_table()."\n". + &Apache::loncommon::start_data_table_header_row()."\n". + ''.$lt{'act'}.''.$lt{'rol'}.''. + ''.$lt{'ext'}.''.$lt{'sta'}.''. + ''.$lt{'end'}.''."\n". + &Apache::loncommon::end_data_table_header_row()."\n". + &Apache::loncommon::start_data_table_row()."\n". + ' + + + '.$lt{'cau'}.' + '.$cudom.'_'.$cuname.' + + '.$lt{'ssd'}.' + +'.$lt{'sed'}.''."\n". + &Apache::loncommon::end_data_table_row()."\n". + &Apache::loncommon::start_data_table_row()."\n". +' +'.$lt{'caa'}.' +'.$cudom.'_'.$cuname.' + +'.$lt{'ssd'}.' + +'.$lt{'sed'}.''."\n". + &Apache::loncommon::end_data_table_row()."\n". + &Apache::loncommon::end_data_table()); + } elsif ($env{'request.role'} =~ /^au\./) { + if (!(&authorpriv($env{'user.name'},$env{'request.role.domain'}))) { + $r->print(''. + &mt('You do not have privileges to assign co-author roles.'). + ''); + } elsif (($env{'user.name'} eq $ccuname) && + ($env{'user.domain'} eq $ccdomain)) { + $r->print(&mt('Assigning yourself a co-author or assistant co-author role in your own author area in Construction Space is not permitted')); + } + } +# +# Domain level +# + my $num_domain_level = 0; + my $domaintext = + '

'.&mt('Domain Level').'

'. + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). + ''.&mt('Activate').''.&mt('Role').''. + &mt('Extent').''. + ''.&mt('Start').''.&mt('End').''. + &Apache::loncommon::end_data_table_header_row(); + foreach my $thisdomain (sort(&Apache::lonnet::all_domains())) { + foreach my $role ('dc','li','dg','au','sc') { + if (&Apache::lonnet::allowed('c'.$role,$thisdomain)) { + my $plrole=&Apache::lonnet::plaintext($role); + my %lt=&Apache::lonlocal::texthash( + 'ssd' => "Set Start Date", + 'sed' => "Set End Date" + ); + $num_domain_level ++; + $domaintext .= +&Apache::loncommon::start_data_table_row(). +' +'.$plrole.' +'.$thisdomain.' + +'.$lt{'ssd'}.' + +'.$lt{'sed'}.''. +&Apache::loncommon::end_data_table_row(); + } + } + } + $domaintext.= &Apache::loncommon::end_data_table(); + if ($num_domain_level > 0) { + $r->print($domaintext); + $addrolesdisplay = 1; + } +# +# Course level +# + + if ($env{'request.role'} =~ m{^dc\./($match_domain)/$}) { + $r->print(&course_level_dc($1,'Course')); + $r->print('
'."\n"); + } elsif ($env{'request.role'} =~ m{^au\./($match_domain)/$}) { + if ($addrolesdisplay) { + $r->print('
print(' onClick="verify_message(this.form)" \>'."\n"); + } else { + $r->print('onClick="this.form.submit()" \>'."\n"); + } + } else { + $r->print('
'. + &mt('Back to previous page').''); + } + } else { + $r->print(&course_level_table(%inccourses)); + $r->print('
'."\n"); + } + $r->print(&Apache::lonhtmlcommon::echo_form_input(['phase','userrole','ccdomain','prevphase','currstate','ccuname','ccdomain'])); + $r->print(''); + $r->print(''); + $r->print("".&Apache::loncommon::end_page()); } + +sub user_authentication { + my ($ccuname,$ccdomain,$krbdefdom,$abv_auth) = @_; + my $currentauth=&Apache::lonnet::queryauthenticate($ccuname,$ccdomain); + my ($loginscript,$outcome); + if ($currentauth=~/^(krb)(4|5):(.*)/) { + my $long_auth = $1.$2; + my $curr_kerb_ver = $2; + my $krbdefdom=$3; + my $curr_authtype = $abv_auth->{$long_auth}; + my %param = ( formname => 'document.cu', + kerb_def_dom => $krbdefdom, + domain => $ccdomain, + curr_authtype => $curr_authtype, + curr_kerb_ver => $curr_kerb_ver, + ); + $loginscript = &Apache::loncommon::authform_header(%param); + } + # Check for a bad authentication type + if ($currentauth !~ /^(krb4|krb5|unix|internal|localauth):/) { + # bad authentication scheme + my %lt=&Apache::lonlocal::texthash( + 'err' => "ERROR", + 'uuas' => "This user has an unrecognized authentication scheme", + 'adcs' => "Please alert a domain coordinator of this situation", + 'sldb' => "Please specify login data below", + 'ld' => "Login Data" + ); + if (&Apache::lonnet::allowed('mau',$ccdomain)) { + &initialize_authen_forms($ccdomain); + my $choices = &Apache::lonuserutils::set_login($ccdomain,$authformkrb,$authformint,$authformloc); + $outcome = < +$loginscript - -

Personal Data

-First Name:
-Middle Name:
-Last Name:
-Generation:

- -ID/Student Number:

- -

Login Data

- -Kerberos authenticated with domain -

- -Internally authenticated (with initial password -) -ENDNUSER - } else { - $r->print('

Existing user '.$ccuname.' at '.$ccdomain.'

'); - - my $rolesdump=&Apache::lonnet::reply( - "dump:$ccdomain:$ccuname:roles",$uhome); - unless ($rolesdump eq 'con_lost') { - my $now=time; - $r->print('

Revoke Existing Roles

'. - ''. - ''); - map { - if ($_!~/^rolesdef\&/) { - - my ($area,$role)=split(/=/,$_); - my $thisrole=$area; - $area=~s/\_\w\w$//; - my ($trole,$tend,$tstart)=split(/_/,$role); - my $bgcol='ffffff'; - my $allows=0; - if ($area=~/^\/(\w+)\/(\d\w+)/) { - my %coursedata=&Apache::lonnet::coursedescription($1.'_'.$2); - my $carea='Course: '.$coursedata{'description'}; - $inccourses{$1.'_'.$2}=1; - if (&Apache::lonnet::allowed('c'.$trole,$1.'/'.$2)) { - $allows=1; - } - $bgcol=$1.'_'.$2; - $bgcol=~s/[^8-9b-e]//g; - $bgcol=substr($bgcol.$bgcol.$bgcol.'ffffff',0,6); - if ($area=~/^\/(\w+)\/(\d\w+)\/(\w+)/) { - $carea.='
Section/Group: '.$3; - } - $area=$carea; - } else { - if ($area=~/^\/(\w+)\//) { - $incdomains{$1}=1; - if (&Apache::lonnet::allowed('c'.$trole,$1)) { - $allows=1; - } - } else { - if (&Apache::lonnet::allowed('c'.$trole,'/')) { - $allows=1; - } - } - } - - my $active=1; - if (($tend) && ($now>$tend)) { $active=0; } - - $r->print('\n"); - } - } split(/&/,$rolesdump); - $r->print('
RevokeRoleExtentStartEnd
'); - if ($active) { - if ($allows) { - $r->print( - ''); - } else { - $r->print(' '); - } - } else { - $r->print(' '); - } - $r->print(''.&Apache::lonnet::plaintext($trole). - ''.$area.''. - ($tstart?localtime($tstart):' ').''. - ($tend?localtime($tend):' ')."
'); - } - } - $r->print('

Add Roles

System Level

'); - $r->print('

Domain Level

'); - map { - my $thisdomain=$_; - map { - if (&Apache::lonnet::allowed('c'.$_,$thisdomain)) { - $r->print($_.' - '.$thisdomain.'
'); - } - } ('dc','cc','li','dg','au'); - } sort keys %incdomains; - $r->print('

Course Level

'. - ''. - ''); - map { - my $thiscourse=$_; - my %coursedata=&Apache::lonnet::coursedescription($thiscourse); - my $area=$coursedata{'description'}; - my $bgcol=$thiscourse; - $bgcol=~s/[^8-9b-e]//g; - $bgcol=substr($bgcol.$bgcol.$bgcol.'ffffff',0,6); - map { - if (&Apache::lonnet::allowed('c'.$_,$thiscourse)) { - my $plrole=&Apache::lonnet::plaintext($_); - $r->print(< - - - - - - - -ENDROW - - } - } ('st','ta','ep','ad','in'); - } sort keys %inccourses; - $r->print('
ActivateRoleExtentGroup/SectionStartEnd
$plrole$area -Set Start Date -Set End Date
'); - $r->print(''); - $r->print(''); +$lt{'err'}: +$lt{'uuas'} ($currentauth). $lt{'sldb'}. +

$lt{'ld'}

+$choices +ENDBADAUTH + } else { + # This user is not allowed to modify the user's + # authentication scheme, so just notify them of the problem + $outcome = < $lt{'err'}: +$lt{'uuas'} ($currentauth). $lt{'adcs'}. + +ENDBADAUTH + } + } else { # Authentication type is valid + &initialize_authen_forms($ccdomain,$currentauth,'modifyuser'); + my ($authformcurrent,$can_modify,@authform_others) = + &modify_login_block($ccdomain,$currentauth); + if (&Apache::lonnet::allowed('mau',$ccdomain)) { + # Current user has login modification privileges + my %lt=&Apache::lonlocal::texthash ( + 'ld' => "Login Data", + 'ccld' => "Change Current Login Data", + 'enld' => "Enter New Login Data" + ); + $outcome = + ''."\n". + '

'.$lt{'ld'}.'

'. + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_row(). + ''.$authformnop; + if ($can_modify) { + $outcome .= ''."\n". + &Apache::loncommon::end_data_table_row(). + &Apache::loncommon::start_data_table_row(). + ''.$authformcurrent.''. + &Apache::loncommon::end_data_table_row()."\n"; + } else { + $outcome .= ' ('.$authformcurrent.')'. + &Apache::loncommon::end_data_table_row()."\n"; + } + foreach my $item (@authform_others) { + $outcome .= &Apache::loncommon::start_data_table_row(). + ''.$item.''. + &Apache::loncommon::end_data_table_row()."\n"; + } + $outcome .= &Apache::loncommon::end_data_table(); + } else { + if (&Apache::lonnet::allowed('mau',$env{'request.role.domain'})) { + my %lt=&Apache::lonlocal::texthash( + 'ccld' => "Change Current Login Data", + 'yodo' => "You do not have privileges to modify the authentication configuration for this user.", + 'ifch' => "If a change is required, contact a domain coordinator for the domain", + ); + $outcome .= <$lt{'ccld'} +$lt{'yodo'} $lt{'ifch'}: $ccdomain +ENDNOPRIV + } + } + } ## End of "check for bad authentication type" logic + return $outcome; +} + +sub modify_login_block { + my ($dom,$currentauth) = @_; + my %domconfig = &Apache::lonnet::get_dom('configuration',['usercreation'],$dom); + my ($authnum,%can_assign) = + &Apache::loncommon::get_assignable_auth($dom); + my ($authformcurrent,@authform_others,$show_override_msg); + if ($currentauth=~/^krb(4|5):/) { + $authformcurrent=$authformkrb; + if ($can_assign{'int'}) { + push(@authform_others,$authformint); + } + if ($can_assign{'loc'}) { + push(@authform_others,$authformloc); + } + if (($can_assign{'krb4'}) || ($can_assign{'krb5'})) { + $show_override_msg = 1; + } + } elsif ($currentauth=~/^internal:/) { + $authformcurrent=$authformint; + if (($can_assign{'krb4'}) || ($can_assign{'krb5'})) { + push(@authform_others,$authformkrb); + } + if ($can_assign{'loc'}) { + push(@authform_others,$authformloc); + } + if ($can_assign{'int'}) { + $show_override_msg = 1; + } + } elsif ($currentauth=~/^unix:/) { + $authformcurrent=$authformfsys; + if (($can_assign{'krb4'}) || ($can_assign{'krb5'})) { + push(@authform_others,$authformkrb); + } + if ($can_assign{'int'}) { + push(@authform_others,$authformint); + } + if ($can_assign{'loc'}) { + push(@authform_others,$authformloc); + } + if ($can_assign{'fsys'}) { + $show_override_msg = 1; + } + } elsif ($currentauth=~/^localauth:/) { + $authformcurrent=$authformloc; + if (($can_assign{'krb4'}) || ($can_assign{'krb5'})) { + push(@authform_others,$authformkrb); + } + if ($can_assign{'int'}) { + push(@authform_others,$authformint); + } + if ($can_assign{'loc'}) { + $show_override_msg = 1; + } + } + if ($show_override_msg) { + $authformcurrent = ''."\n". + ''. + ''. + '
'.$authformcurrent. + '
   '.&mt('Currently in use').''. + &mt('will override current values'). + '
'; + } + return ($authformcurrent,$show_override_msg,@authform_others); +} + +sub personal_data_display { + my ($ccuname,$ccdomain,$newuser,%inst_results) = @_; + my ($output,%userenv); + if (!$newuser) { + # Get the users information + %userenv = &Apache::lonnet::get('environment', + ['firstname','middlename','lastname','generation', + 'permanentemail','id'],$ccdomain,$ccuname); + } + my %lt=&Apache::lonlocal::texthash( + 'pd' => "Personal Data", + 'firstname' => "First Name", + 'middlename' => "Middle Name", + 'lastname' => "Last Name", + 'generation' => "Generation", + 'permanentemail' => "Permanent e-mail address", + 'id' => "ID/Student Number", + 'lg' => "Login Data" + ); + my @userinfo = ('firstname','middlename','lastname','generation', + 'permanentemail','id'); + my %textboxsize = ( + firstname => '15', + middlename => '15', + lastname => '15', + generation => '5', + permanentemail => '25', + id => '15', + ); + my $genhelp=&Apache::loncommon::help_open_topic('Generation'); + $output = '

'.$lt{'pd'}.'

'. + &Apache::lonhtmlcommon::start_pick_box(); + foreach my $item (@userinfo) { + my $rowtitle = $lt{$item}; + if ($item eq 'generation') { + $rowtitle = $genhelp.$rowtitle; + } + $output .= &Apache::lonhtmlcommon::row_title($rowtitle,undef,'LC_oddrow_value')."\n"; + if ($newuser) { + if ($inst_results{$item} ne '') { + $output .= ''.$inst_results{$item}; + } else { + $output .= ''; + } + } else { + if (&Apache::lonnet::allowed('mau',$ccdomain)) { + $output .= ''; + } else { + $output .= $userenv{$item}; + } + } + $output .= &Apache::lonhtmlcommon::row_closure(1); + } + $output .= &Apache::lonhtmlcommon::end_pick_box(); + return $output; } # ================================================================= Phase Three +sub update_user_data { + my ($r) = @_; + my $uhome=&Apache::lonnet::homeserver($env{'form.ccuname'}, + $env{'form.ccdomain'}); + # Error messages + my $error = ''.&mt('Error').': '; + my $end = '

'; + my $rtnlink = ''. + &mt('Return to previous page').''.&Apache::loncommon::end_page(); + my $title; + if (exists($env{'form.makeuser'})) { + $title='Set Privileges for New User'; + } else { + $title='Modify User Privileges'; + } + + my ($jsback,$elements) = &crumb_utilities(); + my $jscript = ''."\n"; + + $r->print(&Apache::loncommon::start_page($title,$jscript)); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:backPage(document.userupdate)", + text=>"Create/modify user", + faq=>282,bug=>'Instructor Interface',}); + if ($env{'form.prevphase'} eq 'userpicked') { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:backPage(document.userupdate,'get_user_info','select')", + text=>"Select a user", + faq=>282,bug=>'Instructor Interface',}); + } + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:backPage(document.userupdate,'$env{'form.prevphase'}','modify')", + text=>"Set user role", + faq=>282,bug=>'Instructor Interface',}, + {href=>"/adm/createuser", + text=>"Result", + faq=>282,bug=>'Instructor Interface',}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management')); + + my %disallowed; + $r->print(&update_result_form($uhome)); + # Check Inputs + if (! $env{'form.ccuname'} ) { + $r->print($error.&mt('No login name specified').'.'.$end.$rtnlink); + return; + } + if ( $env{'form.ccuname'} ne + &LONCAPA::clean_username($env{'form.ccuname'}) ) { + $r->print($error.&mt('Invalid login name').'. '. + &mt('Only letters, numbers, periods, dashes, @, and underscores are valid').'.'. + $end.$rtnlink); + return; + } + if (! $env{'form.ccdomain'} ) { + $r->print($error.&mt('No domain specified').'.'.$end.$rtnlink); + return; + } + if ( $env{'form.ccdomain'} ne + &LONCAPA::clean_domain($env{'form.ccdomain'}) ) { + $r->print($error.&mt ('Invalid domain name').'. '. + &mt('Only letters, numbers, periods, dashes, and underscores are valid').'.'. + $end.$rtnlink); + return; + } + if (! exists($env{'form.makeuser'})) { + # Modifying an existing user, so check the validity of the name + if ($uhome eq 'no_host') { + $r->print($error.&mt('Unable to determine home server for '). + $env{'form.ccuname'}.&mt(' in domain '). + $env{'form.ccdomain'}.'.'); + return; + } + } + # Determine authentication method and password for the user being modified + my $amode=''; + my $genpwd=''; + if ($env{'form.login'} eq 'krb') { + $amode='krb'; + $amode.=$env{'form.krbver'}; + $genpwd=$env{'form.krbarg'}; + } elsif ($env{'form.login'} eq 'int') { + $amode='internal'; + $genpwd=$env{'form.intarg'}; + } elsif ($env{'form.login'} eq 'fsys') { + $amode='unix'; + $genpwd=$env{'form.fsysarg'}; + } elsif ($env{'form.login'} eq 'loc') { + $amode='localauth'; + $genpwd=$env{'form.locarg'}; + $genpwd=" " if (!$genpwd); + } elsif (($env{'form.login'} eq 'nochange') || + ($env{'form.login'} eq '' )) { + # There is no need to tell the user we did not change what they + # did not ask us to change. + # If they are creating a new user but have not specified login + # information this will be caught below. + } else { + $r->print($error.&mt('Invalid login mode or password').$end.$rtnlink); + return; + } -sub phase_three { - my $r=shift; - $r->print(< - -The LearningOnline Network with CAPA - - - -

Create User, Change User Privileges

-ENDTHREEHEAD - $r->print('

'.$ENV{'form.cuname'}.' at '.$ENV{'form.cdomain'}.'

'); - if ($ENV{'form.makeuser'}) { - $r->print('

Creating User

'); - if (($ENV{'form.cuname'})&&($ENV{'form.cuname'}!~/\W/)&& - ($ENV{'form.cdomain'})&&($ENV{'form.cdomain'}!~/\W/)) { - my $amode=''; - my $genpwd=''; - if ($ENV{'form.login'} eq 'krb') { - $amode='krb4'; - $genpwd=$ENV{'form.krbdom'}; - } elsif ($ENV{'form.login'} eq 'int') { - $amode='internal'; - $genpwd=$ENV{'form.intpwd'}; - } - if (($amode) && ($genpwd)) { - $r->print('Generating user: '.&Apache::lonnet::modifyuser( - $ENV{'form.cdomain'},$ENV{'form.cuname'}, - $ENV{'form.cstid'},$amode,$genpwd, - $ENV{'form.cfirst'},$ENV{'form.cmiddle'}, - $ENV{'form.clast'},$ENV{'form.cgen'})); - $r->print('
Home server: '.&Apache::lonnet::homeserver - ($ENV{'form.cuname'},$ENV{'form.cdomain'})); + $r->print('

'.&mt('User [_1] in domain [_2]', + $env{'form.ccuname'}, $env{'form.ccdomain'}).'

'); + my (%alerts,%rulematch,%inst_results,%curr_rules); + if ($env{'form.makeuser'}) { + $r->print('

'.&mt('Creating new account.').'

'); + # Check for the authentication mode and password + if (! $amode || ! $genpwd) { + $r->print($error.&mt('Invalid login mode or password').$end.$rtnlink); + return; + } + # Determine desired host + my $desiredhost = $env{'form.hserver'}; + if (lc($desiredhost) eq 'default') { + $desiredhost = undef; + } else { + my %home_servers = + &Apache::lonnet::get_servers($env{'form.ccdomain'},'library'); + if (! exists($home_servers{$desiredhost})) { + $r->print($error.&mt('Invalid home server specified').$end.$rtnlink); + return; + } + } + # Check ID format + my %checkhash; + my %checks = ('id' => 1); + %{$checkhash{$env{'form.ccuname'}.':'.$env{'form.ccdomain'}}} = ( + 'newuser' => 1, + 'id' => $env{'form.cid'}, + ); + if ($env{'form.cid'} ne '') { + &Apache::loncommon::user_rule_check(\%checkhash,\%checks,\%alerts, + \%rulematch,\%inst_results,\%curr_rules); + if (ref($alerts{'id'}) eq 'HASH') { + if (ref($alerts{'id'}{$env{'form.ccdomain'}}) eq 'HASH') { + my $domdesc = + &Apache::lonnet::domain($env{'form.ccdomain'},'description'); + if ($alerts{'id'}{$env{'form.ccdomain'}}{$env{'form.cid'}}) { + my $userchkmsg; + if (ref($curr_rules{$env{'form.ccdomain'}}) eq 'HASH') { + $userchkmsg = + &Apache::loncommon::instrule_disallow_msg('id', + $domdesc,1). + &Apache::loncommon::user_rule_formats($env{'form.ccdomain'}, + $domdesc,$curr_rules{$env{'form.ccdomain'}}{'id'},'id'); + } + $r->print($error.&mt('Invalid ID format').$end. + $userchkmsg.$rtnlink); + return; + } + } + } + } + # Call modifyuser + my $result = &Apache::lonnet::modifyuser + ($env{'form.ccdomain'},$env{'form.ccuname'},$env{'form.cid'}, + $amode,$genpwd,$env{'form.cfirstname'}, + $env{'form.cmiddlename'},$env{'form.clastname'}, + $env{'form.cgeneration'},undef,$desiredhost, + $env{'form.cpermanentemail'}); + $r->print(&mt('Generating user').': '.$result); + my $home = &Apache::lonnet::homeserver($env{'form.ccuname'}, + $env{'form.ccdomain'}); + $r->print('
'.&mt('Home server').': '.$home.' '. + &Apache::lonnet::hostname($home)); + } elsif (($env{'form.login'} ne 'nochange') && + ($env{'form.login'} ne '' )) { + # Modify user privileges + if (! $amode || ! $genpwd) { + $r->print($error.'Invalid login mode or password'.$end.$rtnlink); + return; + } + # Only allow authentification modification if the person has authority + if (&Apache::lonnet::allowed('mau',$env{'form.ccdomain'})) { + $r->print('Modifying authentication: '. + &Apache::lonnet::modifyuserauth( + $env{'form.ccdomain'},$env{'form.ccuname'}, + $amode,$genpwd)); + $r->print('
'.&mt('Home server').': '.&Apache::lonnet::homeserver + ($env{'form.ccuname'},$env{'form.ccdomain'})); } else { - $r->print('Invalid login mode or password'); - } - } else { - $r->print('Invalid username or domain'); + # Okay, this is a non-fatal error. + $r->print($error.&mt('You do not have the authority to modify this users authentification information').'.'.$end); + } + } + ## + if (! $env{'form.makeuser'} ) { + # Check for need to change + my %userenv = &Apache::lonnet::get + ('environment',['firstname','middlename','lastname','generation', + 'id','permanentemail','portfolioquota','inststatus'], + $env{'form.ccdomain'},$env{'form.ccuname'}); + my ($tmp) = keys(%userenv); + if ($tmp =~ /^(con_lost|error)/i) { + %userenv = (); + } + # Check to see if we need to change user information + foreach my $item ('firstname','middlename','lastname','generation','permanentemail','id') { + # Strip leading and trailing whitespace + $env{'form.c'.$item} =~ s/(\s+$|^\s+)//g; + } + # Check to see if we can change the ID/student number + my $forceid = $env{'form.forceid'}; + my $recurseid = $env{'form.recurseid'}; + my $newuser = 0; + my (%alerts,%rulematch,%idinst_results,%curr_rules,%got_rules); + my %uidhash = &Apache::lonnet::idrget($env{'form.ccdomain'}, + $env{'form.ccuname'}); + if (($uidhash{$env{'form.ccuname'}}) && + ($uidhash{$env{'form.ccuname'}}!~/error\:/) && + (!$forceid)) { + if ($env{'form.cid'} ne $uidhash{$env{'form.ccuname'}}) { + $env{'form.cid'} = $userenv{'id'}; + } + } + if ($env{'form.cid'} ne $userenv{'id'}) { + my $checkhash; + my $checks = { 'id' => 1 }; + $checkhash->{$env{'form.ccuname'}.':'.$env{'form.ccdomain'}} = + { 'newuser' => $newuser, + 'id' => $env{'form.cid'}, + }; + &Apache::loncommon::user_rule_check($checkhash,$checks, + \%alerts,\%rulematch,\%idinst_results,\%curr_rules,\%got_rules); + if (ref($alerts{'id'}) eq 'HASH') { + if (ref($alerts{'id'}{$env{'form.ccdomain'}}) eq 'HASH') { + $env{'form.cid'} = $userenv{'id'}; + } + } + } + my ($quotachanged,$namechanged,$oldportfolioquota,$newportfolioquota, + $inststatus,$oldisdefault,$newisdefault,$olddefquotatext, + $newdefquotatext); + my ($defquota,$settingstatus) = + &Apache::loncommon::default_quota($env{'form.ccdomain'},$inststatus); + my %changeHash; + $changeHash{'portfolioquota'} = $userenv{'portfolioquota'}; + if ($userenv{'portfolioquota'} ne '') { + $oldportfolioquota = $userenv{'portfolioquota'}; + if ($env{'form.customquota'} == 1) { + if ($env{'form.portfolioquota'} eq '') { + $newportfolioquota = 0; + } else { + $newportfolioquota = $env{'form.portfolioquota'}; + $newportfolioquota =~ s/[^\d\.]//g; + } + if ($newportfolioquota != $oldportfolioquota) { + $quotachanged = "a_admin($newportfolioquota,\%changeHash); + } + } else { + $quotachanged = "a_admin('',\%changeHash); + $newportfolioquota = $defquota; + $newisdefault = 1; + } + } else { + $oldisdefault = 1; + $oldportfolioquota = $defquota; + if ($env{'form.customquota'} == 1) { + if ($env{'form.portfolioquota'} eq '') { + $newportfolioquota = 0; + } else { + $newportfolioquota = $env{'form.portfolioquota'}; + $newportfolioquota =~ s/[^\d\.]//g; + } + $quotachanged = "a_admin($newportfolioquota,\%changeHash); + } else { + $newportfolioquota = $defquota; + $newisdefault = 1; + } + } + if ($oldisdefault) { + $olddefquotatext = &get_defaultquota_text($settingstatus); + } + if ($newisdefault) { + $newdefquotatext = &get_defaultquota_text($settingstatus); + } + if (&Apache::lonnet::allowed('mau',$env{'form.ccdomain'}) && + ($env{'form.cfirstname'} ne $userenv{'firstname'} || + $env{'form.cmiddlename'} ne $userenv{'middlename'} || + $env{'form.clastname'} ne $userenv{'lastname'} || + $env{'form.cgeneration'} ne $userenv{'generation'} || + $env{'form.cid'} ne $userenv{'id'} || + $env{'form.cpermanentemail'} ne $userenv{'permanentemail'} )) { + $namechanged = 1; + } + if ($namechanged || $quotachanged) { + $changeHash{'firstname'} = $env{'form.cfirstname'}; + $changeHash{'middlename'} = $env{'form.cmiddlename'}; + $changeHash{'lastname'} = $env{'form.clastname'}; + $changeHash{'generation'} = $env{'form.cgeneration'}; + $changeHash{'id'} = $env{'form.cid'}; + $changeHash{'permanentemail'} = $env{'form.cpermanentemail'}; + my ($quotachgresult,$namechgresult); + if ($quotachanged) { + $quotachgresult = + &Apache::lonnet::put('environment',\%changeHash, + $env{'form.ccdomain'},$env{'form.ccuname'}); + } + if ($namechanged) { + # Make the change + $namechgresult = + &Apache::lonnet::modifyuser($env{'form.ccdomain'}, + $env{'form.ccuname'},$changeHash{'id'},undef,undef, + $changeHash{'firstname'},$changeHash{'middlename'}, + $changeHash{'lastname'},$changeHash{'generation'}, + $changeHash{'id'},undef,$changeHash{'permanentemail'}); + } + if (($namechanged && $namechgresult eq 'ok') || + ($quotachanged && $quotachgresult eq 'ok')) { + # Tell the user we changed the name + my %lt=&Apache::lonlocal::texthash( + 'uic' => "User Information Changed", + 'frst' => "first", + 'mddl' => "middle", + 'lst' => "last", + 'gen' => "generation", + 'id' => "ID/Student number", + 'mail' => "permanent e-mail", + 'disk' => "disk space allocated to portfolio files", + 'prvs' => "Previous", + 'chto' => "Changed To" + ); + $r->print('

'.$lt{'uic'}.'

'. + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row()); + $r->print(<<"END"); +   + $lt{'frst'} + $lt{'mddl'} + $lt{'lst'} + $lt{'gen'} + $lt{'id'} + $lt{'mail'} + $lt{'disk'} +END + $r->print(&Apache::loncommon::end_data_table_header_row(). + &Apache::loncommon::start_data_table_row()); + $r->print(<<"END"); + $lt{'prvs'} + $userenv{'firstname'} + $userenv{'middlename'} + $userenv{'lastname'} + $userenv{'generation'} + $userenv{'id'} + $userenv{'permanentemail'} + $oldportfolioquota Mb $olddefquotatext +END + $r->print(&Apache::loncommon::end_data_table_row(). + &Apache::loncommon::start_data_table_row()); + $r->print(<<"END"); + $lt{'chto'} + $env{'form.cfirstname'} + $env{'form.cmiddlename'} + $env{'form.clastname'} + $env{'form.cgeneration'} + $env{'form.cid'} + $env{'form.cpermanentemail'} + $newportfolioquota Mb $newdefquotatext +END + $r->print(&Apache::loncommon::end_data_table_row(). + &Apache::loncommon::end_data_table()); + if ($env{'form.cid'} ne $userenv{'id'}) { + &Apache::lonnet::idput($env{'form.ccdomain'}, + ($env{'form.ccuname'} => $env{'form.cid'})); + if (($recurseid) && + (&Apache::lonnet::allowed('mau',$env{'form.ccdomain'}))) { + my %userupdate = ( + lastname => $env{'form.clasaname'}, + middlename => $env{'form.cmiddlename'}, + firstname => $env{'form.cfirstname'}, + generation => $env{'fora.cgeneration'}, + id => $env{'form.cid'}, + ); + my $idresult = + &Apache::lonuserutils::propagate_id_change( + $env{'form.ccuname'},$env{'form.ccdomain'}, + \%userupdate); + $r->print('
'.$idresult.'
'); + } + } + if (($env{'form.ccdomain'} eq $env{'user.domain'}) && + ($env{'form.ccuname'} eq $env{'user.name'})) { + my %newenvhash; + foreach my $key (keys(%changeHash)) { + $newenvhash{'environment.'.$key} = $changeHash{$key}; + } + &Apache::lonnet::appenv(%newenvhash); + } + } else { # error occurred + $r->print(''.&mt('Unable to successfully change environment for').' '. + $env{'form.ccuname'}.' '.&mt('in domain').' '. + $env{'form.ccdomain'}.''); + } + } else { # End of if ($env ... ) logic + # They did not want to change the users name or quota but we can + # still tell them what the name and quota are + my %lt=&Apache::lonlocal::texthash( + 'id' => "ID/Student number", + 'mail' => "Permanent e-mail", + 'disk' => "Disk space allocated to user's portfolio files", + ); + $r->print(<<"END"); +

$userenv{'firstname'} $userenv{'middlename'} $userenv{'lastname'} $userenv{'generation'} +END + if ($userenv{'permanentemail'} ne '') { + $r->print('
['.$lt{'mail'}.': '. + $userenv{'permanentemail'}.']'); + } + $r->print('
['.$lt{'disk'}.': '.$oldportfolioquota.' Mb '. + $olddefquotatext.']

'); + } } - } + ## my $now=time; - $r->print('

Modifying Roles

'); - map { - if (($_=~/^form\.rev\:([^\_]+)\_([^\_]+)$/) && ($ENV{$_})) { - $r->print('Revoking '.$2.' in '.$1.': '. - &Apache::lonnet::assignrole($ENV{'form.cdomain'},$ENV{'form.cuname'}, - $1,$2,$now).'
'); - } - } keys %ENV; - map { - if (($_=~/^form\.act\_([^\_]+)\_([^\_]+)\_([^\_]+)$/) && ($ENV{$_})) { - my $url='/'.$1.'/'.$2; - if ($ENV{'form.sec_'.$1.'_'.$2.'_'.$3}) { - $url.='/'.$ENV{'form.sec_'.$1.'_'.$2.'_'.$3}; - } - my $start=$now; - if ($ENV{'form.start_'.$1.'_'.$2.'_'.$3}) { - $start=$ENV{'form.start_'.$1.'_'.$2.'_'.$3}; - } - my $end=0; - if ($ENV{'form.end_'.$1.'_'.$2.'_'.$3}) { - $end=$ENV{'form.end_'.$1.'_'.$2.'_'.$3}; - } - $r->print('Assigning: '.$3.' in '.$url.': '. - &Apache::lonnet::assignrole($ENV{'form.cdomain'},$ENV{'form.cuname'}, - $url,$3,$end,$start).'
'); + my $rolechanges = 0; + $r->print('

'.&mt('Modifying Roles').'

'); + foreach my $key (keys (%env)) { + next if (! $env{$key}); + next if ($key eq 'form.action'); + # Revoke roles + if ($key=~/^form\.rev/) { + if ($key=~/^form\.rev\:([^\_]+)\_([^\_\.]+)$/) { +# Revoke standard role + my ($scope,$role) = ($1,$2); + my $result = + &Apache::lonnet::revokerole($env{'form.ccdomain'}, + $env{'form.ccuname'}, + $scope,$role); + $r->print(&mt('Revoking [_1] in [_2]: [_3]', + $role,$scope,''.$result.'').'
'); + if ($role eq 'st') { + my $result = + &Apache::lonuserutils::classlist_drop($scope, + $env{'form.ccuname'},$env{'form.ccdomain'}, + $now); + $r->print($result); + } + } + if ($key=~m{^form\.rev\:([^_]+)_cr\.cr/($match_domain)/($match_username)/(\w+)$}s) { +# Revoke custom role + $r->print(&mt('Revoking custom role:'). + ' '.$4.' by '.$3.':'.$2.' in '.$1.': '. + &Apache::lonnet::revokecustomrole($env{'form.ccdomain'}, + $env{'form.ccuname'},$1,$2,$3,$4). + '
'); + } + $rolechanges ++; + } elsif ($key=~/^form\.del/) { + if ($key=~/^form\.del\:([^\_]+)\_([^\_\.]+)$/) { +# Delete standard role + my ($scope,$role) = ($1,$2); + my $result = + &Apache::lonnet::assignrole($env{'form.ccdomain'}, + $env{'form.ccuname'}, + $scope,$role,$now,0,1); + $r->print(&mt('Deleting [_1] in [_2]: [_3]',$role,$scope, + ''.$result.'').'
'); + if ($role eq 'st') { + my $result = + &Apache::lonuserutils::classlist_drop($scope, + $env{'form.ccuname'},$env{'form.ccdomain'}, + $now); + $r->print($result); + } + } + if ($key=~m{^form\.del\:([^_]+)_cr\.cr/($match_domain)/($match_username)/(\w+)$}) { + my ($url,$rdom,$rnam,$rolename) = ($1,$2,$3,$4); +# Delete custom role + $r->print(&mt('Deleting custom role [_1] by [_2]:[_3] in [_4]', + $rolename,$rnam,$rdom,$url).': '. + &Apache::lonnet::assigncustomrole($env{'form.ccdomain'}, + $env{'form.ccuname'},$url,$rdom,$rnam,$rolename,$now, + 0,1).'
'); + } + $rolechanges ++; + } elsif ($key=~/^form\.ren/) { + my $udom = $env{'form.ccdomain'}; + my $uname = $env{'form.ccuname'}; +# Re-enable standard role + if ($key=~/^form\.ren\:([^\_]+)\_([^\_\.]+)$/) { + my $url = $1; + my $role = $2; + my $logmsg; + my $output; + if ($role eq 'st') { + if ($url =~ m-^/($match_domain)/($match_courseid)/?(\w*)$-) { + my $result = &Apache::loncommon::commit_studentrole(\$logmsg,$udom,$uname,$url,$role,$now,0,$1,$2,$3); + if (($result =~ /^error/) || ($result eq 'not_in_class') || ($result eq 'unknown_course')) { + $output = "Error: $result\n"; + } else { + $output = &mt('Assigning').' '.$role.' in '.$url. + &mt('starting').' '.localtime($now). + ':
'.$logmsg.'
'. + &mt('Add to classlist').': ok
'; + } + } + } else { + my $result=&Apache::lonnet::assignrole($env{'form.ccdomain'}, + $env{'form.ccuname'},$url,$role,0,$now); + $output = &mt('Re-enabling [_1] in [_2]: [_3]', + $role,$url,$result).'
'; + } + $r->print($output); + } +# Re-enable custom role + if ($key=~m{^form\.ren\:([^_]+)_cr\.cr/($match_domain)/($match_username)/(\w+)$}) { + my ($url,$rdom,$rnam,$rolename) = ($1,$2,$3,$4); + my $result = &Apache::lonnet::assigncustomrole( + $env{'form.ccdomain'}, $env{'form.ccuname'}, + $url,$rdom,$rnam,$rolename,0,$now); + $r->print(&mt('Re-enabling custom role [_1] by [_2]@[_3] in [_4] : [_5]', + $rolename,$rnam,$rdom,$url,$result).'
'); + } + $rolechanges ++; + } elsif ($key=~/^form\.act/) { + my $udom = $env{'form.ccdomain'}; + my $uname = $env{'form.ccuname'}; + if ($key=~/^form\.act\_($match_domain)\_($match_courseid)\_cr_cr_($match_domain)_($match_username)_([^\_]+)$/) { + # Activate a custom role + my ($one,$two,$three,$four,$five)=($1,$2,$3,$4,$5); + my $url='/'.$one.'/'.$two; + my $full=$one.'_'.$two.'_cr_cr_'.$three.'_'.$four.'_'.$five; + + my $start = ( $env{'form.start_'.$full} ? + $env{'form.start_'.$full} : + $now ); + my $end = ( $env{'form.end_'.$full} ? + $env{'form.end_'.$full} : + 0 ); + + # split multiple sections + my %sections = (); + my $num_sections = &build_roles($env{'form.sec_'.$full},\%sections,$5); + if ($num_sections == 0) { + $r->print(&Apache::loncommon::commit_customrole($udom,$uname,$url,$three,$four,$five,$start,$end)); + } else { + my %curr_groups = + &Apache::longroup::coursegroups($one,$two); + foreach my $sec (sort {$a cmp $b} keys %sections) { + if (($sec eq 'none') || ($sec eq 'all') || + exists($curr_groups{$sec})) { + $disallowed{$sec} = $url; + next; + } + my $securl = $url.'/'.$sec; + $r->print(&Apache::loncommon::commit_customrole($udom,$uname,$securl,$three,$four,$five,$start,$end)); + } + } + } elsif ($key=~/^form\.act\_($match_domain)\_($match_name)\_([^\_]+)$/) { + # 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} : + $now ); + my $end = ( $env{'form.end_'.$one.'_'.$two.'_'.$three} ? + $env{'form.end_'.$one.'_'.$two.'_'.$three} : + 0 ); + my $url='/'.$one.'/'.$two; + my $type = 'three'; + # split multiple sections + my %sections = (); + my $num_sections = &build_roles($env{'form.sec_'.$one.'_'.$two.'_'.$three},\%sections,$three); + if ($num_sections == 0) { + $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$three,$start,$end,$one,$two,'')); + } else { + my %curr_groups = + &Apache::longroup::coursegroups($one,$two); + my $emptysec = 0; + foreach my $sec (sort {$a cmp $b} keys %sections) { + $sec =~ s/\W//g; + if ($sec ne '') { + if (($sec eq 'none') || ($sec eq 'all') || + exists($curr_groups{$sec})) { + $disallowed{$sec} = $url; + next; + } + my $securl = $url.'/'.$sec; + $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$securl,$three,$start,$end,$one,$two,$sec)); + } else { + $emptysec = 1; + } + } + if ($emptysec) { + $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$three,$start,$end,$one,$two,'')); + } + } + } 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} : + $now ); + my $end = ( $env{'form.end_'.$1.'_'.$2} ? + $env{'form.end_'.$1.'_'.$2} : + 0 ); + my $url='/'.$1.'/'; + # split multiple sections + my %sections = (); + my $num_sections = &build_roles($env{'form.sec_'.$1.'_'.$2},\%sections,$2); + if ($num_sections == 0) { + $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$2,$start,$end,$1,undef,'')); + } else { + my $emptysec = 0; + foreach my $sec (sort {$a cmp $b} keys %sections) { + if ($sec ne '') { + my $securl = $url.'/'.$sec; + $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$securl,$2,$start,$end,$1,undef,$sec)); + } else { + $emptysec = 1; + } + } + if ($emptysec) { + $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$2,$start,$end,$1,undef,'')); + } + } + } else { + $r->print('

'.&mt('ERROR').': '.&mt('Unknown command').' '.$key.'


'); + } + foreach my $key (sort(keys(%disallowed))) { + if (($key eq 'none') || ($key eq 'all')) { + $r->print('

'.&mt('[_1] may not be used as the name for a section, as it is a reserved word.',$key)); + } else { + $r->print('

'.&mt('[_1] may not be used as the name for a section, as it is the name of a course group.',$key)); + } + $r->print(' '.&mt('Please go back and choose a different section name.').'


'); + } + $rolechanges ++; + } + } # End of foreach (keys(%env)) +# Flush the course logs so reverse user roles immediately updated + &Apache::lonnet::flushcourselogs(); + if (!$rolechanges) { + $r->print(&mt('No roles to modify')); + } + $r->print(&Apache::loncommon::end_page()); +} + +sub get_defaultquota_text { + my ($settingstatus) = @_; + my $defquotatext; + if ($settingstatus eq '') { + $defquotatext = &mt('(default)'); + } else { + my ($usertypes,$order) = + &Apache::lonnet::retrieve_inst_usertypes($env{'form.ccdomain'}); + if ($usertypes->{$settingstatus} eq '') { + $defquotatext = &mt('(default)'); + } else { + $defquotatext = &mt('(default for [_1])',$usertypes->{$settingstatus}); + } + } + return $defquotatext; +} + +sub update_result_form { + my ($uhome) = @_; + my $outcome = + '
'."\n"; + foreach my $item ('srchby','srchin','srchtype','srchterm','srchdomain','ccuname','ccdomain') { + $outcome .= ''."\n"; + } + foreach my $item ('sortby','seluname','seludom') { + if (exists($env{'form.'.$item})) { + $outcome .= ''."\n"; + } + } + if ($uhome eq 'no_host') { + $outcome .= ''."\n"; + } + $outcome .= ''."\n". + ''."\n". + ''."\n". + '
'; + return $outcome; +} + +sub quota_admin { + my ($setquota,$changeHash) = @_; + my $quotachanged; + if (&Apache::lonnet::allowed('mpq',$env{'form.ccdomain'})) { + # Current user has quota modification privileges + $quotachanged = 1; + $changeHash->{'portfolioquota'} = $setquota; + } + return $quotachanged; +} + +sub build_roles { + my ($sectionstr,$sections,$role) = @_; + my $num_sections = 0; + if ($sectionstr=~ /,/) { + my @secnums = split/,/,$sectionstr; + if ($role eq 'st') { + $secnums[0] =~ s/\W//g; + $$sections{$secnums[0]} = 1; + $num_sections = 1; + } else { + foreach my $sec (@secnums) { + $sec =~ ~s/\W//g; + if (!($sec eq "")) { + if (exists($$sections{$sec})) { + $$sections{$sec} ++; + } else { + $$sections{$sec} = 1; + $num_sections ++; + } + } + } + } + } else { + $sectionstr=~s/\W//g; + unless ($sectionstr eq '') { + $$sections{$sectionstr} = 1; + $num_sections ++; + } + } + + return $num_sections; +} + +# ========================================================== Custom Role Editor + +sub custom_role_editor { + my ($r) = @_; + my $rolename=$env{'form.rolename'}; + + if ($rolename eq 'make new role') { + $rolename=$env{'form.newrolename'}; + } + + $rolename=~s/[^A-Za-z0-9]//gs; + + if (!$rolename || $env{'form.phase'} eq 'pickrole') { + &print_username_entry_form($r); + return; + } +# ------------------------------------------------------- What can be assigned? + my %full=(); + my %courselevel=(); + my %courselevelcurrent=(); + my $syspriv=''; + my $dompriv=''; + my $coursepriv=''; + my $body_top; + my ($disp_dummy,$disp_roles) = &Apache::lonnet::get('roles',["st"]); + my ($rdummy,$roledef)= + &Apache::lonnet::get('roles',["rolesdef_$rolename"]); +# ------------------------------------------------------- Does this role exist? + $body_top .= '

'; + if (($rdummy ne 'con_lost') && ($roledef ne '')) { + $body_top .= &mt('Existing Role').' "'; +# ------------------------------------------------- Get current role privileges + ($syspriv,$dompriv,$coursepriv)=split(/\_/,$roledef); + } else { + $body_top .= &mt('New Role').' "'; + $roledef=''; + } + $body_top .= $rolename.'"

'; + foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:c'})) { + my ($priv,$restrict)=split(/\&/,$item); + if (!$restrict) { $restrict='F'; } + $courselevel{$priv}=$restrict; + if ($coursepriv=~/\:$priv/) { + $courselevelcurrent{$priv}=1; + } + $full{$priv}=1; + } + my %domainlevel=(); + my %domainlevelcurrent=(); + foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:d'})) { + my ($priv,$restrict)=split(/\&/,$item); + if (!$restrict) { $restrict='F'; } + $domainlevel{$priv}=$restrict; + if ($dompriv=~/\:$priv/) { + $domainlevelcurrent{$priv}=1; + } + $full{$priv}=1; + } + my %systemlevel=(); + my %systemlevelcurrent=(); + foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:s'})) { + my ($priv,$restrict)=split(/\&/,$item); + if (!$restrict) { $restrict='F'; } + $systemlevel{$priv}=$restrict; + if ($syspriv=~/\:$priv/) { + $systemlevelcurrent{$priv}=1; + } + $full{$priv}=1; + } + my ($jsback,$elements) = &crumb_utilities(); + my $button_code = "\n"; + my $head_script = "\n"; + $head_script .= ''."\n"; + $r->print(&Apache::loncommon::start_page('Custom Role Editor',$head_script)); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:backPage(document.form1,'pickrole','')", + text=>"Pick custom role", + faq=>282,bug=>'Instructor Interface',}, + {href=>"javascript:backPage(document.form1,'','')", + text=>"Edit custom role", + faq=>282,bug=>'Instructor Interface',}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management')); + + $r->print($body_top); + my %lt=&Apache::lonlocal::texthash( + 'prv' => "Privilege", + 'crl' => "Course Level", + 'dml' => "Domain Level", + 'ssl' => "System Level"); + $r->print('Select a Template
'); + $r->print('
'); + $r->print($button_code); + $r->print('
'); + $r->print(< + + +ENDCCF + $r->print(&Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). +''.$lt{'prv'}.''.$lt{'crl'}.''.$lt{'dml'}. +''.$lt{'ssl'}.''. + &Apache::loncommon::end_data_table_header_row()); + foreach my $priv (sort keys %full) { + my $privtext = &Apache::lonnet::plaintext($priv); + $r->print(&Apache::loncommon::start_data_table_row(). + ''.$privtext.''. + ($courselevel{$priv}?'':' '). + ''. + ($domainlevel{$priv}?'':' '). + ''. + ($systemlevel{$priv}?'':' '). + ''. + &Apache::loncommon::end_data_table_row()); + } + $r->print(&Apache::loncommon::end_data_table(). + ''. + ''."\n".''."\n". + ''."\n". + ''. + &Apache::loncommon::end_page()); +} +# -------------------------------------------------------- +sub make_script_template { + my ($role) = @_; + my %full_c=(); + my %full_d=(); + my %full_s=(); + my $return_script; + foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:c'})) { + my ($priv,$restrict)=split(/\&/,$item); + $full_c{$priv}=1; + } + foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:d'})) { + my ($priv,$restrict)=split(/\&/,$item); + $full_d{$priv}=1; + } + foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:s'})) { + my ($priv,$restrict)=split(/\&/,$item); + $full_s{$priv}=1; + } + $return_script .= 'function set_'.$role.'() {'."\n"; + my @temp = split(/:/,$Apache::lonnet::pr{$role.':c'}); + my %role_c; + foreach my $priv (@temp) { + my ($priv_item, $dummy) = split(/\&/,$priv); + $role_c{$priv_item} = 1; + } + foreach my $priv_item (keys(%full_c)) { + my ($priv, $dummy) = split(/\&/,$priv_item); + if (exists($role_c{$priv})) { + $return_script .= "document.form1.$priv"."_c.checked = true;\n"; + } else { + $return_script .= "document.form1.$priv"."_c.checked = false;\n"; + } + } + my %role_d; + @temp = split(/:/,$Apache::lonnet::pr{$role.':d'}); + foreach my $priv(@temp) { + my ($priv_item, $dummy) = split(/\&/,$priv); + $role_d{$priv_item} = 1; + } + foreach my $priv_item (keys(%full_d)) { + my ($priv, $dummy) = split(/\&/,$priv_item); + if (exists($role_d{$priv})) { + $return_script .= "document.form1.$priv"."_d.checked = true;\n"; + } else { + $return_script .= "document.form1.$priv"."_d.checked = false;\n"; + } + } + my %role_s; + @temp = split(/:/,$Apache::lonnet::pr{$role.':s'}); + foreach my $priv(@temp) { + my ($priv_item, $dummy) = split(/\&/,$priv); + $role_s{$priv_item} = 1; + } + foreach my $priv_item (keys(%full_s)) { + my ($priv, $dummy) = split(/\&/,$priv_item); + if (exists($role_s{$priv})) { + $return_script .= "document.form1.$priv"."_s.checked = true;\n"; + } else { + $return_script .= "document.form1.$priv"."_s.checked = false;\n"; + } + } + $return_script .= '}'."\n"; + return ($return_script); +} +# ---------------------------------------------------------- +sub make_button_code { + my ($role) = @_; + my $label = &Apache::lonnet::plaintext($role); + my $button_code = ''; + return ($button_code); +} +# ---------------------------------------------------------- Call to definerole +sub set_custom_role { + my ($r) = @_; + my $rolename=$env{'form.rolename'}; + $rolename=~s/[^A-Za-z0-9]//gs; + if (!$rolename) { + &custom_role_editor($r); + return; + } + my ($jsback,$elements) = &crumb_utilities(); + my $jscript = ''; + + $r->print(&Apache::loncommon::start_page('Save Custom Role'),$jscript); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:backPage(document.customresult,'pickrole','')", + text=>"Pick custom role", + faq=>282,bug=>'Instructor Interface',}, + {href=>"javascript:backPage(document.customresult,'selected_custom_edit','')", + text=>"Edit custom role", + faq=>282,bug=>'Instructor Interface',}, + {href=>"javascript:backPage(document.customresult,'set_custom_roles','')", + text=>"Result", + faq=>282,bug=>'Instructor Interface',}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management')); + + my ($rdummy,$roledef)= + &Apache::lonnet::get('roles',["rolesdef_$rolename"]); + +# ------------------------------------------------------- Does this role exist? + $r->print('

'); + if (($rdummy ne 'con_lost') && ($roledef ne '')) { + $r->print(&mt('Existing Role').' "'); + } else { + $r->print(&mt('New Role').' "'); + $roledef=''; + } + $r->print($rolename.'"

'); +# ------------------------------------------------------- What can be assigned? + my $sysrole=''; + my $domrole=''; + my $courole=''; + + foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:c'})) { + my ($priv,$restrict)=split(/\&/,$item); + if (!$restrict) { $restrict=''; } + if ($env{'form.'.$priv.'_c'}) { + $courole.=':'.$item; } - } keys %ENV; - $r->print(''); + } + + foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:d'})) { + my ($priv,$restrict)=split(/\&/,$item); + if (!$restrict) { $restrict=''; } + if ($env{'form.'.$priv.'_d'}) { + $domrole.=':'.$item; + } + } + + foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:s'})) { + my ($priv,$restrict)=split(/\&/,$item); + if (!$restrict) { $restrict=''; } + if ($env{'form.'.$priv.'_s'}) { + $sysrole.=':'.$item; + } + } + $r->print('
Defining Role: '. + &Apache::lonnet::definerole($rolename,$sysrole,$domrole,$courole)); + if ($env{'request.course.id'}) { + my $url='/'.$env{'request.course.id'}; + $url=~s/\_/\//g; + $r->print('
'.&mt('Assigning Role to Self').': '. + &Apache::lonnet::assigncustomrole($env{'user.domain'}, + $env{'user.name'}, + $url, + $env{'user.domain'}, + $env{'user.name'}, + $rolename)); + } + $r->print('

'.&mt('Create or edit another custom role').'

'); + $r->print(&Apache::lonhtmlcommon::echo_form_input([]).'
'); + $r->print(&Apache::loncommon::end_page()); } # ================================================================ Main Handler sub handler { my $r = shift; - if ($r->header_only) { - $r->content_type('text/html'); + &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; return OK; } + my $context; + if ($env{'request.course.id'}) { + $context = 'course'; + } elsif ($env{'request.role'} =~ /^au\./) { + $context = 'construction_space'; + } else { + $context = 'domain'; + } + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, + ['action','state','callingform','roletype','showrole','bulkaction']); + &Apache::lonhtmlcommon::clear_breadcrumbs(); + if ($env{'form.action'} ne 'dateselect') { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"/adm/createuser", + text=>"User Management"}); + } + my ($permission,$allowed) = &get_permission($context); + if (!$allowed) { + $env{'user.error.msg'}= + "/adm/createuser:cst:0:0:Cannot create/modify user data ". + "or view user status."; + return HTTP_NOT_ACCEPTABLE; + } - if ((&Apache::lonnet::allowed('cta',$ENV{'request.course.id'})) || - (&Apache::lonnet::allowed('cin',$ENV{'request.course.id'})) || - (&Apache::lonnet::allowed('ccr',$ENV{'request.course.id'})) || - (&Apache::lonnet::allowed('cep',$ENV{'request.course.id'})) || - (&Apache::lonnet::allowed('mau',$ENV{'user.domain'}))) { - $r->content_type('text/html'); - $r->send_http_header; - unless ($ENV{'form.phase'}) { - &phase_one($r); - } - if ($ENV{'form.phase'} eq 'two') { - &phase_two($r); - } elsif ($ENV{'form.phase'} eq 'three') { - &phase_three($r); - } - } else { - $ENV{'user.error.msg'}= - "/adm/createcourse:mau:0:0:Cannot modify user data"; - return HTTP_NOT_ACCEPTABLE; - } - return OK; -} + &Apache::loncommon::content_type($r,'text/html'); + $r->send_http_header; + + # Main switch on form.action and form.state, as appropriate + if (! exists($env{'form.action'})) { + $r->print(&header()); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management')); + $r->print(&print_main_menu($permission)); + $r->print(&Apache::loncommon::end_page()); + } elsif ($env{'form.action'} eq 'upload' && $permission->{'cusr'}) { + $r->print(&header()); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'/adm/createuser?action=upload&state=', + text=>"Upload Users List"}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Upload Users List', + 'User_Management_Upload')); + $r->print('
'."\n"); + if (! exists($env{'form.state'})) { + &Apache::lonuserutils::print_first_users_upload_form($r,$context); + } elsif ($env{'form.state'} eq 'got_file') { + &Apache::lonuserutils::print_upload_manager_form($r,$context); + } elsif ($env{'form.state'} eq 'enrolling') { + if ($env{'form.datatoken'}) { + &Apache::lonuserutils::upfile_drop_add($r,$context); + } + } else { + &Apache::lonuserutils::print_first_users_upload_form($r,$context); + } + $r->print('
'.&Apache::loncommon::end_page()); + } elsif ($env{'form.action'} eq 'expire' && $permission->{'cusr'}) { + $r->print(&header()); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'/adm/createuser?action=expire', + text=>"Expire User Roles"}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Expire User Roles', + 'User_Management_Drops')); + if (! exists($env{'form.state'})) { + &Apache::lonuserutils::print_expire_menu($r,$context); + } elsif ($env{'form.state'} eq 'done') { + &Apache::lonuserutils::expire_user_list($r,$context); + } else { + &Apache::lonuserutils::print_expire_menu($r,$context); + } + $r->print(&Apache::loncommon::end_page()); + } elsif ($env{'form.action'} eq 'singleuser' && $permission->{'cusr'}) { + my $phase = $env{'form.phase'}; + my @search = ('srchterm','srchby','srchin','srchtype','srchdomain'); + &Apache::loncreateuser::restore_prev_selections(); + my $srch; + foreach my $item (@search) { + $srch->{$item} = $env{'form.'.$item}; + } + + if (($phase eq 'get_user_info') || ($phase eq 'userpicked')) { + if ($env{'form.phase'} eq 'get_user_info') { + my ($currstate,$response,$forcenewuser,$results) = + &user_search_result($srch); + if ($env{'form.currstate'} eq 'modify') { + $currstate = $env{'form.currstate'}; + } + if ($currstate eq 'select') { + &print_user_selection_page($r,$response,$srch,$results, + 'createuser',\@search); + } elsif ($currstate eq 'modify') { + my ($ccuname,$ccdomain); + if (($srch->{'srchby'} eq 'uname') && + ($srch->{'srchtype'} eq 'exact')) { + $ccuname = $srch->{'srchterm'}; + $ccdomain= $srch->{'srchdomain'}; + } else { + my @matchedunames = keys(%{$results}); + ($ccuname,$ccdomain) = split(/:/,$matchedunames[0]); + } + $ccuname =&LONCAPA::clean_username($ccuname); + $ccdomain=&LONCAPA::clean_domain($ccdomain); + if ($env{'form.forcenewuser'}) { + $response = ''; + } + &print_user_modification_page($r,$ccuname,$ccdomain, + $srch,$response,$context); + } elsif ($currstate eq 'query') { + &print_user_query_page($r,'createuser'); + } else { + &print_username_entry_form($r,$response,$srch, + $forcenewuser); + } + } elsif ($env{'form.phase'} eq 'userpicked') { + my $ccuname = &LONCAPA::clean_username($env{'form.seluname'}); + my $ccdomain = &LONCAPA::clean_domain($env{'form.seludom'}); + &print_user_modification_page($r,$ccuname,$ccdomain,$srch,'', + $context); + } + } elsif ($env{'form.phase'} eq 'update_user_data') { + &update_user_data($r); + } else { + &print_username_entry_form($r,undef,$srch); + } + } elsif ($env{'form.action'} eq 'custom' && $permission->{'custom'}) { + if ($env{'form.phase'} eq 'set_custom_roles') { + &set_custom_role($r); + } else { + &custom_role_editor($r); + } + } elsif ($env{'form.action'} eq 'listusers' && $permission->{'view'}) { + if ($env{'form.phase'} eq 'bulkchange') { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'backPage(document.studentform)', + text=>"List Users"}); + my $setting = $env{'form.roletype'}; + my $choice = $env{'form.bulkaction'}; + $r->print(&header()); + $r->print(&Apache::lonhtmlcommon::breadcrumbs("List Users", + 'User_Management_List')); + if ($permission->{'cusr'}) { + &Apache::lonuserutils::update_user_list($r,$context,$setting,$choice); + } + } else { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'/adm/createuser?action=listusers', + text=>"List Users"}); + my ($cb_jscript,$jscript,$totcodes,$codetitles,$idlist,$idlist_titles); + my $formname = 'studentform'; + if ($context eq 'domain' && $env{'form.roletype'} eq 'course') { + ($cb_jscript,$jscript,$totcodes,$codetitles,$idlist,$idlist_titles) = + &Apache::lonuserutils::courses_selector($env{'request.role.domain'}, + $formname); + $jscript .= &verify_user_display(); + my $js = &add_script($jscript).$cb_jscript; + my $loadcode = + &Apache::lonuserutils::course_selector_loadcode($formname); + if ($loadcode ne '') { + $r->print(&header($js,{'onload' => $loadcode,})); + } else { + $r->print(&header($js)); + } + } else { + $r->print(&header(&add_script(&verify_user_display()))); + } + $r->print(&Apache::lonhtmlcommon::breadcrumbs("List Users", + 'User_Management_List')); + &Apache::lonuserutils::print_userlist($r,undef,$permission,$context, + $formname,$totcodes,$codetitles,$idlist,$idlist_titles); + $r->print(&Apache::loncommon::end_page()); + } + } elsif ($env{'form.action'} eq 'expire' && $permission->{'cusr'}) { + $r->print(&header()); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'/adm/createuser?action=drop', + text=>"Expire Users"}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Expire User Roles', + 'User_Management_Drops')); + if (! exists($env{'form.state'})) { + &Apache::lonuserutils::print_expire_menu($r,$context); + } elsif ($env{'form.state'} eq 'done') { + &Apache::lonuserutiles::expire_user_list($r,$context); + } else { + &print_expire_menu($r,$context); + } + $r->print(&Apache::loncommon::end_page()); + } elsif ($env{'form.action'} eq 'dateselect') { + if ($permission->{'cusr'}) { + $r->print(&header(undef,undef,{'no_nav_bar' => 1}). + &Apache::lonuserutils::date_section_selector($context). + &Apache::loncommon::end_page()); + } else { + $r->print(&header(). + ''.&mt('You do not have permission to modify dates or sections for users').''. + &Apache::loncommon::end_page()); + } + } else { + $r->print(&header()); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management')); + $r->print(&print_main_menu($permission)); + $r->print(&Apache::loncommon::end_page()); + } + return OK; +} + +sub header { + my ($jscript,$loaditems,$args) = @_; + my $start_page; + if (ref($loaditems) eq 'HASH') { + $start_page=&Apache::loncommon::start_page('User Management',$jscript,{'add_entries' => $loaditems}); + } else { + $start_page=&Apache::loncommon::start_page('User Management',$jscript,$args); + } + return $start_page; +} + +sub add_script { + my ($js) = @_; + return ''; +} + +sub verify_user_display { + my $output = <<"END"; + +function display_update() { + document.studentform.action.value = 'listusers'; + document.studentform.phase.value = 'display'; + document.studentform.submit(); +} + +END + return $output; + +} + +############################################################### +############################################################### +# Menu Phase One +sub print_main_menu { + my ($permission) = @_; + my @menu = + ( + { text => 'Upload a File of Users to Modify/Create Users and/or Add roles', + help => 'User_Management_Upload', + action => 'upload', + permission => $permission->{'cusr'}, + }, + { text => 'Create User/Set User Roles for a single user', + help => 'User_Management_Single_User', + action => 'singleuser', + permission => $permission->{'cusr'}, + }, + { text => 'Display Lists of Users', + help => 'User_Management_List', + action => 'listusers', + permission => $permission->{'view'}, + }, +# { text => 'Expire User Roles', +# help => 'User_Management_Drops', +# action => 'expire', +# permission => $permission->{'cusr'}, +# }, + { text => 'Edit Custom Roles', + help => 'Custom_Role_Edit', + action => 'custom', + permission => $permission->{'custom'}, + }, + ); + my $menu_html = ''; + foreach my $menu_item (@menu) { + next if (! $menu_item->{'permission'}); + $menu_html.='

'; + $menu_html.=''; + if (exists($menu_item->{'url'})) { + $menu_html.=qq{}; + } else { + $menu_html.= + qq{}; + } + $menu_html.= &mt($menu_item->{'text'}).''; + if (exists($menu_item->{'help'})) { + $menu_html.= + &Apache::loncommon::help_open_topic($menu_item->{'help'}); + } + $menu_html.='

'; + } + return $menu_html; +} + +sub get_permission { + my ($context) = @_; + my %permission; + if ($context eq 'course') { + if ((&Apache::lonnet::allowed('cta',$env{'request.course.id'})) || + (&Apache::lonnet::allowed('cin',$env{'request.course.id'})) || + (&Apache::lonnet::allowed('ccr',$env{'request.course.id'})) || + (&Apache::lonnet::allowed('cep',$env{'request.course.id'})) || + (&Apache::lonnet::allowed('cst',$env{'request.course.id'}))) { + $permission{'cusr'} = 1; + $permission{'view'} = + &Apache::lonnet::allowed('vcl',$env{'request.course.id'}); + + } + if (&Apache::lonnet::allowed('ccr',$env{'request.course.id'})) { + $permission{'custom'} = 1; + } + if (&Apache::lonnet::allowed('vcl',$env{'request.course.id'})) { + $permission{'view'} = 1; + if (!$permission{'view'}) { + my $scope = $env{'request.course.id'}.'/'.$env{'request.course.sec'}; + $permission{'view'} = &Apache::lonnet::allowed('vcl',$scope); + if ($permission{'view'}) { + $permission{'view_section'} = $env{'request.course.sec'}; + } + } + } + } elsif ($context eq 'construction_space') { + $permission{'cusr'} = &authorpriv($env{'user.name'},$env{'request.role.domain'}); + $permission{'view'} = $permission{'cusr'}; + } else { + if ((&Apache::lonnet::allowed('cad',$env{'request.role.domain'})) || + (&Apache::lonnet::allowed('cli',$env{'request.role.domain'})) || + (&Apache::lonnet::allowed('cau',$env{'request.role.domain'})) || + (&Apache::lonnet::allowed('csc',$env{'request.role.domain'})) || + (&Apache::lonnet::allowed('cdg',$env{'request.role.domain'})) || + (&Apache::lonnet::allowed('mau',$env{'request.role.domain'}))) { + $permission{'cusr'} = 1; + } + if (&Apache::lonnet::allowed('ccr',$env{'request.role.domain'})) { + $permission{'custom'} = 1; + } + $permission{'view'} = $permission{'cusr'}; + } + my $allowed = 0; + foreach my $perm (values(%permission)) { + if ($perm) { $allowed=1; last; } + } + return (\%permission,$allowed); +} + +sub restore_prev_selections { + my %saveable_parameters = ('srchby' => 'scalar', + 'srchin' => 'scalar', + 'srchtype' => 'scalar', + ); + &Apache::loncommon::store_settings('user','user_picker', + \%saveable_parameters); + &Apache::loncommon::restore_settings('user','user_picker', + \%saveable_parameters); +} + +#-------------------------------------------------- functions for &phase_two +sub user_search_result { + my ($srch) = @_; + my %allhomes; + my %inst_matches; + my %srch_results; + my ($response,$currstate,$forcenewuser,$dirsrchres); + $srch->{'srchterm'} =~ s/\s+/ /g; + if ($srch->{'srchby'} !~ /^(uname|lastname|lastfirst)$/) { + $response = &mt('Invalid search.'); + } + if ($srch->{'srchin'} !~ /^(crs|dom|alc|instd)$/) { + $response = &mt('Invalid search.'); + } + if ($srch->{'srchtype'} !~ /^(exact|contains|begins)$/) { + $response = &mt('Invalid search.'); + } + if ($srch->{'srchterm'} eq '') { + $response = &mt('You must enter a search term.'); + } + if ($srch->{'srchterm'} =~ /^\s+$/) { + $response = &mt('Your search term must contain more than just spaces.'); + } + if (($srch->{'srchin'} eq 'dom') || ($srch->{'srchin'} eq 'instd')) { + if (($srch->{'srchdomain'} eq '') || + ! (&Apache::lonnet::domain($srch->{'srchdomain'}))) { + $response = &mt('You must specify a valid domain when searching in a domain or institutional directory.') + } + } + if (($srch->{'srchin'} eq 'dom') || ($srch->{'srchin'} eq 'crs') || + ($srch->{'srchin'} eq 'alc')) { + if ($srch->{'srchby'} eq 'uname') { + if ($srch->{'srchterm'} !~ /^$match_username$/) { + $response = &mt('You must specify a valid username. Only the following are allowed: letters numbers - . @'); + } + } + } + if ($response ne '') { + $response = ''.$response.''; + } + if ($srch->{'srchin'} eq 'instd') { + my $instd_chk = &directorysrch_check($srch); + if ($instd_chk ne 'ok') { + $response = ''.$instd_chk.''. + '
'.&mt('You may want to search in the LON-CAPA domain instead of the institutional directory.').'

'; + } + } + if ($response ne '') { + return ($currstate,$response); + } + if ($srch->{'srchby'} eq 'uname') { + if (($srch->{'srchin'} eq 'dom') || ($srch->{'srchin'} eq 'crs')) { + if ($env{'form.forcenew'}) { + if ($srch->{'srchdomain'} ne $env{'request.role.domain'}) { + my $uhome=&Apache::lonnet::homeserver($srch->{'srchterm'},$srch->{'srchdomain'}); + if ($uhome eq 'no_host') { + my $domdesc = &Apache::lonnet::domain($env{'request.role.domain'},'description'); + my $showdom = &display_domain_info($env{'request.role.domain'}); + $response = &mt('New users can only be created in the domain to which your current role belongs - [_1].',$showdom); + } else { + $currstate = 'modify'; + } + } else { + $currstate = 'modify'; + } + } else { + if ($srch->{'srchin'} eq 'dom') { + if ($srch->{'srchtype'} eq 'exact') { + my $uhome=&Apache::lonnet::homeserver($srch->{'srchterm'},$srch->{'srchdomain'}); + if ($uhome eq 'no_host') { + ($currstate,$response,$forcenewuser) = + &build_search_response($srch,%srch_results); + } else { + $currstate = 'modify'; + } + } else { + %srch_results = &Apache::lonnet::usersearch($srch); + ($currstate,$response,$forcenewuser) = + &build_search_response($srch,%srch_results); + } + } else { + my $courseusers = &get_courseusers(); + if ($srch->{'srchtype'} eq 'exact') { + if (exists($courseusers->{$srch->{'srchterm'}.':'.$srch->{'srchdomain'}})) { + $currstate = 'modify'; + } else { + ($currstate,$response,$forcenewuser) = + &build_search_response($srch,%srch_results); + } + } else { + foreach my $user (keys(%$courseusers)) { + my ($cuname,$cudomain) = split(/:/,$user); + if ($cudomain eq $srch->{'srchdomain'}) { + my $matched = 0; + if ($srch->{'srchtype'} eq 'begins') { + if ($cuname =~ /^\Q$srch->{'srchterm'}\E/i) { + $matched = 1; + } + } else { + if ($cuname =~ /\Q$srch->{'srchterm'}\E/i) { + $matched = 1; + } + } + if ($matched) { + $srch_results{$user} = + {&Apache::lonnet::get('environment', + ['firstname', + 'lastname', + 'permanentemail'], + $cudomain,$cuname)}; + } + } + } + ($currstate,$response,$forcenewuser) = + &build_search_response($srch,%srch_results); + } + } + } + } elsif ($srch->{'srchin'} eq 'alc') { + $currstate = 'query'; + } elsif ($srch->{'srchin'} eq 'instd') { + ($dirsrchres,%srch_results) = &Apache::lonnet::inst_directory_query($srch); + if ($dirsrchres eq 'ok') { + ($currstate,$response,$forcenewuser) = + &build_search_response($srch,%srch_results); + } else { + my $showdom = &display_domain_info($srch->{'srchdomain'}); + $response = ''. + &mt('Institutional directory search is not available in domain: [_1]',$showdom). + '
'. + &mt('You may want to search in the LON-CAPA domain instead of the institutional directory.'). + '

'; + } + } + } else { + if ($srch->{'srchin'} eq 'dom') { + %srch_results = &Apache::lonnet::usersearch($srch); + ($currstate,$response,$forcenewuser) = + &build_search_response($srch,%srch_results); + } elsif ($srch->{'srchin'} eq 'crs') { + my $courseusers = &get_courseusers(); + foreach my $user (keys(%$courseusers)) { + my ($uname,$udom) = split(/:/,$user); + my %names = &Apache::loncommon::getnames($uname,$udom); + my %emails = &Apache::loncommon::getemails($uname,$udom); + if ($srch->{'srchby'} eq 'lastname') { + if ((($srch->{'srchtype'} eq 'exact') && + ($names{'lastname'} eq $srch->{'srchterm'})) || + (($srch->{'srchtype'} eq 'begins') && + ($names{'lastname'} =~ /^\Q$srch->{'srchterm'}\E/i)) || + (($srch->{'srchtype'} eq 'contains') && + ($names{'lastname'} =~ /\Q$srch->{'srchterm'}\E/i))) { + $srch_results{$user} = {firstname => $names{'firstname'}, + lastname => $names{'lastname'}, + permanentemail => $emails{'permanentemail'}, + }; + } + } elsif ($srch->{'srchby'} eq 'lastfirst') { + my ($srchlast,$srchfirst) = split(/,/,$srch->{'srchterm'}); + $srchlast =~ s/\s+$//; + $srchfirst =~ s/^\s+//; + if ($srch->{'srchtype'} eq 'exact') { + if (($names{'lastname'} eq $srchlast) && + ($names{'firstname'} eq $srchfirst)) { + $srch_results{$user} = {firstname => $names{'firstname'}, + lastname => $names{'lastname'}, + permanentemail => $emails{'permanentemail'}, + + }; + } + } elsif ($srch->{'srchtype'} eq 'begins') { + if (($names{'lastname'} =~ /^\Q$srchlast\E/i) && + ($names{'firstname'} =~ /^\Q$srchfirst\E/i)) { + $srch_results{$user} = {firstname => $names{'firstname'}, + lastname => $names{'lastname'}, + permanentemail => $emails{'permanentemail'}, + }; + } + } else { + if (($names{'lastname'} =~ /\Q$srchlast\E/i) && + ($names{'firstname'} =~ /\Q$srchfirst\E/i)) { + $srch_results{$user} = {firstname => $names{'firstname'}, + lastname => $names{'lastname'}, + permanentemail => $emails{'permanentemail'}, + }; + } + } + } + } + ($currstate,$response,$forcenewuser) = + &build_search_response($srch,%srch_results); + } elsif ($srch->{'srchin'} eq 'alc') { + $currstate = 'query'; + } elsif ($srch->{'srchin'} eq 'instd') { + ($dirsrchres,%srch_results) = &Apache::lonnet::inst_directory_query($srch); + if ($dirsrchres eq 'ok') { + ($currstate,$response,$forcenewuser) = + &build_search_response($srch,%srch_results); + } else { + my $showdom = &display_domain_info($srch->{'srchdomain'}); $response = ''. + &mt('Institutional directory search is not available in domain: [_1]',$showdom). + '
'. + &mt('You may want to search in the LON-CAPA domain instead of the institutional directory.'). + '

'; + } + } + } + return ($currstate,$response,$forcenewuser,\%srch_results); +} + +sub directorysrch_check { + my ($srch) = @_; + my $can_search = 0; + my $response; + my %dom_inst_srch = &Apache::lonnet::get_dom('configuration', + ['directorysrch'],$srch->{'srchdomain'}); + my $showdom = &display_domain_info($srch->{'srchdomain'}); + if (ref($dom_inst_srch{'directorysrch'}) eq 'HASH') { + if (!$dom_inst_srch{'directorysrch'}{'available'}) { + return &mt('Institutional directory search is not available in domain: [_1]',$showdom); + } + if ($dom_inst_srch{'directorysrch'}{'localonly'}) { + if ($env{'request.role.domain'} ne $srch->{'srchdomain'}) { + return &mt('Institutional directory search in domain: [_1] is only allowed for users with a current role in the domain.',$showdom); + } + my @usertypes = split(/:/,$env{'environment.inststatus'}); + if (!@usertypes) { + push(@usertypes,'default'); + } + if (ref($dom_inst_srch{'directorysrch'}{'cansearch'}) eq 'ARRAY') { + foreach my $type (@usertypes) { + if (grep(/^\Q$type\E$/,@{$dom_inst_srch{'directorysrch'}{'cansearch'}})) { + $can_search = 1; + last; + } + } + } + if (!$can_search) { + my ($insttypes,$order) = &Apache::lonnet::retrieve_inst_usertypes($srch->{'srchdomain'}); + my @longtypes; + foreach my $item (@usertypes) { + push (@longtypes,$insttypes->{$item}); + } + my $insttype_str = join(', ',@longtypes); + return &mt('Institutional directory search in domain: [_1] is not available to your user type: ',$showdom).$insttype_str; + } + } else { + $can_search = 1; + } + } else { + return &mt('Institutional directory search has not been configured for domain: [_1]',$showdom); + } + my %longtext = &Apache::lonlocal::texthash ( + uname => 'username', + lastfirst => 'last name, first name', + lastname => 'last name', + contains => 'contains', + exact => 'as exact match to', + begins => 'begins with', + ); + if ($can_search) { + if (ref($dom_inst_srch{'directorysrch'}{'searchby'}) eq 'ARRAY') { + if (!grep(/^\Q$srch->{'srchby'}\E$/,@{$dom_inst_srch{'directorysrch'}{'searchby'}})) { + return &mt('Institutional directory search in domain: [_1] is not available for searching by "[_2]"',$showdom,$longtext{$srch->{'srchby'}}); + } + } else { + return &mt('Institutional directory search in domain: [_1] is not available.', $showdom); + } + } + if ($can_search) { + if (ref($dom_inst_srch{'directorysrch'}{'searchtypes'}) eq 'ARRAY') { + if (grep(/^\Q$srch->{'srchtype'}\E/,@{$dom_inst_srch{'directorysrch'}{'searchtypes'}})) { + return 'ok'; + } else { + return &mt('Institutional directory search in domain [_1] is not available for the requested search type: "[_2]"',$showdom,$longtext{$srch->{'srchtype'}}); + } + } else { + if ((($dom_inst_srch{'directorysrch'}{'searchtypes'} eq 'specify') && + ($srch->{'srchtype'} eq 'exact' || $srch->{'srchtype'} eq 'contains')) || + ($dom_inst_srch{'directorysrch'}{'searchtypes'} eq $srch->{'srchtype'})) { + return 'ok'; + } else { + return &mt('Institutional directory search in domain [_1] is not available for the requested search type: "[_2]"',$showdom,$longtext{$srch->{'srchtype'}}); + } + } + } +} + +sub get_courseusers { + my %advhash; + my $classlist = &Apache::loncoursedata::get_classlist(); + my %coursepersonnel=&Apache::lonnet::get_course_adv_roles(); + foreach my $role (sort(keys(%coursepersonnel))) { + foreach my $user (split(/\,/,$coursepersonnel{$role})) { + if (!exists($classlist->{$user})) { + $classlist->{$user} = []; + } + } + } + return $classlist; +} + +sub build_search_response { + my ($srch,%srch_results) = @_; + my ($currstate,$response,$forcenewuser); + my %names = ( + 'uname' => 'username', + 'lastname' => 'last name', + 'lastfirst' => 'last name, first name', + 'crs' => 'this course', + 'dom' => 'LON-CAPA domain: ', + 'instd' => 'the institutional directory for domain: ', + ); + + my %single = ( + begins => 'A match', + contains => 'A match', + exact => 'An exact match', + ); + my %nomatch = ( + begins => 'No match', + contains => 'No match', + exact => 'No exact match', + ); + if (keys(%srch_results) > 1) { + $currstate = 'select'; + } else { + if (keys(%srch_results) == 1) { + $currstate = 'modify'; + $response = &mt("$single{$srch->{'srchtype'}} was found for the $names{$srch->{'srchby'}} ([_1]) in $names{$srch->{'srchin'}}.",$srch->{'srchterm'}); + if ($srch->{'srchin'} eq 'dom' || $srch->{'srchin'} eq 'instd') { + $response .= &display_domain_info($srch->{'srchdomain'}); + } + } else { + $response = ''.&mt("$nomatch{$srch->{'srchtype'}} found for the $names{$srch->{'srchby'}} ([_1]) in $names{$srch->{'srchin'}}",$srch->{'srchterm'}); + if ($srch->{'srchin'} eq 'dom' || $srch->{'srchin'} eq 'instd') { + $response .= &display_domain_info($srch->{'srchdomain'}); + } + $response .= ''; + if ($srch->{'srchin'} ne 'alc') { + $forcenewuser = 1; + my $cansrchinst = 0; + if ($srch->{'srchdomain'}) { + my %domconfig = &Apache::lonnet::get_dom('configuration',['directorysrch'],$srch->{'srchdomain'}); + if (ref($domconfig{'directorysrch'}) eq 'HASH') { + if ($domconfig{'directorysrch'}{'available'}) { + $cansrchinst = 1; + } + } + } + if ((($srch->{'srchby'} eq 'lastfirst') || + ($srch->{'srchby'} eq 'lastname')) && + ($srch->{'srchin'} eq 'dom')) { + if ($cansrchinst) { + $response .= '
'.&mt('You may want to broaden your search to a search of the institutional directory for the domain.'); + } + } + if ($srch->{'srchin'} eq 'crs') { + $response .= '
'.&mt('You may want to broaden your search to the selected LON-CAPA domain.'); + } + } + if (!($srch->{'srchby'} eq 'uname' && $srch->{'srchin'} eq 'dom' && $srch->{'srchtype'} eq 'exact' && $srch->{'srchdomain'} eq $env{'request.role.domain'})) { + my $showdom = &display_domain_info($env{'request.role.domain'}); + $response .= '

'.&mt("To add a new user (you can only create new users in your current role's domain - [_1]):",$env{'request.role.domain'}).'
  • '.&mt("Set 'Domain/institution to search' to: [_1]",$showdom).'
  • '.&mt("Set 'Search criteria' to: 'username is ...... in selected LON-CAPA domain'").'
  • '.&mt('Provide the proposed username').'
  • '.&mt('Search').'

'; + } + } + } + return ($currstate,$response,$forcenewuser); +} + +sub display_domain_info { + my ($dom) = @_; + my $output = $dom; + if ($dom ne '') { + my $domdesc = &Apache::lonnet::domain($dom,'description'); + if ($domdesc ne '') { + $output .= ' ('.$domdesc.')'; + } + } + return $output; +} + +sub crumb_utilities { + my %elements = ( + crtuser => { + srchterm => 'text', + srchin => 'selectbox', + srchby => 'selectbox', + srchtype => 'selectbox', + srchdomain => 'selectbox', + }, + docustom => { + rolename => 'selectbox', + newrolename => 'textbox', + }, + studentform => { + srchterm => 'text', + srchin => 'selectbox', + srchby => 'selectbox', + srchtype => 'selectbox', + srchdomain => 'selectbox', + }, + ); + + my $jsback .= qq| +function backPage(formname,prevphase,prevstate) { + formname.phase.value = prevphase; + formname.currstate.value = prevstate; + formname.submit(); +} +|; + return ($jsback,\%elements); +} + +sub course_level_table { + my (%inccourses) = @_; + my $table = ''; +# Custom Roles? + + my %customroles=&Apache::lonuserutils::my_custom_roles(); + my %lt=&Apache::lonlocal::texthash( + 'exs' => "Existing sections", + 'new' => "Define new section", + 'ssd' => "Set Start Date", + 'sed' => "Set End Date", + 'crl' => "Course Level", + 'act' => "Activate", + 'rol' => "Role", + 'ext' => "Extent", + 'grs' => "Section", + 'sta' => "Start", + 'end' => "End" + ); + + foreach my $protectedcourse (sort( keys(%inccourses))) { + my $thiscourse=$protectedcourse; + $thiscourse=~s:_:/:g; + my %coursedata=&Apache::lonnet::coursedescription($thiscourse); + my $area=$coursedata{'description'}; + my $type=$coursedata{'type'}; + if (!defined($area)) { $area=&mt('Unavailable course').': '.$protectedcourse; } + my ($domain,$cnum)=split(/\//,$thiscourse); + my %sections_count; + if (defined($env{'request.course.id'})) { + if ($env{'request.course.id'} eq $domain.'_'.$cnum) { + %sections_count = + &Apache::loncommon::get_sections($domain,$cnum); + } + } + foreach my $role ('st','ta','ep','in','cc') { + if (&Apache::lonnet::allowed('c'.$role,$thiscourse)) { + my $plrole=&Apache::lonnet::plaintext($role); + $table .= &Apache::loncommon::start_data_table_row(). +' +'.$plrole.' +'.$area.'
Domain: '.$domain.''."\n"; + if ($role ne 'cc') { + if (%sections_count) { + my $currsec = + &Apache::lonuserutils::course_sections(\%sections_count, + $protectedcourse.'_'.$role); + $table .= + ''. + ' + '. + ''. + ''. + '
'.$lt{'exs'}.'
'. + $currsec.'
   '.$lt{'new'}.'
'. + ''. + '
'; + } else { + $table .= ''; + } + } else { + $table .= ' '; + } + $table .= < +$lt{'ssd'} + +$lt{'sed'} +ENDTIMEENTRY + $table.= &Apache::loncommon::end_data_table_row(); + } + } + foreach my $cust (sort keys %customroles) { + if (&Apache::lonnet::allowed('ccr',$thiscourse)) { + my $plrole=$cust; + my $customrole=$protectedcourse.'_cr_cr_'.$env{'user.domain'}. + '_'.$env{'user.name'}.'_'.$plrole; + $table .= &Apache::loncommon::start_data_table_row(). +' +'.$plrole.' +'.$area.''."\n"; + if (%sections_count) { + my $currsec = + &Apache::lonuserutils::course_sections(\%sections_count, + $customrole); + $table.= + ''. + ''. + ''. + ''. + ''. + '
'. + $lt{'exs'}.'
'.$currsec.'
   '.$lt{'new'}.'
'. + '
'; + } else { + $table .= ''; + } + $table .= < +$lt{'ssd'} + +$lt{'sed'} +ENDENTRY + $table .= &Apache::loncommon::end_data_table_row(); + } + } + } + return '' if ($table eq ''); # return nothing if there is nothing + # in the table + my $result; + if (!$env{'request.course.id'}) { + $result = '

'.$lt{'crl'}.'

'."\n"; + } + $result .= +&Apache::loncommon::start_data_table(). +&Apache::loncommon::start_data_table_header_row(). +''.$lt{'act'}.''.$lt{'rol'}.''.$lt{'ext'}.' +'.$lt{'grs'}.''.$lt{'sta'}.''.$lt{'end'}.''. +&Apache::loncommon::end_data_table_header_row(). +$table. +&Apache::loncommon::end_data_table(); + return $result; +} + +sub course_level_dc { + my ($dcdom) = @_; + my %customroles=&Apache::lonuserutils::my_custom_roles(); + my $hiddenitems = ''. + ''. + ''; + my $courseform=''.&Apache::loncommon::selectcourse_link + ('cu','dccourse','dcdomain','coursedesc',undef,undef,'Course').''; + my $cb_jscript = &Apache::loncommon::coursebrowser_javascript($dcdom,'currsec','cu'); + my %lt=&Apache::lonlocal::texthash( + 'rol' => "Role", + 'grs' => "Section", + 'exs' => "Existing sections", + 'new' => "Define new section", + 'sta' => "Start", + 'end' => "End", + 'ssd' => "Set Start Date", + 'sed' => "Set End Date" + ); + my $header = '

'.&mt('Course Level').'

'. + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). + ''.$courseform.''.$lt{'rol'}.''.$lt{'grs'}.''.$lt{'sta'}.''.$lt{'end'}.''. + &Apache::loncommon::end_data_table_header_row(); + my $otheritems = &Apache::loncommon::start_data_table_row()."\n". + ''."\n". + ''. + ''. + ''. + ''. + ''. + '
'.$lt{'exs'}.'
   '.$lt{'new'}.'
'. + ''. + '
'; + $otheritems .= < +$lt{'ssd'} + +$lt{'sed'} +ENDTIMEENTRY + $otheritems .= &Apache::loncommon::end_data_table_row(). + &Apache::loncommon::end_data_table()."\n"; + return $cb_jscript.$header.$hiddenitems.$otheritems; +} + +#---------------------------------------------- end functions for &phase_two + +#--------------------------------- functions for &phase_two and &phase_three + +#--------------------------end of functions for &phase_two and &phase_three 1; __END__