<?php
/********************

   Engsoc PHP Registry

 Copyright 2000 Philip Steinke and Kevin Everets
 Licensed under the GNU General Public License

********************/ 
include ('includes/header.inc.php'); 
disp_header("Create an Account");

include (
'includes/dbform.inc.php');

# addStep controls our flow through the add a new user process.
# The flow is as follows:
# pickHandle -> checkHandle -> enterPassword -> checkPassword -> getInfo ->
# createAcct
#
# Prompts and forms are contained in the dbform.inc.php file.

switch ($addStep) {
    case 
"checkHandle":
        
// convert all letters to lowercase
        
$handle strtolower($handle);
        
// check handle
        // rough check to make sure it's a valid email address
        
if (!preg_match("/^[a-z][a-z0-9\-]*$/"$handle$parts)) {
            
// user entered something that can't be an email address.  
            // print a "sorry you must use one word" message 
?>
<p>
    The handle you entered cannot be used.  Please begin with a letter, and
    use a combination of letters, numbers, and the &quot;<tt>_ -</tt>&quot;
    (underscore and hyphen) characters.  Spaces are not allowed.
</p>
<?php         // done printing message
            
handle_prompt();
            break;
        }
        
// see if it's already taken -- this chunk should probably be moved
        // into its own function
        
$taken false;
        
// Build a list of invalid handles from system accounts and aliases.
        
$system_files = array(
            
'/etc/passwd'
            
'/etc/aliases'
            
'/etc/aliases.registry',
            
'/etc/aliases.mailman');
        foreach (
$system_files as $file) {
            
$size filesize($file);
            
$fp fopen($file'r');
            while (
$data_line fgetcsv($fp$size':')) {
                if (
ereg('^[^[:blank:]#]'$data_line[0])) {
                    
$bad_handles[] = $data_line[0];
                }
            }
            
fclose($fp);
        }
        
// Stop people from using a class name as their handle.
        
for ($i '00'$i 100$i++) {
            
$bad_handles[] = "sci$i";
        }
        
// Do a database check.
        
$handle_check $regdb->getOne("SELECT handle FROM people 
                                        WHERE handle='$handle'"
);
        if ((
$handle_check == $handle)
            || 
in_array($handle$bad_handles)) {
            
// found this handle already in registry or a system file
            // print a "sorry your handle is taken" messsage 
?>
<p>
    The handle you entered has already been taken.  Please choose another.
    Here are some similar handles that are still available:
    <ul>
<?php        // done printing message
            
$taken true;
            
preg_match("/(.*)(\d*)$/"$handle$parts);
            
// feeling a bit of indecision here.  If we use SQL 'LIKE'
            // for all pattern matching it's very portable, but not too
            // powerful.  On the other hand, if we use Postgres's '~'
            // and '~*' operators we can use regexp's, but it'll only
            // work with Postgres.  Others do regexp's, but in different
            // ways (e.g. MySQL uses 'REGEXP').
            // I'm going to go with SQL 'LIKE' for now.
            
$handle_root $parts[1];
            
$query "select handle from people 
                      where handle like '$handle_root%'"
;
            
$taken_handles $regdb->query($query);
            
$nextavail 1;
            
$_taken false;
            while (
$similar_row 
                           
$taken_handles->fetchRow(DB_FETCHMODE_ASSOC)) {
                
$similar $similar_row['handle'];
                if (
preg_match("/$handle_root(\d+)$/"$similar$parts)) {
                    if (
$parts[2] > $nextavail) {
                        
$nextavail $parts[2] + 1;
                    }
                } elseif (
preg_match("/$handle_root\_$/"$similar$parts)) {
                    
$_taken true;
                }
            } 
// end while going through similar matches
            
echo "\t\t<li>$handle_root$nextavail\n";
            if (!
$_taken) {
                echo 
"\t\t<li>${handle_root}_\n";
            }
            echo 
"\t</ul>\n";
            
// Re-display the handle prompt and break out of the switch.
            
handle_prompt();
            break;
        } 
// end seeing if it's already taken
        // Handle wasn't taken, carry on to the password prompt.
    
case "enterPassword":
        
// get password
        // display password choosing message 
?>
<p>
    Your password is what keeps others from using your account.  It has to 
</p>
<ol>
    <li>be at least 6 characters long,</li>
    <li>have no relation to your handle and</li>
    <li>contain at least one non-letter character.</li>
</ol>
<?php    // end password choosing message
        
password_prompt();
        break;
    case 
"checkPassword":
        
// check password
        
if ($password[1] != $password[2]) {
            
// print password not matching error ?>
<p>
    The passwords you entered didn't match.  Please try again.
</p>
<?php        // end not matching message
            
password_prompt();
            break;
        } 
        
// matching passwords were entered.  check to make sure they're
        // secure.  Figured cracklib is overkill.  Just do some simple
        // checks.
        
$password $password[1];
        list(
$pwfail$reason) = password_check($password);
        if (
$pwfail) {
            
// print error message and prompt user ?>
<p>
    The password you entered is <?php echo $reason ?>.<br>
    Please choose another.
</p>
<?php        // end of error message
            
password_prompt();
            break;
        }
    case 
"getInfo":
        
$reqimg "<img src=\"images/checkmark.png\" alt=\"->\" />";
        
// get info ?>
<p>
    Now for the juicy bits.  Here you get to supply the info that will be
    stored in the registry.  Required fields are marked with a <?php echo
    
$reqimg ?>
</p>
<p>
    The "Publish" column along the right hand side
    lets you decide how much of your information you want others to see.  If
    you opt not to publish an item, it will only be used in general reports
    like "Sci'00 has 20 people in Finland," or "There are 30 mechanical
    grads employed at Pratt &amp; Whitney."
</p>
<?php    // end of intro text
        
build_dbform('all');
        break;
    case 
"createAcct":
        
// write info to db and create system account
        // format date entries for db entry, check for empty required
        // fields, and count the number of empty address fields we need to
        // prompt for.
        
        // Check out how many other people there are with
        // this name
        
$dupnum 0;
        
$query "SELECT dupnum FROM people 
                  WHERE lower(first_name)='"
.strtolower($first_name)."' 
              AND lower(last_name)='"
.strtolower($last_name)."'";
        
$dupresults $regdb->query($query);
        while (
$row $dupresults->fetchRow()) {
            
$dupnum++;
        }
        
$dupresults->free();
        
check_info();
        if (isset(
$need)) {
            
// some required fields are missing; prompt them for info ?>
<p>
    Some required information is missing.  Please complete all shown
    sections:
</p>
<?php        // display form
            
build_dbform('req');
        } else {
            
// put info in db and show closing message
            
$listlen strlen($fieldList) - 2;
            
$fieldList substr($fieldList0$listlen);
            
$listlen strlen($values) - 2;
            
$values substr($values0$listlen);
            
$addsql "INSERT INTO people 
                        ($fieldList, newuser) 
                        VALUES ($values, 'true')"
;
            
$fieldList "handle, ";
            
$values "'$handle', ";
            foreach (
$publish as $field) {
                
$fieldList .= "$field, ";
                
$values .= "'true', ";
            }
            
$listlen strlen($fieldList) - 2;
            
$fieldList substr($fieldList0$listlen);
            
$listlen strlen($values) - 2;
            
$values substr($values0$listlen);
            
$pubsql "INSERT INTO publish
                        ($fieldList) 
                        VALUES ($values)"
;
            
$insResult $regdb->query($addsql);
            if (!
DB::isError($insResult)) {
                
$addok true;
            }
            if (
$addok) {
                
$insResult $regdb->query($pubsql);
                if (!
DB::isError($insResult)) {
                    
$pubok true;
                }
            }
            if (
$addok && $pubok) {
            
// spit out a congrats and please wait till you're authenticated
            // message 
?>
<p>
    Congratulations, your information has been added to the registry.
</p>
<p>
    Your email addresses are <tt><?php echo $handle'@' $reg_domain ?></tt>
    and <tt><?php 
        $alias 
"$first_name $last_name";
        if (
$dupnum$alias .= $dupnum;
        echo 
strtolower(preg_replace("/ /""."$alias));
        echo 
"@$reg_domain"?></tt>
</p>
<p>
    You will not be able to log into the registry until your information has
    been validated by your year executive.  Once you've been approved, your
    <tt>@<?php echo $reg_domain ?></tt> email addresses and registry access will be
    enabled.  An email will be sent to your preferred account once your
    application has been reviewed.
</p>
<p>
    <a href="index.php">Return to the login page.</a>
</p>
<?php    // Send a notification message to this person's administrator.
        // Find out who the admins are for this year, and get their
        // preferred email addresses.
        
$query "SELECT handle FROM people 
                  WHERE admin='t' AND class='$class'"
;
        
$result $regdb->query($query);
        while (
$row $result->fetchRow()) {
            
$notify_email[] = get_preferred_email($row[0]);
        }
        
$result->free();
        foreach (
$master_admins as $admin_handle) {
            
$master_email[] = get_preferred_email($admin_handle);
        }
        if (
sizeof($notify_email) == 0) {
            
$notify_email $master_email;
        }
        
// Set up the mail headers.
        
$notify_to implode(', '$notify_email);
        
$notify_from $maint_mail;
        
$notify_body "Greetings, $first_name $last_name has just
applied for registry access.  Please visit
http://$SERVER_NAME/ to authenticate or remove them.\n"
;
        
# DEBUG $notify_body .= "SQL for add:\n";
        # DEBUG $notify_body .= $addsql . "\n\n" . $pubsql . "\n\n";
        
mail($notify_to"New Engsoc Registry Applicant",
            
$notify_body"From: $notify_from");
        
// user has been added.  That's all, folks!
        
} else { // User wasn't added to the DB successfully
            
print "<p>An error occurred when trying to put your
            information in the database.  Please use your 'back'
            button and try re-submitting the form.</p>\n"
;
            
// Set up the mail headers.
            
$notify_to $maint_mail;
            
$notify_from $maint_mail;
            
$notify_body "Greetings, $first_name $last_name just
had their info screw up the database:
$addsql\n\n$pubsql\n\n"
;
            
mail($notify_to"New Engsoc Registry Applicant",
            
$notify_body"From: $notify_from");
        }
        }
        break;
    case 
"pickHandle":
    default: 
        
// display initial handle-choosing message ?>
<h2>Step 1: Pick a Handle</h2>
<p>
    Please note - the registry is currently only available for alumni use.
</p>
<p>
    Your handle is your login name for the registry.  Along with being in
    the registry, you'll get an email account that uses two addresses.  One
    is your handle and the other is your real name, each followed by
    <tt>@<?php echo $reg_domain ?></tt>.  
</p>
<p>
    For example if Joe Rokinski were to add himself, he might pick
    "rockinjoe" as his handle.  If there were already one Joe Rokinski
    in the registry, he would then have <tt>rockinjoe@<?php echo
    
$reg_domain ?></tt> as well as <tt>joe.rokinski2@<?php echo
    
$reg_domain ?></tt> as his email addresses.
</p>
<p>
    Please enter your handle now.  The registry will check to see if it's
    already in use.  Should someone else have taken your name of
    choice the registry will try to present some similar alternatives.
</p> 
<?php    // done handle-choosing message
        
handle_prompt();
// end switch
include ('includes/footer.inc.php'); ?>