Saturday, October 29, 2011

Security Points

The first point, about the security of my web site, is that Active Math Java is a test bed for code developed for the Rasch-ItemBank open source project. It is intended as a free resource for use by any child anywhere in the world with access to a computer connected to the Internet and running Java.

So the purpose of my login page is not to secure a web resource for which users pay money. Nor is it like a forum, where the login page protects the forum from spammers. It is simply there for the convenience of certain users who have requested the ability to track the performance of their children.

The second point, about the security of web sites in general, is that secure pages usually include a server side script, such as PHP, and if security is desired, all the pages have to be in the same or compatible format.

Using PHP has some advantages, besides security, such as retaining variables across pages, within sessions.

I have enjoyed writing business rules in JavaScript, for a mock login page and a mock add user page, because I have never liked JavaScript, and I enjoyed getting something to work with it. However, I am now resigned to rewriting everything in PHP, not for security, but for the convenience of retaining and passing variables about the place.

Oh boy am I glad this is a blog about learning Java and related languages and not a formal lesson. If it were a formal lesson, any readers might be really pissed off by now, because I have done about 3 180 degree turns.

Friday, October 28, 2011

Add User to Database

Having created an HTML layout and an external CSS page, and having written business rules for a login page, creating a page with a form to add users to the database was relatively easy.

The layout was almost identical to the login screen, except for what I call combo boxes for the age of the student users, and to comply with convention, a password confirmation field. But for that convention, the business rules could have been cut and pasted verbatim from the login page, and that would have made the job nice and easy.

Identification of users is not mission critical for me, and if teachers can't record and type in accurately a password on the first attempt, my first instinct was to say "who cares?". But part of the point of this exercise is to make my web site/application look "professional", so I put in the second field.

The login rules comprised four independent conditions nested within a super condition, triggered by any of the four being met, the alternative (or else) to which was the calling of the database query code. So where to put the fifth condition, the inequality of the passwords?

The nest of four are together because they are not mutually exclusive. Most often the user will click the button with nothing in either field, and you want a message to appear over both fields. Or the name might be too long, and the password field empty.

Technically the fifth condition might overlap with one or more of the other four. For example the password fields may be unequal and too long. But if they are too long, and they are told to make them equal first, they will be annoyed if they are told to shorten them after they have made them equal. I guess if I had enough space for messages I could tell them both, but I don't. So in my business rules they have to get the length right (between 1 and eight characters) first, and then make the passwords match. The rules are as follows:

function busrules(form)
{
var subtype = form.usertype.value;
var subname = form.username.value;
var subpass = form.password.value;
var subpassc = form.passwordc.value;
var subagey = form.ageyears.value;
var subagem = form.agemonths.value;
var showmessn;
var showmessp;
var ubercell1v = document.getElementById("ubercell1").innerHTML;
var ubercell2v = document.getElementById("ubercell2").innerHTML;
var myarg;
if (ubercell1v.length > 0)
{
document.getElementById("ubercell1").innerHTML="";
} //end of null check
if (ubercell2v.length > 0)
{
document.getElementById("ubercell2").innerHTML="";
} //end of null check
if (subname.length > 8 || subname.length ==0 || subpass.length ==0 || subpass.length ==0 )
{
if (subname.length > 8)
{
showmessn = "Your user name is too long. Please use 8 characters.";
document.getElementById("ubercell1").innerHTML=showmessn;
} //end of condition 1
if (subname.length ==0)
{
showmessn = "Oh Dear! You have not entered a user name.";
document.getElementById("ubercell1").innerHTML=showmessn;
} //end of condition 2
if (subpass.length > 8)
{
showmessp = "Your user password is too long. Please use 8 characters.";
document.getElementById("ubercell2").innerHTML=showmessp;
} //end of condition 3
if (subpass.length ==0)
{
showmessp = "Oh Dear! You have not entered a user password.";
document.getElementById("ubercell2").innerHTML=showmessp;
} //end of condition 4
} //end of group of 4 conditions
else if (subpass != subpassc)
{
showmessp = "Oh Dear! You need to enter the same password in both password fields.";
document.getElementById("ubercell2").innerHTML=showmessp;
} //end of condition 5

Then if all those rules are satisfied, the PHP script for the data connection is called:

else { //Code below is to set up parameters for the php script
if (window.XMLHttpRequest) //format and create request variable according to browser type
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
} //end of current option
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
} // end of old option
xmlhttp.onreadystatechange=function()
{ // this code displays response text
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("untencell1").innerHTML=xmlhttp.responseText;
}
} //the code below calls the php script on the server
myarg = "('"+subname+"','"+subpass+"','"+subtype+"',"+subagey+","+subagem+")"
xmlhttp.open("POST","adduser.php?myarg="+myarg,true);
xmlhttp.send();
} //end of master conditional statement
} //end of function

