File:  [LON-CAPA] / loncom / interface / loncreateuser.pm
Revision 1.131: download - view: text, annotated - select for diffs
Thu Nov 9 22:25:27 2006 UTC (17 years, 6 months ago) by raeburn
Branches: MAIN
CVS tags: HEAD
Elimination of term 'Group' when referring to a non-standard course.  Renaming of form elements when DC assigns a new course role looks up index of relevant form elements based on elements' names instead of using hardcoded numerical offsets. Fix typo in onFocus() call when user clicks in textbox for course name in DC's course level role setter.

    1: # The LearningOnline Network with CAPA
    2: # Create a user
    3: #
    4: # $Id: loncreateuser.pm,v 1.131 2006/11/09 22:25:27 raeburn Exp $
    5: #
    6: # Copyright Michigan State University Board of Trustees
    7: #
    8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
    9: #
   10: # LON-CAPA is free software; you can redistribute it and/or modify
   11: # it under the terms of the GNU General Public License as published by
   12: # the Free Software Foundation; either version 2 of the License, or
   13: # (at your option) any later version.
   14: #
   15: # LON-CAPA is distributed in the hope that it will be useful,
   16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18: # GNU General Public License for more details.
   19: #
   20: # You should have received a copy of the GNU General Public License
   21: # along with LON-CAPA; if not, write to the Free Software
   22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   23: #
   24: # /home/httpd/html/adm/gpl.txt
   25: #
   26: # http://www.lon-capa.org/
   27: #
   28: ###
   29: 
   30: package Apache::loncreateuser;
   31: 
   32: =pod
   33: 
   34: =head1 NAME
   35: 
   36: Apache::loncreateuser - handler to create users and custom roles
   37: 
   38: =head1 SYNOPSIS
   39: 
   40: Apache::loncreateuser provides an Apache handler for creating users,
   41:     editing their login parameters, roles, and removing roles, and
   42:     also creating and assigning custom roles.
   43: 
   44: =head1 OVERVIEW
   45: 
   46: =head2 Custom Roles
   47: 
   48: In LON-CAPA, roles are actually collections of privileges. "Teaching
   49: Assistant", "Course Coordinator", and other such roles are really just
   50: collection of privileges that are useful in many circumstances.
   51: 
   52: Creating custom roles can be done by the Domain Coordinator through
   53: the Create User functionality. That screen will show all privileges
   54: that can be assigned to users. For a complete list of privileges,
   55: please see C</home/httpd/lonTabs/rolesplain.tab>.
   56: 
   57: Custom role definitions are stored in the C<roles.db> file of the role
   58: author.
   59: 
   60: =cut
   61: 
   62: use strict;
   63: use Apache::Constants qw(:common :http);
   64: use Apache::lonnet;
   65: use Apache::loncommon;
   66: use Apache::lonlocal;
   67: use Apache::longroup;
   68: use lib '/home/httpd/lib/perl/';
   69: use LONCAPA;
   70: 
   71: my $loginscript; # piece of javascript used in two separate instances
   72: my $generalrule;
   73: my $authformnop;
   74: my $authformkrb;
   75: my $authformint;
   76: my $authformfsys;
   77: my $authformloc;
   78: 
   79: sub initialize_authen_forms {
   80:     my ($krbdefdom)=( $ENV{'SERVER_NAME'}=~/(\w+\.\w+)$/);
   81:     $krbdefdom= uc($krbdefdom);
   82:     my %param = ( formname => 'document.cu',
   83:                   kerb_def_dom => $krbdefdom 
   84:                   );
   85: # no longer static due to configurable kerberos defaults
   86: #    $loginscript  = &Apache::loncommon::authform_header(%param);
   87:     $generalrule  = &Apache::loncommon::authform_authorwarning(%param);
   88:     $authformnop  = &Apache::loncommon::authform_nochange(%param);
   89: # no longer static due to configurable kerberos defaults
   90: #    $authformkrb  = &Apache::loncommon::authform_kerberos(%param);
   91:     $authformint  = &Apache::loncommon::authform_internal(%param);
   92:     $authformfsys = &Apache::loncommon::authform_filesystem(%param);
   93:     $authformloc  = &Apache::loncommon::authform_local(%param);
   94: }
   95: 
   96: 
   97: # ======================================================= Existing Custom Roles
   98: 
   99: sub my_custom_roles {
  100:     my %returnhash=();
  101:     my %rolehash=&Apache::lonnet::dump('roles');
  102:     foreach (keys %rolehash) {
  103: 	if ($_=~/^rolesdef\_(\w+)$/) {
  104: 	    $returnhash{$1}=$1;
  105: 	}
  106:     }
  107:     return %returnhash;
  108: }
  109: 
  110: # ==================================================== Figure out author access
  111: 
  112: sub authorpriv {
  113:     my ($auname,$audom)=@_;
  114:     unless ((&Apache::lonnet::allowed('cca',$audom.'/'.$auname))
  115:          || (&Apache::lonnet::allowed('caa',$audom.'/'.$auname))) { return ''; }
  116:     return 1;
  117: }
  118: 
  119: # =================================================================== Phase one
  120: 
  121: sub print_username_entry_form {
  122:     my ($r) = @_;
  123:     my $defdom=$env{'request.role.domain'};
  124:     my @domains = &Apache::loncommon::get_domains();
  125:     my $domform = &Apache::loncommon::select_dom_form($defdom,'ccdomain');
  126:     my $selscript=&Apache::loncommon::studentbrowser_javascript();
  127:     my $start_page =
  128: 	&Apache::loncommon::start_page('Create Users, Change User Privileges',
  129: 				       $selscript);
  130: 
  131:     my $sellink=&Apache::loncommon::selectstudent_link
  132:                                         ('crtuser','ccuname','ccdomain');
  133:     my %existingroles=&my_custom_roles();
  134:     my $choice=&Apache::loncommon::select_form('make new role','rolename',
  135: 		('make new role' => 'Generate new role ...',%existingroles));
  136:     my %lt=&Apache::lonlocal::texthash(
  137: 		    'siur'   => "Set Individual User Roles",
  138: 		    'usr'  => "Username",
  139:                     'dom'  => "Domain",
  140:                     'usrr' => "User Roles",
  141:                     'ecrp' => "Edit Custom Role Privileges",
  142:                     'nr'   => "Name of Role",
  143:                     'cre'  => "Custom Role Editor"
  144: 				       );
  145:     my $help = &Apache::loncommon::help_open_menu(undef,undef,282,'Instructor Interface');
  146:     my $helpsiur=&Apache::loncommon::help_open_topic('Course_Change_Privileges');
  147:     my $helpecpr=&Apache::loncommon::help_open_topic('Course_Editing_Custom_Roles');
  148:     $r->print(<<"ENDDOCUMENT");
  149: $start_page
  150: <form action="/adm/createuser" method="post" name="crtuser">
  151: <input type="hidden" name="phase" value="get_user_info">
  152: <h2>$lt{siur}$helpsiur</h2>
  153: <table>
  154: <tr><td>$lt{usr}:</td><td><input type="text" size="15" name="ccuname">
  155: </td><td rowspan="2">$sellink</td></tr><tr><td>
  156: $lt{'dom'}:</td><td>$domform</td></tr>
  157: </table>
  158: <input name="userrole" type="submit" value="$lt{usrr}" />
  159: </form>
  160: ENDDOCUMENT
  161:    if (&Apache::lonnet::allowed('mcr','/')) {
  162:        $r->print(<<ENDCUSTOM);
  163: <form action="/adm/createuser" method="post" name="docustom">
  164: <input type="hidden" name="phase" value="selected_custom_edit">
  165: <h2>$lt{'ecrp'}$helpecpr</h2>
  166: $lt{'nr'}: $choice <input type="text" size="15" name="newrolename" /><br />
  167: <input name="customeditor" type="submit" value="$lt{'cre'}" />
  168: </form>
  169: ENDCUSTOM
  170:     }
  171:     $r->print(&Apache::loncommon::end_page());
  172: }
  173: 
  174: 
  175: sub user_modification_js {
  176:     my ($pjump_def,$dc_setcourse_code,$nondc_setsection_code,$groupslist)=@_;
  177:     
  178:     return <<END;
  179: <script type="text/javascript" language="Javascript">
  180: 
  181:     function pclose() {
  182:         parmwin=window.open("/adm/rat/empty.html","LONCAPAparms",
  183:                  "height=350,width=350,scrollbars=no,menubar=no");
  184:         parmwin.close();
  185:     }
  186: 
  187:     $pjump_def
  188:     $dc_setcourse_code
  189: 
  190:     function dateset() {
  191:         eval("document.cu."+document.cu.pres_marker.value+
  192:             ".value=document.cu.pres_value.value");
  193:         pclose();
  194:     }
  195: 
  196:     $nondc_setsection_code
  197: 
  198: </script>
  199: END
  200: }
  201: 
  202: # =================================================================== Phase two
  203: sub print_user_modification_page {
  204:     my $r=shift;
  205:     my $ccuname=$env{'form.ccuname'};
  206:     my $ccdomain=$env{'form.ccdomain'};
  207: 
  208:     $ccuname=~s/\W//g;
  209:     $ccdomain=~s/\W//g;
  210: 
  211:     unless (($ccuname) && ($ccdomain)) {
  212: 	&print_username_entry_form($r);
  213:         return;
  214:     }
  215: 
  216:     my $defdom=$env{'request.role.domain'};
  217: 
  218:     my ($krbdef,$krbdefdom) =
  219:        &Apache::loncommon::get_kerberos_defaults($defdom);
  220: 
  221:     my %param = ( formname => 'document.cu',
  222:                   kerb_def_dom => $krbdefdom,
  223:                   kerb_def_auth => $krbdef
  224:                   );
  225:     $loginscript  = &Apache::loncommon::authform_header(%param);
  226:     $authformkrb  = &Apache::loncommon::authform_kerberos(%param);
  227: 
  228:     $ccuname=~s/\W//g;
  229:     $ccdomain=~s/\W//g;
  230:     my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition();
  231:     my $dc_setcourse_code = '';
  232:     my $nondc_setsection_code = '';                                        
  233: 
  234:     my %loaditem;
  235: 
  236:     my $groupslist;
  237:     my %curr_groups = &Apache::longroup::coursegroups();
  238:     if (%curr_groups) {
  239:         $groupslist = join('","',sort(keys(%curr_groups)));
  240:         $groupslist = '"'.$groupslist.'"';   
  241:     }
  242: 
  243:     if ($env{'request.role'} =~ m-^dc\./(\w+)/$-) {
  244:         my $dcdom = $1;
  245:         $loaditem{'onload'} = "document.cu.coursedesc.value='';";
  246:         my @rolevals = ('st','ta','ep','in','cc');
  247:         my (@crsroles,@grproles);
  248:         for (my $i=0; $i<@rolevals; $i++) {
  249:             $crsroles[$i]=&Apache::lonnet::plaintext($rolevals[$i],'Course');
  250:             $grproles[$i]=&Apache::lonnet::plaintext($rolevals[$i],'Group');
  251:         }
  252:         my $rolevalslist = join('","',@rolevals);
  253:         my $crsrolenameslist = join('","',@crsroles);
  254:         my $grprolenameslist = join('","',@grproles);
  255:         my $pickcrsfirst = '<--'.&mt('Pick course first');
  256:         my $pickgrpfirst = '<--'.&mt('Pick group first'); 
  257:         $dc_setcourse_code = <<"ENDSCRIPT";
  258:     function setCourse() {
  259:         var course = document.cu.dccourse.value;
  260:         if (course != "") {
  261:             if (document.cu.dcdomain.value != document.cu.origdom.value) {
  262:                 alert("You must select a course in the current domain");
  263:                 return;
  264:             } 
  265:             var userrole = document.cu.role.options[document.cu.role.selectedIndex].value
  266:             var section="";
  267:             var numsections = 0;
  268:             var newsecs = new Array();
  269:             for (var i=0; i<document.cu.currsec.length; i++) {
  270:                 if (document.cu.currsec.options[i].selected == true ) {
  271:                     if (document.cu.currsec.options[i].value != "" && document.cu.currsec.options[i].value != null) { 
  272:                         if (numsections == 0) {
  273:                             section = document.cu.currsec.options[i].value
  274:                             numsections = 1;
  275:                         }
  276:                         else {
  277:                             section = section + "," +  document.cu.currsec.options[i].value
  278:                             numsections ++;
  279:                         }
  280:                     }
  281:                 }
  282:             }
  283:             if (document.cu.newsec.value != "" && document.cu.newsec.value != null) {
  284:                 if (numsections == 0) {
  285:                     section = document.cu.newsec.value
  286:                 }
  287:                 else {
  288:                     section = section + "," +  document.cu.newsec.value
  289:                 }
  290:                 newsecs = document.cu.newsec.value.split(/,/g);
  291:                 numsections = numsections + newsecs.length;
  292:             }
  293:             if ((userrole == 'st') && (numsections > 1)) {
  294:                 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.")
  295:                 return;
  296:             }
  297:             for (var j=0; j<newsecs.length; j++) {
  298:                 if ((newsecs[j] == 'all') || (newsecs[j] == 'none')) {
  299:                     alert("'"+newsecs[j]+"' may not be used as the name for a section, as it is a reserved word.\\nPlease choose a different section name.");
  300:                     return;
  301:                 }
  302:                 if (document.cu.groups.value != '') {
  303:                     var groups = document.cu.groups.value.split(/,/g);
  304:                     for (var k=0; k<groups.length; k++) {
  305:                         if (newsecs[j] == groups[k]) {
  306:                             alert("'"+newsecs[j]+"' may not be used as the name for a section, as it is the name of a course group.\\nSection names and group names must be distinct. Please choose a different section name.");
  307:                             return; 
  308:                         }
  309:                     }
  310:                 }
  311:             }
  312:             if ((userrole == 'cc') && (numsections > 0)) {
  313:                 alert("Section designations do not apply to Course Coordinator roles.\\nA course coordinator role will be added with access to all sections.");
  314:                 section = "";
  315:             }
  316:             var coursename = "_$dcdom"+"_"+course+"_"+userrole
  317:             var numcourse = getIndex(document.cu.dccourse);
  318:             if (numcourse == "-1") {
  319:                 alert("There was a problem with your course selection");
  320:                 return
  321:             }
  322:             else {
  323:                 document.cu.elements[numcourse].name = "act"+coursename;
  324:                 var numnewsec = getIndex(document.cu.newsec);
  325:                 if (numnewsec != "-1") {
  326:                     document.cu.elements[numnewsec].name = "sec"+coursename;
  327:                     document.cu.elements[numnewsec].value = section;
  328:                 }
  329:                 var numstart = getIndex(document.cu.start);
  330:                 if (numstart != "-1") {
  331:                     document.cu.elements[numstart].name = "start"+coursename;
  332:                 }
  333:                 var numend = getIndex(document.cu.end);
  334:                 if (numend != "-1") {
  335:                     document.cu.elements[numend].name = "end"+coursename
  336:                 }
  337:             }
  338:         }
  339:         document.cu.submit();
  340:     }
  341: 
  342:     function getIndex(caller) {
  343:         for (var i=0;i<document.cu.elements.length;i++) {
  344:             if (document.cu.elements[i] == caller) {
  345:                 return i;
  346:             }
  347:         }
  348:         return -1;
  349:     }
  350: 
  351:     function setType() {
  352:         var crstype = document.cu.crstype.options[document.cu.crstype.selectedIndex].value;
  353:         rolevals = new Array("$rolevalslist");
  354:         if (crstype == 'Group') {
  355:             if (document.cu.currsec.options[0].text == "$pickcrsfirst") {
  356:                 document.cu.currsec.options[0].text = "$pickgrpfirst";
  357:             } 
  358:             grprolenames = new Array("$grprolenameslist");
  359:             for (var i=0; i<rolevals.length; i++) {
  360:                 if (document.cu.role.selectedIndex == i) {
  361:                     document.cu.role.options[i] = new Option(grprolenames[i],rolevals[i],true,false);
  362:                 } else {
  363:                     document.cu.role.options[i] = new Option(grprolenames[i],rolevals[i],false,false);
  364:                 }
  365:             }
  366:         } else {
  367:             if (document.cu.currsec.options[0].text == "$pickgrpfirst") {
  368:                 document.cu.currsec.options[0].text = "$pickcrsfirst";
  369:             }
  370:             crsrolenames = new Array("$crsrolenameslist");
  371:             for (var i=0; i<rolevals.length; i++) {
  372:                 if (document.cu.role.selectedIndex == i) {
  373:                     document.cu.role.options[i] = new Option(crsrolenames[i],rolevals[i],true,false);
  374:                 } else {
  375:                     document.cu.role.options[i] = new Option(crsrolenames[i],rolevals[i],false,false);
  376:                 }
  377:             }
  378:         }
  379:     }
  380: ENDSCRIPT
  381:     } else {
  382:         $nondc_setsection_code = <<"ENDSECCODE";
  383:     function setSections() {
  384:         var re1 = /^currsec_/;
  385:         var groups = new Array($groupslist);
  386:         for (var i=0;i<document.cu.elements.length;i++) {
  387:             var str = document.cu.elements[i].name;
  388:             var checkcurr = str.match(re1);
  389:             if (checkcurr != null) {
  390:                 if (document.cu.elements[i-1].checked == true) {
  391:                     var re2 = /^currsec_[a-zA-Z0-9]+_[a-zA-Z0-9]+_(\\w+)\$/;
  392:                     match = re2.exec(str);
  393:                     var role = match[1];
  394:                     if (role == 'cc') {
  395:                         alert("Section designations do not apply to Course Coordinator roles.\\nA course coordinator role will be added with access to all sections.");
  396:                     }
  397:                     else {
  398:                         var sections = '';
  399:                         var numsec = 0;
  400:                         var sections;
  401:                         for (var j=0; j<document.cu.elements[i].length; j++) {
  402:                             if (document.cu.elements[i].options[j].selected == true ) {
  403:                                 if (document.cu.elements[i].options[j].value != "") {
  404:                                     if (numsec == 0) {
  405:                                         if (document.cu.elements[i].options[j].value != "") {
  406:                                             sections = document.cu.elements[i].options[j].value;
  407:                                             numsec ++;
  408:                                         }
  409:                                     }
  410:                                     else {
  411:                                         sections = sections + "," +  document.cu.elements[i].options[j].value
  412:                                         numsec ++;
  413:                                     }
  414:                                 }
  415:                             }
  416:                         }
  417:                         if (numsec > 0) {
  418:                             if (document.cu.elements[i+1].value != "" && document.cu.elements[i+1].value != null) {
  419:                                 sections = sections + "," +  document.cu.elements[i+1].value;
  420:                             }
  421:                         }
  422:                         else {
  423:                             sections = document.cu.elements[i+1].value;
  424:                         }
  425:                         var newsecs = document.cu.elements[i+1].value;
  426: 			var numsplit;
  427:                         if (newsecs != null && newsecs != "") {
  428:                             numsplit = newsecs.split(/,/g);
  429:                             numsec = numsec + numsplit.length;
  430:                         }
  431: 
  432:                         if ((role == 'st') && (numsec > 1)) {
  433:                             alert("In each course, each user may only have one student role at a time. You had selected "+numsec+" sections.\\nPlease modify your selections so they include no more than one section.")
  434:                             return;
  435:                         }
  436:                         else if (numsplit != null) {
  437:                             for (var j=0; j<numsplit.length; j++) {
  438:                                 if ((numsplit[j] == 'all') ||
  439:                                     (numsplit[j] == 'none')) {
  440:                                     alert("'"+numsplit[j]+"' may not be used as the name for a section, as it is a reserved word.\\nPlease choose a different section name.");
  441:                                     return;
  442:                                 }
  443:                                 for (var k=0; k<groups.length; k++) {
  444:                                     if (numsplit[j] == groups[k]) {
  445:                                         alert("'"+numsplit[j]+"' may not be used as a section name, as it is the name of a course group.\\nSection names and group names must be distinct. Please choose a different section name.");
  446:                                         return;
  447:                                     }
  448:                                 }
  449:                             }
  450:                         }
  451:                         document.cu.elements[i+2].value = sections;
  452:                     }
  453:                 }
  454:             }
  455:         }
  456:         document.cu.submit();
  457:     }
  458: ENDSECCODE
  459:     }
  460:     my $js = &user_modification_js($pjump_def,$dc_setcourse_code,
  461:                                    $nondc_setsection_code,$groupslist);
  462:     my $start_page = 
  463: 	&Apache::loncommon::start_page('Create Users, Change User Privileges',
  464: 				       $js,{'add_entries' => \%loaditem,});
  465: 
  466:     my $forminfo =<<"ENDFORMINFO";
  467: <form action="/adm/createuser" method="post" name="cu">
  468: <input type="hidden" name="phase"       value="update_user_data">
  469: <input type="hidden" name="ccuname"     value="$ccuname">
  470: <input type="hidden" name="ccdomain"    value="$ccdomain">
  471: <input type="hidden" name="pres_value"  value="" >
  472: <input type="hidden" name="pres_type"   value="" >
  473: <input type="hidden" name="pres_marker" value="" >
  474: ENDFORMINFO
  475:     my $uhome=&Apache::lonnet::homeserver($ccuname,$ccdomain);
  476:     my %incdomains; 
  477:     my %inccourses;
  478:     foreach (values(%Apache::lonnet::hostdom)) {
  479:        $incdomains{$_}=1;
  480:     }
  481:     foreach (keys(%env)) {
  482: 	if ($_=~/^user\.priv\.cm\.\/(\w+)\/(\w+)/) {
  483: 	    $inccourses{$1.'_'.$2}=1;
  484:         }
  485:     }
  486:     if ($uhome eq 'no_host') {
  487:         my $home_server_list=
  488:             '<option value="default" selected>default</option>'."\n".
  489:                 &Apache::loncommon::home_server_option_list($ccdomain);
  490:         
  491: 	my %lt=&Apache::lonlocal::texthash(
  492:                     'cnu'  => "Create New User",
  493:                     'nu'   => "New User",
  494:                     'id'   => "in domain",
  495:                     'pd'   => "Personal Data",
  496:                     'fn'   => "First Name",
  497:                     'mn'   => "Middle Name",
  498:                     'ln'   => "Last Name",
  499:                     'gen'  => "Generation",
  500:                     'idsn' => "ID/Student Number",
  501:                     'hs'   => "Home Server",
  502:                     'lg'   => "Login Data"
  503: 				       );
  504: 	my $genhelp=&Apache::loncommon::help_open_topic('Generation');
  505:         &initialize_authen_forms();
  506: 	$r->print(<<ENDNEWUSER);
  507: $start_page
  508: <h1>$lt{'cnu'}</h1>
  509: $forminfo
  510: <h2>$lt{'nu'} "$ccuname" $lt{'id'} $ccdomain</h2>
  511: <script type="text/javascript" language="Javascript">
  512: $loginscript
  513: </script>
  514: <input type='hidden' name='makeuser' value='1' />
  515: <h3>$lt{'pd'}</h3>
  516: <p>
  517: <table>
  518: <tr><td>$lt{'fn'}  </td>
  519:     <td><input type='text' name='cfirst'  size='15' /></td></tr>
  520: <tr><td>$lt{'mn'} </td> 
  521:     <td><input type='text' name='cmiddle' size='15' /></td></tr>
  522: <tr><td>$lt{'ln'}   </td>
  523:     <td><input type='text' name='clast'   size='15' /></td></tr>
  524: <tr><td>$lt{'gen'}$genhelp</td>
  525:     <td><input type='text' name='cgen'    size='5'  /></td></tr>
  526: </table>
  527: $lt{'idsn'} <input type='text' name='cstid'   size='15' /></p>
  528: $lt{'hs'}: <select name="hserver" size="1"> $home_server_list </select>
  529: <hr />
  530: <h3>$lt{'lg'}</h3>
  531: <p>$generalrule </p>
  532: <p>$authformkrb </p>
  533: <p>$authformint </p>
  534: <p>$authformfsys</p>
  535: <p>$authformloc </p>
  536: ENDNEWUSER
  537:     } else { # user already exists
  538: 	my %lt=&Apache::lonlocal::texthash(
  539:                     'cup'  => "Change User Privileges",
  540:                     'usr'  => "User",                    
  541:                     'id'   => "in domain",
  542:                     'fn'   => "first name",
  543:                     'mn'   => "middle name",
  544:                     'ln'   => "last name",
  545:                     'gen'  => "generation"
  546: 				       );
  547: 	$r->print(<<ENDCHANGEUSER);
  548: $start_page
  549: <h1>$lt{'cup'}</h1>
  550: $forminfo
  551: <h2>$lt{'usr'} "$ccuname" $lt{'id'} "$ccdomain"</h2>
  552: ENDCHANGEUSER
  553:         # Get the users information
  554:         my %userenv = &Apache::lonnet::get('environment',
  555:                           ['firstname','middlename','lastname','generation'],
  556:                           $ccdomain,$ccuname);
  557:         my %rolesdump=&Apache::lonnet::dump('roles',$ccdomain,$ccuname);
  558:         $r->print(<<END);
  559: <hr />
  560: <table border="2">
  561: <tr>
  562: <th>$lt{'fn'}</th><th>$lt{'mn'}</th><th>$lt{'ln'}</th><th>$lt{'gen'}</th>
  563: </tr>
  564: <tr>
  565: END
  566:         foreach ('firstname','middlename','lastname','generation') {
  567:            if (&Apache::lonnet::allowed('mau',$ccdomain)) {
  568:               $r->print(<<"END");            
  569: <td><input type="text" name="c$_" value="$userenv{$_}" size="15" /></td>
  570: END
  571:            } else {
  572:                $r->print('<td>'.$userenv{$_}.'</td>');
  573:            }
  574:         }
  575:       $r->print(<<END);
  576: </tr>
  577: </table>
  578: END
  579:         # Build up table of user roles to allow revocation of a role.
  580:         my ($tmp) = keys(%rolesdump);
  581:         unless ($tmp =~ /^(con_lost|error)/i) {
  582:            my $now=time;
  583: 	   my %lt=&Apache::lonlocal::texthash(
  584: 		    'rer'  => "Revoke Existing Roles",
  585:                     'rev'  => "Revoke",                    
  586:                     'del'  => "Delete",
  587: 		    'ren'  => "Re-Enable",
  588:                     'rol'  => "Role",
  589:                     'ext'  => "Extent",
  590:                     'sta'  => "Start",
  591:                     'end'  => "End"
  592: 				       );
  593:            my (%roletext,%sortrole,%roleclass,%rolepriv);
  594: 	   foreach my $area (sort { my $a1=join('_',(split('_',$a))[1,0]);
  595: 				    my $b1=join('_',(split('_',$b))[1,0]);
  596: 				    return $a1 cmp $b1;
  597: 				} keys(%rolesdump)) {
  598:                next if ($area =~ /^rolesdef/);
  599: 	       my $envkey=$area;
  600:                my $role = $rolesdump{$area};
  601:                my $thisrole=$area;
  602:                $area =~ s/\_\w\w$//;
  603:                my ($role_code,$role_end_time,$role_start_time) = 
  604:                    split(/_/,$role);
  605: # Is this a custom role? Get role owner and title.
  606: 	       my ($croleudom,$croleuname,$croletitle)=
  607: 	           ($role_code=~/^cr\/(\w+)\/(\w+)\/(\w+)$/);
  608:                my $bgcol='ffffff';
  609:                my $allowed=0;
  610:                my $delallowed=0;
  611: 	       my $sortkey=$role_code;
  612: 	       my $class='Unknown';
  613:                if ($area =~ /^\/(\w+)\/(\d\w+)/ ) {
  614: 		   $class='Course';
  615:                    my ($coursedom,$coursedir) = ($1,$2);
  616: 		   $sortkey.="\0$coursedom";
  617:                    # $1.'_'.$2 is the course id (eg. 103_12345abcef103l3).
  618:                    my %coursedata=
  619:                        &Apache::lonnet::coursedescription($1.'_'.$2);
  620: 		   my $carea;
  621: 		   if (defined($coursedata{'description'})) {
  622: 		       $carea=$coursedata{'description'}.
  623:                            '<br />'.&mt('Domain').': '.$coursedom.('&nbsp;'x8).
  624:      &Apache::loncommon::syllabuswrapper('Syllabus',$coursedir,$coursedom);
  625: 		       $sortkey.="\0".$coursedata{'description'};
  626:                        $class=$coursedata{'type'};
  627: 		   } else {
  628: 		       $carea=&mt('Unavailable course').': '.$area;
  629: 		       $sortkey.="\0".&mt('Unavailable course').': '.$area;
  630: 		   }
  631: 		   $sortkey.="\0$coursedir";
  632:                    $inccourses{$1.'_'.$2}=1;
  633:                    if ((&Apache::lonnet::allowed('c'.$role_code,$1.'/'.$2)) ||
  634:                        (&Apache::lonnet::allowed('c'.$role_code,$ccdomain))) {
  635:                        $allowed=1;
  636:                    }
  637:                    if ((&Apache::lonnet::allowed('dro',$1)) ||
  638:                        (&Apache::lonnet::allowed('dro',$ccdomain))) {
  639:                        $delallowed=1;
  640:                    }
  641: # - custom role. Needs more info, too
  642: 		   if ($croletitle) {
  643: 		       if (&Apache::lonnet::allowed('ccr',$1.'/'.$2)) {
  644: 			   $allowed=1;
  645: 			   $thisrole.='.'.$role_code;
  646: 		       }
  647: 		   }
  648:                    # Compute the background color based on $area
  649:                    $bgcol=$1.'_'.$2;
  650:                    $bgcol=~s/[^7-9a-e]//g;
  651:                    $bgcol=substr($bgcol.$bgcol.$bgcol.'ffffff',2,6);
  652:                    if ($area=~/^\/(\w+)\/(\d\w+)\/(\w+)/) {
  653:                        $carea.='<br />Section: '.$3;
  654: 		       $sortkey.="\0$3";
  655:                    }
  656:                    $area=$carea;
  657:                } else {
  658: 		   $sortkey.="\0".$area;
  659:                    # Determine if current user is able to revoke privileges
  660:                    if ($area=~ /^\/(\w+)\//) {
  661:                        if ((&Apache::lonnet::allowed('c'.$role_code,$1)) ||
  662:                        (&Apache::lonnet::allowed('c'.$role_code,$ccdomain))) {
  663:                            $allowed=1;
  664:                        }
  665:                        if (((&Apache::lonnet::allowed('dro',$1))  ||
  666:                             (&Apache::lonnet::allowed('dro',$ccdomain))) &&
  667:                            ($role_code ne 'dc')) {
  668:                            $delallowed=1;
  669:                        }
  670:                    } else {
  671:                        if (&Apache::lonnet::allowed('c'.$role_code,'/')) {
  672:                            $allowed=1;
  673:                        }
  674:                    }
  675: 		   if ($role_code eq 'ca' || $role_code eq 'au') {
  676: 		       $class='Construction Space';
  677: 		   } elsif ($role_code eq 'su') {
  678: 		       $class='System';
  679: 		   } else {
  680: 		       $class='Domain';
  681: 		   }
  682:                }
  683:                if (($role_code eq 'ca') || ($role_code eq 'aa')) {
  684:                    $area=~/\/(\w+)\/(\w+)/;
  685: 		   if (&authorpriv($2,$1)) {
  686: 		       $allowed=1;
  687:                    } else {
  688:                        $allowed=0;
  689:                    }
  690:                }
  691: 	       $bgcol='77FF77';
  692:                my $row = '';
  693:                $row.='<tr bgcolor="#'.$bgcol.'"><td>';
  694:                my $active=1;
  695:                $active=0 if (($role_end_time) && ($now>$role_end_time));
  696:                if (($active) && ($allowed)) {
  697:                    $row.= '<input type="checkbox" name="rev:'.$thisrole.'">';
  698:                } else {
  699:                    if ($active) {
  700:                       $row.='&nbsp;';
  701: 		   } else {
  702:                       $row.=&mt('expired or revoked');
  703: 		   }
  704:                }
  705: 	       $row.='</td><td>';
  706:                if ($allowed && !$active) {
  707:                    $row.= '<input type="checkbox" name="ren:'.$thisrole.'">';
  708:                } else {
  709:                    $row.='&nbsp;';
  710:                }
  711: 	       $row.='</td><td>';
  712:                if ($delallowed) {
  713:                    $row.= '<input type="checkbox" name="del:'.$thisrole.'">';
  714:                } else {
  715:                    $row.='&nbsp;';
  716:                }
  717: 	       my $plaintext='';
  718: 	       unless ($croletitle) {
  719:                    $plaintext=&Apache::lonnet::plaintext($role_code,$class)
  720: 	       } else {
  721: 	           $plaintext=
  722: 		"Customrole '$croletitle' defined by $croleuname\@$croleudom";
  723: 	       }
  724:                $row.= '</td><td>'.$plaintext.
  725:                       '</td><td>'.$area.
  726:                       '</td><td>'.($role_start_time?localtime($role_start_time)
  727:                                                    : '&nbsp;' ).
  728:                       '</td><td>'.($role_end_time  ?localtime($role_end_time)
  729:                                                    : '&nbsp;' )
  730:                       ."</td></tr>\n";
  731: 	       $sortrole{$sortkey}=$envkey;
  732: 	       $roletext{$envkey}=$row;
  733: 	       $roleclass{$envkey}=$class;
  734:                $rolepriv{$envkey}=$allowed;
  735:                #$r->print($row);
  736:            } # end of foreach        (table building loop)
  737:            my $rolesdisplay = 0;
  738:            my %output = ();
  739: 	   foreach my $type ('Construction Space','Course','Group','Domain','System','Unknown') {
  740: 	       $output{$type} = '';
  741: 	       foreach my $which (sort {uc($a) cmp uc($b)} (keys(%sortrole))) {
  742: 		   if ( ($roleclass{$sortrole{$which}} =~ /^\Q$type\E/ ) && ($rolepriv{$sortrole{$which}}) ) { 
  743: 		       $output{$type}.=$roletext{$sortrole{$which}};
  744: 		   }
  745: 	       }
  746: 	       unless($output{$type} eq '') {
  747: 		   $output{$type} = "<tr bgcolor='#BBffBB'>".
  748: 			     "<td align='center' colspan='7'>".&mt($type)."</td>".
  749:                               $output{$type};
  750:                    $rolesdisplay = 1;
  751: 	       }
  752: 	   }
  753:            if ($rolesdisplay == 1) {
  754:                $r->print(<<END);
  755: <hr />
  756: <h3>$lt{'rer'}</h3>
  757: <table>
  758: <tr><th>$lt{'rev'}</th><th>$lt{'ren'}</th><th>$lt{'del'}</th><th>$lt{'rol'}</th><th>$lt{'e
  759: xt'}</th><th>$lt{'sta'}</th><th>$lt{'end'}</th>
  760: END
  761:                foreach my $type ('Construction Space','Course','Group','Domain','System','Unknown') {
  762:                    if ($output{$type}) {
  763:                        $r->print($output{$type}."\n");
  764:                    }
  765:                }
  766: 	       $r->print('</table>');
  767:            }
  768:         }  # End of unless
  769: 	my $currentauth=&Apache::lonnet::queryauthenticate($ccuname,$ccdomain);
  770: 	if ($currentauth=~/^krb(4|5):/) {
  771: 	    $currentauth=~/^krb(4|5):(.*)/;
  772: 	    my $krbdefdom=$2;
  773:             my %param = ( formname => 'document.cu',
  774:                           kerb_def_dom => $krbdefdom 
  775:                           );
  776:             $loginscript  = &Apache::loncommon::authform_header(%param);
  777: 	}
  778: 	# Check for a bad authentication type
  779:         unless ($currentauth=~/^krb(4|5):/ or
  780: 		$currentauth=~/^unix:/ or
  781: 		$currentauth=~/^internal:/ or
  782: 		$currentauth=~/^localauth:/
  783: 		) { # bad authentication scheme
  784: 	    if (&Apache::lonnet::allowed('mau',$env{'request.role.domain'})) {
  785:                 &initialize_authen_forms();
  786: 		my %lt=&Apache::lonlocal::texthash(
  787:                                'err'   => "ERROR",
  788: 			       'uuas'  => "This user has an unrecognized authentication scheme",
  789:                                'sldb'  => "Please specify login data below",
  790:                                'ld'    => "Login Data"
  791: 						   );
  792: 		$r->print(<<ENDBADAUTH);
  793: <hr />
  794: <script type="text/javascript" language="Javascript">
  795: $loginscript
  796: </script>
  797: <font color='#ff0000'>$lt{'err'}:</font>
  798: $lt{'uuas'} ($currentauth). $lt{'sldb'}.
  799: <h3>$lt{'ld'}</h3>
  800: <p>$generalrule</p>
  801: <p>$authformkrb</p>
  802: <p>$authformint</p>
  803: <p>$authformfsys</p>
  804: <p>$authformloc</p>
  805: ENDBADAUTH
  806:             } else { 
  807:                 # This user is not allowed to modify the users 
  808:                 # authentication scheme, so just notify them of the problem
  809: 		my %lt=&Apache::lonlocal::texthash(
  810:                                'err'   => "ERROR",
  811: 			       'uuas'  => "This user has an unrecognized authentication scheme",
  812:                                'adcs'  => "Please alert a domain coordinator of this situation"
  813: 						   );
  814: 		$r->print(<<ENDBADAUTH);
  815: <hr />
  816: <script type="text/javascript" language="Javascript">
  817: $loginscript
  818: </script>
  819: <font color="#ff0000"> $lt{'err'}: </font>
  820: $lt{'uuas'} ($currentauth). $lt{'adcs'}.
  821: <hr />
  822: ENDBADAUTH
  823:             }
  824:         } else { # Authentication type is valid
  825: 	    my $authformcurrent='';
  826: 	    my $authform_other='';
  827:             &initialize_authen_forms();
  828: 	    if ($currentauth=~/^krb(4|5):/) {
  829: 		$authformcurrent=$authformkrb;
  830: 		$authform_other="<p>$authformint</p>\n".
  831:                     "<p>$authformfsys</p><p>$authformloc</p>";
  832: 	    }
  833: 	    elsif ($currentauth=~/^internal:/) {
  834: 		$authformcurrent=$authformint;
  835: 		$authform_other="<p>$authformkrb</p>".
  836:                     "<p>$authformfsys</p><p>$authformloc</p>";
  837: 	    }
  838: 	    elsif ($currentauth=~/^unix:/) {
  839: 		$authformcurrent=$authformfsys;
  840: 		$authform_other="<p>$authformkrb</p>".
  841:                     "<p>$authformint</p><p>$authformloc;</p>";
  842: 	    }
  843: 	    elsif ($currentauth=~/^localauth:/) {
  844: 		$authformcurrent=$authformloc;
  845: 		$authform_other="<p>$authformkrb</p>".
  846:                     "<p>$authformint</p><p>$authformfsys</p>";
  847: 	    }
  848:             $authformcurrent.=' <i>(will override current values)</i><br />';
  849:             if (&Apache::lonnet::allowed('mau',$env{'request.role.domain'})) {
  850: 		# Current user has login modification privileges
  851: 		my %lt=&Apache::lonlocal::texthash(
  852:                                'ccld'  => "Change Current Login Data",
  853: 			       'enld'  => "Enter New Login Data"
  854: 						   );
  855: 		$r->print(<<ENDOTHERAUTHS);
  856: <hr />
  857: <script type="text/javascript" language="Javascript">
  858: $loginscript
  859: </script>
  860: <h3>$lt{'ccld'}</h3>
  861: <p>$generalrule</p>
  862: <p>$authformnop</p>
  863: <p>$authformcurrent</p>
  864: <h3>$lt{'enld'}</h3>
  865: $authform_other
  866: ENDOTHERAUTHS
  867:             }
  868:         }  ## End of "check for bad authentication type" logic
  869:     } ## End of new user/old user logic
  870:     $r->print('<hr /><h3>'.&mt('Add Roles').'</h3>');
  871: #
  872: # Co-Author
  873: # 
  874:     if (&authorpriv($env{'user.name'},$env{'request.role.domain'}) &&
  875:         ($env{'user.name'} ne $ccuname || $env{'user.domain'} ne $ccdomain)) {
  876:         # No sense in assigning co-author role to yourself
  877: 	my $cuname=$env{'user.name'};
  878:         my $cudom=$env{'request.role.domain'};
  879: 	   my %lt=&Apache::lonlocal::texthash(
  880: 		    'cs'   => "Construction Space",
  881:                     'act'  => "Activate",                    
  882:                     'rol'  => "Role",
  883:                     'ext'  => "Extent",
  884:                     'sta'  => "Start",
  885:                     'end'  => "End",
  886:                     'cau'  => "Co-Author",
  887:                     'caa'  => "Assistant Co-Author",
  888:                     'ssd'  => "Set Start Date",
  889:                     'sed'  => "Set End Date"
  890: 				       );
  891:        $r->print(<<ENDCOAUTH);
  892: <h4>$lt{'cs'}</h4>
  893: <table border=2><tr><th>$lt{'act'}</th><th>$lt{'rol'}</th><th>$lt{'ext'}</th>
  894: <th>$lt{'sta'}</th><th>$lt{'end'}</th></tr>
  895: <tr>
  896: <td><input type=checkbox name="act_$cudom\_$cuname\_ca" /></td>
  897: <td>$lt{'cau'}</td>
  898: <td>$cudom\_$cuname</td>
  899: <td><input type=hidden name="start_$cudom\_$cuname\_ca" value='' />
  900: <a href=
  901: "javascript:pjump('date_start','Start Date Co-Author',document.cu.start_$cudom\_$cuname\_ca.value,'start_$cudom\_$cuname\_ca','cu.pres','dateset')">$lt{'ssd'}</a></td>
  902: <td><input type=hidden name="end_$cudom\_$cuname\_ca" value='' />
  903: <a href=
  904: "javascript:pjump('date_end','End Date Co-Author',document.cu.end_$cudom\_$cuname\_ca.value,'end_$cudom\_$cuname\_ca','cu.pres','dateset')">$lt{'sed'}</a></td>
  905: </tr>
  906: <tr>
  907: <td><input type=checkbox name="act_$cudom\_$cuname\_aa" /></td>
  908: <td>$lt{'caa'}</td>
  909: <td>$cudom\_$cuname</td>
  910: <td><input type=hidden name="start_$cudom\_$cuname\_aa" value='' />
  911: <a href=
  912: "javascript:pjump('date_start','Start Date Assistant Co-Author',document.cu.start_$cudom\_$cuname\_aa.value,'start_$cudom\_$cuname\_aa','cu.pres','dateset')">$lt{'ssd'}</a></td>
  913: <td><input type=hidden name="end_$cudom\_$cuname\_aa" value='' />
  914: <a href=
  915: "javascript:pjump('date_end','End Date Assistant Co-Author',document.cu.end_$cudom\_$cuname\_aa.value,'end_$cudom\_$cuname\_aa','cu.pres','dateset')">$lt{'sed'}</a></td>
  916: </tr>
  917: </table>
  918: ENDCOAUTH
  919:     }
  920: #
  921: # Domain level
  922: #
  923:     my $num_domain_level = 0;
  924:     my $domaintext = 
  925:     '<h4>'.&mt('Domain Level').'</h4>'.
  926:     '<table border=2><tr><th>'.&mt('Activate').'</th><th>'.&mt('Role').'</th><th>'.&mt('Extent').'</th>'.
  927:     '<th>'.&mt('Start').'</th><th>'.&mt('End').'</th></tr>';
  928:     foreach ( sort( keys(%incdomains))) {
  929: 	my $thisdomain=$_;
  930:         foreach ('dc','li','dg','au','sc') {
  931:             if (&Apache::lonnet::allowed('c'.$_,$thisdomain)) {
  932:                my $plrole=&Apache::lonnet::plaintext($_);
  933: 	       my %lt=&Apache::lonlocal::texthash(
  934:                     'ssd'  => "Set Start Date",
  935:                     'sed'  => "Set End Date"
  936: 				       );
  937:                $num_domain_level ++;
  938:                $domaintext .= <<"ENDDROW";
  939: <tr>
  940: <td><input type=checkbox name="act_$thisdomain\_$_"></td>
  941: <td>$plrole</td>
  942: <td>$thisdomain</td>
  943: <td><input type=hidden name="start_$thisdomain\_$_" value=''>
  944: <a href=
  945: "javascript:pjump('date_start','Start Date $plrole',document.cu.start_$thisdomain\_$_.value,'start_$thisdomain\_$_','cu.pres','dateset')">$lt{'ssd'}</a></td>
  946: <td><input type=hidden name="end_$thisdomain\_$_" value=''>
  947: <a href=
  948: "javascript:pjump('date_end','End Date $plrole',document.cu.end_$thisdomain\_$_.value,'end_$thisdomain\_$_','cu.pres','dateset')">$lt{'sed'}</a></td>
  949: </tr>
  950: ENDDROW
  951:             }
  952:         } 
  953:     }
  954:     $domaintext.='</table>';
  955:     if ($num_domain_level > 0) {
  956:         $r->print($domaintext);
  957:     }
  958: #
  959: # Course and group levels
  960: #
  961: 
  962:     if ($env{'request.role'} =~ m-^dc\./(\w+)/$-) {
  963:         $r->print(&course_level_dc($1,'Course'));
  964:         $r->print('<hr /><input type="button" value="'.&mt('Modify User').'" onClick="setCourse()">'."\n");
  965:     } else {
  966:         $r->print(&course_level_table(%inccourses));
  967:         $r->print('<hr /><input type="button" value="'.&mt('Modify User').'" onClick="setSections()">'."\n");
  968:     }
  969:     $r->print("</form>".&Apache::loncommon::end_page());
  970: }
  971: 
  972: # ================================================================= Phase Three
  973: sub update_user_data {
  974:     my $r=shift;
  975:     my $uhome=&Apache::lonnet::homeserver($env{'form.ccuname'},
  976:                                           $env{'form.ccdomain'});
  977:     # Error messages
  978:     my $error     = '<font color="#ff0000">'.&mt('Error').':</font>';
  979:     my $end       = &Apache::loncommon::end_page();
  980: 
  981:     my $title;
  982:     if (exists($env{'form.makeuser'})) {
  983: 	$title='Set Privileges for New User';
  984:     } else {
  985:         $title='Modify User Privileges';
  986:     }
  987:     $r->print(&Apache::loncommon::start_page($title));
  988:     my %disallowed;
  989:     # Check Inputs
  990:     if (! $env{'form.ccuname'} ) {
  991: 	$r->print($error.&mt('No login name specified').'.'.$end);
  992: 	return;
  993:     }
  994:     if (  $env{'form.ccuname'}  =~/\W/) {
  995: 	$r->print($error.&mt('Invalid login name').'.  '.
  996: 		  &mt('Only letters, numbers, and underscores are valid').'.'.
  997: 		  $end);
  998: 	return;
  999:     }
 1000:     if (! $env{'form.ccdomain'}       ) {
 1001: 	$r->print($error.&mt('No domain specified').'.'.$end);
 1002: 	return;
 1003:     }
 1004:     if (  $env{'form.ccdomain'} =~/\W/) {
 1005: 	$r->print($error.&mt ('Invalid domain name').'.  '.
 1006: 		  &mt('Only letters, numbers, and underscores are valid').'.'.
 1007: 		  $end);
 1008: 	return;
 1009:     }
 1010:     if (! exists($env{'form.makeuser'})) {
 1011:         # Modifying an existing user, so check the validity of the name
 1012:         if ($uhome eq 'no_host') {
 1013:             $r->print($error.&mt('Unable to determine home server for ').
 1014:                       $env{'form.ccuname'}.&mt(' in domain ').
 1015:                       $env{'form.ccdomain'}.'.');
 1016:             return;
 1017:         }
 1018:     }
 1019:     # Determine authentication method and password for the user being modified
 1020:     my $amode='';
 1021:     my $genpwd='';
 1022:     if ($env{'form.login'} eq 'krb') {
 1023: 	$amode='krb';
 1024: 	$amode.=$env{'form.krbver'};
 1025: 	$genpwd=$env{'form.krbarg'};
 1026:     } elsif ($env{'form.login'} eq 'int') {
 1027: 	$amode='internal';
 1028: 	$genpwd=$env{'form.intarg'};
 1029:     } elsif ($env{'form.login'} eq 'fsys') {
 1030: 	$amode='unix';
 1031: 	$genpwd=$env{'form.fsysarg'};
 1032:     } elsif ($env{'form.login'} eq 'loc') {
 1033: 	$amode='localauth';
 1034: 	$genpwd=$env{'form.locarg'};
 1035: 	$genpwd=" " if (!$genpwd);
 1036:     } elsif (($env{'form.login'} eq 'nochange') ||
 1037:              ($env{'form.login'} eq ''        )) { 
 1038:         # There is no need to tell the user we did not change what they
 1039:         # did not ask us to change.
 1040:         # If they are creating a new user but have not specified login
 1041:         # information this will be caught below.
 1042:     } else {
 1043: 	    $r->print($error.&mt('Invalid login mode or password').$end);    
 1044: 	    return;
 1045:     }
 1046:     if ($env{'form.makeuser'}) {
 1047:         # Create a new user
 1048: 	my %lt=&Apache::lonlocal::texthash(
 1049:                     'cru'  => "Creating user",                    
 1050:                     'id'   => "in domain"
 1051: 					   );
 1052: 	$r->print(<<ENDNEWUSERHEAD);
 1053: <h3>$lt{'cru'} "$env{'form.ccuname'}" $lt{'id'} "$env{'form.ccdomain'}"</h3>
 1054: ENDNEWUSERHEAD
 1055:         # Check for the authentication mode and password
 1056:         if (! $amode || ! $genpwd) {
 1057: 	    $r->print($error.&mt('Invalid login mode or password').$end);    
 1058: 	    return;
 1059: 	}
 1060:         # Determine desired host
 1061:         my $desiredhost = $env{'form.hserver'};
 1062:         if (lc($desiredhost) eq 'default') {
 1063:             $desiredhost = undef;
 1064:         } else {
 1065:             my %home_servers = &Apache::loncommon::get_library_servers
 1066:                 ($env{'form.ccdomain'});  
 1067:             if (! exists($home_servers{$desiredhost})) {
 1068:                 $r->print($error.&mt('Invalid home server specified'));
 1069:                 return;
 1070:             }
 1071:         }
 1072: 	# Call modifyuser
 1073: 	my $result = &Apache::lonnet::modifyuser
 1074: 	    ($env{'form.ccdomain'},$env{'form.ccuname'},$env{'form.cstid'},
 1075:              $amode,$genpwd,$env{'form.cfirst'},
 1076:              $env{'form.cmiddle'},$env{'form.clast'},$env{'form.cgen'},
 1077:              undef,$desiredhost
 1078: 	     );
 1079: 	$r->print(&mt('Generating user').': '.$result);
 1080:         my $home = &Apache::lonnet::homeserver($env{'form.ccuname'},
 1081:                                                $env{'form.ccdomain'});
 1082:         $r->print('<br />'.&mt('Home server').': '.$home.' '.
 1083:                   $Apache::lonnet::libserv{$home});
 1084:     } elsif (($env{'form.login'} ne 'nochange') &&
 1085:              ($env{'form.login'} ne ''        )) {
 1086: 	# Modify user privileges
 1087:     my %lt=&Apache::lonlocal::texthash(
 1088:                     'usr'  => "User",                    
 1089:                     'id'   => "in domain"
 1090: 				       );
 1091: 	$r->print(<<ENDMODIFYUSERHEAD);
 1092: <h2>$lt{'usr'} "$env{'form.ccuname'}" $lt{'id'} "$env{'form.ccdomain'}"</h2>
 1093: ENDMODIFYUSERHEAD
 1094:         if (! $amode || ! $genpwd) {
 1095: 	    $r->print($error.'Invalid login mode or password'.$end);    
 1096: 	    return;
 1097: 	}
 1098: 	# Only allow authentification modification if the person has authority
 1099: 	if (&Apache::lonnet::allowed('mau',$env{'form.ccdomain'})) {
 1100: 	    $r->print('Modifying authentication: '.
 1101:                       &Apache::lonnet::modifyuserauth(
 1102: 		       $env{'form.ccdomain'},$env{'form.ccuname'},
 1103:                        $amode,$genpwd));
 1104:             $r->print('<br />'.&mt('Home server').': '.&Apache::lonnet::homeserver
 1105: 		  ($env{'form.ccuname'},$env{'form.ccdomain'}));
 1106: 	} else {
 1107: 	    # Okay, this is a non-fatal error.
 1108: 	    $r->print($error.&mt('You do not have the authority to modify this users authentification information').'.');    
 1109: 	}
 1110:     }
 1111:     ##
 1112:     if (! $env{'form.makeuser'} ) {
 1113:         # Check for need to change
 1114:         my %userenv = &Apache::lonnet::get
 1115:             ('environment',['firstname','middlename','lastname','generation'],
 1116:              $env{'form.ccdomain'},$env{'form.ccuname'});
 1117:         my ($tmp) = keys(%userenv);
 1118:         if ($tmp =~ /^(con_lost|error)/i) { 
 1119:             %userenv = ();
 1120:         }
 1121:         # Check to see if we need to change user information
 1122:         foreach ('firstname','middlename','lastname','generation') {
 1123:             # Strip leading and trailing whitespace
 1124:             $env{'form.c'.$_} =~ s/(\s+$|^\s+)//g; 
 1125:         }
 1126:         if (&Apache::lonnet::allowed('mau',$env{'form.ccdomain'}) && 
 1127:             ($env{'form.cfirstname'}  ne $userenv{'firstname'}  ||
 1128:              $env{'form.cmiddlename'} ne $userenv{'middlename'} ||
 1129:              $env{'form.clastname'}   ne $userenv{'lastname'}   ||
 1130:              $env{'form.cgeneration'} ne $userenv{'generation'} )) {
 1131:             # Make the change
 1132:             my %changeHash;
 1133:             $changeHash{'firstname'}  = $env{'form.cfirstname'};
 1134:             $changeHash{'middlename'} = $env{'form.cmiddlename'};
 1135:             $changeHash{'lastname'}   = $env{'form.clastname'};
 1136:             $changeHash{'generation'} = $env{'form.cgeneration'};
 1137:             my $putresult = &Apache::lonnet::put
 1138:                 ('environment',\%changeHash,
 1139:                  $env{'form.ccdomain'},$env{'form.ccuname'});
 1140:             if ($putresult eq 'ok') {
 1141:             # Tell the user we changed the name
 1142: 		my %lt=&Apache::lonlocal::texthash(
 1143:                              'uic'  => "User Information Changed",             
 1144:                              'frst' => "first",
 1145:                              'mddl' => "middle",
 1146:                              'lst'  => "last",
 1147: 			     'gen'  => "generation",
 1148:                              'prvs' => "Previous",
 1149:                              'chto' => "Changed To"
 1150: 						   );
 1151:                 $r->print(<<"END");
 1152: <table border="2">
 1153: <caption>$lt{'uic'}</caption>
 1154: <tr><th>&nbsp;</th>
 1155:     <th>$lt{'frst'}</th>
 1156:     <th>$lt{'mddl'}</th>
 1157:     <th>$lt{'lst'}</th>
 1158:     <th>$lt{'gen'}</th></tr>
 1159: <tr><td>$lt{'prvs'}</td>
 1160:     <td>$userenv{'firstname'}  </td>
 1161:     <td>$userenv{'middlename'} </td>
 1162:     <td>$userenv{'lastname'}   </td>
 1163:     <td>$userenv{'generation'} </td></tr>
 1164: <tr><td>$lt{'chto'}</td>
 1165:     <td>$env{'form.cfirstname'}  </td>
 1166:     <td>$env{'form.cmiddlename'} </td>
 1167:     <td>$env{'form.clastname'}   </td>
 1168:     <td>$env{'form.cgeneration'} </td></tr>
 1169: </table>
 1170: END
 1171:             } else { # error occurred
 1172:                 $r->print("<h2>".&mt('Unable to successfully change environment for')." ".
 1173:                       $env{'form.ccuname'}." ".&mt('in domain')." ".
 1174:                       $env{'form.ccdomain'}."</h2>");
 1175:             }
 1176:         }  else { # End of if ($env ... ) logic
 1177:             # They did not want to change the users name but we can
 1178:             # still tell them what the name is
 1179: 	    my %lt=&Apache::lonlocal::texthash(
 1180:                            'usr'  => "User",                    
 1181:                            'id'   => "in domain",
 1182:                            'gen'  => "Generation"
 1183: 					       );
 1184:                 $r->print(<<"END");
 1185: <h2>$lt{'usr'} "$env{'form.ccuname'}" $lt{'id'} "$env{'form.ccdomain'}"</h2>
 1186: <h4>$userenv{'firstname'} $userenv{'middlename'} $userenv{'lastname'} </h4>
 1187: <h4>$lt{'gen'}: $userenv{'generation'}</h4>
 1188: END
 1189:         }
 1190:     }
 1191:     ##
 1192:     my $now=time;
 1193:     $r->print('<h3>'.&mt('Modifying Roles').'</h3>');
 1194:     foreach (keys (%env)) {
 1195: 	next if (! $env{$_});
 1196: 	# Revoke roles
 1197: 	if ($_=~/^form\.rev/) {
 1198: 	    if ($_=~/^form\.rev\:([^\_]+)\_([^\_\.]+)$/) {
 1199: # Revoke standard role
 1200: 	        $r->print(&mt('Revoking').' '.$2.' in '.$1.': <b>'.
 1201:                      &Apache::lonnet::revokerole($env{'form.ccdomain'},
 1202:                      $env{'form.ccuname'},$1,$2).'</b><br />');
 1203: 		if ($2 eq 'st') {
 1204: 		    $1=~/^\/(\w+)\/(\w+)/;
 1205: 		    my $cid=$1.'_'.$2;
 1206: 		    $r->print(&mt('Drop from classlist').': <b>'.
 1207: 			 &Apache::lonnet::critical('put:'.
 1208:                              $env{'course.'.$cid.'.domain'}.':'.
 1209: 	                     $env{'course.'.$cid.'.num'}.':classlist:'.
 1210:                          &escape($env{'form.ccuname'}.':'.
 1211:                              $env{'form.ccdomain'}).'='.
 1212:                          &escape($now.':'),
 1213: 	                     $env{'course.'.$cid.'.home'}).'</b><br />');
 1214: 		}
 1215: 	    } 
 1216: 	    if ($_=~/^form\.rev\:([^\_]+)\_cr\.cr\/(\w+)\/(\w+)\/(\w+)$/) {
 1217: # Revoke custom role
 1218: 		$r->print(&mt('Revoking custom role:').
 1219:                       ' '.$4.' by '.$3.'@'.$2.' in '.$1.': <b>'.
 1220:                       &Apache::lonnet::revokecustomrole($env{'form.ccdomain'},
 1221: 				  $env{'form.ccuname'},$1,$2,$3,$4).
 1222: 		'</b><br />');
 1223: 	    }
 1224: 	} elsif ($_=~/^form\.del/) {
 1225: 	    if ($_=~/^form\.del\:([^\_]+)\_([^\_\.]+)$/) {
 1226: # Delete standard role
 1227: 	        $r->print(&mt('Deleting').' '.$2.' in '.$1.': '.
 1228:                      &Apache::lonnet::assignrole($env{'form.ccdomain'},
 1229:                      $env{'form.ccuname'},$1,$2,$now,0,1).'<br />');
 1230: 		if ($2 eq 'st') {
 1231: 		    $1=~/^\/(\w+)\/(\w+)/;
 1232: 		    my $cid=$1.'_'.$2;
 1233: 		    $r->print(&mt('Drop from classlist').': <b>'.
 1234: 			 &Apache::lonnet::critical('put:'.
 1235:                              $env{'course.'.$cid.'.domain'}.':'.
 1236: 	                     $env{'course.'.$cid.'.num'}.':classlist:'.
 1237:                          &escape($env{'form.ccuname'}.':'.
 1238:                              $env{'form.ccdomain'}).'='.
 1239:                          &escape($now.':'),
 1240: 	                     $env{'course.'.$cid.'.home'}).'</b><br />');
 1241: 		}
 1242:             }
 1243:             if ($_=~/^form\.del\:([^\_]+)\_cr\.cr\/(\w+)\/(\w+)\/(\w+)$/) {
 1244:                 my ($url,$rdom,$rnam,$rolename) = ($1,$2,$3,$4);
 1245: # Delete custom role
 1246:                 $r->print(&mt('Deleting custom role [_1] by [_2]@[_3] in [_4]',
 1247:                       $rolename,$rnam,$rdom,$url).': <b>'.
 1248:                       &Apache::lonnet::assigncustomrole($env{'form.ccdomain'},
 1249:                          $env{'form.ccuname'},$url,$rdom,$rnam,$rolename,$now,
 1250:                          0,1).'</b><br />');
 1251:             }
 1252: 	} elsif ($_=~/^form\.ren/) {
 1253:             my $udom = $env{'form.ccdomain'};
 1254:             my $uname = $env{'form.ccuname'};
 1255: # Re-enable standard role
 1256: 	    if ($_=~/^form\.ren\:([^\_]+)\_([^\_\.]+)$/) {
 1257:                 my $url = $1;
 1258:                 my $role = $2;
 1259:                 my $logmsg;
 1260:                 my $output;
 1261:                 if ($role eq 'st') {
 1262:                     if ($url =~ m-^/(\w+)/(\w+)/?(\w*)$-) {
 1263:                         my $result = &Apache::loncommon::commit_studentrole(\$logmsg,$udom,$uname,$url,$role,$now,0,$1,$2,$3);
 1264:                         if (($result =~ /^error/) || ($result eq 'not_in_class') || ($result eq 'unknown_course')) {
 1265:                             $output = "Error: $result\n";
 1266:                         } else {
 1267:                             $output = &mt('Assigning').' '.$role.' in '.$url.
 1268:                                       &mt('starting').' '.localtime($now).
 1269:                                       ': <br />'.$logmsg.'<br />'.
 1270:                                       &mt('Add to classlist').': <b>ok</b><br />';
 1271:                         }
 1272:                     }
 1273:                 } else {
 1274: 		    my $result=&Apache::lonnet::assignrole($env{'form.ccdomain'},
 1275:                                $env{'form.ccuname'},$url,$role,0,$now);
 1276: 		    $output = &mt('Re-enabling [_1] in [_2]: <b>[_3]</b>',
 1277: 			      $role,$url,$result).'<br />';
 1278: 		}
 1279:                 $r->print($output);
 1280: 	    }
 1281: # Re-enable custom role
 1282:             if ($_=~/^form\.ren\:([^\_]+)\_cr\.cr\/(\w+)\/(\w+)\/(\w+)$/) {
 1283:                 my ($url,$rdom,$rnam,$rolename) = ($1,$2,$3,$4);
 1284:                 my $result = &Apache::lonnet::assigncustomrole(
 1285:                                $env{'form.ccdomain'}, $env{'form.ccuname'},
 1286:                                $url,$rdom,$rnam,$rolename,0,$now);
 1287:                 $r->print(&mt('Re-enabling custom role [_1] by [_2]@[_3] in [_4] : <b>[_5]</b>',
 1288:                           $rolename,$rnam,$rdom,$url,$result).'<br />');
 1289:             }
 1290: 	} elsif ($_=~/^form\.act/) {
 1291:             my $udom = $env{'form.ccdomain'};
 1292:             my $uname = $env{'form.ccuname'};
 1293: 	    if ($_=~/^form\.act\_([^\_]+)\_([^\_]+)\_cr_cr_([^\_]+)_(\w+)_([^\_]+)$/) {
 1294:                 # Activate a custom role
 1295: 		my ($one,$two,$three,$four,$five)=($1,$2,$3,$4,$5);
 1296: 		my $url='/'.$one.'/'.$two;
 1297: 		my $full=$one.'_'.$two.'_cr_cr_'.$three.'_'.$four.'_'.$five;
 1298: 
 1299:                 my $start = ( $env{'form.start_'.$full} ?
 1300:                               $env{'form.start_'.$full} :
 1301:                               $now );
 1302:                 my $end   = ( $env{'form.end_'.$full} ?
 1303:                               $env{'form.end_'.$full} :
 1304:                               0 );
 1305:                                                                                      
 1306:                 # split multiple sections
 1307:                 my %sections = ();
 1308:                 my $num_sections = &build_roles($env{'form.sec_'.$full},\%sections,$5);
 1309:                 if ($num_sections == 0) {
 1310:                     $r->print(&Apache::loncommon::commit_customrole($udom,$uname,$url,$three,$four,$five,$start,$end));
 1311:                 } else {
 1312: 		    my %curr_groups =
 1313: 			&Apache::longroup::coursegroups($one,$two);
 1314:                     foreach my $sec (sort {$a cmp $b} keys %sections) {
 1315:                         if (($sec eq 'none') || ($sec eq 'all') || 
 1316:                             exists($curr_groups{$sec})) {
 1317:                             $disallowed{$sec} = $url;
 1318:                             next;
 1319:                         }
 1320:                         my $securl = $url.'/'.$sec;
 1321: 		        $r->print(&Apache::loncommon::commit_customrole($udom,$uname,$securl,$three,$four,$five,$start,$end));
 1322:                     }
 1323:                 }
 1324: 	    } elsif ($_=~/^form\.act\_([^\_]+)\_(\w+)\_([^\_]+)$/) {
 1325: 		# Activate roles for sections with 3 id numbers
 1326: 		# set start, end times, and the url for the class
 1327: 		my ($one,$two,$three)=($1,$2,$3);
 1328: 		my $start = ( $env{'form.start_'.$one.'_'.$two.'_'.$three} ? 
 1329: 			      $env{'form.start_'.$one.'_'.$two.'_'.$three} : 
 1330: 			      $now );
 1331: 		my $end   = ( $env{'form.end_'.$one.'_'.$two.'_'.$three} ? 
 1332: 			      $env{'form.end_'.$one.'_'.$two.'_'.$three} :
 1333: 			      0 );
 1334: 		my $url='/'.$one.'/'.$two;
 1335:                 my $type = 'three';
 1336:                 # split multiple sections
 1337:                 my %sections = ();
 1338:                 my $num_sections = &build_roles($env{'form.sec_'.$one.'_'.$two.'_'.$three},\%sections,$three);
 1339:                 if ($num_sections == 0) {
 1340:                     $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$three,$start,$end,$one,$two,''));
 1341:                 } else {
 1342:                     my %curr_groups = 
 1343: 			&Apache::longroup::coursegroups($one,$two);
 1344:                     my $emptysec = 0;
 1345:                     foreach my $sec (sort {$a cmp $b} keys %sections) {
 1346:                         $sec =~ s/\W//g;
 1347:                         if ($sec ne '') {
 1348:                             if (($sec eq 'none') || ($sec eq 'all') || 
 1349:                                 exists($curr_groups{$sec})) {
 1350:                                 $disallowed{$sec} = $url;
 1351:                                 next;
 1352:                             }
 1353:                             my $securl = $url.'/'.$sec;
 1354:                             $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$securl,$three,$start,$end,$one,$two,$sec));
 1355:                         } else {
 1356:                             $emptysec = 1;
 1357:                         }
 1358:                     }
 1359:                     if ($emptysec) {
 1360:                         $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$three,$start,$end,$one,$two,''));
 1361:                     }
 1362:                 } 
 1363: 	    } elsif ($_=~/^form\.act\_([^\_]+)\_([^\_]+)$/) {
 1364: 		# Activate roles for sections with two id numbers
 1365: 		# set start, end times, and the url for the class
 1366: 		my $start = ( $env{'form.start_'.$1.'_'.$2} ? 
 1367: 			      $env{'form.start_'.$1.'_'.$2} : 
 1368: 			      $now );
 1369: 		my $end   = ( $env{'form.end_'.$1.'_'.$2} ? 
 1370: 			      $env{'form.end_'.$1.'_'.$2} :
 1371: 			      0 );
 1372: 		my $url='/'.$1.'/';
 1373:                 # split multiple sections
 1374:                 my %sections = ();
 1375:                 my $num_sections = &build_roles($env{'form.sec_'.$1.'_'.$2},\%sections,$2);
 1376:                 if ($num_sections == 0) {
 1377:                     $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$2,$start,$end,$1,undef,''));
 1378:                 } else {
 1379:                     my $emptysec = 0;
 1380:                     foreach my $sec (sort {$a cmp $b} keys %sections) {
 1381:                         if ($sec ne '') {
 1382:                             my $securl = $url.'/'.$sec;
 1383:                             $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$securl,$2,$start,$end,$1,undef,$sec));
 1384:                         } else {
 1385:                             $emptysec = 1;
 1386:                         }
 1387:                     }
 1388:                     if ($emptysec) {
 1389:                         $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$2,$start,$end,$1,undef,''));
 1390:                     }
 1391:                 }
 1392: 	    } else {
 1393: 		$r->print('<p>'.&mt('ERROR').': '.&mt('Unknown command').' <tt>'.$_.'</tt></p><br />');
 1394:             }
 1395:             foreach my $key (sort(keys(%disallowed))) {
 1396:                 if (($key eq 'none') || ($key eq 'all')) {  
 1397:                     $r->print('<p>'.&mt('[_1] may not be used as the name for a section, as it is a reserved word.',$key));
 1398:                 } else {
 1399:                     $r->print('<p>'.&mt('[_1] may not be used as the name for a section, as it is the name of a course group.',$key));
 1400:                 }
 1401:                 $r->print(' '.&mt('Please <a href="javascript:history.go(-1)">go back</a> and choose a different section name.').'</p><br />');
 1402:             }
 1403: 	}
 1404:     } # End of foreach (keys(%env))
 1405: # Flush the course logs so reverse user roles immediately updated
 1406:     &Apache::lonnet::flushcourselogs();
 1407:     $r->print('<p><a href="/adm/createuser">Create/Modify Another User</a></p>');
 1408:     $r->print(&Apache::loncommon::end_page());
 1409: }
 1410: 
 1411: sub build_roles {
 1412:     my ($sectionstr,$sections,$role) = @_;
 1413:     my $num_sections = 0;
 1414:     if ($sectionstr=~ /,/) {
 1415:         my @secnums = split/,/,$sectionstr;
 1416:         if ($role eq 'st') {
 1417:             $secnums[0] =~ s/\W//g;
 1418:             $$sections{$secnums[0]} = 1;
 1419:             $num_sections = 1;
 1420:         } else {
 1421:             foreach my $sec (@secnums) {
 1422:                 $sec =~ ~s/\W//g;
 1423:                 unless ($sec eq "") {
 1424:                     if (exists($$sections{$sec})) {
 1425:                         $$sections{$sec} ++;
 1426:                     } else {
 1427:                         $$sections{$sec} = 1;
 1428:                         $num_sections ++;
 1429:                     }
 1430:                 }
 1431:             }
 1432:         }
 1433:     } else {
 1434:         $sectionstr=~s/\W//g;
 1435:         unless ($sectionstr eq '') {
 1436:             $$sections{$sectionstr} = 1;
 1437:             $num_sections ++;
 1438:         }
 1439:     }
 1440: 
 1441:     return $num_sections;
 1442: }
 1443: 
 1444: # ========================================================== Custom Role Editor
 1445: 
 1446: sub custom_role_editor {
 1447:     my $r=shift;
 1448:     my $rolename=$env{'form.rolename'};
 1449: 
 1450:     if ($rolename eq 'make new role') {
 1451: 	$rolename=$env{'form.newrolename'};
 1452:     }
 1453: 
 1454:     $rolename=~s/[^A-Za-z0-9]//gs;
 1455: 
 1456:     unless ($rolename) {
 1457: 	&print_username_entry_form($r);
 1458:         return;
 1459:     }
 1460: 
 1461:     $r->print(&Apache::loncommon::start_page('Custom Role Editor'));
 1462:     my $syspriv='';
 1463:     my $dompriv='';
 1464:     my $coursepriv='';
 1465:     my ($rdummy,$roledef)=
 1466: 			 &Apache::lonnet::get('roles',["rolesdef_$rolename"]);
 1467: # ------------------------------------------------------- Does this role exist?
 1468:     $r->print('<h2>');
 1469:     if (($rdummy ne 'con_lost') && ($roledef ne '')) {
 1470: 	$r->print(&mt('Existing Role').' "');
 1471: # ------------------------------------------------- Get current role privileges
 1472: 	($syspriv,$dompriv,$coursepriv)=split(/\_/,$roledef);
 1473:     } else {
 1474: 	$r->print(&mt('New Role').' "');
 1475: 	$roledef='';
 1476:     }
 1477:     $r->print($rolename.'"</h2>');
 1478: # ------------------------------------------------------- What can be assigned?
 1479:     my %full=();
 1480:     my %courselevel=();
 1481:     my %courselevelcurrent=();
 1482:     foreach (split(/\:/,$Apache::lonnet::pr{'cr:c'})) {
 1483: 	my ($priv,$restrict)=split(/\&/,$_);
 1484:         unless ($restrict) { $restrict='F'; }
 1485:         $courselevel{$priv}=$restrict;
 1486:         if ($coursepriv=~/\:$priv/) {
 1487: 	    $courselevelcurrent{$priv}=1;
 1488: 	}
 1489: 	$full{$priv}=1;
 1490:     }
 1491:     my %domainlevel=();
 1492:     my %domainlevelcurrent=();
 1493:     foreach (split(/\:/,$Apache::lonnet::pr{'cr:d'})) {
 1494: 	my ($priv,$restrict)=split(/\&/,$_);
 1495:         unless ($restrict) { $restrict='F'; }
 1496:         $domainlevel{$priv}=$restrict;
 1497:         if ($dompriv=~/\:$priv/) {
 1498: 	    $domainlevelcurrent{$priv}=1;
 1499: 	}
 1500: 	$full{$priv}=1;
 1501:     }
 1502:     my %systemlevel=();
 1503:     my %systemlevelcurrent=();
 1504:     foreach (split(/\:/,$Apache::lonnet::pr{'cr:s'})) {
 1505: 	my ($priv,$restrict)=split(/\&/,$_);
 1506:         unless ($restrict) { $restrict='F'; }
 1507:         $systemlevel{$priv}=$restrict;
 1508:         if ($syspriv=~/\:$priv/) {
 1509: 	    $systemlevelcurrent{$priv}=1;
 1510: 	}
 1511: 	$full{$priv}=1;
 1512:     }
 1513:     my %lt=&Apache::lonlocal::texthash(
 1514: 		    'prv'  => "Privilege",
 1515: 		    'crl'  => "Course Level",
 1516:                     'dml'  => "Domain Level",
 1517:                     'ssl'  => "System Level"
 1518: 				       );
 1519:     $r->print(<<ENDCCF);
 1520: <form method="post">
 1521: <input type="hidden" name="phase" value="set_custom_roles" />
 1522: <input type="hidden" name="rolename" value="$rolename" />
 1523: <table border="2">
 1524: <tr><th>$lt{'prv'}</th><th>$lt{'crl'}</th><th>$lt{'dml'}</th>
 1525: <th>$lt{'ssl'}</th></tr>
 1526: ENDCCF
 1527:     foreach my $priv (sort keys %full) {
 1528:         my $privtext = &Apache::lonnet::plaintext($priv);
 1529: 	$r->print('<tr><td>'.$privtext.'</td><td>'.
 1530:     ($courselevel{$priv}?'<input type="checkbox" name="'.$priv.':c" '.
 1531:     ($courselevelcurrent{$priv}?'checked="1"':'').' />':'&nbsp;').
 1532:     '</td><td>'.
 1533:     ($domainlevel{$priv}?'<input type="checkbox" name="'.$priv.':d" '.
 1534:     ($domainlevelcurrent{$priv}?'checked="1"':'').' />':'&nbsp;').
 1535:     '</td><td>'.
 1536:     ($systemlevel{$priv}?'<input type="checkbox" name="'.$priv.':s" '.
 1537:     ($systemlevelcurrent{$priv}?'checked="1"':'').' />':'&nbsp;').
 1538:     '</td></tr>');
 1539:     }
 1540:     $r->print(
 1541:    '<table><input type="submit" value="'.&mt('Define Role').'" /></form>'.
 1542: 	      &Apache::loncommon::end_page());
 1543: }
 1544: 
 1545: # ---------------------------------------------------------- Call to definerole
 1546: sub set_custom_role {
 1547:     my ($r) = @_;
 1548: 
 1549:     my $rolename=$env{'form.rolename'};
 1550: 
 1551:     $rolename=~s/[^A-Za-z0-9]//gs;
 1552: 
 1553:     unless ($rolename) {
 1554: 	&print_username_entry_form($r);
 1555:         return;
 1556:     }
 1557: 
 1558:     $r->print(&Apache::loncommon::start_page('Save Custom Role').'<h2>');
 1559:     my ($rdummy,$roledef)=
 1560: 	&Apache::lonnet::get('roles',["rolesdef_$rolename"]);
 1561: 
 1562: # ------------------------------------------------------- Does this role exist?
 1563:     if (($rdummy ne 'con_lost') && ($roledef ne '')) {
 1564: 	$r->print(&mt('Existing Role').' "');
 1565:     } else {
 1566: 	$r->print(&mt('New Role').' "');
 1567: 	$roledef='';
 1568:     }
 1569:     $r->print($rolename.'"</h2>');
 1570: # ------------------------------------------------------- What can be assigned?
 1571:     my $sysrole='';
 1572:     my $domrole='';
 1573:     my $courole='';
 1574: 
 1575:     foreach (split(/\:/,$Apache::lonnet::pr{'cr:c'})) {
 1576: 	my ($priv,$restrict)=split(/\&/,$_);
 1577:         unless ($restrict) { $restrict=''; }
 1578:         if ($env{'form.'.$priv.':c'}) {
 1579: 	    $courole.=':'.$_;
 1580: 	}
 1581:     }
 1582: 
 1583:     foreach (split(/\:/,$Apache::lonnet::pr{'cr:d'})) {
 1584: 	my ($priv,$restrict)=split(/\&/,$_);
 1585:         unless ($restrict) { $restrict=''; }
 1586:         if ($env{'form.'.$priv.':d'}) {
 1587: 	    $domrole.=':'.$_;
 1588: 	}
 1589:     }
 1590: 
 1591:     foreach (split(/\:/,$Apache::lonnet::pr{'cr:s'})) {
 1592: 	my ($priv,$restrict)=split(/\&/,$_);
 1593:         unless ($restrict) { $restrict=''; }
 1594:         if ($env{'form.'.$priv.':s'}) {
 1595: 	    $sysrole.=':'.$_;
 1596: 	}
 1597:     }
 1598:     $r->print('<br />Defining Role: '.
 1599: 	   &Apache::lonnet::definerole($rolename,$sysrole,$domrole,$courole));
 1600:     if ($env{'request.course.id'}) {
 1601:         my $url='/'.$env{'request.course.id'};
 1602:         $url=~s/\_/\//g;
 1603: 	$r->print('<br />'.&mt('Assigning Role to Self').': '.
 1604: 	      &Apache::lonnet::assigncustomrole($env{'user.domain'},
 1605: 						$env{'user.name'},
 1606: 						$url,
 1607: 						$env{'user.domain'},
 1608: 						$env{'user.name'},
 1609: 						$rolename));
 1610:     }
 1611:     $r->print('<p><a href="/adm/createuser">Create another role, or Create/Modify a user.</a></p>');
 1612:     $r->print(&Apache::loncommon::end_page());
 1613: }
 1614: 
 1615: # ================================================================ Main Handler
 1616: sub handler {
 1617:     my $r = shift;
 1618: 
 1619:     if ($r->header_only) {
 1620:        &Apache::loncommon::content_type($r,'text/html');
 1621:        $r->send_http_header;
 1622:        return OK;
 1623:     }
 1624: 
 1625:     if ((&Apache::lonnet::allowed('cta',$env{'request.course.id'})) ||
 1626:         (&Apache::lonnet::allowed('cin',$env{'request.course.id'})) || 
 1627:         (&Apache::lonnet::allowed('ccr',$env{'request.course.id'})) || 
 1628:         (&Apache::lonnet::allowed('cep',$env{'request.course.id'})) ||
 1629: 	(&authorpriv($env{'user.name'},$env{'request.role.domain'})) ||
 1630:         (&Apache::lonnet::allowed('mau',$env{'request.role.domain'}))) {
 1631:        &Apache::loncommon::content_type($r,'text/html');
 1632:        $r->send_http_header;
 1633:        unless ($env{'form.phase'}) {
 1634: 	   &print_username_entry_form($r);
 1635:        }
 1636:        if ($env{'form.phase'} eq 'get_user_info') {
 1637:            &print_user_modification_page($r);
 1638:        } elsif ($env{'form.phase'} eq 'update_user_data') {
 1639:            &update_user_data($r);
 1640:        } elsif ($env{'form.phase'} eq 'selected_custom_edit') {
 1641:            &custom_role_editor($r);
 1642:        } elsif ($env{'form.phase'} eq 'set_custom_roles') {
 1643: 	   &set_custom_role($r);
 1644:        }
 1645:    } else {
 1646:       $env{'user.error.msg'}=
 1647:         "/adm/createuser:mau:0:0:Cannot modify user data";
 1648:       return HTTP_NOT_ACCEPTABLE; 
 1649:    }
 1650:    return OK;
 1651: } 
 1652: 
 1653: #-------------------------------------------------- functions for &phase_two
 1654: sub course_level_table {
 1655:     my (%inccourses) = @_;
 1656:     my $table = '';
 1657: # Custom Roles?
 1658: 
 1659:     my %customroles=&my_custom_roles();
 1660:     my %lt=&Apache::lonlocal::texthash(
 1661:             'exs'  => "Existing sections",
 1662:             'new'  => "Define new section",
 1663:             'ssd'  => "Set Start Date",
 1664:             'sed'  => "Set End Date",
 1665:             'crl'  => "Course Level",
 1666:             'act'  => "Activate",
 1667:             'rol'  => "Role",
 1668:             'ext'  => "Extent",
 1669:             'grs'  => "Section",
 1670:             'sta'  => "Start",
 1671:             'end'  => "End"
 1672:     );
 1673: 
 1674:     foreach (sort( keys(%inccourses))) {
 1675: 	my $thiscourse=$_;
 1676: 	my $protectedcourse=$_;
 1677: 	$thiscourse=~s:_:/:g;
 1678: 	my %coursedata=&Apache::lonnet::coursedescription($thiscourse);
 1679: 	my $area=$coursedata{'description'};
 1680:         my $type=$coursedata{'type'};
 1681: 	if (!defined($area)) { $area=&mt('Unavailable course').': '.$_; }
 1682: 	my $bgcol=$thiscourse;
 1683: 	$bgcol=~s/[^7-9a-e]//g;
 1684: 	$bgcol=substr($bgcol.$bgcol.$bgcol.'ffffff',2,6);
 1685: 	my ($domain,$cnum)=split(/\//,$thiscourse);
 1686:         my %sections_count;
 1687:         if (defined($env{'request.course.id'})) {
 1688:             if ($env{'request.course.id'} eq $domain.'_'.$cnum) {
 1689:                 %sections_count = 
 1690: 		    &Apache::loncommon::get_sections($domain,$cnum);
 1691:             }
 1692:         }
 1693: 	foreach  ('st','ta','ep','in','cc') {
 1694: 	    if (&Apache::lonnet::allowed('c'.$_,$thiscourse)) {
 1695: 		my $plrole=&Apache::lonnet::plaintext($_);
 1696: 		$table .= <<ENDEXTENT;
 1697: <tr bgcolor="#$bgcol">
 1698: <td><input type="checkbox" name="act_$protectedcourse\_$_"></td>
 1699: <td>$plrole</td>
 1700: <td>$area<br />Domain: $domain</td>
 1701: ENDEXTENT
 1702: 	        if ($_ ne 'cc') {
 1703:                     if (%sections_count) {
 1704:                         my $currsec = &course_sections(\%sections_count,$protectedcourse.'_'.$_);
 1705:                         $table .= 
 1706:                     '<td><table border="0" cellspacing="0" cellpadding="0">'.
 1707:                      '<tr><td valign="top">'.$lt{'exs'}.'<br />'.
 1708:                         $currsec.'</td>'.
 1709:                      '<td>&nbsp;&nbsp;</td>'.
 1710:                      '<td valign="top">&nbsp;'.$lt{'new'}.'<br />'.
 1711:                      '<input type="text" name="newsec_'.$protectedcourse.'_'.$_.'" value="" /></td>'.
 1712:                      '<input type="hidden" '.
 1713:                      'name="sec_'.$protectedcourse.'_'.$_.'"></td>'.
 1714:                      '</tr></table></td>';
 1715:                     } else {
 1716:                         $table .= '<td><input type="text" size="10" '.
 1717:                      'name="sec_'.$protectedcourse.'_'.$_.'"></td>';
 1718:                     }
 1719:                 } else { 
 1720: 		    $table .= '<td>&nbsp</td>';
 1721:                 }
 1722: 		$table .= <<ENDTIMEENTRY;
 1723: <td><input type=hidden name="start_$protectedcourse\_$_" value=''>
 1724: <a href=
 1725: "javascript:pjump('date_start','Start Date $plrole',document.cu.start_$protectedcourse\_$_.value,'start_$protectedcourse\_$_','cu.pres','dateset')">$lt{'ssd'}</a></td>
 1726: <td><input type=hidden name="end_$protectedcourse\_$_" value=''>
 1727: <a href=
 1728: "javascript:pjump('date_end','End Date $plrole',document.cu.end_$protectedcourse\_$_.value,'end_$protectedcourse\_$_','cu.pres','dateset')">$lt{'sed'}</a></td>
 1729: ENDTIMEENTRY
 1730:                 $table.= "</tr>\n";
 1731:             }
 1732:         }
 1733:         foreach (sort keys %customroles) {
 1734: 	    if (&Apache::lonnet::allowed('ccr',$thiscourse)) {
 1735: 		my $plrole=$_;
 1736:                 my $customrole=$protectedcourse.'_cr_cr_'.$env{'user.domain'}.
 1737: 		    '_'.$env{'user.name'}.'_'.$plrole;
 1738: 		$table .= <<END;
 1739: <tr bgcolor="#$bgcol">
 1740: <td><input type="checkbox" name="act_$customrole"></td>
 1741: <td>$plrole</td>
 1742: <td>$area</td>
 1743: END
 1744:                 if (%sections_count) {
 1745:                     my $currsec = &course_sections(\%sections_count,$customrole);
 1746:                     $table.=
 1747:                    '<td><table border="0" cellspacing="0" cellpadding="0">'.
 1748:                    '<tr><td valign="top">'.$lt{'exs'}.'<br />'.
 1749:                      $currsec.'</td>'.
 1750:                    '<td>&nbsp;&nbsp;</td>'.
 1751:                    '<td valign="top">&nbsp;'.$lt{'new'}.'<br />'.
 1752:                    '<input type="text" name="newsec_'.$customrole.'" value="" /></td>'.
 1753:                    '<input type="hidden" '.
 1754:                    'name="sec_'.$customrole.'"></td>'.
 1755:                    '</tr></table></td>';
 1756:                 } else {
 1757:                     $table .= '<td><input type="text" size="10" '.
 1758:                      'name="sec_'.$customrole.'"></td>';
 1759:                 }
 1760:                 $table .= <<ENDENTRY;
 1761: <td><input type=hidden name="start_$customrole" value=''>
 1762: <a href=
 1763: "javascript:pjump('date_start','Start Date $plrole',document.cu.start_$customrole.value,'start_$customrole','cu.pres','dateset')">$lt{'ssd'}</a></td>
 1764: <td><input type=hidden name="end_$customrole" value=''>
 1765: <a href=
 1766: "javascript:pjump('date_end','End Date $plrole',document.cu.end_$customrole.value,'end_$customrole','cu.pres','dateset')">$lt{'sed'}</a></td></tr>
 1767: ENDENTRY
 1768:            }
 1769: 	}
 1770:     }
 1771:     return '' if ($table eq ''); # return nothing if there is nothing 
 1772:                                  # in the table
 1773:     my $result = <<ENDTABLE;
 1774: <h4>$lt{'crl'}</h4>
 1775: <table border=2><tr><th>$lt{'act'}</th><th>$lt{'rol'}</th><th>$lt{'ext'}</th>
 1776: <th>$lt{'grs'}</th><th>$lt{'sta'}</th><th>$lt{'end'}</th></tr>
 1777: $table
 1778: </table>
 1779: ENDTABLE
 1780:     return $result;
 1781: }
 1782: 
 1783: sub course_sections {
 1784:     my ($sections_count,$role) = @_;
 1785:     my $output = '';
 1786:     my @sections = (sort {$a <=> $b} keys %{$sections_count});
 1787:     if (scalar(@sections) == 1) {
 1788:         $output = '<select name="currsec_'.$role.'" >'."\n".
 1789:                   '  <option value="">Select</option>'."\n".
 1790:                   '  <option value="">No section</option>'."\n".
 1791:                   '  <option value="'.$sections[0].'" >'.$sections[0].'</option>'."\n";
 1792:     } else {
 1793:         $output = '<select name="currsec_'.$role.'" ';
 1794:         my $multiple = 4;
 1795:         if (scalar(@sections) < 4) { $multiple = scalar(@sections); }
 1796:         $output .= '"multiple" size="'.$multiple.'">'."\n";
 1797:         foreach (@sections) {
 1798:             $output .= '<option value="'.$_.'">'.$_."</option>\n";
 1799:         }
 1800:     }
 1801:     $output .= '</select>'; 
 1802:     return $output;
 1803: }
 1804: 
 1805: sub course_level_dc {
 1806:     my ($dcdom) = @_;
 1807:     my %customroles=&my_custom_roles();
 1808:     my $hiddenitems = '<input type="hidden" name="dcdomain" value="'.$dcdom.'" />'.
 1809:                       '<input type="hidden" name="origdom" value="'.$dcdom.'" />'.
 1810:                       '<input type="hidden" name="dccourse" value="'.$dcdom.'" />';
 1811:     my $courseform='<b>'.&Apache::loncommon::selectcourse_link
 1812:             ('cu','dccourse','dcdomain','coursedesc',undef,undef,'Course').'</b>';
 1813:     my $cb_jscript = &Apache::loncommon::coursebrowser_javascript($dcdom,'currsec','cu');
 1814:     my %lt=&Apache::lonlocal::texthash(
 1815:                     'typ' => "Type",
 1816:                     'rol'  => "Role",
 1817:                     'grs'  => "Section",
 1818:                     'exs'  => "Existing sections",
 1819:                     'new'  => "Define new section", 
 1820:                     'sta'  => "Start",
 1821:                     'end'  => "End",
 1822:                     'ssd'  => "Set Start Date",
 1823:                     'sed'  => "Set End Date"
 1824:                   );
 1825:     my $header = '<h4>'.&mt('Course Level').'</h4>'.
 1826:                  '<table border="2"><tr><th>'.$lt{'typ'}.'</th><th>'.$courseform.'</th><th>'.$lt{'rol'}.'</th><th>'.$lt{'grs'}.'</th><th>'.$lt{'sta'}.'</th><th>'.$lt{'end'}.'</th></tr>';
 1827:     my $otheritems = '<tr><td><select name="crstype" onChange="javascript:setType();">'."\n".
 1828:                      ' <option value="">'.&mt('Please select')."\n".
 1829:                      ' <option value="Course">'.&mt('Course')."\n".
 1830:                      ' <option value="Non-standard course">'.&mt('Non-standard course')."\n".
 1831:                      '</select>'."\n".
 1832:                      '<td><input type="text" name="coursedesc" value="" onFocus="this.blur();opencrsbrowser('."'cu','dccourse','dcdomain','coursedesc',''".')" /></td>'."\n".
 1833:                      '<td><select name="role">'."\n";
 1834:     foreach  ('st','ta','ep','in','cc') {
 1835:         my $plrole=&Apache::lonnet::plaintext($_);
 1836:         $otheritems .= '  <option value="'.$_.'">'.$plrole;
 1837:     }
 1838:     if ( keys %customroles > 0) {
 1839:         foreach (sort keys %customroles) {
 1840:             my $custrole='cr_cr_'.$env{'user.domain'}.
 1841:                     '_'.$env{'user.name'}.'_'.$_;
 1842:             $otheritems .= '  <option value="'.$custrole.'">'.$_;
 1843:         }
 1844:     }
 1845:     $otheritems .= '</select></td><td>'.
 1846:                      '<table border="0" cellspacing="0" cellpadding="0">'.
 1847:                      '<tr><td valign="top"><b>'.$lt{'exs'}.'</b><br /><select name="currsec">'.
 1848:                      ' <option value=""><--'.&mt('Pick course first').'</select></td>'.
 1849:                      '<td>&nbsp;&nbsp;</td>'.
 1850:                      '<td valign="top">&nbsp;<b>'.$lt{'new'}.'</b><br />'.
 1851:                      '<input type="text" name="newsec" value="" />'.
 1852:                      '<input type="hidden" name="groups" value="" /></td>'.
 1853:                      '</tr></table></td>';
 1854:     $otheritems .= <<ENDTIMEENTRY;
 1855: <td><input type=hidden name="start" value=''>
 1856: <a href=
 1857: "javascript:pjump('date_start','Start Date',document.cu.start.value,'start','cu.pres','dateset')">$lt{'ssd'}</a></td>
 1858: <td><input type=hidden name="end" value=''>
 1859: <a href=
 1860: "javascript:pjump('date_end','End Date',document.cu.end.value,'end','cu.pres','dateset')">$lt{'sed'}</a></td>
 1861: ENDTIMEENTRY
 1862:     $otheritems .= "</tr></table>\n";
 1863:     return $cb_jscript.$header.$hiddenitems.$otheritems;
 1864: }
 1865: 
 1866: #---------------------------------------------- end functions for &phase_two
 1867: 
 1868: #--------------------------------- functions for &phase_two and &phase_three
 1869: 
 1870: #--------------------------end of functions for &phase_two and &phase_three
 1871: 
 1872: 1;
 1873: __END__
 1874: 
 1875: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>