[LON-CAPA-cvs] cvs: loncom /interface createaccount.pm loncoursequeueadmin.pm

raeburn raeburn at source.lon-capa.org
Wed Feb 12 15:47:40 EST 2014


raeburn		Wed Feb 12 20:47:40 2014 EDT

  Modified files:              
    /loncom/interface	createaccount.pm loncoursequeueadmin.pm 
  Log:
  - Bug 6646
    - Self-creation of user accounts with e-mail address as username.
    - User information and password requested from prospective user in a single
      web form.
    - Add routines to handle creation of user accounts and notification 
      following approval by Domain Coordinator.
  
  
-------------- next part --------------
Index: loncom/interface/createaccount.pm
diff -u loncom/interface/createaccount.pm:1.57 loncom/interface/createaccount.pm:1.58
--- loncom/interface/createaccount.pm:1.57	Thu Jan 30 12:15:06 2014
+++ loncom/interface/createaccount.pm	Wed Feb 12 20:47:40 2014
@@ -1,9 +1,10 @@
 # The LearningOnline Network
 # Allow visitors to create a user account with the username being either an 
-# institutional log-in ID (institutional authentication required - localauth
-#  or kerberos) or an e-mail address.
+# institutional log-in ID (institutional authentication required - localauth,
+# kerberos, or SSO) or an e-mail address. Requests to use an e-mail address as
+# username may be processed automatically, or may be queued for approval.
 #
-# $Id: createaccount.pm,v 1.57 2014/01/30 12:15:06 raeburn Exp $
+# $Id: createaccount.pm,v 1.58 2014/02/12 20:47:40 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -44,8 +45,6 @@
 use LONCAPA qw(:DEFAULT :match);
 use HTML::Entities;
 
-#TODO this module needs documentation
-
 sub handler {
     my $r = shift;
     &Apache::loncommon::content_type($r,'text/html');
@@ -103,7 +102,8 @@
         my $end_page =
             &Apache::loncommon::end_page();
         $r->print($start_page."\n".'<h2>'.&mt('You are already logged in').'</h2>'.
-                  '<p>'.&mt('Please either [_1]continue the current session[_2] or [_3]log out[_4].','<a href="/adm/roles">','</a>','<a href="/adm/logout">','</a>').
+                  '<p>'.&mt('Please either [_1]continue the current session[_2] or [_3]log out[_4].',
+                            '<a href="/adm/roles">','</a>','<a href="/adm/logout">','</a>').
                   '</p><p><a href="/adm/loginproblems.html">'.&mt('Login problems?').'</a></p>'.$end_page);
         return OK;
     }
@@ -124,14 +124,17 @@
 
         my %domconfig = 
             &Apache::lonnet::get_dom('configuration',['usercreation'],$domain);
-        my ($cancreate,$statustocreate) = 
+        my ($cancreate,$statustocreate,$emailusername) = 
             &get_creation_controls($domain,$domconfig{'usercreation'});
 
         my ($result,$output) =
             &username_validation($r,$env{'form.uname'},$domain,$domdesc,
                                  $contact_name,$contact_email,$courseid,
                                  $lonhost,$statustocreate);