I took the opportunity to tidy up the layout a bit. The "row" divisions I had set up (following the structure of a table) seemed a bit redundant, so I lost them, and I defined the warning divisions more concisely, to stop the form jumping about, when the warnings come up. And I made everything a bit wider:

.inputtable {margin:50; background-color:#BDEDFF}
.row {width:520;}
.col1 {text-align:right; float:left; width:300; height:25; margin:0 5 0 5;}
.col2 {text-align:left; float:right; width:200; margin:0 5 0 5;}
.itext {width:150;}
.cbox {width:150; margin-left:5;}
.warning {color="red";margin-bottom:0;margin-top:0;float:left; width:520; }


The PHP script was similar in structure to the login script, but differed in important details (such as running an INSERT command rather than a SELECT query):

<?php
include('newinfo.php');// collect database variables.
$myarg = $_GET['myarg']; // collect passed variable
// To protect MySQL injection
$myarg = stripslashes($myarg);
// Connect to server and select database.
$con = mysql_connect( $dbhost, $dbuser, $dbpass );
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db($dbname, $con);
$query = "INSERT INTO $table1 (Softid, PartPass, PartType, AgeYears, AgeMonths) VALUES ";
$query = $query . $myarg;
$result = mysql_query($query) or die(mysql_error() . $query );
if($result==1){
echo"<p>Hooray you have added a user</p>";
} else {
echo"<p>Oh Dear! Something went wrong. Query: <br/>$query </p>";
}
mysql_close($con);
?>

If the password were unequal, but everything else correct, the screen looked as shown below:

And after successfully adding a user is looked as shown below:

Wednesday, October 26, 2011

Check Login Details against the Database

After rewriting my business rules in JavaScript, the time now really had come to create the live database interface. So I busily changed the file extension back to .php and added back the include() statement, and started adding PHP code to the JavaScript function called by the button click event, and paused when I needed to pass a javascript variable to PHP. I had a feeling that what I was doing would not work, and a quick Google search confirmed that it would not.

The whole point of converting my business rules to JavaScript was to keep the field input checking local. But as PHP scripts run on the server, you need to call something on the server, and pass any variables to that.

It was a bit frustrating because neither of the login page examples I'd found on the web used any business rules at all; they just called a PHP script from the form submit button, one on the same page, one on another.

As a first pass I tried AJAX.

I had sidestepped the issue in my business rules test page with the line:

alert ("Well Done. Your username and password were correctly entered.");

I now replaced this with:

if (window.XMLHttpRequest) //format and create request variable according to browser type
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
} //end of current option
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
} // end of old option
xmlhttp.onreadystatechange=function()
{ // this code displays response text
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("untencell1").innerHTML=xmlhttp.responseText;
}
} //the code below calls the php script on the server
xmlhttp.open("POST","logincheck.php?id="+subname+"&pw="+subpass,true);
xmlhttp.send();

I also added one more division to receive a message back from the PHP script:

<div id=untencell1></div>

This cell was placed under the button but within the form division. The PHP script was:

<?php
include('newinfo.php');// collect database variables.
$id = $_GET['id']; // collect passed variable 1
$pw = $_GET['pw']; // collect passed variable 2
// To protect MySQL injection
$id = stripslashes($id);
$pw = stripslashes($pw);
// $id = mysql_real_escape_string($id);
// $pw = mysql_real_escape_string($pw);

// Connect to server and select databse.
$con = mysql_connect( $dbhost, $dbuser, $dbpass );
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db($dbname, $con);
$query = "SELECT Softid, PartPass FROM $table1 WHERE Softid = '$id' and PartPass = '$pw'";
$result = mysql_query($query) or die(mysql_error() . $query );
// Mysql_num_row is counting table row
$count=mysql_num_rows($result);
if($count==1){
echo"<p>Hooray you are logged in</p>";
} else {
echo"<p>Oh Dear! Something went wrong. Query: <br/>$query </p>";
}
mysql_close($con);
?>

A couple of things still need fixing. First the user is not taken anywhere useful after logging in successfully. That is because there is currently nowhere to go. The second is that the diagnostic display of the query on login failure needs removing, after everything is definitely working.

