#!/util/perl/bin/perl


require( 'config.pl' );






&checkWritable;



# Open & read the data file.
open( hDataFile, "<$DATA_FILE" ) || die;
flock( hDataFile, LOCK_SH );
@dataFile = <hDataFile>;
flock( hDataFile, LOCK_UN );
close( hDataFile );


&parse;



# If the administrator password was sent, but not the action specifier, then
# check the password and show the database and options.

if ( defined $FORM{'password'} && !defined $FORM{'action'} ) {

    &checkPassword( $FORM{'password'} );
    &showDatabaseAndOptions( "" );



# If the administrator password was sent along with the action specifier,
# then check the password and call the apropriate method to deal with the
# requested action.

} elsif ( defined $FORM{'password'} && defined $FORM{'action'} ) {


    &checkPassword( $FORM{'password'} );
    if ( $FORM{'action'} eq 'delete_record' ) {
        &deleteRecord;
    } elsif ( $FORM{'action'} eq 'change_user_password' ) {
        &changeUserPassword;
    } elsif ( $FORM{'action'} eq 'create_new_user' ) {
        &createNewUser;
    } elsif ( $FORM{'action'} eq 'change_admin_password' ) {
        &changeAdminPassword;
    } else {
        print "Content-type: text/html\n\n";
        print "<html><body><center><b>";
        print "Internal error: invalid action specifier - $FORM{'action'}";
        print "</b></center></body></html>";
    }



# If the administrator password was not present, then return a form to
# send the password back to this script.

} else {
    &promptForPassword;
}



# Explicitly clear the dataFile array from memory... just in case.
undef @dataFile;
exit( 0 );




sub checkPassword {



    # Crypt the sent password; retrieve the stored password.
    $sentPassword = crypt( $_[ 0 ], $SALT_CHARS );
    $storedPassword = $dataFile[ 0 ];
    chomp( $storedPassword );


    # If the stored password does not match the crypted sent password...
    if ( !( $sentPassword eq $storedPassword ) ) {
        print "Content-type: text/html\n\n";
        print "<html><br><br><br><br><center><b>Incorrect password.</b></center></html>";
        exit( 0 );
    }



}




sub promptForPassword {


    print "Content-type: text/html\n\n";


    print "<html>\n\n<head>\n<title>Authorization required</title>\n</head>\n\n<br><br><br><br>\n\n";
    print "<center>The administrator password is required to edit the user database.</center>\n\n";

    print "<form action=\"$PROTOCOL$HOSTNAME$ADMIN_SCRIPT\" method=\"POST\">\n";
    print "<center><input type=\"password\" name=\"password\"><input type=\"submit\" value=\"login!\"></center>\n";

    print "</form>\n\n</html>";


}




sub showDatabaseAndOptions {



    print "Content-type: text/html\n\n";
    print "<html><head>";



############################
    $javaScript =<< "END_JAVASCRIPT";
<script language="JavaScript" type="text/javascript">


function passwordButtonClicked( i ) {



    if ( i == 666 && document.theForm.newUserName.value == "" ) {
        alert( "You must enter the name of the new user first!" );
        return;
    }


    var passwordOne = prompt( "Enter the new password for this entry:", "" );
    if ( passwordOne == null )  return;

    var passwordTwo = prompt( "Enter the new password again to verify:", "" );
    if ( passwordTwo == null )  return;
    

    if ( passwordOne == passwordTwo ) {
        document.theForm.record.value = i;
        document.theForm.userPassword.value = passwordOne;


        if ( i == 666 )
            document.theForm.action.value = "create_new_user";
        else if ( i == 0 )
            document.theForm.action.value = "change_admin_password";
        else
            document.theForm.action.value = "change_user_password";


        document.theForm.submit();
    } else
        alert( "Error: passwords do not match!  Database will not be modified." );


    // OCD:  I've been programming in C++ too much lately...
    passwordOne = null;
    passwordTwo = null;


}



function deleteButtonClicked( i ) {


    if ( confirm( "Are you sure you want to delete this record?" ) ) {
        document.theForm.record.value = i;
        document.theForm.action.value = "delete_record";
        document.theForm.submit();
    }
    

}

</script>
END_JAVASCRIPT
############################


    print $javaScript;
    print "<title>Administration</title></head><body><br><br><br>\n\n";

    print "<form action=\"$PROTOCOL$HOSTNAME$ADMIN_SCRIPT\" method=\"POST\" name=\"theForm\">";

    if (!( $_[ 0 ] eq "" )) {  print "<center><b>$_[ 0 ]</b></center>";  }



    print "<table>\n";
    print "<tr>";
    print "<td><b>Administrator</b></td>";
    print "<td><input type=\"button\" name=\"pwButton_0\" value=\"Change Password...\" onClick=\"passwordButtonClicked( 0 );\"></td>";
    print "<td>&nbsp;</td>";
    print "</tr>";


    # Start with the second entry (index #1), because the first entry (index #0)
    # is the administrator password.

    for( $p = 1; $p < scalar @dataFile; $p++ ) {

        @dataLine = split( /\|/, $dataFile[ $p ] );
        print "<tr>";
        print "<td>$dataLine[ 0 ]</td>";
        print "<td><input type=\"button\" name=\"pwButton_$p\" value=\"Change Password...\" onClick=\"passwordButtonClicked( $p );\"></td>";
        print "<td><input type=\"button\" name=\"delButton_$p\" value=\"Delete\" onClick=\"deleteButtonClicked( $p );\"></td>";
        print "</tr>\n";
        undef $dataLine;

    }


    print "</table>";


    print "<br><br><center><b>Create a new roster entry</b>:<br><br>";


    print "<table>";
    print "<tr><td>Name of new user:</td><td><input type=\"text\" name=\"newUserName\"></td></tr>";
    print "<tr><td>&nbsp;</td><td><input type=\"button\" name=\"pwButton_newUser\" value=\"Set password...\" onClick=\"passwordButtonClicked( 666 );\"></td></tr>";
    print "</table></center>";



    print "<input type=\"hidden\" name=\"record\">";
    print "<input type=\"hidden\" name=\"userPassword\">";
    print "<input type=\"hidden\" name=\"password\" value=\"$FORM{'password'}\">";
    print "<input type=\"hidden\" name=\"action\">";
    print "</form><br><br><br><br><center><a href=\"http://$HOSTNAME$VIEW_SCRIPT\">View Roster</a></center></body></html>";


}