-        if ($result eq 'existingaccount') {
+        if ($result eq 'redirect') {
+            $r->internal_redirect('/adm/switchserver');
+            return OK;
+        } elsif ($result eq 'existingaccount') {
             $r->print($output);
             &print_footer($r);
             return OK;
@@ -147,12 +150,14 @@
 
     my %domconfig = 
         &Apache::lonnet::get_dom('configuration',['usercreation'],$domain);
-    my ($cancreate,$statustocreate) = &get_creation_controls($domain,$domconfig{'usercreation'});
+    my ($cancreate,$statustocreate,$emailusername) = 
+        &get_creation_controls($domain,$domconfig{'usercreation'});
     if (@{$cancreate} == 0) {
         &print_header($r,$start_page,$courseid);
         my $output = '<h3>'.&mt('Account creation unavailable').'</h3>'.
                      '<span class="LC_warning">'.
-                     &mt('Creation of a new user account using an e-mail address or an institutional log-in ID as username is not permitted at this institution ([_1]).',$domdesc).'</span><br /><br />';
+                     &mt('Creation of a new user account using an e-mail address or an institutional log-in ID as username is not permitted at this institution ([_1]).',$domdesc).
+                     '</span><br /><br />';
         $r->print($output);
         &print_footer($r);
         return OK;
@@ -179,13 +184,17 @@
         return OK;
     }
 
-    my ($output,$nostart,$noend);
+    my ($output,$nostart,$noend,$redirect);
     my $token = $env{'form.token'};
     if ($token) {
-        ($output,$nostart,$noend) = 
+        ($output,$nostart,$noend,$redirect) = 
             &process_mailtoken($r,$token,$contact_name,$contact_email,$domain,
-                               $domdesc,$lonhost,$include,$start_page);
-        if ($nostart) {
+                               $domdesc,$lonhost,$include,$start_page,$cancreate,
+                               $domconfig{'usercreation'});
+        if ($redirect) {
+            $r->internal_redirect('/adm/switchserver');
+            return OK;
+        } elsif ($nostart) {
             if ($noend) {
                 return OK;
             } else {
@@ -205,7 +214,10 @@
         (my $result,$output,$nostart) = 
             &username_activation($r,$env{'form.uname'},$domain,$domdesc,
                                  $courseid);
-        if ($result eq 'ok') {
+        if ($result eq 'redirect') {
+            $r->internal_redirect('/adm/switchserver');
+            return OK; 
+        } elsif ($result eq 'ok') {
             if ($nostart) {
                 return OK;
             }
@@ -228,23 +240,29 @@
         }
     } elsif ($env{'form.create_with_email'}) {
         &print_header($r,$start_page,$courseid);
-        $output = &process_email_request($env{'form.useremail'},$domain,$domdesc,
+        $output = &process_email_request($env{'form.uname'},$domain,$domdesc,
                                          $contact_name,$contact_email,$cancreate,
                                          $lonhost,$domconfig{'usercreation'},
-                                         $courseid);
+                                         $emailusername,$courseid);
     } elsif (!$token) {
         &print_header($r,$start_page,$courseid);
         my $now=time;
+        my $gotlondes;
         if (grep(/^login$/,@{$cancreate})) {
-            my $jsh=Apache::File->new($include."/londes.js");
-            $r->print(<$jsh>);
-            $r->print(&javascript_setforms($now));
+            if (open(my $jsh,"<$include/londes.js")) {
+                while(my $line = <$jsh>) {
+                    $r->print($line);
+                }
+                close($jsh);
+                $r->print(&javascript_setforms($now));
+                $gotlondes = 1;
+            }
         }
-        if (grep(/^email$/,@{$cancreate})) {
+        if (grep(/^email(|approval)$/,@{$cancreate})) {
             $r->print(&javascript_validmail());
         }
-        $output = &print_username_form($domain,$domdesc,$cancreate,$now,$lonhost,
-                                       $courseid);
+        $output = &print_username_form($r,$domain,$domdesc,$cancreate,$now,$lonhost,
+                                       $include,$courseid,$gotlondes,$emailusername);
     }
     $r->print($output);
     &print_footer($r);
@@ -272,7 +290,7 @@
         $r->print('<form name="backupcrumbs" method="post" action="">'.
                   &Apache::lonhtmlcommon::echo_form_input(['backto','logtoken',
                       'token','serverid','uname','upass','phase','create_with_email',
-                      'code','useremail','crypt','cfirstname','clastname',
+                      'code','crypt','cfirstname','clastname',
                       'cmiddlename','cgeneration','cpermanentemail','cid']).
                   '</form>');
     }
@@ -303,53 +321,84 @@
 }
 
 sub javascript_setforms {
-    my ($now) =  @_;
+    my ($now,$emailusername) =  @_;
+    my $setuserinfo; 
+    if (ref($emailusername) eq 'HASH') {
+        foreach my $key (sort(keys(%{$emailusername}))) {
+            $setuserinfo .= '      server.elements.'.$key.'.value=client.elements.'.$key.'.value;'."\n";
+        }
+    }
     my $js = <<ENDSCRIPT;
- <script type="text/javascript" language="JavaScript">
-    function send() {
-        this.document.server.elements.uname.value = this.document.client.elements.uname.value;
-        this.document.server.elements.udom.value = this.document.client.elements.udom.value;
-        uextkey=this.document.client.elements.uextkey.value;
-        lextkey=this.document.client.elements.lextkey.value;
-        initkeys();
-
-        this.document.server.elements.upass.value
-            = crypted(this.document.client.elements.upass$now.value);
-
-        this.document.client.elements.uname.value='';
-        this.document.client.elements.upass$now.value='';
+<script type="text/javascript">
+// <![CDATA[
+    function send(one,two,context) {
+        var server;
+        var client;
+        if (document.forms[one]) {
+            server = document.forms[one];
+            if (document.forms[two]) {
+                client = document.forms[two];
+                server.elements.uname.value = client.elements.uname.value;
+                server.elements.udom.value = client.elements.udom.value;
+                if (context == 'email') {
+                    $setuserinfo
+                }
+                server.elements.code.value=client.elements.code.value;
+                server.elements.crypt.value=client.elements.crypt.value;
 
-        this.document.server.submit();
+                uextkey=client.elements.uextkey.value;
+                lextkey=client.elements.lextkey.value;
+                initkeys();
+
+                server.elements.upass.value
+                    = crypted(client.elements.upass$now.value);
+
+                client.elements.uname.value='';
+                client.elements.upass$now.value='';
+                client.elements.upasscheck$now.value='';
+                server.submit();
+            }
+        }
         return false;
     }
- </script>
+// ]]>
+</script>
 ENDSCRIPT
     return $js;
 }
 
 sub javascript_checkpass {
-    my ($now) = @_;
+    my ($now,$context) = @_;
     my $nopass = &mt('You must enter a password.');
     my $mismatchpass = &mt('The passwords you entered did not match.').'\\n'.
                        &mt('Please try again.'); 
     my $js = <<"ENDSCRIPT";
-<script type="text/javascript" language="JavaScript">
-    function checkpass() {
-        var upass = this.document.client.elements.upass$now.value;
-        var upasscheck = this.document.client.elements.upasscheck$now.value;
-        if (upass == '') {
-            alert("$nopass");
-            return false;
-        }
-        if (upass == upasscheck) {
-            this.document.client.elements.upasscheck$now.value='';
-            send();
-            return false;
-        } else {
-            alert("$mismatchpass");
-            return false;
+<script type="text/javascript">
+// <![CDATA[
+    function checkpass(one,two) {
+        var client;
+        if (document.forms[two]) {
+            client = document.forms[two]; 
+            var upass = client.elements.upass$now.value;
+            var upasscheck = client.elements.upasscheck$now.value;
+            if (upass == '') {
+                alert("$nopass");
+                return false;
+            }
+            if (upass == upasscheck) {
+                client.elements.upasscheck$now.value='';
+                if (validate_email(client)) {
+                    send(one,two,'$context');
+                } 
+                return false;
+            } else {
+                alert("$mismatchpass");
+                return false;
+            }
         }
+        return false; 
     }
+// ]]>
 </script>
 ENDSCRIPT
     return $js;
@@ -361,10 +410,11 @@
                notv  => 'is not a valid e-mail address',
     );
     my $output =  "\n".'<script type="text/javascript">'."\n".
+                  '// <![CDATA['."\n".
                   &Apache::lonhtmlcommon::javascript_valid_email()."\n";
     $output .= <<"ENDSCRIPT";
-function validate_email() {
-    field = document.createaccount.useremail;
+function validate_email(client) {
+    field = client.uname;
     if (validmail(field) == false) {
         alert("$lt{'email'}: "+field.value+" $lt{'notv'}.");
         return false;
@@ -372,12 +422,12 @@
     return true;
 }
 ENDSCRIPT
-    $output .= "\n".'</script>'."\n";
+    $output .= "\n".'// ]]>'."\n".'</script>'."\n";
     return $output;
 }
 
 sub print_username_form {
-    my ($domain,$domdesc,$cancreate,$now,$lonhost,$courseid) = @_;
+    my ($r,$domain,$domdesc,$cancreate,$now,$lonhost,$include,$courseid,$gotlondes,$emailusername) = @_;
     my %lt = &Apache::lonlocal::texthash(
                                          unam => 'username',
                                          udom => 'domain',
@@ -390,12 +440,15 @@
             if ((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) || ($domdefaults{'auth_def'} eq 'localauth')) {
                 $output = '<div class="LC_left_float"><h3>'.&mt('Create account with a username provided by this institution').'</h3>';
                 my $submit_text = &mt('Create LON-CAPA account');
-                $output .= &mt('If you already have a log-in ID at this institution,[_1] you may be able to use it for LON-CAPA.','<br />').'<br /><br />'.&mt('Type in your log-in ID and password to find out.').'<br /><br />';
+                $output .= &mt('If you already have a log-in ID at this institution,[_1] you may be able to use it for LON-CAPA.','<br />').
+                           '<br /><br />'.
+                           &mt('Type in your log-in ID and password to find out.').
+                           '<br /><br />';
                 $output .= &login_box($now,$lonhost,$courseid,$submit_text,
                                       $domain,'createaccount').'</div>';
             }
         }
-        if (grep(/^email$/,@{$cancreate})) {
+        if (grep(/^email(|approval)$/,@{$cancreate})) {
             $output .= '<div class="LC_left_float"><h3>'.&mt('Create account with an e-mail address as your username').'</h3>';
             my ($captchaform,$error) = &Apache::loncommon::captcha_display('usercreation',$lonhost);
             if ($error) {
@@ -403,39 +456,30 @@
                 if ($courseid ne '') {
                     $helpdesk .= '&courseid='.$courseid;
                 }
-                $output .= '<span class="LC_error">'.&mt('An error occurred generating the validation code[_1] required for an e-mail address to be used as username.','<br />').'</span><br /><br />'.&mt('[_1]Contact the helpdesk[_2] or [_3]reload[_2] the page and try again.','<a href="'.$helpdesk.'">','</a>','<a href="javascript:window.location.reload()">');
+                $output .= '<span class="LC_error">'.
+                           &mt('An error occurred generating the validation code[_1] required for an e-mail address to be used as username.','<br />').
+                           '</span><br /><br />'.
+                           &mt('[_1]Contact the helpdesk[_2] or [_3]reload[_2] the page and try again.',
+                               '<a href="'.$helpdesk.'">','</a>','<a href="javascript:window.location.reload()">');
             } else {
-                my $submit_text = &mt('Request LON-CAPA account');
-                my $emailform = '<input type="text" name="useremail" size="25" value="" />';
                 if (grep(/^login$/,@{$cancreate})) {
                     $output .= &mt('Provide your e-mail address to request a LON-CAPA account,[_1] if you do not have a log-in ID at your institution.','<br />').'<br /><br />';
                 } else {
                     $output .= '<br />';
                 }
-                $output .=  '<form name="createaccount" method="post" onsubmit="return validate_email()" action="/adm/createaccount">'.
-                            &Apache::lonhtmlcommon::start_pick_box()."\n".
-                            &Apache::lonhtmlcommon::row_title(&mt('E-mail address'),
-                                                              'LC_pick_box_title')."\n".
-                            $emailform."\n";
-                if ($captchaform) {
-                    $output .= &Apache::lonhtmlcommon::row_closure(1).
-                               &Apache::lonhtmlcommon::row_title(&mt('Validation'),
-                                                                 'LC_pick_box_title')."\n".
-                               $captchaform."\n".'<br /><br />';
-                }
-                if ($courseid ne '') {
-                    $output .= '<input type="hidden" name="courseid" value="'.$courseid.'"/>'."\n"; 
+                $output .= &mt('Please provide user information and a password for your new account.').'<br />'.
+                           &mt('Your password, which must contain at least seven characters, will be sent to the LON-CAPA server in an encrypted form.').'<br />';
+                if (grep(/^login$/,@{$cancreate})) {
+                    $output .= &mt('Provide your e-mail address to request a LON-CAPA account,[_1] if you do not have a log-in ID at your institution.','<br />').'<br /><br />';
+                } else {
+                    $output .= '<br />';
                 }
-                $output .=  &Apache::lonhtmlcommon::row_closure(1).
-                            &Apache::lonhtmlcommon::row_title().'<br />'.
-                            '<input type="submit" name="create_with_email" value="'. 
-                            $submit_text.'" />'.
-                            &Apache::lonhtmlcommon::row_closure(1).
-                            &Apache::lonhtmlcommon::end_pick_box().'<br /><br />';
-                if ($courseid ne '') {
-                    $output .= &Apache::lonhtmlcommon::echo_form_input(['courseid']);
+                $output .= &print_dataentry_form($r,$domain,$lonhost,$include,$now,$captchaform,$courseid,$gotlondes,$emailusername);
+                if (grep(/^login$/,@{$cancreate})) {
+                    $output .= &mt('Provide your e-mail address to request a LON-CAPA account,[_1] if you do not have a log-in ID at your institution.','<br />').'<br /><br />';
+                } else {
+                    $output .= '<br />';
                 }
-                $output .= '</form>';
             }
             $output .= '</div>';
         }
@@ -455,14 +499,14 @@
                                               createaccount => 'Log-in ID',
                                               selfenroll    => 'Username',
                                             );
-    my ($lkey,$ukey) = &Apache::lonpreferences::des_keys();
+    my ($lkey,$ukey) = &Apache::loncommon::des_keys();
     my ($lextkey,$uextkey) = &getkeys($lkey,$ukey);
     my $logtoken=Apache::lonnet::reply('tmpput:'.$ukey.$lkey.'&createaccount:createaccount',
                                        $lonhost);
     $output = &serverform($logtoken,$lonhost,undef,$courseid,$context);
     my $unameform = '<input type="text" name="uname" size="20" value="" />';
     my $upassform = '<input type="password" name="upass'.$now.'" size="20" />';
-    $output .= '<form name="client" method="post" action="" onsubmit="return(send());">'."\n".
+    $output .= '<form name="client" method="post" action="" onsubmit="return(send('."'server','client'".'));">'."\n".
                &Apache::lonhtmlcommon::start_pick_box()."\n".
                &Apache::lonhtmlcommon::row_title($titles{$context},
                                                  'LC_pick_box_title')."\n".
@@ -501,11 +545,10 @@
 
 sub process_email_request {
     my ($useremail,$domain,$domdesc,$contact_name,$contact_email,$cancreate,
-        $server,$settings,$courseid) = @_;
-    $useremail = $env{'form.useremail'};
+        $server,$settings,$emailusername,$courseid) = @_;
     my $output;
     if (ref($cancreate) eq 'ARRAY') {
-        if (!grep(/^email$/,@{$cancreate})) {
+        if (!grep(/^email(|approval)$/,@{$cancreate})) {
             $output = &invalid_state('noemails',$domdesc,
                                      $contact_name,$contact_email);
             return $output;
@@ -514,6 +557,13 @@
                                      $contact_name,$contact_email);
             return $output;
         } else {
+            $useremail =~ s/^\s+|\s+$//g;
+            my $uname=&LONCAPA::clean_username($useremail);
+            if ($useremail ne $uname) {
+                $output = &invalid_state('badusername',$domdesc,
+                                         $contact_name,$contact_email);
+                return $output;
+            }
             my $uhome = &Apache::lonnet::homeserver($useremail,$domain);
             if ($uhome ne 'no_host') {
                 $output = &invalid_state('existinguser',$domdesc,
@@ -526,33 +576,30 @@
                                              $contact_email,$captcha_error);
                     return $output;
                 }
-                my $uhome=&Apache::lonnet::homeserver($useremail,$domain);
-                if ($uhome eq 'no_host') {
-                    my (%rulematch,%inst_results,%curr_rules,%got_rules,%alerts);
-                    &call_rulecheck($useremail,$domain,\%alerts,\%rulematch,
-                                    \%inst_results,\%curr_rules,\%got_rules,'username');
-                    if (ref($alerts{'username'}) eq 'HASH') {
-                        if (ref($alerts{'username'}{$domain}) eq 'HASH') {
-                            if ($alerts{'username'}{$domain}{$useremail}) {
-                                $output = &invalid_state('userrules',$domdesc,
-                                                         $contact_name,$contact_email);
-                                return $output;
-                            }
+                my (%rulematch,%inst_results,%curr_rules,%got_rules,%alerts);
+                &call_rulecheck($useremail,$domain,\%alerts,\%rulematch,
+                                \%inst_results,\%curr_rules,\%got_rules,'username');
+                if (ref($alerts{'username'}) eq 'HASH') {
+                    if (ref($alerts{'username'}{$domain}) eq 'HASH') {
+                        if ($alerts{'username'}{$domain}{$useremail}) {
+                            $output = &invalid_state('userrules',$domdesc,
+                                                     $contact_name,$contact_email);
+                            return $output;
                         }
                     }
-                    my $format_msg = 
-                        &guest_format_check($useremail,$domain,$cancreate,
-                                            $settings);
-                    if ($format_msg) {
-                        $output = &invalid_state('userformat',$domdesc,$contact_name,
-                                                 $contact_email,$format_msg);
-                        return $output;
-                    }
+                }
+                my $format_msg = 
+                    &guest_format_check($useremail,$domain,$cancreate,
+                                        $settings);
+                if ($format_msg) {
+                    $output = &invalid_state('userformat',$domdesc,$contact_name,
+                                             $contact_email,$format_msg);
+                    return $output;
                 }
             }
         }
         $output = &send_token($domain,$useremail,$server,$domdesc,$contact_name,
-                          $contact_email,$courseid);
+                              $contact_email,$courseid,$emailusername);
     }
     return $output;
 }
@@ -572,86 +619,124 @@
 }
 
 sub send_token {
-    my ($domain,$email,$server,$domdesc,$contact_name,$contact_email,$courseid) = @_;
+    my ($domain,$email,$server,$domdesc,$contact_name,$contact_email,$courseid,$emailusername) = @_;
     my $msg = '<h3>'.&mt('Account creation status').'</h3>'.
               &mt('Thank you for your request to create a new LON-CAPA account.').
               '<br /><br />';
     my $now = time;
-    my %info = ('ip'         => $ENV{'REMOTE_ADDR'},
-                'time'       => $now,
-                'domain'     => $domain,
-                'username'   => $email,
-                'courseid'   => $courseid);
-    my $token = &Apache::lonnet::tmpput(\%info,$server,'createaccount');
-    if ($token !~ /^error/ && $token ne 'no_such_host') {
-        my $esc_token = &escape($token);
-        my $showtime = localtime(time);
-        my $mailmsg = &mt('A request was submitted on [_1] for creation of a LON-CAPA account at the following institution: [_2].',$showtime,$domdesc).' '.
-             &mt('To complete this process please open a web browser and enter the following URL in the address/location box: [_1]',
-                 &Apache::lonnet::absolute_url().'/adm/createaccount?token='.$esc_token);
-        my $result = &Apache::resetpw::send_mail($domdesc,$email,$mailmsg,$contact_name,
-                                                 $contact_email);
-        if ($result eq 'ok') {
-            $msg .= &mt('A message has been sent to the e-mail address you provided.').'<br />'.&mt('The message includes the web address for the link you will use to complete the account creation process.').'<br />'.&mt("The link included in the message will be valid for the next [_1]two[_2] hours.",'<b>','</b>');
+    $env{'form.logtoken'} =~ s/(`)//g;
+    if ($env{'form.logtoken'}) {
+        my $logtoken = $env{'form.logtoken'};
+        my $tmpinfo=Apache::lonnet::reply('tmpget:'.$logtoken,$server);
+        if (($tmpinfo=~/^error/) || ($tmpinfo eq 'con_lost')) {
+            $msg = &mt('Information needed to process your request is missing, inaccessible or expired.')
+                  .'<br />'.&mt('Return to the previous page to try again.');
+        } else {
+            my $reply = &Apache::lonnet::reply('tmpdel:'.$logtoken,$server);
+            unless ($reply eq 'ok') {
+                $msg .= &mt('Request could not be processed.');
+            }
+        }
+        my %info = ('ip'         => $ENV{'REMOTE_ADDR'},
+                    'time'       => $now,
+                    'domain'     => $domain,
+                    'username'   => $email,
+                    'courseid'   => $courseid,
+                    'upass'      => $env{'form.upass'},
+                    'serverid'   => $env{'form.serverid'},
+                    'tmpinfo'    => $tmpinfo);
+
+        if (ref($emailusername) eq 'HASH') {
+            foreach my $item (keys(%{$emailusername})) {
+                $info{$item} = $env{'form.'.$item};
+                $info{$item} =~ s/(`)//g;
+            }
+        }
+        my $token = &Apache::lonnet::tmpput(\%info,$server,'createaccount');
+        if ($token !~ /^error/ && $token ne 'no_such_host') {
+            my $esc_token = &escape($token);
+            my $showtime = localtime(time);
+            my $mailmsg = &mt('A request was submitted on [_1] for creation of a LON-CAPA account at the following institution: [_2].',$showtime,$domdesc).' '.
+                          &mt('To complete this process please open a web browser and enter the following URL in the address/location box: [_1]',
+                          &Apache::lonnet::absolute_url().'/adm/createaccount?token='.$esc_token);
+            my $result = &Apache::resetpw::send_mail($domdesc,$email,$mailmsg,$contact_name,
+                                                     $contact_email);
+            if ($result eq 'ok') {
+                $msg .= &mt('A message has been sent to the e-mail address you provided.').'<br />'.
+                        &mt('The message includes the web address for the link you will use to complete the account creation process.').'<br />'.
+                        &mt("The link included in the message will be valid for the next [_1]two[_2] hours.",'<b>','</b>');
+            } else {
+                $msg .= '<span class="LC_error">'.
+                        &mt('An error occurred when sending a message to the e-mail address you provided.').'</span><br />'.
+                        ' '.&mt('Please contact the [_1] ([_2]) for assistance.',$contact_name,$contact_email);
+            }
         } else {
             $msg .= '<span class="LC_error">'.
-                    &mt('An error occurred when sending a message to the e-mail address you provided.').'</span><br />'.
+                    &mt('An error occurred creating a token required for the account creation process.').'</span><br />'.
                     ' '.&mt('Please contact the [_1] ([_2]) for assistance.',$contact_name,$contact_email);
         }
     } else {
-        $msg .= '<span class="LC_error">'.
-                &mt('An error occurred creating a token required for the account creation process.').'</span><br />'.
-                ' '.&mt('Please contact the [_1] ([_2]) for assistance.',$contact_name,$contact_email);
+        $msg .=  $msg = &mt('Information needed to process your request is missing, inaccessible or expired.')
+                .'<br />'.&mt('Return to the previous page to try again.');
+
     }
     return $msg;
 }
 
 sub process_mailtoken {
     my ($r,$token,$contact_name,$contact_email,$domain,$domdesc,$lonhost,
-        $include,$start_page) = @_;
-    my ($msg,$nostart,$noend);
+        $include,$start_page,$cancreate,$settings) = @_;
+    my ($msg,$nostart,$noend,$redirect);
     my %data = &Apache::lonnet::tmpget($token);
     my $now = time;
     if (keys(%data) == 0) {
         $msg = &mt('Sorry, the URL you provided to complete creation of a new LON-CAPA account was invalid.')
                .' '.&mt('Either the token included in the URL has been deleted or the URL you provided was invalid.')
-               .' '.&mt('Please submit a [_1]new request[_2] for account creation and follow the new link page included in the e-mail that will be sent to you.','<a href="/adm/createaccount">','</a>');
+               .' '.&mt('Please submit a [_1]new request[_2] for account creation and follow the new link page included in the e-mail that will be sent to you.',
+                        '<a href="/adm/createaccount">','</a>');
         return $msg;
     }
     if (($data{'time'} =~ /^\d+$/) &&
         ($data{'domain'} ne '') &&
         ($data{'username'}  =~ /^[^\@]+\@[^\@]+\.[^\@\.]+$/)) {
         if ($now - $data{'time'} < 7200) {
-            if ($env{'form.phase'} eq 'createaccount') {
-                my ($result,$output,$uhome) = 
-                    &create_account($r,$domain,$data{'username'},$domdesc);
-                if ($result eq 'ok') {
-                    $msg = $output; 
-                    my $shownow = &Apache::lonlocal::locallocaltime($now);
-                    my $mailmsg = &mt('A LON-CAPA account for the institution: [_1] has been created [_2] from IP address: [_3]. If you did not perform this action or authorize it, please contact the [_4] ([_5]).',$domdesc,$shownow,$ENV{'REMOTE_ADDR'},$contact_name,$contact_email)."\n";
-                    my $mailresult = &Apache::resetpw::send_mail($domdesc,$data{'email'},
-                                                                 $mailmsg,$contact_name,
-                                                                 $contact_email);
-                    if ($mailresult eq 'ok') {
-                        $msg .= &mt('An e-mail confirming creation of your new LON-CAPA account has been sent to [_1].',$data{'username'});
+# Check if request should be queued.
+            if (ref($cancreate) eq 'ARRAY') {
+                if (grep(/^email$/,@{$cancreate})) {
+                    my ($result,$output,$uhome) = 
+                        &create_account($r,$domain,$domdesc,\%data);
+                    if ($result eq 'ok') {
+                        $msg = $output;
+                        my $shownow = &Apache::lonlocal::locallocaltime($now);
+                        my $mailmsg = &mt('A LON-CAPA account for the institution: [_1] has been created [_2] from IP address: [_3]. If you did not perform this action or authorize it, please contact the [_4] ([_5]).',$domdesc,$shownow,$ENV{'REMOTE_ADDR'},$contact_name,$contact_email)."\n";
+                        my $mailresult = &Apache::resetpw::send_mail($domdesc,$data{'email'},
+                                                                     $mailmsg,$contact_name,
+                                                                     $contact_email);
+                        if ($mailresult eq 'ok') {
+                            $msg .= &mt('An e-mail confirming creation of your new LON-CAPA account has been sent to [_1].',$data{'username'});
+                        } else {
+                            $msg .= &mt('An error occurred when sending e-mail to [_1] confirming creation of your LON-CAPA account.',$data{'username'});
+                        }
+                        $redirect = &start_session($r,$data{'username'},$domain,$uhome,
+                                                   $data{'courseid'},$token);
+                        $nostart = 1;
+                        $noend = 1;
                     } else {
-                        $msg .= &mt('An error occurred when sending e-mail to [_1] confirming creation of your LON-CAPA account.',$data{'username'});
+                        $msg .= &mt('A problem occurred when attempting to create your new LON-CAPA account.')
+                               .'<br />'.$output;
+                        if (($contact_name ne '') && ($contact_email ne '')) {
+                            $msg .= &mt('Please contact the [_1] ([_2]) for assistance.',$contact_name,$contact_email);
+                        }
                     }
-                    &start_session($r,$data{'username'},$domain,$uhome,
-                                   $data{'courseid'},$token);
-                    $nostart = 1;
-                    $noend = 1;
+                    my $delete = &Apache::lonnet::tmpdel($token);
+                } elsif (grep(/^emailapproval$/,@{$cancreate})) {
+                    $msg = &store_request($domain,$data{'username'},'approval',\%data,$settings);
+                    my $delete = &Apache::lonnet::tmpdel($token);
                 } else {
-                    $msg .= &mt('A problem occurred when attempting to create your new LON-CAPA account.')
-                           .'<br />'.$output
-#                           .&mt('Please contact the [_1] ([_2]) for assistance.',$contact_name,'<a href="mailto:'.$contact_email.'">'.$contact_email.'</a>');
-                           .&mt('Please contact the [_1] ([_2]) for assistance.',$contact_name,$contact_email);
+                    $msg = &invalid_state('noemails',$domdesc,$contact_name,$contact_email);
                 }
-                my $delete = &Apache::lonnet::tmpdel($token);
             } else {
-                $msg .= &mt('Please provide user information and a password for your new account.').'<br />'.&mt('Your password, which must contain at least seven characters, will be sent to the LON-CAPA server in an encrypted form.').'<br />';
-                $msg .= &print_dataentry_form($r,$domain,$lonhost,$include,$token,$now,$data{'username'},$start_page);
-                $nostart = 1;
+                $msg = &invalid_state('noemails',$domdesc,$contact_name,$contact_email);
             }
         } else {
             $msg = &mt('Sorry, the token generated when you requested creation of an account has expired.')
@@ -661,7 +746,7 @@
         $msg .= &mt('Sorry, the URL generated when you requested creation of an account contained incomplete information.')
                .' '.&mt('Please submit a [_1]new request[_2] for account creation and follow the new link included in the e-mail that will be sent to you.','<a href="/adm/createaccount">','</a>');
     }
-    return ($msg,$nostart,$noend);
+    return ($msg,$nostart,$noend,$redirect);
 }
 
 sub start_session {
@@ -673,7 +758,7 @@
 
         Apache::lonnet::tmpdel($token) if $token;
 
-        $r->internal_redirect('/adm/switchserver');
+        return 'redirect';
     } else {
         $courseid = Apache::lonnet::is_course($courseid); 
 
@@ -691,74 +776,61 @@
 # Stores token to store DES-key and stage during creation session
 #
 sub print_dataentry_form {
-    my ($r,$domain,$lonhost,$include,$mailtoken,$now,$username,$start_page) = @_;
+    my ($r,$domain,$lonhost,$include,$now,$captchaform,$courseid,$gotlondes,$emailusername) = @_;
     my ($error,$output);
-    &print_header($r,$start_page);
-    if (open(my $jsh,"<$include/londes.js")) {
-        while(my $line = <$jsh>) {
-            $r->print($line);
-        }
-        close($jsh);
-        $output .= &javascript_setforms($now)."\n".&javascript_checkpass($now);
-        my ($lkey,$ukey) = &Apache::lonpreferences::des_keys();
+    unless ($gotlondes) {
+        if (open(my $jsh,"<$include/londes.js")) {
+            while(my $line = <$jsh>) {
+                $r->print($line);
+            }
+            close($jsh);
+            $output = &javascript_setforms($now,$emailusername)."\n";
+            $gotlondes = 1;
+        }
+    }
+    if ($gotlondes) {
+        $output .= &javascript_checkpass($now,'email');
+        my ($lkey,$ukey) = &Apache::loncommon::des_keys();
         my ($lextkey,$uextkey) = &getkeys($lkey,$ukey);
         my $logtoken=Apache::lonnet::reply('tmpput:'.$ukey.$lkey.'&createaccount:createaccount',
                                            $lonhost);
-        my $formtag = '<form name="server" method="post" target="_top" action="/adm/createaccount">';
-        my ($datatable,$rowcount) =
-            &Apache::loncreateuser::personal_data_display($username,$domain,
-                                                          'email','selfcreate');
-        if ($rowcount) {
-            $output .= '<div class="LC_left_float">'.$formtag.$datatable;
-        } else {
-            $output .= $formtag;
+        $output .=
+            '<form name="createaccount" method="post" target="_top" action="/adm/createaccount">';
+        if ($courseid ne '') {
+            $output .= '<input type="hidden" name="courseid" value="'.$courseid.'"/>'."\n";
+        }
+        if (ref($emailusername) eq 'HASH') {
+            foreach my $field (sort(keys(%{$emailusername}))) {
+                $output .= '<input type="hidden" name="'.$field.'" value="" />'."\n";
+            }
         }
         $output .= <<"ENDSERVERFORM";
    <input type="hidden" name="logtoken" value="$logtoken" />
-   <input type="hidden" name="token" value="$mailtoken" />
    <input type="hidden" name="serverid" value="$lonhost" />
    <input type="hidden" name="uname" value="" />
    <input type="hidden" name="upass" value="" />
    <input type="hidden" name="udom" value="" />
+   <input type="hidden" name="crypt" value="" />
+   <input type="hidden" name="code" value="" />
    <input type="hidden" name="phase" value="createaccount" />
+   <input type="hidden" name="create_with_email" value="1" />
   </form>
 ENDSERVERFORM
+        my $beginclientform = '<form name="newemail" method="post" action="" '.
+                              'onsubmit="return checkpass('."'createaccount','newemail'".');">'."\n";
+        my $endclientform = '<input type="hidden" name="udom" value="'.$domain.'" />'."\n".
+                            '<input type="hidden" name="lextkey" value="'.$lextkey.'" />'."\n".
+                            '<input type="hidden" name="uextkey" value="'.$uextkey.'" />'."\n".
+                            '</form>';
+        my ($datatable,$rowcount) =
+            &Apache::loncreateuser::personal_data_display('',$domain,'email','selfcreate',
+                                                          '','',$now,$captchaform,
+                                                          $emailusername);
         if ($rowcount) {
-            $output .= '</div>'.
-                       '<div class="LC_left_float">';
+            $output .= '<div class="LC_left_float">'.$beginclientform.$datatable.$endclientform;
+        } else {
+            $output .= $beginclientform.$endclientform;
         }
-        my $upassone = '<input type="password" name="upass'.$now.'" size="10" />';
-        my $upasstwo = '<input type="password" name="upasscheck'.$now.'" size="10" />';
-        my $submit_text = &mt('Create LON-CAPA account');
-        $output .= '<h3>'.&mt('Login Data').'</h3>'."\n".
-                   '<form name="client" method="post" action="" '.
-                   'onsubmit="return checkpass();">'."\n".
-                   &Apache::lonhtmlcommon::start_pick_box()."\n".
-                   &Apache::lonhtmlcommon::row_title(&mt('Username'),
-                                                     'LC_pick_box_title',
-                                                     'LC_oddrow_value')."\n".
-                   $username."\n".
-                   &Apache::lonhtmlcommon::row_closure(1)."\n".
-                   &Apache::lonhtmlcommon::row_title(&mt('Password'),
-                                                    'LC_pick_box_title',
-                                                    'LC_oddrow_value')."\n".
-                   $upassone."\n".
-                   &Apache::lonhtmlcommon::row_closure(1)."\n".
-                   &Apache::lonhtmlcommon::row_title(&mt('Confirm password'),
-                                                     'LC_pick_box_title',
-                                                     'LC_oddrow_value')."\n".
-                   $upasstwo.
-                   &Apache::lonhtmlcommon::row_closure(1)."\n".
-                   &Apache::lonhtmlcommon::row_title()."\n".
-                   '<br /><input type="submit" name="createaccount" value="'.
-                   $submit_text.'" />'.
-                   &Apache::lonhtmlcommon::row_closure(1)."\n".
-                   &Apache::lonhtmlcommon::end_pick_box()."\n".
-                   '<input type="hidden" name="uname" value="'.$username.'" />'."\n".
-                   '<input type="hidden" name="udom" value="'.$domain.'" />'."\n".
-                   '<input type="hidden" name="lextkey" value="'.$lextkey.'" />'."\n".
-                   '<input type="hidden" name="uextkey" value="'.$uextkey.'" />'."\n".
-                   '</form>';
         if ($rowcount) {
             $output .= '</div>'."\n".
                        '<div class="LC_clear_float_footer"></div>'."\n";
@@ -775,7 +847,7 @@
 
 sub get_creation_controls {
     my ($domain,$usercreation) = @_;
-    my (@cancreate, at statustocreate);
+    my (@cancreate, at statustocreate,$emailusername);
     if (ref($usercreation) eq 'HASH') {
         if (ref($usercreation->{'cancreate'}) eq 'HASH') {
             if (ref($usercreation->{'cancreate'}{'statustocreate'}) eq 'ARRAY') {
@@ -805,80 +877,147 @@
                      ($usercreation->{'cancreate'}{'selfcreate'} ne '')) {
                 @cancreate = ($usercreation->{'cancreate'}{'selfcreate'});
             }
+            if (ref($usercreation->{'cancreate'}{'emailusername'}) eq 'HASH') {
+                $emailusername = $usercreation->{'cancreate'}{'emailusername'};
+            }
         }
     }
-    return (\@cancreate,\@statustocreate);
+    return (\@cancreate,\@statustocreate,$emailusername);
 }
 
 sub create_account {
-    my ($r,$domain,$username,$domdesc) = @_;
-# Get the token info
-    my ($retrieved,$output,$upass) = &process_credentials($env{'form.logtoken'},
-                                                          $env{'form.serverid'}); 
-# $retrieved is 'ok' if things worked
-# $output is user error output
-# $upass is the decrypted password
-    # Error messages
-    my $error     = '<span class="LC_error">'.&mt('Error:').' ';
-    my $end       = '</span><br /><br />';
-    my $rtnlink   = '<a href="javascript:history.back();">'.
+    my ($r,$domain,$domdesc,$dataref) = @_;
+    my $error    = '<span class="LC_error">'.&mt('Error:').' ';
+    my $end      = '</span><br /><br />';
+    my $rtnlink  = '<a href="javascript:history.back();">'.
                     &mt('Return to previous page').'</a>'.
                     &Apache::loncommon::end_page();
-    if ($retrieved eq 'ok') {
-        if ($env{'form.courseid'} ne '') {
-# See if we are allowed to use this username per domain rules (number of characters, etc)
-            my ($result,$userchkmsg) = &check_id($username,$domain,$domdesc);
-            if ($result eq 'fail') {
-                $output = $error.&mt('Invalid ID format').$end.
-                          $userchkmsg.$rtnlink;
-                return ('fail',$output);
+    my $output;
+    if (ref($dataref) eq 'HASH') {
+        my ($username,$encpass,$serverid,$courseid,$id,$firstname,$middlename,$lastname,
+            $generation);
+        $username   = $dataref->{'username'};
+        $encpass    = $dataref->{'upass'};
+        $serverid   = $dataref->{'serverid'};
+        $courseid   = $dataref->{'courseid'};
+        $id         = $dataref->{'id'};
+        $firstname  = $dataref->{'firstname'};
+        $middlename = $dataref->{'middlename'};
+        $lastname   = $dataref->{'lastname'};
+        $generation = $dataref->{'generation'};
+       
+        my $currhome = &Apache::lonnet::homeserver($username,$domain);
+        unless ($currhome eq 'no_host') {
+            $output = &mt('User account requested for username: [_1] in domain: [_2] already exists.',$username,$domain);
+            return ('fail',$error.$output.$end.$rtnlink);
+        }
+
+# Split the logtoken to retrieve the DES key and decrypt the encypted password
+
+        my ($key,$caller)=split(/&/,$dataref->{'tmpinfo'});
+        if ($caller eq 'createaccount') {
+            my $upass = &Apache::loncommon::des_decrypt($key,$encpass);
+
+# See if we are allowed to use the proposed student/employee ID,
+# as per domain rules; if not, student/employee will be left blank.
+
+            if ($id ne '') {
+                my ($result,$userchkmsg) = &check_id($username,$domain,$id,$domdesc,'email');
+                if ($result eq 'fail') {
+                    $output = $error.&mt('Invalid ID format').$end.
+                              $userchkmsg;
+                    undef($id);
+                }
             }
+
+# Create an internally authenticated account with password $upass
+# if the user account does not already exist.
+# Assign student/employee id, first name, last name, etc.
+
+            my $result =
+                &Apache::lonnet::modifyuser($domain,$username,$id,
+                                            'internal',$upass,$firstname,$middlename,
+                                            $lastname,$generation,undef,undef,$username);
+            $output = &mt('Generating user: [_1]',$result);
+
+# Now that the user account exists, retrieve the homeserver, and include it in the output.
+
+            my $uhome = &Apache::lonnet::homeserver($username,$domain);
+            $output .= '<br />'.&mt('Home server: [_1]',$uhome).' '.
+                       &Apache::lonnet::hostname($uhome).'<br /><br />';
+            return ('ok',$output,$uhome);
+        } else {
+            $output = &mt('Unable to retrieve your account creation information - unexpected context');
+            undef($encpass);
+            return ('fail',$error.$output.$end.$rtnlink);
         }
     } else {
+        $output = &mt('Unable to retrieve information for your account request.');
         return ('fail',$error.$output.$end.$rtnlink);
     }
-    # Yes! We can do this. Valid token, valid username format
-    # Create an internally authenticated account with password $upass 
-    # if the account does not exist yet
-    # Assign student/staff number $env{'form.cid'}, first name, last name, etc
-    my $result = 
-        &Apache::lonnet::modifyuser($domain,$username,$env{'form.cid'},
-                                    'internal',$upass,$env{'form.cfirstname'},
-                                    $env{'form.cmiddlename'},$env{'form.clastname'},
-                                    $env{'form.cgeneration'},undef,undef,$username);
-    $output = &mt('Generating user: [_1]',$result);
-    # Now that the user exists, we can have a homeserver
-    my $uhome = &Apache::lonnet::homeserver($username,$domain);
-    $output .= '<br />'.&mt('Home server: [_1]',$uhome).' '.
-              &Apache::lonnet::hostname($uhome).'<br /><br />';
-    return ('ok',$output,$uhome);
 }
 
 sub username_validation {
     my ($r,$username,$domain,$domdesc,$contact_name,$contact_email,$courseid,
         $lonhost,$statustocreate) = @_;
+# $r: request object
 # $username,$domain: for the user who needs to be validated
 # $domdesc: full name of the domain (for error messages)
-# $contact_name, $contact_email: name and email for user assistance (for error messages in &username_check
-# $courseid: ID of the course that the user should be validated for, goes into start_session
+# $contact_name, $contact_email: name and email for user assistance (for error messages in &username_check)
+# $courseid: ID of the course if user came to username_validation via self-enroll link,
+#             passed to start_session()
+# $lonhost: LON-CAPA lonHostID
 # $statustocreate: -> inststatus in username_check ('faculty', 'staff', 'student', ...)
  
-    my ($retrieved,$output,$upass);
-
+#
+# Sanitize incoming username and domain
+#
     $username= &LONCAPA::clean_username($username);
     $domain = &LONCAPA::clean_domain($domain);
+
+#
+# Check if LON-CAPA account already exists for $username:$domain
+#
     my $uhome = &Apache::lonnet::homeserver($username,$domain);
 
-    ($retrieved,$output,$upass) = &process_credentials($env{'form.logtoken'},
-                                                       $env{'form.serverid'});
-    if ($retrieved ne 'ok') {
+    my $output;
+
+# Retrieve DES key from server using logtoken
+ 
+    my $tmpinfo=Apache::lonnet::reply('tmpget:'.$env{'form.logtoken'},$env{'form.serverid'});
+    if (($tmpinfo=~/^error/) || ($tmpinfo eq 'con_lost')) {
+        $output = &mt('Information needed to verify your login information is missing, inaccessible or expired.')
+                 .'<br />'.&mt('You may need to reload the previous page to obtain a new token.');
+        return ('fail',$output);
+    } else {
+        my $reply = &Apache::lonnet::reply('tmpdel:'.$env{'form.logtoken'},$env{'form.serverid'});
+        unless ($reply eq 'ok') {
+            $output = &mt('Session could not be opened.');
+            return ('fail',$output); 
+        }
+    }
+
+# Split the logtoken to retrieve the DES key and decrypt the encypted password
+
+    my ($key,$caller)=split(/&/,$tmpinfo);
+    my $upass;
+    if ($caller eq 'createaccount') {
+        $upass = &Apache::loncommon::des_decrypt($key,$env{'form.upass'});
+    } else {
+        $output = &mt('Unable to retrieve your log-in information - unexpected context');
         return ('fail',$output);
     }
     if ($uhome ne 'no_host') {
         my $result = &Apache::lonnet::authenticate($username,$upass,$domain);
         if ($result ne 'no_host') { 
-            &start_session($r,$username,$domain,$uhome,$courseid);
-            $output = '<br /><br />'.&mt('A LON-CAPA account already exists for username [_1] at this institution ([_2]).','<tt>'.$username.'</tt>',$domdesc).'<br />'.&mt('The password entered was also correct so you have been logged in.');
+            my $redirect = &start_session($r,$username,$domain,$uhome,$courseid);
+            if ($redirect) {
+                return ($redirect);
+            }
+            $output = '<br /><br />'.
+                      &mt('A LON-CAPA account already exists for username [_1] at this institution ([_2]).',
+                          '<tt>'.$username.'</tt>',$domdesc).'<br />'.
+                      &mt('The password entered was also correct so you have been logged in.');
             return ('existingaccount',$output);
         } else {
             $output = &login_failure_msg($courseid);
@@ -887,7 +1026,8 @@
         my $primlibserv = &Apache::lonnet::domain($domain,'primary');
         my $authok;
         my %domdefaults = &Apache::lonnet::get_domain_defaults($domain);
-        if ((($domdefaults{'auth_def'} =~/^krb(4|5)$/) && ($domdefaults{'auth_arg_def'} ne '')) || ($domdefaults{'auth_def'} eq 'localauth')) {
+        if ((($domdefaults{'auth_def'} =~/^krb(4|5)$/) && ($domdefaults{'auth_arg_def'} ne '')) || 
+             ($domdefaults{'auth_def'} eq 'localauth')) {
             my $checkdefauth = 1;
             $authok = 
                 &Apache::lonnet::reply("encrypt:auth:$domain:$username:$upass:$checkdefauth",$primlibserv);
@@ -1069,7 +1209,8 @@
          ($domdefaults{'auth_arg_def'} ne '')) || 
         ($domdefaults{'auth_def'} eq 'localauth')) {
         if ($env{'form.courseid'} ne '') {
-            my ($result,$userchkmsg) = &check_id($username,$domain,$domdesc);
+            my $id = $env{'form.cid'}; 
+            my ($result,$userchkmsg) = &check_id($username,$domain,$id,$domdesc,'institutional');
             if ($result eq 'fail') {
                 $output = $error.&mt('Invalid ID format').$end.
                           $userchkmsg.$rtnlink;
@@ -1107,9 +1248,13 @@
             my $delete = &Apache::lonnet::tmpdel($env{'form.authtoken'});
             $output = &mt('A LON-CAPA account has been created for username: [_1] in domain: [_2].',$username,$domain);
             my $uhome=&Apache::lonnet::homeserver($username,$domain,'true');
-            &start_session($r,$username,$domain,$uhome,$courseid);
             my $nostart = 1;
-            return ('ok',$output,$nostart);
+            my $response = 'ok';
+            my $redirect = &start_session($r,$username,$domain,$uhome,$courseid);
+            if ($redirect) {
+                $response = $redirect;
+            }
+            return ($response,$output,$nostart);
         } else {
             $output = &mt('Account creation failed for username: [_1] in domain: [_2].',$username,$domain).'<br /><span class="LC_error">'.&mt('Error: [_1]',$result).'</span>';
             return ('fail',$output);
@@ -1121,16 +1266,15 @@
 }
 
 sub check_id {
-    my ($username,$domain,$domdesc) = @_;
-    # Check ID format
-    # Is $username in an okay format for $domain 
-    # (right number of characters, special characters, etc - follow domain rules)?
+    my ($username,$domain,$id,$domdesc,$usernametype) = @_;
+    # Check student/employee ID format
+    # Is proposed student/employee ID acceptable according to domain's rules.  
     # $domdesc is just used for user error messages
     my (%alerts,%rulematch,%inst_results,%curr_rules,%checkhash);
     my %checks = ('id' => 1);
     %{$checkhash{$username.':'.$domain}} = (
                                             'newuser' => 1,
-                                            'id' => $env{'form.cid'},
+                                            'id' => $id,
                                            );
     &Apache::loncommon::user_rule_check(\%checkhash,\%checks,\%alerts,
                                         \%rulematch,\%inst_results,\%curr_rules);
@@ -1139,11 +1283,15 @@
             if ($alerts{'id'}{$domain}{$env{'form.cid'}}) {
                 my $userchkmsg;
                 if (ref($curr_rules{$domain}) eq 'HASH') {
-                    $userchkmsg  =
-                        &Apache::loncommon::instrule_disallow_msg('id',
-                                                           $domdesc,1).
-                        &Apache::loncommon::user_rule_formats($domain,
-                              $domdesc,$curr_rules{$domain}{'id'},'id');
+                    if ($usernametype eq 'email') {
+                        $userchkmsg = &mt('A student/employee ID has not been set because the value suggested matched the format used for institutional users in the domain, and you are using an e-mail address as username, not an institutional username.');
+                    } else {
+                        $userchkmsg =
+                            &Apache::loncommon::instrule_disallow_msg('id',
+                                                                      $domdesc,1).
+                            &Apache::loncommon::user_rule_formats($domain,
+                                $domdesc,$curr_rules{$domain}{'id'},'id');
+                    }
                 }
                 return ('fail',$userchkmsg);
             }
@@ -1157,6 +1305,8 @@
     my $msg = '<h3>'.&mt('Account creation unavailable').'</h3><span class="LC_error">';
     if ($error eq 'baduseremail') {
         $msg .= &mt('The e-mail address you provided does not appear to be a valid address.');
+    } elsif ($error eq 'badusername') {
+        $msg .= &mt('The e-mail address you provided contains characters which prevent its use as a username in LON-CAPA.');
     } elsif ($error eq 'existinguser') {
         $msg .= &mt('The e-mail address you provided is already in use as a username in LON-CAPA at this institution.');
     } elsif ($error eq 'userrules') {
@@ -1230,39 +1380,72 @@
     return $output;
 }
 
-sub process_credentials {
-#
-# Fetches the information from the logtoken via tmpget
-# Token contains the DES-key and the stage of the process (would only be "createaccount")
-# $lonhost in this routine is *not* necessarily the machine that this runs on,
-# but $env{'form.serverid'}, the machine that issued the token. 
-#
-    my ($logtoken,$lonhost) = @_;
-    my $tmpinfo=Apache::lonnet::reply('tmpget:'.$logtoken,$lonhost);
-    my ($retrieved,$output,$upass);
-    if (($tmpinfo=~/^error/) || ($tmpinfo eq 'con_lost')) {
-        $output = &mt('Information needed to verify your login information is missing, inaccessible or expired.')
-                 .'<br />'.&mt('You may need to reload the previous page to obtain a new token.');
-        return ($retrieved,$output,$upass); 
-    } else {
-        my $reply = &Apache::lonnet::reply('tmpdel:'.$logtoken,$lonhost);
-        if ($reply eq 'ok') {
-            $retrieved = 'ok';
-        } else {
-            $output = &mt('Session could not be opened.');
+sub store_request {
+    my ($dom,$username,$val,$dataref,$settings) = @_;
+    my $output;
+    my $domconfiguser = &Apache::lonnet::get_domainconfiguser($dom);
+    my $key = &escape($username);
+    my $now = time();
+    if (&Apache::lonnet::put('usernamequeue', { $key.'_'.$val => $now },
+                             $dom,$domconfiguser) eq 'ok') {
+        if (ref($dataref) eq 'HASH') {
+            my $logtoken = $dataref->{'tmpinfo'};
+            my $serverid = $dataref->{'serverid'}; 
+            if ($logtoken && $serverid) {
+                my $tmpinfo=Apache::lonnet::reply('tmpget:'.$logtoken,$serverid);
+                unless (($tmpinfo=~/^error/) || ($tmpinfo eq 'con_lost')) {
+                    my $reply = &Apache::lonnet::reply('tmpdel:'.$logtoken,$serverid);
+                    if ($reply eq 'ok') {
+                        my ($key,$caller)=split(/&/,$tmpinfo);
+                        $dataref->{'key'} = $key;
+                        undef($dataref->{'tmpinfo'});
+                        undef($dataref->{'serverid'});
+                    }
+                }
+            }
         }
-    }
-    my ($key,$caller)=split(/&/,$tmpinfo);
-    if ($caller eq 'createaccount') {
-        $upass = &Apache::lonpreferences::des_decrypt($key,$env{'form.upass'});
+        my %userrequest = ( $username => $dataref );
+        $userrequest{$username}{timestamp} = $now;
+        $userrequest{$username}{status} = $val;
+        my $notifylist;
+        if (ref($settings) eq 'HASH') {
+            if (ref($settings->{'cancreate'}) eq 'HASH') {
+                if (ref($settings->{'cancreate'}{'notify'}) eq 'HASH') {
+                    my $notifylist = $settings->{'cancreate'}{'notify'}{'approval'};
+                    if ($notifylist) {
+                        my $sender = $domconfiguser.':'.$dom;
+                        my $domdesc = &Apache::lonnet::domain($dom,'description');
+                        my $fullname;
+                        if (ref($dataref) eq 'HASH') {
+                            if ($dataref->{'firstname'}) {
+                                $fullname = $dataref->{'firstname'};
+                            }
+                            if ($dataref->{'lastname'}) {
+                                $fullname .= ' '.$dataref->{'lastname'};
+                            }
+                            $fullname =~ s/^\s+|\s+$//g; 
+                        }
+                        &Apache::loncoursequeueadmin::send_selfserve_notification($notifylist,
+                                                     "$fullname ($username)",
+                                                     undef,$domdesc,$now,'usernamereq',$sender);
+                    }
+                }
+            }
+        }
+        my $userresult =
+            &Apache::lonnet::put('nohist_requestedusernames',\%userrequest,$dom,$domconfiguser);
+        $output = '<p class="LC_info">'.
+                  &mt('Your request for a LON-CAPA account has been submitted for approval.').
+                  '</p>'.
+                  '<p class="LC_info">'.
+                  &mt('An e-mail will be sent to [_1] when your request has been reviewed by an administrator and action has been taken.',$username).
+                  '</p>';
     } else {
-        $output = &mt('Unable to retrieve your log-in information - unexpected context');
+        $output = '<span class="LC_error">'.
+                  &mt('An error occurred when attempting to save your request for a LON-CAPA account.');
+                  '</span>';
     }
-# $retrieved is 'ok' if retrieved okay
-# $output is screen output for the user
-# $upass is $env{'form.upass'}, decrypted with the DES-key, if stage was 'createaccount'
-
-    return ($retrieved,$output,$upass);
+    return $output;
 }
 
 sub guest_format_check {
@@ -1288,7 +1471,9 @@
     }
     if ($format_match) {
         ($login) = ($useremail =~ /^([^\@]+)\@/);
-        $format_msg = '<br />'.&mt("Your e-mail address uses the same internet domain as your institution's LON-CAPA service.").'<br />'.&mt('Creation of a LON-CAPA account with this type of e-mail address as username is not permitted.').'<br />';
+        $format_msg = '<br />'.
+                      &mt("Your e-mail address uses the same internet domain as your institution's LON-CAPA service.").'<br />'.
+                      &mt('Creation of a LON-CAPA account with this type of e-mail address as username is not permitted.').'<br />';
         if (ref($cancreate) eq 'ARRAY') {
             if (grep(/^login$/,@{$cancreate})) {
                 $format_msg .= &mt('You should request creation of a LON-CAPA account for a log-in ID of "[_1]" at your institution instead.',$login).'<br />'; 
Index: loncom/interface/loncoursequeueadmin.pm
diff -u loncom/interface/loncoursequeueadmin.pm:1.42 loncom/interface/loncoursequeueadmin.pm:1.43
--- loncom/interface/loncoursequeueadmin.pm:1.42	Wed Jan  8 17:18:11 2014
+++ loncom/interface/loncoursequeueadmin.pm	Wed Feb 12 20:47:40 2014
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Utilities to administer domain course requests and course self-enroll requests
 #
-# $Id: loncoursequeueadmin.pm,v 1.42 2014/01/08 17:18:11 bisitz Exp $
+# $Id: loncoursequeueadmin.pm,v 1.43 2014/02/12 20:47:40 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -124,6 +124,15 @@
         if (ref($textstr) eq 'ARRAY') {
             push(@rawmsg,@{$textstr});
         }
+    } elsif ($context eq 'usernamemanagers') {
+        $rawsubj = 'LON-CAPA account requests reviewed';
+        push(@rawmsg,{
+                      mt  => 'Account requests in the following domain: "[_1]" have been reviewed.',
+                      args => ["\n$contextdesc"],
+                     });
+        if (ref($textstr) eq 'ARRAY') {
+            push(@rawmsg,@{$textstr});
+        }
     } elsif ($context eq 'enroller') {
         $rawsubj = 'Enrollment request';
         if ($crstype eq 'community') {
@@ -223,6 +232,28 @@
         if (ref($textstr) eq 'ARRAY') {
             push(@rawmsg,@{$textstr});
         }
+    } elsif ($context eq 'usernamereq') {
+        $rawsubj = 'LON-CAPA account request';
+        $msgtxt = 'Creation of a LON-CAPA account in the [_1] domain[_2]was requested by [_3] on [_4].';
+        push(@rawmsg,{
+                      mt  => $msgtxt,
+                      args => [$contextdesc,"\n",$textstr,$timestamp],
+                     },
+                     {
+                      mt =>'[_1]As Domain Coordinator, use: [_2]Main Menu -> Create users or modify the roles and privileges of users
+ -> LON-CAPA account requests[_3]to display a list of pending requests, which you can either approve or reject.',
+                      args => ["\n","\n\n  ","\n\n"],
+                     });
+    } elsif ($context eq 'requestusername') {
+        $rawsubj = 'LON-CAPA account request';
+        $msgtxt = 'Your request for a LON-CAPA account requested on [_1]has been reviewed by a Domain Coordinator.';
+        push(@rawmsg,{
+                      mt  => $msgtxt,
+                      args => [$timestamp."\n"],
+                     });
+        if (ref($textstr) eq 'ARRAY') {
+            push(@rawmsg,@{$textstr});
+        }
     } elsif ($context eq 'uniquecode') {
         $rawsubj = 'Course Identifier';
         if (ref($textstr) eq 'ARRAY') {
@@ -255,9 +286,14 @@
     my %reciphash = (
                      cc => $msgcc,
     );
-    my ($uname,$udom);
+    my ($uname,$udom,$need_temp_env);
     if ($sender =~ /:/) {
         ($uname,$udom) = split(/:/,$sender);
+        if ($context eq 'usernamereq') {
+            unless ($env{'user.name'} && $env{'user.domain'}) {
+                $need_temp_env = 1;
+            }
+        }
     } elsif ($context eq 'course') {
         $uname = $sender;
         my %courseinfo = &Apache::lonnet::coursedescription($cid);
@@ -274,9 +310,14 @@
             $message .= &Apache::lonlocal::mt_user($sender_lh,$item->{mt},@{$item->{args}})."\n";
         }
     }
-    &Apache::lonmsg::process_sent_mail($subject,'',$numsent,$stamp,$uname,$udom,$msgcount,$cid,$$,$message,\@recusers,\@recudoms,undef,undef,undef,undef,$senderuname,$senderudom);
+    &Apache::lonmsg::process_sent_mail($subject,'',$numsent,$stamp,$uname,$udom,$msgcount,$cid,$$,$message,
+                                       \@recusers,\@recudoms,undef,undef,undef,undef,$senderuname,$senderudom);
     my ($recipid,$recipstatus) = &Apache::lonmsg::store_recipients($subject,$uname,$udom,\%reciphash);
     my $status;
+    if ($need_temp_env) {
+        $env{'user.name'} = $uname;
+        $env{'user.domain'} = $udom;
+    }
     foreach my $recip (sort(keys(%{$msgcc}))) {
         my ($ccname,$ccdom) = split(/:/,$recip);
         my $recip_lh = &Apache::loncommon::user_lang($ccname,$ccdom,$cid);
@@ -309,10 +350,22 @@
             if ($rejectedlist) {
                 $message .= "\n\n".&Apache::lonlocal::mt_user($sender_lh,'Rejected author role requests:')."\n".$rejectedlist;
             }
+        } elsif ($context eq 'usernamemanagers') {
+            if ($approvedlist) {
+                $message .= "\n\n".&Apache::lonlocal::mt_user($sender_lh,'Approved LON-CAPA account requests:')."\n".$approvedlist;
+            }
+            if ($rejectedlist) {
+                $message .= "\n\n".&Apache::lonlocal::mt_user($sender_lh,'Rejected LON-CAPA account requests:')."\n".$rejectedlist;
+            }
         }
-        $status .= &Apache::lonmsg::user_normal_msg($ccname,$ccdom,$subject,$message,undef,undef,undef,1,\%sentmessage,undef,undef,undef,1,$recipid).',';
+        $status .= &Apache::lonmsg::user_normal_msg($ccname,$ccdom,$subject,$message,undef,undef,undef,1,
+                                                    \%sentmessage,undef,undef,undef,1,$recipid).',';
     }
     $status =~ s/,$//;
+    if ($need_temp_env) {
+        undef($env{'user.name'});
+        undef($env{'user.domain'});
+    }
     return ($recipstatus,$status);
 }
 
@@ -329,6 +382,11 @@
         $namespace = 'requestauthorqueue';
         %requesthash = &Apache::lonnet::dump_dom($namespace,$dom);
         $nextelement = '<input type="hidden" name="state" value="done" />';
+    } elsif ($context eq 'requestusername') {
+        $formaction = '/adm/createuser';
+        $namespace = 'usernamequeue';
+        %requesthash = &Apache::lonnet::dump_dom($namespace,$dom);
+        $nextelement = '<input type="hidden" name="state" value="done" />';
     } else {
         $formaction = '/adm/createcourse';
         $namespace = 'courserequestqueue';
@@ -354,6 +412,9 @@
             } elsif ($context eq 'requestauthor') {
                 $timestamp = $requesthash{$item};
                 ($entry) = ($item =~ /^($match_username)_approval$/);
+            } elsif ($context eq 'requestusername') {
+                $timestamp = $requesthash{$item};
+                ($entry) = (&unescape($item) =~ /^($match_username)_approval$/);
             } else {
                 $timestamp = $requesthash{$item}{'timestamp'};
                 if (ref($requesthash{$item}) eq 'HASH') {
@@ -385,6 +446,8 @@
                            &mt('Validation is attempted when the request is submitted.').' '.&mt('If unvalidated, the request will be held in a queue.').' '.&mt('Validation of pending requests is automatically repeated daily.').'</p>';
             } elsif ($context eq 'requestauthor') {
                 $output .= '<h3>'.&mt('Requests for Authoring Space queued pending approval by a Domain Coordinator').'</h3>';
+            } elsif ($context eq 'requestusername') {
+                $output .= '<h3>'.&mt('Requests for LON-CAPA accounts queued pending approval by a Domain Coordinator').'</h3>';
             } else {
                 $output .= '<h3>'.&mt('Course/Community requests queued pending approval by a Domain Coordinator').'</h3>';
             } 
@@ -398,6 +461,8 @@
                 $output .= &mt('There are currently no requests for official courses awaiting validation.');
             } elsif ($context eq 'requestauthor') {
                 $output .= &mt('There are currently no requests for Authoring Space awaiting approval.');
+            } elsif ($context eq 'requestusername') {
+                $output .= &mt('There are currently no requests for LON-CAPA accounts awaiting approval.');
             } elsif ($context eq 'domain') {
                 $output .= &mt('There are currently no course or community requests awaiting approval.');
             }
@@ -417,6 +482,10 @@
             $output .= &mt('There are currently no enrollment requests awaiting approval.');
         } elsif ($context eq 'pending') {
             $output .= &mt('There are currently no requests for official courses awaiting validation.');
+        } elsif ($context eq 'requestauthor') {
+            $output .= &mt('There are currently no requests for Authoring Space awaiting approval.');
+        } elsif ($context eq 'requestusername') {
+            $output .= &mt('There are currently no requests for LON-CAPA accounts awaiting approval.');
         } else {
             $output .= &mt('There are currently no course or community requests awaiting approval.');
         }
@@ -440,6 +509,9 @@
                    '<th>'.&mt('Date requested').'</th>';
     } elsif ($context eq 'requestauthor') {
         $output .= '<th>'.&mt('Date requested').'</th>';
+    } elsif ($context eq 'requestusername') {
+        $output .= '<th>'.&mt('Date requested').'</th>'.
+                   '<th>'.&mt('Details').'</th>';
     } elsif ($context eq 'pending' || $context eq 'stillpending') {
         $output .= '<th>'.&mt('Institutional code').'</th>'.
                    '<th>'.&mt('Date requested').'</th>'.
@@ -483,12 +555,21 @@
                                     &Apache::loncommon::plainname($request,$dom),
                                     $request,$dom);
                     }
+                } elsif ($context eq 'requestusername') {
+                    if (&Apache::lonnet::homeserver($request,$dom) eq 'no_host') {
+                        my $queued = 'approval';
+                        $approve = $count.':'.$request;
+                        $reject = $request;
+                        $detailslink='<a href="javascript:openusernamereqdisplay('.
+                                     "'$dom','$request','$queued'".');">'.$request.'</a>';
+                        $namelink = $request;
+                    }
                 } else {
                     my ($cnum,$ownername,$ownerdom,$type,$cdesc);
-                    my $queue = 'approval'; 
+                    my $queued = 'approval'; 
                     if ($context eq 'pending' || $context eq 'stillpending') {
                         ($cnum,$ownername,$ownerdom,$instcode,$cdesc)=split(/:/,$request,5);
-                        $queue = 'pending';                        
+                        $queued = 'pending';                        
                     } else {
                         ($cnum,$ownername,$ownerdom,$type,$cdesc)=split(/:/,$request,5);
                         $crstype = $type;
@@ -497,7 +578,7 @@
                         }
                     }
                     $detailslink='<a href="javascript:opencoursereqdisplay('.
-                                  "'$dom','$cnum','$queue'".');">'.$cdesc.'</a>';
+                                  "'$dom','$cnum','$queued'".');">'.$cdesc.'</a>';
                     $approve = $count.':'.$cnum;
                     $reject = $cnum;
                     $namelink = &Apache::loncommon::aboutmewrapper(
@@ -519,6 +600,9 @@
                             '<td>'.$showtime.'</td>'."\n";
                 } elsif ($context eq 'requestauthor') {
                     $row .= '<td>'.$showtime.'</td>'."\n";
+                } elsif ($context eq 'requestusername') {
+                    $row .= '<td>'.$showtime.'</td>'."\n".
+                            '<td>'.$detailslink.'</td>'."\n";
                 } else { 
                     if ($context eq 'pending' || $context eq 'stillpending') {
                         $row .= '<td>'.$instcode.'</td>'."\n";
@@ -550,15 +634,13 @@
         %communityroles,%domdefs,%approvalmsg,%rejectionmsg,$crstype,$queue,
         $firsturl,$uniquecode,%codes);
     my $count=0;
-    while (my @course = &Apache::loncommon::get_env_multiple('form.'.$count.'radioreq')) {
-        if ($course[0] =~ /^\d+:.*/) {
-            push(@approvals,$course[0]);
-        } elsif ($course[0] =~ /^later:.*/) {
-            #decide later
-        } else {
-            push(@rejections,$course[0]);
+    while (my $item = $env{'form.'.$count.'radioreq'}) {
+        if ($item =~ /^\d+:/) {
+            push(@approvals,$item);
+        } elsif ($item !~ /^later:/) {
+            push(@rejections,$item);
         }
-        $count+=1;
+        $count ++;
     }
 
     $now = time;
@@ -609,6 +691,31 @@
                             mt => 'Your request for Authoring Space has not been approved.',
                         }];
         $domdesc = &Apache::lonnet::domain($cdom);
+    } elsif ($context eq 'requestusername') {
+        $namespace = 'usernamequeue';
+        $beneficiary = 'requestusername';
+        %requesthash = &Apache::lonnet::dump_dom($namespace,$cdom);
+        my %domconfig = &Apache::lonnet::get_dom('configuration',['usercreation'],$cdom);
+        if (ref($domconfig{'usercreation'}) eq 'HASH') {
+            if (ref($domconfig{'usercreation'}{'cancreate'}) eq 'HASH') {
+                if (ref($domconfig{'usercreation'}{'cancreate'}{'notify'}) eq 'HASH') {
+                    $notifylist = $domconfig{'usercreation'}{'cancreate'}{'notify'}{'approval'};
+                }
+            }
+        }
+        my $domconfiguser = &Apache::lonnet::get_domainconfiguser($cdom);
+        $firsturl = &course_portal_url($domconfiguser,$cdom);
+        $approvedmsg = [{
+                            mt => 'Your request for a LON-CAPA account has been approved.',
+                        },
+                        {
+                            mt   => 'Visit [_1] to log-in.',
+                            args => [$firsturl],
+                        }];
+        $rejectedmsg =  [{
+                            mt => 'Your request for a LON-CAPA account has not been approved.',
+                        }];
+        $domdesc = &Apache::lonnet::domain($cdom);
     } else {
         $domdesc = &Apache::lonnet::domain($cdom);
         $namespace = 'courserequestqueue';
@@ -732,9 +839,6 @@
                     if (&Apache::lonnet::allowed('cau',$cdom)) {
                         if (&Apache::lonnet::assignrole($cdom,$uname,'/'.$cdom.'/','au',undef,time,undef,undef,'requestauthor') eq 'ok') {
                             push(@completed,$uname);
-                            unless (&Apache::lonnet::del_dom($namespace,[$uname.'_approval'],$cdom) eq 'ok') {
-                                push(@warn_dels,$uname);
-                            }
                             &send_selfserve_notification($uname.':'.$cdom,
                                                          $approvedmsg,undef,undef,$now,
                                                          $beneficiary,$sender);
@@ -749,7 +853,7 @@
                             my $userresult =
                                 &Apache::lonnet::put('requestauthor',\%userrequest,$cdom,$uname);
                             if ($userresult ne 'ok') {
-                                push(@warn_approves,$item);
+                                push(@warn_approves,$uname.':'.$cdom);
                             }
                         } else {
                             push(@processing_errors,$uname);
@@ -764,6 +868,56 @@
                 push(@invalidusers,$uname.':'.$cdom);
             }
             push(@toremove,(@invalidusers, at nopermissions));
+        } elsif ($context eq 'requestusername') {
+            my ($num,$uname) = split(/:/,$item);
+            my $dbname = 'nohist_requestedusernames';
+            my $domconfiguser = &Apache::lonnet::get_domainconfiguser($cdom);
+            my %curr = &Apache::lonnet::get($dbname,[$uname],$cdom,$domconfiguser);
+            
+            if (ref($curr{$uname}) eq 'HASH') {
+                my ($username,$logtoken,$serverid,$encpass,$courseid,$id,$firstname,
+                    $middlename,$lastname,$generation);
+                $curr{$uname}{'timestamp'} = $now;
+                $curr{$uname}{'adjudicator'} = $env{'user.name'}.':'.$env{'user.domain'};
+                $courseid   = $curr{$uname}{'courseid'};
+                $id         = $curr{$uname}{'id'};
+                $firstname  = $curr{$uname}{'firstname'};
+                $middlename = $curr{$uname}{'middlename'};
+                $lastname   = $curr{$uname}{'lastname'};
+                $generation = $curr{$uname}{'generation'};
+
+                my ($key,$caller)=split(/&/,$curr{$uname}{'tmpinfo'});
+                if ($caller eq 'createaccount') {
+                    my $upass = &Apache::loncommon::des_decrypt($key,$curr{$uname}{'upass'});
+                    undef($curr{$uname}{'upass'});
+                    my $result =
+                        &Apache::lonnet::modifyuser($cdom,$uname,$id,'internal',$upass,
+                                                    $firstname,$middlename,$lastname,
+                                                    $generation,undef,undef,$uname);
+                    if ($result eq 'ok') {
+                        $curr{$uname}{'status'} = 'created';
+                        push(@completed,$uname); 
+                        my $uhome = &Apache::lonnet::homeserver($uname,$cdom);
+                        if ($uhome eq 'no_host') {
+                            push(@warn_approves,$uname);
+                        } else {
+                            &send_selfserve_notification($uname.':'.$cdom,
+                                                         $approvedmsg,undef,undef,$now,
+                                                         $beneficiary,$sender);
+                            if (&Apache::lonnet::put($dbname,\%curr,$cdom,$domconfiguser) ne 'ok') {
+                                push(@warn_approves,$uname);
+                            }
+                        }
+                    } else {
+                        push(@processing_errors,$uname);
+                    }
+                } else {
+                    push(@processing_errors,$uname);
+                }
+            } else {
+                push(@invalidusers,$uname);
+            }
+            push(@toremove, at invalidusers);
         } else {
             my ($num,$cnum) = split(':',$item);
             if (ref($requesthash{$cnum.'_'.$queue}) eq 'HASH') {
@@ -899,20 +1053,24 @@
         @changes = map {$_.'_'.$queue} (@changes);
     } elsif ($context eq 'requestauthor') {
         @changes = map {$_.'_approval'} (@changes);
+    } elsif ($context eq 'requestusername') {
+        @changes = map {&escape($_).'_approval'} (@changes);
     }
     if (@rejections) {
         foreach my $item (@rejections) {
             if (($context eq 'course') || ($context eq 'requestauthor')) {
-                my ($user,$uname,$udom,%userrequest,$key);
+                my ($user,$uname,$udom,%userrequest,$key,$dbname);
                 if ($context eq 'requestauthor') {
                     $uname = $item;
                     $udom = $cdom;
                     $user = $uname.':'.$udom;
                     $key = 'author';
+                    $dbname = 'requestauthor';
                 } else {
                     $user = $item;
                     ($uname,$udom) = split(/:/,$user);
                     $key = $cdom.'_'.$cnum;
+                    $dbname = $namespace;
                 }
                 &send_selfserve_notification($user,$rejectedmsg,$cid,$coursedesc,
                                              $now,$beneficiary,$sender,undef,undef,
@@ -928,10 +1086,29 @@
                     $userrequest{'author_status'} = 'rejection';  
                 }
                 my $userresult =
-                    &Apache::lonnet::put('requestauthor',\%userrequest,$udom,$uname);
+                    &Apache::lonnet::put($dbname,\%userrequest,$udom,$uname);
                 if ($userresult ne 'ok') {
                     push(@warn_rejects,$item);
                 }
+            } elsif ($context eq 'requestusername') {
+                my ($uname,$udom,$dbname);
+                $uname = $item;
+                $udom = $cdom;
+                $dbname = 'nohist_requestedusernames';
+                my $domconfiguser = &Apache::lonnet::get_domainconfiguser($cdom);
+                my %curr = &Apache::lonnet::get($dbname,[$uname],$cdom,$domconfiguser);
+                if (ref($curr{$uname}) eq 'HASH') {
+                     $curr{$uname}{'status'} = 'rejected';
+                     $curr{$uname}{'timestamp'} = $now;
+                     $curr{$uname}{'adjudicator'} =  $env{'user.name'}.':'.$env{'user.domain'};
+                     undef($curr{$uname}{'tmpinfo'});
+                     undef($curr{$uname}{'upass'}); 
+                }
+                my $userresult =
+                    &Apache::lonnet::put($dbname,\%curr,$cdom,$domconfiguser);
+                if ($userresult ne 'ok') {
+                    push(@warn_rejects,$uname);
+                }
             } else {
                 my $cnum = $item;
                 if (ref($requesthash{$cnum.'_'.$queue}) eq 'HASH') {
@@ -994,16 +1171,29 @@
         }
     }
     if (@toremove) {
+        my $domconfiguser = &Apache::lonnet::get_domainconfiguser($cdom);
         foreach my $item (@toremove) {
-            my %userrequest = (
-                author => {
-                            timestamp   => $now,
-                            adjudicator => $env{'user.name'}.':'.$env{'user.domain'},
-                            status      => 'deleted',
-                          },
-                          author_status => 'deleted',
-            );
-            &Apache::lonnet::put('requestauthor',\%userrequest,$cdom,$item);
+            if ($context eq 'requestauthor') {
+                my %userrequest = (
+                    author => {
+                                timestamp   => $now,
+                                adjudicator => $env{'user.name'}.':'.$env{'user.domain'},
+                                status      => 'deleted',
+                              },
+                              author_status => 'deleted',
+                );
+                &Apache::lonnet::put('requestauthor',\%userrequest,$cdom,$item);
+            } elsif ($context eq 'requestusername') {
+                my $dbname = 'nohist_requestedusernames';
+                my %curr = &Apache::lonnet::get($dbname,[$item],$cdom,$domconfiguser);
+                if (ref($curr{$item}) eq 'HASH') {
+                    $curr{$item}{'status'} = 'deleted';
+                    $curr{$item}{'timestamp'} = $now;
+                    $curr{$item}{'adjudicator'} = $env{'user.name'}.':'.$env{'user.domain'};
+                    undef($curr{$item}{'upass'});
+                    undef($curr{$item}{'tmpinfo'}); 
+                }
+            }
         }
         @toremove = map {$_.'_approval'} (@toremove);
         my $delresult = &Apache::lonnet::del_dom($namespace,\@toremove,$cdom);
@@ -1077,6 +1267,30 @@
                                                  $now,'authormanagers',$sender,
                                                  $approvedlist,$rejectedlist);
                 }
+            } elsif ($context eq 'requestusername') {
+                $chgmsg = "'Action was taken on the following LON-CAPA account requests by [_1].',$namelink";
+                if (@completed) {
+                    $approvedlist = join("\n", at completed);
+                    $output .= '<p>'.&mt('The following requests were approved:').'<ul>';
+                    foreach my $uname (@completed) {
+                        $output .= '<li>'.$uname.'</li>';
+
+                    }
+                    $output .= '</ul></p>';
+                }
+                if (@rejections) {
+                    $rejectedlist = join("\n", at rejections);
+                    $output .= '<p>'.&mt('The following requests were rejected:').'<ul>';
+                    foreach my $uname (@rejections) {
+                        $output .= '<li>'.$uname.'</li>';
+                    }
+                    $output .= '</ul></p>';
+                }
+                if ($notifylist ne '') {
+                    &send_selfserve_notification($notifylist,$chgmsg,undef,$domdesc,
+                                                 $now,'usernamemanagers',$sender,
+                                                 $approvedlist,$rejectedlist);
+                }
             } else {
                 $chgmsg = "'Action was taken on the following course and community requests by [_1].',$namelink";
                 if (@completed) {
@@ -1118,6 +1332,10 @@
                                                  $approvedlist,$rejectedlist,$crstype);
                 }
             }
+        } else {
+            if (($context eq 'requestauthor') || ($context eq 'requestusername')) {
+                push(@warn_dels, at changes);
+            }
         }
     }
     if (@existing) {
@@ -1237,6 +1455,12 @@
                 $output .= '<li>'.$userlink.'</li>';
             }
             $output .= '</ul></p>';
+        } elsif ($context eq 'requestusername') {
+            $output .= '<p>'.&mt('The following requests could not be processed because an error occurred:').'<ul>';
+            foreach my $uname (@processing_errors) {
+                $output .= '<li>'.$uname.'</li>';
+            }
+            $output .= '</ul></p>';
         } else {
             $output .= '<p>'.&mt('The following course/community creation requests could not be processed because an error occurred:').'<ul>';
             foreach my $cnum (@processing_errors) {
@@ -1279,6 +1503,12 @@
                 $output .= '<li>'.$userlink.'</li>';
             }
             $output .= '</ul></p>';
+        } elsif ($context eq 'requestusername') {
+            $output .= '<p>'.&mt("For the following users, an error occurred when updating the account request record for the user:").'<ul>';
+            foreach my $uname (@warn_approves, at warn_rejects) {
+                $output .= '<li>'.$uname.'</li>';
+            }
+            $output .= '</ul></p>';
         } else {
             $output .= '<p>'.&mt("For the following course/community requests an error occurred when updating the requestor's own requests record:").'<ul>';
             foreach my $cnum (@warn_approves, at warn_rejects) {
@@ -1302,6 +1532,13 @@
                 $output .= '<li>'.$userlink.'</li>';
             }
             $output .= '</ul></p>';
+        } elsif ($context eq 'requestusername') {
+            $output .= '<p>'.&mt("For the following requests an error occurred when removing the request from the queue:").'<ul>';
+            foreach my $item (@warn_dels) {
+                my ($escuname) = split(/_/,$item);
+                $output .= '<li>'.&unescape($escuname).'</li>';
+            }
+            $output .= '</ul></p>';            
         } else {
             $output .= '<p>'.&mt("For the following course/community requests an error occurred when removing requests from the pending queue:").'<ul>';
             foreach my $cnum (@warn_dels) {


More information about the LON-CAPA-cvs mailing list