After a successful login, the page currently looks as shown below:

Tuesday, October 25, 2011

JavaScript Business Rules

In my last two entries, I created the front end interface for a login screen, and wrote a couple of simple business rules in a PHP script to ensure both username and password fields are filled before running a query on the database. The time has now come to write the query and check it against the field entries.

Reading tutorials on the topic, I am first fascinated by the level of paranoia and then I become paranoid myself. So instead of getting on with writing a query, I add another business rule prohibiting usernames or passwords over eight characters. Eight is the length of the fields in the database, so it is as silly for users to enter 9 characters as no characters, so I might as well stop them doing it. It won't stop every SQL injection exploit, but it will preclude them from attempting to write essays.

I'm looking at a couple of tutorials for inspiration. They both use different SQL injection protection code. One uses the ereg() function, which is apparently being phased out, so I won't use that. The other takes the user to another page on login, which won't work with my business rules code.

I have to say I am not sure why I wrote the business rules into a PHP script. If I used Java Script for the business rules, I could take the user to a new page on successful login, and I could completely avoid unnecessary calls on the server itself, as well as on the database. But it will require a complete rethink.

To start fiddling, I change the login page back to an HTML file and remove all PHP. I then replace the PHP scripted error messages with division placed in the same place. The first is as follows:

<div id=ubercell1 class=warning></div><br/>

In the CSS file the class warning takes the color red. I then reduce the form tag down from:

<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">

to:

<form>

And the button is changed from:

<input type="submit" name="login" value="Log in to Portal" class=itext />

to:

<input type="button" value="Log in to Portal" class=itext onclick="busrules(this.form)" />

And of course the PHP code is replaced by the JavaScript function busrules(form). I spent some time fiddling with the JavaScript, because I don't know it very well. The essential logic is that any one or more of four possible errors will generate a warning and preclude the call to the database. When an error is corrected the warning message must be cleared, but where there is no warning (i.e. if the user gets it right first time) nothing needs to happen. And in this test page, if everything is OK, an alert message says everything is OK.

The rest of the page code remained the same, and the page looked the same, but without needing a call back to the server, the error messages came up a lot quicker than they did using PHP. The full JavaScript was:

<script type="text/javascript">
function busrules(form)
{
var subname = form.username.value;
var subpass = form.password.value;
var showmessn;
var showmessp;
var ubercell1v = document.getElementById("ubercell1").innerHTML;
var ubercell2v = document.getElementById("ubercell2").innerHTML;
if (ubercell1v.length > 0)
{
document.getElementById("ubercell1").innerHTML="";
} //end of null check
if (ubercell2v.length > 0)
{
document.getElementById("ubercell2").innerHTML="";
} //end of null check
if (subname.length > 8 || subname.length ==0 || subpass.length ==0 || subpass.length ==0)
{
if (subname.length > 8)
{
showmessn = "Your user name is too long. Please use 8 characters.";
document.getElementById("ubercell1").innerHTML=showmessn;
} //end of condition 1
if (subname.length ==0)
{
showmessn = "Oh Dear! You have not entered your user name.";
document.getElementById("ubercell1").innerHTML=showmessn;
} //end of condition 2
if (subpass.length > 8)
{
showmessp = "Your user password is too long. Please use 8 characters.";
document.getElementById("ubercell2").innerHTML=showmessp;
} //end of condition 3
if (subpass.length ==0)
{
showmessp = "Oh Dear! You have not entered your user password.";
document.getElementById("ubercell2").innerHTML=showmessp;
} //end of condition 4
} else {
alert ("Well Done. Your username and password were correctly entered.");
} //end of master conditional statement
} //end of function
</script>

Sunday, October 23, 2011

PHP Business Rules

The purpose of the business rules layer is to prevent gibberish being written to a database. If you have a field designated to record currency values, you don't want someone posting a long letter to their mother to it. Of course if you try to write text to a numeric field the database itself will probably reject it, but doing so wastes server resources and risks corrupting the database.

And in an age of web applications, where servers and clients are separated by long distance and heavy traffic, sending redundant requests to the server wastes time and annoys the user.

There are two aspects to the business rules layer:

  1. The coded rules;
  2. The front end manifestation when one or more of the conditions set out in the rules is not met.

In the olden days, if you tried to make an illegal entry into a database field, a new window or dialog box opened up with a rude message, and sometimes the computer would beep at you. The dialog box would then have to be closed manually by the user before they could continue with their work.

Nowadays a more subtle approach is preferred. Usually a message is written on to the data entry form itself, just above or close to the field with the inappropriate or missing entry.