sub deleteRecord {


    $record = int( $FORM{'record'} );
    if ( $record <= 0 ) {  $record = 1;  }
    if ( $record >= scalar @dataFile ) {  $record = 1;  }


    # Remove the specified record, and re-write the database.

    for( $p = 0; $p < $record; $p++ ) {
        push( @tempArray, $dataFile[ $p ] );
    }


    for( $p = $record + 1; $p < scalar @dataFile; $p++ ) {
        push( @tempArray, $dataFile[ $p ] );
    }


    open( hDataFile, ">$DATA_FILE" ) || die;
    flock( hDataFile, LOCK_EX );
    print hDataFile @tempArray;
    flock( hDataFile, LOCK_UN );
    close( hDataFile );


    @dataFile = @tempArray;
    &showDatabaseAndOptions( "Deleted record." );


}




sub changeUserPassword {



    $record = int( $FORM{'record'} );
    if ( $record <= 0 ) {  $record = 1;  }
    if ( $record >= scalar @dataFile ) {  $record = 1;  }



    $cryptedUserPassword = crypt( $FORM{'userPassword'}, $SALT_CHARS );
    $theLine = $dataFile[ $record ];

    @dataFields = split( /\|/, $theLine );
    $dataFields[ 11 ] = $cryptedUserPassword;
    $theUser = $dataFields[ 0 ];


    $theLine = join( '|', @dataFields );    
    undef @dataFields;



    for( $p = 0; $p < $record; $p++ ) {
        push( @tempArray, $dataFile[ $p ] );
    }


    push( @tempArray, $theLine );
    undef $theLine;


    for( $p = $record + 1; $p < scalar @dataFile; $p++ ) {
        push( @tempArray, $dataFile[ $p ] );
    }



    @dataFile = @tempArray;
    undef @tempArray;


    open( hDataFile, ">$DATA_FILE" ) || die;
    flock( hDataFile, LOCK_EX );
    print hDataFile @dataFile;
    flock( hDataFile, LOCK_UN );
    close( hDataFile );



    &showDatabaseAndOptions( "Successfully changed password for \"$theUser\"." );


}




sub createNewUser {



    $cryptedUserPassword = crypt( $FORM{'userPassword'}, $SALT_CHARS );
    $newEntry = "$FORM{'newUserName'}|||||||||||$cryptedUserPassword|\n";


    open( hDataFile, ">>$DATA_FILE" ) || die;
    flock( hDataFile, LOCK_EX );
    print hDataFile $newEntry;
    flock( hDataFile, LOCK_UN );
    close( hDataFile );


    push( @dataFile, $newEntry );
    &showDatabaseAndOptions( "Successfully created user \"$FORM{'newUserName'}\"." );



}




sub changeAdminPassword {



    $cryptedAdminPassword = crypt( $FORM{'userPassword'}, $SALT_CHARS );
    $dataFile[ 0 ] = $cryptedAdminPassword . "\n";


    # Open & save the data file.
    open( hDataFile, ">$DATA_FILE" ) || die;
    flock( hDataFile, LOCK_EX );
    print hDataFile @dataFile;
    flock( hDataFile, LOCK_UN );
    close( hDataFile );


    $FORM{'password'} = $FORM{'userPassword'};
    &showDatabaseAndOptions( "Administrator password successfully changed." );

}