In the case of a login screen, nothing is being written to the database, and a null field is conceptually similar to an incorrect entry, so some applications skip business rules in the login screen and send null fields for checking against the database along with everything else.

My server is particularly slow, and I am always aware of the implicit cost of making unnecessary calls on the database, so I shall write a couple of lines to ensure users at least put something in both username and password fields.

The login screen shown in my previous post was written in HTML and tested at home. I shall now have to migrate across to PHP and as I don't have PHP installed at home, I shall have to work on my web host server.

The PHP script will open with the include() statement and a variable declaration for the error condition:

include('dbinfo.php'); // get database information
$error = false; //boolean used to contain error condition

It will continue with the equivalent of event code for the button click event. In this case there is no need to register an actual event, because the login button is calling the containing page:

<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">

The code for the whole page is rerun when the button is clicked, so there is no need to register the event as such, but rather the condition of having been clicked:

if (isset($_POST['login'])) {
// variables filled with form inputs
$usertype = $_POST['usertype'];
$username = $_POST['username'];
$password = $_POST['password'];
// check that neither field is empty
if ( !empty($firstname) && !empty($lastname) ) {
//run crunchy code
} else {
$error = true; // error condition met
} // end of empty field check
} // end of buttonclicked conditional code

The "crunchy code" will be discussed later. For now, I need to insert a couple of extra lines into the page to use the $error variable. The first insert goes at the top of the <div> I called row2, which holds the username field:

<?php
if ( $error && empty($username) ) {
echo '<span style="gt;Oh Dear! You did not enter your name.</span><br>',"\n";
}
?>

The second insert goes at the top of the <div> I called row3, which holds the password field:

<?php
if ( $error && empty($password) ) {
echo '<span style="gt;Oh Dear! You did not enter your password.</span><br>',"\n";
}
?>

I have to admit that this is easier using the <div> tag than it would have been using a table. A table would have required a new row, and a cell spanning two column widths for each insert. Using the <div> tag, I just squashed the new code inside the containing division and above the two floating "cells".

The code for the whole page has now become:

<?php
include('dbinfo.php'); // get database information
$error = false; //boolean used to contain error condition
/**
* The code below is ignored when the page loads
* but is run on reload after button click.
*/
if (isset($_POST['login'])) {
// variables filled with form inputs
$usertype = $_POST['usertype'];
$username = $_POST['username'];
$password = $_POST['password'];
// check that neither field is empty
if ( !empty($firstname) && !empty($lastname) ) {
//run crunchy code
} else {
$error = true; // error condition met
} // end of input check
} // end of buttonclicked conditional code
?>

<html>
<head>
<title>Active Math Java Private Portal</title>
<link rel="stylesheet" type="text/css" href="pportal.css" />
</head>
<body>
<div id="container">
<div id="header">
<h1 class="top">Rasch-ItemBank</h1>
<h3 class="top">A
<a class="top" href="http://www.interactived.com/softway.htm">
Softway</a> Open Source Project <br/>
Hosted by <a class="top" href="http://java.net/projects">Java.net</a>
</h3>
</div>
<div id="left">
<b>Menu</b><br />
<a class="menu" href="http://www.interactived.com/softway.htm">Home</a><br />
<a class="menu" href="http://www.interactived.com/research.htm">Research</a><br />
<a class="menu" href="http://www.interactived.com/software.htm">Software</a>
</div>
<div id="content" style="height:400px;width:85%;">
<h1 class="main">Active Math Java</h1>
<h3 class="main">Private Portal<br/>
The Blueridge School of Apalit, Inc.
</h3>
<div id=logintable class=inputtable>
<div id=row1 class=row>
<h3>Initial Login Screen</h3>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<div id=row1 class=row>
<div id=cell11 class=col1>Please select user or admin</div>
<div id=cell12 class=col2>
<select name="usertype" class=cbox>
<option value="user">user</option>
<option value="admin">admin</option>
</select>
</div>
</div><br/>
<div id=row2 class=row>
<?php
if ( $error && empty($username) ) {
echo '<span style="gt;Oh Dear! You did not enter your name.</span><br>',"\n";
}
?>
<div id=cell21 class=col1>Please enter your name</div>
<div id=cell22 class=col2><input type="text" name="username" class=itext /></div>
</div><br/>
<div id=row3 class=row>
<?php
if ( $error && empty($password) ) {
echo '<span style="gt;Oh Dear! You did not enter your password.</span><br>',"\n";
}
?>
<div id=cell31 class=col1>Please enter your password</div>
<div id=cell32 class=col2><input type="password" name="password" class=itext /></div>
</div><br/>
<div id=row4 class=row>
<div id=cell41 class=col1>Click button to log in</div>
<div id=cell42 class=col2><input type="submit" name="login" value="Log in to Portal" class=itext /></div>
</div><br/>
</form>
</div>
</div>
</div>

<div id="footer">
Helping Children to Achieve their Potential</div>
</div>
</body>
</html>

And when I clicked the login button, with two empty fields, the page came up as shown below:

Saturday, October 22, 2011

Creating a login page

There are three steps to creating a login page, or really any page which exchanges information with a database.
  1. Creating the front end interface;
  2. Writing the business rules;
  3. Writing the interface with the database.

In a previous post I already described a form which added records to a data table. In that example I was a bit sloppy, because I omitted any business rules code. My excuse was that the data table in that example was intended to be populated automatically, so the input form would never be used in real life.

I am now dealing with a request from a school to track student performance, so I have to create a manual database portal or interface for them. The first step is the login screen. At a trivial level, this is just a couple of fields and a button, so not much thought needs to go into it.

But as I am using the exercise to stimulate a web site redesign, I have chosen to go a little deeper. My usual method of making forms look reasonably neat is to shove them in a table. But the HTML purists don't like table any more, so I decided to look into using the <div> tag instead. At the same time, I extended my use of the external CSS page, which I used in my previous post.

Whether correctly or not, I followed the pattern of a table, with a series of horizontal rows, each nested with two "cells", one floating to the left, the other to the right, and all inside a "zone" which I classified as "inputtable", which in turn lay inside the page (code not shown) created in my previous post:

<div id=logintable class=inputtable>
<div id=row0 class=row>
<h3>Initial Login Screen</h3>
<form>
<div id=row1 class=row>
<div id=cell11 class=col1>Please select user or admin</div>
<div id=cell12 class=col2>
<select name="usertype" class=cbox>
<option value="user">user</option>
<option value="admin">admin</option>
</select>
</div>
</div><br/>
<div id=row2 class=row>
<div id=cell21 class=col1>Please enter your name</div>
<div id=cell22 class=col2><input type="text" name="username" class=itext /></div>
</div><br/>
<div id=row3 class=row>
<div id=cell31 class=col1>Please enter your password</div>
<div id=cell32 class=col2><input type="password" name="password" class=itext /></div>
</div><br/>
<div id=row4 class=row>
<div id=cell41 class=col1>Click button to log in</div>
<div id=cell42 class=col2><input type="submit" value="Log in to Portal" class=itext /></div>
</div><br/>
</form>
</div>
</div>

To accommodate the extra classes, the CSS page was expanded as follows:

body {
margin:10px 0px; padding:0px;
text-align:center;
}
#container {width:800;}
#header {background-color:#151B8D;text-align:left;}
#left {background-color:#5CB3FF;height:500px;width:15%;float:left;text-align:left;}
#content {height:400px;width:85%;}
#footer {background-color:#488AC7;clear:both;text-align:center;}

a:link {text-decoration:none;} /* unvisited link */
a:visited {text-decoration:none;} /* visited link */
a:hover {text-decoration:underline;} /* mouse over link */
a:active {text-decoration:none;} /* selected link */

h1.top {margin-bottom:0;color=#FFFF00;}
h3.top {margin-bottom:0;margin-top:0;color=#FFFF00;}
a.top {color=#FFFF00;}

h1.main {margin-bottom:0;text-align:center;}
h3.main {margin-bottom:0;margin-top:0;text-align:center;}

a.menu {color=#000000;}

.inputtable {margin:50; background-color:#BDEDFF}
.row {width:420;}
.col1 {text-align:right; float:left; width:200; margin:0 5 0 5;}
.col2 {text-align:left; float:right; width:200; margin:0 5 0 5;}
.itext {width:150;}
.cbox {width:150; margin-left:5;}

And the finished page looked as follows:

Friday, October 21, 2011

Web site redesign

In my quest to get my Applet talking to a commercially hosted MySQL database, I was forced to update my knowledge of a number of related areas, including HTML. Coincidentally, I get a lot of spam telling me how dreary and old fashioned my MS Front page designed website is.

A school has asked for a private portal to the Applet, and I want the page to remain outside the main website navigation structure. I could just give them a form on a plain page. Or I could use the opportunity to play with HTML layouts and CSS.

My favorite tutorial site, W3schools, has a nice sample layout, similar to their own. I have adapted this with my own colors and text. I have also changed the behavior of links, so that they look more like surrounding test, except when they are hovered over. My HTML was as follows:

<html>
<head>
<title>Active Math Java Private Portal</title>
<style type="text/css">
a:link {text-decoration:none;} /* unvisited link */
a:visited {text-decoration:none;} /* visited link */
a:hover {text-decoration:underline;} /* mouse over link */
a:active {text-decoration:none;} /* selected link */
</style>
</head>
<body>
<div id="container" style="width:100%">
<div id="header" style="background-color:#151B8D">
<h1 style="margin-bottom:0;color=#FFFF00;">Rasch-ItemBank</h1>
<h3 style="margin-bottom:0;margin-top:0;color=#FFFF00;">A
<a href="http://www.interactived.com/softway.htm" style="color=#FFFF00;">
Softway</a> Open Source Project</h3>
<h3 style="margin-bottom:0;margin-top:0;color=#FFFF00;">Hosted by
<a href="http://java.net/projects" style="color=#FFFF00;">Java.net</a></h3>
</div>
<div id="menu" style="background-color:#82CAFA;height:400px;width:15%;float:left;">
<b>Menu</b><br />
<a href="http://www.interactived.com/softway.htm" style="color=#000000;">Home</a><br />
<a href="http://www.interactived.com/research.htm" style="color=#000000;">Research</a><br />
<a href="http://www.interactived.com/software.htm" style="color=#000000;">Software</a></div>
<div id="content" style="height:400px;width:85%;">
<h1 style="margin-bottom:0;text-align:center">Active Math Java</h1>
<h3 style="margin-bottom:0;margin-top:0;text-align:center">Private Portal</h3>
<h3 style="margin-bottom:0;margin-top:0;text-align:center">
The Blueridge School of Apalit, Inc.
</h3>
</div>
<div id="footer" style="background-color:#56A5EC;clear:both;text-align:center;">
Helping Children to Achieve their Potential</div>
</div>
</body>
</html>

And it came up as shown below:

The tutorial recommended using an external CSS style sheet, so as to facilitate site wide design changes. That's fine for colors and fonts, but a question running through my mind is how they achieve site wide menu changes. Their own source code betrays few secrets these days because it might have been generated with a script, although it certainly represents a thorough example of using the <div> tag.

I found the CSS tutorial a bit confusing when it came to classes, but part of the confusion arose because of my inability to type. Anyway, after some fiddling around, my CSS page looked like this:

a:link {text-decoration:none;} /* unvisited link */
a:visited {text-decoration:none;} /* visited link */
a:hover {text-decoration:underline;} /* mouse over link */
a:active {text-decoration:none;} /* selected link */

h1.top {margin-bottom:0;color=#FFFF00;}
h3.top {margin-bottom:0;margin-top:0;color=#FFFF00;}
a.top {color=#FFFF00;}

h1.main {margin-bottom:0;text-align:center;}
h3.main {margin-bottom:0;margin-top:0;text-align:center;}

a.menu {color=#000000;}

#header {background-color:#151B8D;}
#left {background-color:#82CAFA;height:400px;width:15%;float:left;}
#content {height:400px;width:85%;}
#footer {background-color:#56A5EC;clear:both;text-align:center;}

And the HTML became:

<html>
<head>
<title>Active Math Java Private Portal</title>
<link rel="stylesheet" type="text/css" href="pportal.css" />
</head>
<body>
<div id="container" style="width:100%">
<div id="header">
<h1 class="top">Rasch-ItemBank</h1>
<h3 class="top">A
<a class="top" href="http://www.interactived.com/softway.htm">
Softway</a> Open Source Project <br/>
Hosted by <a class="top" href="http://java.net/projects">Java.net</a>
</h3>
</div>
<div id="left">
<b>Menu</b><br />
<a class="menu" href="http://www.interactived.com/softway.htm">Home</a><br />
<a class="menu" href="http://www.interactived.com/research.htm">Research</a><br />
<a class="menu" href="http://www.interactived.com/software.htm">Software</a>
</div>
<div id="content" style="height:400px;width:85%;">
<h1 class="main">Active Math Java</h1>
<h3 class="main">Private Portal<br/>
The Blueridge School of Apalit, Inc.</h3>
</div>
<div id="footer">
Helping Children to Achieve their Potential</div>
</div>
</body>
</html>

And to my enormous surprise it ended up looking exactly the same as that produced by the single page as shown above.