UniverseUniversity


Home Projects Jobs Clientele Contact

uu


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: User registration/authentication



Ok, attached is the new trunk0317.diff. I didn't have time to write a
script that will sort SVN output, so I did it manually.
Some comments below...


> sergey@total-knowledge.com wrote:
>> Attached trunk0316.diff file with current application.
>>
>> It has Register, Login and Home pages. Home page is login protected and
>> not-logged-in user gets redirected to Login page.
>>
> Why?

It's for testing purposes. HomeServlet can't be accessed without login,
like My Account page, for example, in real application.

>>
>> Index: libui/RegisterServlet.h
>> ===================================================================
>> --- libui/RegisterServlet.h	(revision 0)
>> +++ libui/RegisterServlet.h	(revision 0)
>> @@ -0,0 +1,28 @@
>> +#ifndef REGISTERSERVLET_H
>> +#define REGISTERSERVLET_H
>> +
>> +#include <boost/lexical_cast.hpp>
>> +#include "UUServlet.h"
>> +
>> +using boost::lexical_cast;
>> +using namespace std;
>> +using namespace servlet;
>>
> Never put "using" statements in header files.

Done.

>> +
>> +/**
>> +  * This servlet:
>> +  * Receives registration request.
>> +  * Accesses User model object.
>> +  * Stores results in request context.
>> +  * Determines the language to render page in based on user
>> preferences.
>> +  * Forwards the request to the view object (HomeView.csp) if no
>> errors.
>>
> Shouldn't RegisterServlet be using something like Register.csp?


Done.

>> Index: libui/UUServlet.cpp
>> ===================================================================
>> --- libui/UUServlet.cpp	(revision 0)
>> +++ libui/UUServlet.cpp	(revision 0)
>> @@ -0,0 +1,48 @@
>> +#include "UUServlet.h"
>> +
>> +UUServlet::UUServlet ( ) { }
>>
> Do not create empty constructors.
>> +UUServlet::~UUServlet ( ) { }
>>
> Only create empty destructors if they are virtual (so, it's OK in this
> case).

Done.


>> +
>> +/**
>> + * Returns true if the request already has valid associated session,
>> and that
>> + * session contains valid User object
>> + * @return bool
>> + * @param  req Request to check
>> + */
>> +
>> +bool UUServlet::isUserLoggedIn (HttpServletRequest& req ) const {
>>
> Put opening '{' on new line for functions (not for blocks inside
> functions though)

Done.


>> +
>> +  HttpSession* session = req.getSession(true);
>> +  if(!session) throw runtime_error("no session");
>>
> That error message doesn't make that much sense.

Done.

>> +  string sessionid = session->getId();
>> +  user_t user;
>> +  bool hasValidLogin = user.isSessionValid(sessionid);
>>
> Session validity is not defined by whether user is logged in or not,
> so I guess that's a misnomer.

Done.

>> +  return hasValidLogin;
>> +
>> +}
>> +
>> +
>> +/**
>> + * Redirects browser to login page
>> + * @param  resp send redirect through this response object
>> + */
>> +void UUServlet::redirectToLogin (HttpServletRequest& req,
>> HttpServletResponse& resp) {
>> +
>> +  req.setAttribute("Message", setattr_t(new string("Please login
>> first!")));
>>
> What does setattr_t mean? (Again - load your names with real meaning)
> Another thing - why are you specifying that exact message? Couldn't it
> so happen
> that you are redirecting to the login page from somewhere where no log in
> is
> required (LogoutServlet perhaps?)

Done.


>> +  req.getRequestDispatcher("LoginView.csp")->forward(req,resp);
>> +
>> +}
>> +
>> +
>> +/**
>> + * @return User
>> + * @param  req
>> + */
>> +User UUServlet::getCurrentUser (HttpServletRequest& req ) {
>> +
>> +  user_t user;
>> +  return user;
>>
> Eh? If it isn't implemented - leave //FIXME: or //TODO: marker.
> Otherwise, comment this piece of crypto properly.

Done.

>> +
>> +}
>> +
>> +
>>
>>
>> Index: libui/LoginServlet.h
>> ===================================================================
>> --- libui/LoginServlet.h	(revision 0)
>> +++ libui/LoginServlet.h	(revision 0)
>> @@ -0,0 +1,25 @@
>> +#ifndef LOGINSERVLET_H
>> +#define LOGINSERVLET_H
>> +
>> +#include "UUServlet.h"
>> +
>> +using namespace std;
>> +using namespace servlet;
>> +
>> +/**
>> +  *  This servlet:
>> +  *  Receives login request.
>> +  *  Accesses User model object.
>> +  *  Stores results in request context.
>> +  *  Determines the language to render page in based on user
>> preferences.
>> +  *  Forwards the request to the view object (HomeView.csp) if no
>> errors.
>> +  */
>> +
>> +class LoginServlet : public UUServlet
>> +{
>> +public:
>> +  void service(HttpServletRequest& request, HttpServletResponse
>> &response);
>> +};
>> +
>> +#endif//LOGINSERVLET_H
>> +
>>
>>
>> Index: libui/UUServlet.h
>> ===================================================================
>> --- libui/UUServlet.h	(revision 0)
>> +++ libui/UUServlet.h	(revision 0)
>> @@ -0,0 +1,57 @@
>> +#ifndef UUSERVLET_H
>> +#define UUSERVLET_H
>> +class UUServlet : public servlet::HttpServlet
>> +{
>> +public:
>> +  /**
>> +   * Redirects browser to login page
>> +   * @param  resp send redirect through this response object
>> +   */
>> +  void redirectToLogin (servlet::HttpServletRequest& req,
>> servlet::HttpServletResponse& resp);
>>
> Do you need request arg here?

Yes I do. I know I can use resp.sendRedirect(), but I want to be able to
display messages on Login page after redirect. That's why I use
request.getRequestDispatcher(csp)->forward(request,response)



>>
>> Index: libui/Makefile.adon
>> ===================================================================
>> --- libui/Makefile.adon	(revision 82)
>> +++ libui/Makefile.adon	(working copy)
>> +noinst_HEADERS:=../libdm/User.h
> Can't do that. Only files current dir can be mentioned.

Fixed

>> +
>> +EXTRA_DIST:=Footer.csp Header.csp Sidebar.csp
>> +libuu_SOURCES:=../libdm/User.cpp UUServlet.cpp ../libdm/uudb.cpp
>>
> Again. Can't do that. libdm should be a separate library, that you will
> link with.

Fixed

>>
>> Index: engine.xml
>> ===================================================================
>> --- engine.xml	(revision 0)
>> +++ engine.xml	(revision 0)
>> @@ -0,0 +1,10 @@
>> +<?xml version="1.0"?>
>> +<listener protocol="unix" path="/tmp/cppserv.sock"/>
>> +<app name="">
>> +    <servlet name="HomeServlet" dso="./debug/libui/HomeServlet.so"/>
>> +    <servlet name="RegisterServlet"
>> dso="./debug/libui/RegisterServlet.so"/>
>> +    <servlet name="LoginServlet" dso="./debug/libui/LoginServlet.so"/>
>> +    <csp name="themes/HomeView.csp" path="HomeView.csp"
>> dso="./debug/themes/HomeView.so" hidden="true"/>
>> +    <csp name="themes/RegistrationView.csp" path="RegistrationView.csp"
>> dso="./debug/themes/RegistrationView.so" hidden="true"/>
>> +    <csp name="themes/LoginView.csp" path="LoginView.csp"
>> dso="./debug/themes/LoginView.so" hidden="true"/>
>> +</app>
>>
> You know that cppserv now supports multiple servlets in single DSO, right?
> i.e. you could link them all into a single library.. That might make
> some things easier
> (not necessary by all means, but probably good idea for themes).

Done

> Speaking of themes, make sure your templates are in subdirectory of
> themes, not
> in themes directory itself. something like themes/default/

Done


>> Index: libdm/User.cpp
>> ===================================================================
>> --- libdm/User.cpp	(revision 0)
>> +++ libdm/User.cpp	(revision 0)
>> @@ -0,0 +1,128 @@
>> +#include "User.h"
>> +
>> +User::User() {}
>> +User::~User() {}
>> +
>> +/**
>> + * Performs authentication.
>> + * @return bool
>> + */
>> +
>> +bool User::isLoginPasswordValid(string login, string password) {
>> +
>> +  CODBCDatabase db("DSN=PostgreSQL;UID=sergey;PWD=;DATABASE=uu");
>> +  bool isValid = false;
>> +  try {
>> +    CQuery qrySelect(&db,"select pl_id from person_list where
>> pl_login=:login and pl_password=:password");
>> +    qrySelect.param("login") = login;
>> +    qrySelect.param("password") = password;
>> +    qrySelect.open();
>> +    while ( ! qrySelect.eof() ) {
>> +      isValid = true;
>> +      qrySelect.fetch();
>> +    }
>> +    qrySelect.close();
>> +  }
>> +  catch (exception& e) {
>> +    cout<<"\nError: " <<e.what();
>> +    return false;
>> +  }
>> +  return isValid;
>> +
>> +}
>> +
>> +/**
>> + * Sets data to session_info temp table after successful authentication
>> + */
>> +
>> +bool User::setSessionInfo(string login, string password, int server,
>> string sessionid) {
>> +
>> +  CODBCDatabase db("DSN=PostgreSQL;UID=sergey;PWD=;DATABASE=uu");
>> +  try {
>> +    CQuery qryInsert(&db,"select login('"+login+"', '"+password+"',
>> "+lexical_cast<string>(server)+")");
>> +    qryInsert.exec();
>> +  }
>> +  catch (exception& e) {
>> +    cout<<"\nError: " <<e.what();
>> +    return false;
>> +  }
>> +  return true;
>> +
>> +}
>> +
>> +/**
>> + * Gets user data from session_info table.
>> + */
>> +
>> +User::sessioninfo_t User::getSessionInfo(string sessionid) {
>> +
>> +  CODBCDatabase db("DSN=PostgreSQL;UID=sergey;PWD=;DATABASE=uu");
>> +  sessioninfo_t sessioninfo;
>> +  try {
>> +    CQuery qrySelect(&db,"select * from session_info where
>> si_session=:sessionid");
>> +    qrySelect.param("sessionid") = sessionid;
>> +    qrySelect.open();
>> +    CField& idField = qrySelect["si_person"];
>> +    CField& fnameField = qrySelect["si_person_name"];
>> +    CField& serverField = qrySelect["si_server"];
>> +    while ( ! qrySelect.eof() ) {
>> +      SessionInfo sinfo;
>> +      sinfo.person_id = lexical_cast<long>(idField.asString());
>> +      sinfo.person_name = fnameField.asString();
>> +      sinfo.server = serverField.asInteger();
>> +      sessioninfo.push_back(sinfo);
>> +      qrySelect.fetch();
>> +    }
>> +    qrySelect.close();
>> +  }
>> +  catch (exception& e) {
>> +    cout<<"\nError: " <<e.what();
>> +  }
>> +  return sessioninfo;
>> +
>> +}
>> +
>> +/**
>> + * Gets user id from session_info table. Returns true if such user
>> exist.
>> + */
>> +
>> +bool User::isSessionValid(string sessionid) {
>> +
>> +  CODBCDatabase db("DSN=PostgreSQL;UID=sergey;PWD=;DATABASE=uu");
>> +  bool isValid = false;
>> +  try {
>> +    CQuery qrySelect(&db,"select si_person from session_info where
>> si_session=:sessionid");
>> +    qrySelect.param("sessionid") = sessionid;
>> +    qrySelect.open();
>> +    while ( ! qrySelect.eof() ) {
>> +      isValid = true;
>> +      qrySelect.fetch();
>> +    }
>> +    qrySelect.close();
>> +  }
>> +  catch (exception& e) {
>> +    cout<<"\nError: " <<e.what();
>> +  }
>> +  return isValid;
>> +
>> +}
>> +
>> +/**
>> + * Sets all user data during a registration process. Calls stored
>> procedure "person_create" to insert user data into "person_list" table.
>> If insert is successful, returns true. Otherwise returns false.
>> + */
>> +
>> +bool User::setUserInfo(string login, string password, int language,
>> string firstName, string lastName, string street, string city, string
>> state, string zip, string country, string email, string phone ) {
>> +
>> +  CODBCDatabase db("DSN=PostgreSQL;UID=sergey;PWD=;DATABASE=uu");
>> +  try {
>> +    CQuery qryInsert(&db,"select
>> person_create('"+firstName+"','"+lastName+"','"+street+"','"+city+"','"+state+"','"+zip+"','"+country+"','"+email+"','"+phone+"','"+login+"','"+password+"')");
>> +    qryInsert.exec();
>> +  }
>> +  catch (exception& e) {
>> +    cout<<"\nError: " <<e.what();
>> +    return false;
>> +  }
>> +  return true;
>> +
>> +}
>> +
>>
>>
> I will let Alexey review and comment your database code.
>>
>> Index: libdm/uudb.cpp
>> ===================================================================
>> --- libdm/uudb.cpp	(revision 0)
>> +++ libdm/uudb.cpp	(revision 0)
>> @@ -0,0 +1,33 @@
>>
> All of the uudb code you wrote should be replaced with db pool code.
>

Yes, I know. I started working on DB pool functionality already.


>
> I didn't review some of your actual code, for now fixing issues that
> has already been pointed out will be enough for next iteration.
>
> --
> Ilya A. Volynets-Evenbakh
> Total Knowledge. CTO
> http://www.total-knowledge.com
>
>
Index: engine.xml
===================================================================
--- engine.xml	(revision 0)
+++ engine.xml	(revision 0)
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<listener protocol="unix" path="/tmp/cppserv.sock"/>
+<app name="">
+    <servlet name="HomeServlet" dso="./debug/libui/libuu.so"/>
+    <servlet name="RegisterServlet" dso="./debug/libui/libuu.so"/>
+    <servlet name="LoginServlet" dso="./debug/libui/libuu.so"/>
+    <csp name="themes/default/HomeView.csp" path="HomeView.csp" dso="./debug/themes/default/HomeView.so" hidden="true"/>
+    <csp name="themes/default/RegistrationView.csp" path="RegistrationView.csp" dso="./debug/themes/default/RegistrationView.so" hidden="true"/>
+    <csp name="themes/default/LoginView.csp" path="LoginView.csp" dso="./debug/themes/default/LoginView.so" hidden="true"/>
+</app>



Index: env-tests/env-test-custom.mk
===================================================================
--- env-tests/env-test-custom.mk	(revision 82)
+++ env-tests/env-test-custom.mk	(working copy)
@@ -0,0 +1,15 @@
+#####################################################
+ifneq ($(strip $(shell $(CXX) -v 2>&1| grep '^gcc')),)
+$(eval $(call cxx_flag_kirpich,-W))
+$(eval $(call cxx_flag_kirpich,-Wall))
+$(eval $(call cxx_flag_kirpich,-Wextra))
+#$(eval $(call cxx_flag_kirpich,-Wold-style-cast))
+#$(eval $(call cxx_flag_kirpich,-Woverloaded-virtual))
+$(eval $(call cxx_flag_kirpich,-Wredundant-decls))
+#$(eval $(call cxx_flag_kirpich,-pedantic))
+$(eval $(call sptk_kirpich))
+$(eval $(call sptk_namespace_kirpich))
+$(eval $(call sptk_odbc_kirpich))
+$(eval $(call sptk_sqlite_kirpich))
+endif
+#####################################################
Index: Makefile.adon
===================================================================
--- Makefile.adon	(revision 82)
+++ Makefile.adon	(working copy)
@@ -1 +1,6 @@
+## trunk Makefile
+
 ADON_SUBDIRS:=libdm libui themes admin
+EXTRA_DIST := README engine.xml
+export CPPSERV_TEST_HOST ?= sergey
+export CPPSERV_TEST_URLBASE ?= http://localhost/~sergey/csp

   
Index: libui/Makefile.adon
===================================================================
--- libui/Makefile.adon	(revision 82)
+++ libui/Makefile.adon	(working copy)
@@ -0,0 +1,9 @@
+## libui Makefile
+
+noinst_LTLIBRARIES:=libuu
+noinst_HEADERS:=UUServlet.h HomeServlet.h RegisterServlet.h LoginServlet.h
+libuu_SOURCES:=UUServlet.cpp HomeServlet.cpp RegisterServlet.cpp LoginServlet.cpp 
+libuu_LDFLAGS:=-lspdb3 -lsputil3 -luu -ldm
+libuu_DEPS:=libuu
+
+ADON_SUBDIRS:=

   
Index: libdm/Makefile.adon
===================================================================
--- libdm/Makefile.adon	(revision 82)
+++ libdm/Makefile.adon	(working copy)
@@ -0,0 +1,7 @@
+## libdm Makefile
+
+noinst_LTLIBRARIES:=libdm
+noinst_HEADERS:=User.h uudb.h
+libdm_SOURCES:=User.cpp uudb.cpp
+
+ADON_SUBDIRS:=


Index: themes/Makefile.adon
===================================================================
--- themes/Makefile.adon	(revision 82)
+++ themes/Makefile.adon	(working copy)
@@ -1 +1,3 @@
+## themes Makefile
+
 ADON_SUBDIRS:=default



Index: themes/default/Makefile.adon
===================================================================
--- themes/default/Makefile.adon	(revision 82)
+++ themes/default/Makefile.adon	(working copy)
@@ -0,0 +1,39 @@
+## themes/default Makefile
+
+CPP_SERVLETS:=
+CSP_SERVLETS:= \
+	HomeView \
+	LoginView \
+	RegistrationView \
+
+CSP_COMPILE:=cxxsp_compile
+LOCAL_CPPFLAGS:=-I$(ADON_CURDIR)
+
+noinst_LTLIBRARIES:=
+noinst_HEADERS:=
+
+EXTRA_DIST:=Footer.csp Header.csp Sidebar.csp
+define CSP_TMPL
+$(1)_SOURCES:=$(1).cpp
+$(1)_LDFLAGS:=-lspdb3 -lsputil3 -luu -ldm
+$(1)_DEPS:=libuu libdm
+CLEANFILES+=$(1).cpp
+EXTRA_DIST+=$(1).csp
+noinst_LTLIBRARIES+=$(1)
+endef
+define CPP_TMPL
+$(1)_SOURCES:=$(1).cpp
+$(1)_LDFLAGS:=-lspdb3 -lsputil3 -luu -ldm
+$(1)_DEPS:=libuu libdm
+noinst_LTLIBRARIES+=$(1)
+endef
+
+$(foreach srv,$(CSP_SERVLETS),$(eval $(call CSP_TMPL,$(srv))))
+$(foreach srv,$(CPP_SERVLETS),$(eval $(call CPP_TMPL,$(srv))))
+
+
+%.cpp: %.csp
+	@echo "Parsing $< into $@"
+	$(Q)$(CSP_COMPILE) $< $@
+
+ADON_SUBDIRS:=



Index: libui/RegisterServlet.h
===================================================================
--- libui/RegisterServlet.h	(revision 0)
+++ libui/RegisterServlet.h	(revision 0)
@@ -0,0 +1,24 @@
+#ifndef REGISTERSERVLET_H
+#define REGISTERSERVLET_H
+
+#include <boost/lexical_cast.hpp>
+#include "UUServlet.h"
+
+/**
+  * This servlet: 
+  * Receives registration request.
+  * Accesses User model object. 
+  * Stores results in request context.
+  * Determines the language to render page in based on user preferences.
+  * Forwards the request to the view object RegistrationView.csp.
+  */
+
+class RegisterServlet : public UUServlet
+{
+public:
+  void service(servlet::HttpServletRequest& request, servlet::HttpServletResponse &response);
+
+};
+
+#endif//REGISTERSERVLET_H
+


Index: libui/RegisterServlet.cpp
===================================================================
--- libui/RegisterServlet.cpp	(revision 0)
+++ libui/RegisterServlet.cpp	(revision 0)
@@ -0,0 +1,59 @@
+#include "RegisterServlet.h"
+
+using boost::lexical_cast;
+using namespace std;
+using namespace servlet;
+
+void RegisterServlet::service(HttpServletRequest& request, HttpServletResponse &response) 
+{
+
+  string csp = "RegistrationView.csp";
+  try{
+    string newVisit =    request.getParameter("new");
+    if(newVisit != "Y"){
+      string login =     request.getParameter("login");
+      string password =  request.getParameter("passwd");
+      string passwordc = request.getParameter("passwdc");
+      int language =     boost::lexical_cast<int>(request.getParameter("lang"));
+      string firstName = request.getParameter("name1");
+      string lastName =  request.getParameter("name2");
+      string street =    request.getParameter("street");
+      string city =      request.getParameter("city");
+      string state =     request.getParameter("state");
+      string zip =       request.getParameter("zipcode");
+      string country =   request.getParameter("country");
+      string email =     request.getParameter("email");
+      string phone =     request.getParameter("phone");
+      int server = 1;    //FIXME course_server
+      string message;
+      user_t user;
+      bool isSuccess = user.setUserInfo(login, password, language, firstName, lastName, street, city, state, zip, country, email, phone);
+      if(isSuccess){
+	HttpSession* session = request.getSession(true);
+        if(!session){
+	  throw logic_error("No session exist for this request");		
} else {
+	  string sessionid = session->getId();
+	  bool isSession = user.setSessionInfo(login, password, server, sessionid);
+	  if(isSession){
+	    message="Welcome new customer "+firstName+" "+lastName+"!";
+	    csp = "HomeView.csp";
+	  } else {
+	    message = "Login unsuccessful";
+	  }
+	}
+      } else {
+	message = "Login name already exist";
+      }
+      request.setAttribute("Message", setAttribute_t(new string(message)));
+    }
+  }catch(const exception& ex) {
+    request.setAttribute("error", setAttribute_t(new string(ex.what())));
+    cerr<<__PRETTY_FUNCTION__<<": "<<ex.what()<<std::endl;
+  }
+  request.getRequestDispatcher(csp)->forward(request,response);
+
+}
+
+EXPORT_SERVLET(RegisterServlet);
+

Index: themes/default/RegistrationView.csp
===================================================================
--- themes/default/RegistrationView.csp	(revision 0)
+++ themes/default/RegistrationView.csp	(revision 0)
@@ -0,0 +1,137 @@
+<!-- Registration form view CSP -->
+
+<%@ include file="Header.csp" %>
+<%@ include file="Sidebar.csp" %>
+
+
+    <FORM ACTION="RegisterServlet" METHOD="GET">
+
+            <TD ALIGN="center" valign="top" BGCOLOR="#DDEEFF"  width="83%">
+
+<% if(request.hasAttribute("Message")) { %>
+<br>
+<font face=Courier size=2 color="#FF0033""><i><%= request.getAttribute<std::string>("Message") %></i></font>
+<% } %>
+
+
+<!-- Content -->
+
+<table width=100% cellpadding=4 cellspacing=4 border=0>
+<tr><td COLSPAN="2"></td></tr>
+<TR>
+<TD ALIGN="center" COLSPAN="2">
+<font face=Courier size=3 color="#003399"><b>New Membership</B>
+</TD>
+</TR>
+<tr><td COLSPAN="2"></td></tr>
+<tr><td COLSPAN="2"></td></tr>
+        <TR>
+            <TD COLSPAN="2" BGCOLOR="#DDEEFF" ALIGN="center">
+                <font face=Courier size=2>*Membership name:</FONT><BR>
+                <INPUT NAME="login"  VALUE="" SIZE=40 MAXLENGTH=40>
+            </TD>
+        </TR>
+        <TR>
+            <TD BGCOLOR="#DDEEFF" ALIGN="center">
+                <font face=Courier size=2>*Password: </FONT><br>
+                <INPUT TYPE=PASSWORD NAME="passwd" SIZE=30>
+            </FONT></TD>
+            <TD BGCOLOR="#DDEEFF" ALIGN="center"><font face=Courier size=2>
+                <font face=Courier size=2>*Password confirmation: </FONT><BR>
+                <INPUT TYPE=PASSWORD NAME="passwdc" SIZE=30>
+            </TD>
+        </TR>
+<tr><td COLSPAN="2"></td></tr>
+        <TR>
+            <TD BGCOLOR="#DDEEFF" ALIGN="center"><font face=Courier size=2>
+                *First Name:<br>
+                <INPUT NAME="name1" VALUE="" SIZE=28 MAXLENGTH=30>
+            </FONT></TD>
+            <TD COLSPAN="2" BGCOLOR="#DDEEFF" ALIGN="center"><font face=Courier size=2>
+                *Last Name:<br>
+                <INPUT NAME="name2" VALUE="" SIZE=28 MAXLENGTH=30>
+            </FONT></TD>
+        </TR>
+        <TR>
+            <TD BGCOLOR="#DDEEFF" ALIGN="center" colspan=2><font face=Courier size=2>
+                *Street:<br>
+                <INPUT NAME="street" VALUE="" SIZE=62 MAXLENGTH=50>
+            </FONT></TD>
+        </TR>
+        <TR>
+            <TD COLSPAN="2" BGCOLOR="#DDEEFF" ALIGN="center">
+                <TABLE CELLPADDING=5 CELLSPACING=1 BORDER="0">
+                    <TR>
+                        <TD BGCOLOR="#DDEEFF" ALIGN="center"><font face=Courier size=2>
+                            *City:<BR>
+                            <INPUT NAME="city" VALUE="" SIZE=18 MAXLENGTH=60>
+                        </FONT></TD>
+                        <TD BGCOLOR="#DDEEFF" ALIGN="center"><font face=Courier size=2>
+                            *State:<BR>
+		    <SELECT name="state">		                            
+                      <OPTION value="" selected >Select a State</OPTION><OPTION value="AA">Armed Forces the Americas</OPTION><OPTION value="AE">Armed Forces Europe</OPTION><OPTION value="AK">Alaska</OPTION><OPTION value="AL">Alabama</OPTION><OPTION value="AP">Armed Forces Pacific</OPTION><OPTION value="AR">Arkansas</OPTION><OPTION value="AZ">Arizona</OPTION><OPTION value="CA">California</OPTION><OPTION value="CO">Colorado</OPTION><OPTION value="CT">Connecticut</OPTION><OPTION value="DC">District of Columbia</OPTION><OPTION value="DE">Delaware</OPTION><OPTION value="FL">Florida</OPTION><OPTION value="GA">Georgia</OPTION><OPTION value="GU">Guam</OPTION><OPTION value="HI">Hawaii</OPTION><OPTION value="IA">Iowa</OPTION><OPTION value="ID">Idaho</OPTION><OPTION value="IL">Illinois</OPTION><OPTION value="IN">Indiana</OPTION><OPTION value="KS">Kansas</OPTION><OPTION value="KY">Kentucky</OPTION><OPTION value="LA">Louisiana</OPTION><OPTION value="MA">Massachusettes</OPTION><OPTION value="MD">Maryland</OPTION><OPTION value="ME">Maine</OPTION><OPTION value="MI">Michigan</OPTION><OPTION value="MN">Minnesota</OPTION><OPTION value="MO">Missouri</OPTION><OPTION value="MS">Mississippi</OPTION><OPTION value="MT">Montana</OPTION><OPTION value="NC">North Carolina</OPTION><OPTION value="ND">North Dakota</OPTION><OPTION value="NE">Nebraska</OPTION><OPTION value="NH">New Hampshire</OPTION><OPTION value="NJ">New Jersey</OPTION><OPTION value="NM">New Mexico</OPTION><OPTION value="NV">Nevada</OPTION><OPTION value="NY">New York</OPTION><OPTION value="OH">Ohio</OPTION><OPTION value="OK">Oklahoma</OPTION><OPTION value="OR">Oregon</OPTION><OPTION value="PA">Pennsylvania</OPTION><OPTION value="PR">Puerto Rico</OPTION><OPTION value="RI">Rhode Island</OPTION><OPTION value="SC">South Carolina</OPTION><OPTION value="SD">South Dakota</OPTION><OPTION value="TN">Tennessee</OPTION><OPTION value="TX">Texas</OPTION><OPTION value="UT">Utah</OPTION><OPTION value="VA">Virginia</OPTION><OPTION value="VI">Virgin Islands</OPTION><OPTION value="VT">Vermont</OPTION><OPTION value="WA">Washington</OPTION><OPTION value="WI">Wisconsin</OPTION><OPTION value="WV">West Virginia</OPTION><OPTION value="WY">Wyoming</OPTION><OPTION value="MP">Micropolynesia</OPTION><OPTION value="FM">Federated States of Micronesia</OPTION>                      
+                    </SELECT>
+                        </FONT></TD>
+                        <TD BGCOLOR="#DDEEFF" ALIGN="center"><font face=Courier size=2>
+                            *Zip Code:<BR>
+                            <INPUT NAME="zipcode" VALUE="" SIZE=12 MAXLENGTH=200>
+                        </FONT></TD>
+                    </TR>
+                </TABLE>
+            </TD>
+        </TR>
+        <TR>
+            <TD BGCOLOR="#DDEEFF" ALIGN="center"><font face=Courier size=2>
+                Country:<BR>
+
+<SELECT name="country">
+                   <OPTION value="">Select a Country</OPTION><OPTION value="US" selected >United States</OPTION><OPTION value="AF">Afghanistan</OPTION><OPTION value="AL">Albania</OPTION><OPTION value="DZ">Algeria</OPTION><OPTION value="AS">American Samoa</OPTION><OPTION value="AD">Andorra</OPTION><OPTION value="AO">Angola</OPTION><OPTION value="AV">Anguila</OPTION><OPTION value="AI">Anguilla</OPTION><OPTION value="AQ">Antarctica</OPTION><OPTION value="AG">Antigua</OPTION><OPTION value="AR">Argentina</OPTION><OPTION value="AM">Armenia</OPTION><OPTION value="AW">Aruba</OPTION><OPTION value="AU">Australia</OPTION><OPTION value="AT">Austria</OPTION><OPTION value="AZ">Azerbaidjan</OPTION><OPTION value="BS">Bahamas</OPTION><OPTION value="BH">Bahrain</OPTION><OPTION value="BD">Bangladesh</OPTION><OPTION value="BB">Barbados</OPTION><OPTION value="BY">Belarus</OPTION><OPTION value="BE">Belgium</OPTION><OPTION value="BZ">Belize</OPTION><OPTION value="BJ">Benin</OPTION><OPTION value="BM">Bermuda</OPTION><OPTION value="BT">Bhutan</OPTION><OPTION value="BO">Bolivia</OPTION><OPTION value="BA">Bosnia and Herzegovina</OPTION><OPTION value="BW">Botswnan</OPTION><OPTION value="BV">Bouvet Island</OPTION><OPTION value="BR">Brazil</OPTION><OPTION value="IO">British Indian Ocean Territory</OPTION><OPTION value="BN">Brunei Darussalam</OPTION><OPTION value="BG">Bulgaria</OPTION><OPTION value="BF">Burkina Faso</OPTION><OPTION value="BI">Burundi</OPTION><OPTION value="KH">Cambodia</OPTION><OPTION value="CM">Cameroon</OPTION><OPTION value="CA">Canada</OPTION><OPTION value="CV">Cape Verde</OPTION><OPTION value="KY">Cayman Islands</OPTION><OPTION value="CF">Central African Republic</OPTION><OPTION value="TD">Chad</OPTION><OPTION value="CL">Chile</OPTION><OPTION value="CN">China</OPTION><OPTION value="CX">Christmas Island</OPTION><OPTION value="CC">Cocos</OPTION><OPTION value="CO">Columbia</OPTION><OPTION value="KM">Comoros</OPTION><OPTION value="CG">Congo</OPTION><OPTION value="CD">Congo, Domocratic Republic</OPTION><OPTION value="CK">Cook Islands</OPTION><OPTION value="CR">Costa Rica</OPTION><OPTION value="CI">Cote D'lvoire/Ivory Coast</OPTION><OPTION value="HR">Croatia</OPTION><OPTION value="CU">Cuba</OPTION><OPTION value="CY">Cyprus</OPTION><OPTION value="CZ">Czech Republic</OPTION><OPTION value="DK">Denmark</OPTION><OPTION value="DJ">Djibouti</OPTION><OPTION value="DO">Dominican Republic</OPTION><OPTION value="DM">Domonica</OPTION><OPTION value="TP">East Timor</OPTION><OPTION value="EC">Ecuador</OPTION><OPTION value="EG">Egypt</OPTION><OPTION value="SV">EL Salvador</OPTION><OPTION value="GQ">Equatorial Guinea</OPTION><OPTION value="ER">Eritrea</OPTION><OPTION value="EE">Estonia</OPTION><OPTION value="ET">Ethiopia</OPTION><OPTION value="FK">Falkland Islands (Malvinas)</OPTION><OPTION value="FO">Faroe Islands</OPTION><OPTION value="FJ">Fiji</OPTION><OPTION value="FI">Finland</OPTION><OPTION value="FR">France</OPTION><OPTION value="GF">French Guiana</OPTION><OPTION value="PF">French Polynesia</OPTION><OPTION value="TF">French Southern Territories</OPTION><OPTION value="GA">Gabon</OPTION><OPTION value="GM">Gambia</OPTION><OPTION value="GE">Georgia</OPTION><OPTION value="DE">Germany</OPTION><OPTION value="GH">Ghana</OPTION><OPTION value="GI">Gibraltar</OPTION><OPTION value="GB">Great Britian</OPTION><OPTION value="GR">Greece</OPTION><OPTION value="GL">Greenland</OPTION><OPTION value="GD">Grenada</OPTION><OPTION value="GP">Guadelopue</OPTION><OPTION value="GT">Guatemala</OPTION><OPTION value="GN">Guinea</OPTION><OPTION value="GW">Guinea-Bissau</OPTION><OPTION value="GY">Guyana</OPTION><OPTION value="HT">Haiti</OPTION><OPTION value="HM">Heard & McDonald Islands</OPTION><OPTION value="HN">Honduras</OPTION><OPTION value="HK">Hong Kong</OPTION><OPTION value="HU">Hungary</OPTION><OPTION value="IS">Iceland</OPTION><OPTION value="IN">India</OPTION><OPTION value="ID">Indonesia</OPTION><OPTION value="IR">Iran</OPTION><OPTION value="IQ">Iraq</OPTION><OPTION value="IE">Ireland</OPTION><OPTION value="IL">Israel</OPTION><OPTION value="IT">Italy</OPTION><OPTION value="JM">Jamaica</OPTION><OPTION value="JP">Japan</OPTION><OPTION value="JO">Jordan</OPTION><OPTION value="KZ">Kazakhstan</OPTION><OPTION value="KE">Kenya</OPTION><OPTION value="KI">Kiribati</OPTION><OPTION value="KW">Kuwait</OPTION><OPTION value="KG">Kyrgyzstan</OPTION><OPTION value="LA">Laos</OPTION><OPTION value="LV">Latvia</OPTION><OPTION value="LB">Lebanon</OPTION><OPTION value="LS">Lesotho</OPTION><OPTION value="LR">Liberia</OPTION><OPTION value="LY">Libya</OPTION><OPTION value="LI">Liechtenstein</OPTION><OPTION value="LT">Lithuania</OPTION><OPTION value="LU">Luxembourg</OPTION><OPTION value="MO">Macau</OPTION><OPTION value="MK">Macedonia</OPTION><OPTION value="MG">Madagascar</OPTION><OPTION value="MW">Malawi</OPTION><OPTION value="MY">Malaysia</OPTION><OPTION value="MV">Maldives</OPTION><OPTION value="ML">Mali</OPTION><OPTION value="MT">Malta</OPTION><OPTION value="MH">Marshall Islands</OPTION><OPTION value="MQ">Martinique</OPTION><OPTION value="MR">Mauritania</OPTION><OPTION value="MU">Mauritius</OPTION><OPTION value="YT">Mayotte</OPTION><OPTION value="MX">Mexico</OPTION><OPTION value="FM">Micronesia</OPTION><OPTION value="MD">Moldova</OPTION><OPTION value="MC">Monaco</OPTION><OPTION value="MN">Mongolia</OPTION><OPTION value="MS">Montserrat</OPTION><OPTION value="MA">Morocco</OPTION><OPTION value="MZ">Mozambique</OPTION><OPTION value="MM">Myanmar</OPTION><OPTION value="NA">Namibia</OPTION><OPTION value="NR">Nauru</OPTION><OPTION value="NP">Nepal</OPTION><OPTION value="NL">Netherlands</OPTION><OPTION value="AN">Netherlands Antilles</OPTION><OPTION value="NT">Neutral Zone</OPTION><OPTION value="NC">New Caledonia</OPTION><OPTION value="NZ">New Zealand</OPTION><OPTION value="NI">Nicaragua</OPTION><OPTION value="NE">Niger</OPTION><OPTION value="NG">Nigeria</OPTION><OPTION value="NU">Niue</OPTION><OPTION value="NF">Norfolk Island</OPTION><OPTION value="KP">North Korea</OPTION><OPTION value="MP">Northern Mariana Islands</OPTION><OPTION value="NO">Norway</OPTION><OPTION value="OM">Oman</OPTION><OPTION value="PK">Pakistan</OPTION><OPTION value="PW">Palau</OPTION><OPTION value="PA">Panama</OPTION><OPTION value="PG">Papua New Guinea</OPTION><OPTION value="PY">Paraguay</OPTION><OPTION value="PE">Peru</OPTION><OPTION value="PH">Philippines</OPTION><OPTION value="PN">Pitcaim</OPTION><OPTION value="PL">Poland</OPTION><OPTION value="PT">Portugal</OPTION><OPTION value="QA">Qatar</OPTION><OPTION value="RE">Reunion</OPTION><OPTION value="RO">Romania</OPTION><OPTION value="RU">Russia</OPTION><OPTION value="RW">Rwanda</OPTION><OPTION value="GS">S Georgia & S Sandwich Islands</OPTION><OPTION value="KN">Saint Kitts & Nevis</OPTION><OPTION value="LC">Saint Lucia</OPTION><OPTION value="VC">Saint Vicent & the Grenadines</OPTION><OPTION value="WS">Samoa</OPTION><OPTION value="SM">San Marino</OPTION><OPTION value="ST">Sao Tome and Principe</OPTION><OPTION value="SA">Saudi Arabia</OPTION><OPTION value="SN">Senegal</OPTION><OPTION value="SL">Serra Leone</OPTION><OPTION value="SC">Seychelles</OPTION><OPTION value="SG">Singapore</OPTION><OPTION value="SK">Slovak Republic</OPTION><OPTION value="SI">Slovenia</OPTION><OPTION value="SB">Solomon Islands</OPTION><OPTION value="SO">Somalia</OPTION><OPTION value="ZA">South Africa</OPTION><OPTION value="KR">South Korea</OPTION><OPTION value="ES">Spain</OPTION><OPTION value="LK">Sri Lanka</OPTION><OPTION value="SH">St. Helen</OPTION><OPTION value="PM">St. Pierre & Miquelon</OPTION><OPTION value="SD">Sudan</OPTION><OPTION value="SR">Suriname</OPTION><OPTION value="SJ">Svalbard & Jan Mayen Islands</OPTION><OPTION value="SZ">Swaziland</OPTION><OPTION value="SE">Sweden</OPTION><OPTION value="CH">Switzerland</OPTION><OPTION value="SY">Syria</OPTION><OPTION value="TW">Taiwan</OPTION><OPTION value="TJ">Tajikistan</OPTION><OPTION value="TZ">Tanzania</OPTION><OPTION value="TH">Thailand</OPTION><OPTION value="TG">Togo</OPTION><OPTION value="TK">Tokelau</OPTION><OPTION value="TO">Tonga</OPTION><OPTION value="TT">Trinidad and Tobago</OPTION><OPTION value="TN">Tunisia</OPTION><OPTION value="TR">Turkey</OPTION><OPTION value="TM">Turkmenistan</OPTION><OPTION value="TC">Turks and Caicos Islands</OPTION><OPTION value="TV">Tuvalu</OPTION><OPTION value="UG">Uganda</OPTION><OPTION value="UA">Ukraine</OPTION><OPTION value="AE">United Arab Emirates</OPTION><OPTION value="UK">United Kingdom</OPTION><OPTION value="UY">Uruguay</OPTION><OPTION value="UM">US Minor Outlying Islands</OPTION><OPTION value="UZ">Uzbekistan</OPTION><OPTION value="VU">Vanuatu</OPTION><OPTION value="VA">Vatican City State</OPTION><OPTION value="VE">Venezuela</OPTION><OPTION value="VN">Vietnam</OPTION><OPTION value="VG">Virgin Islands (British)</OPTION><OPTION value="WF">Wallis and Futuna Islands</OPTION><OPTION value="EH">Western Sahara</OPTION><OPTION value="YE">Yemen</OPTION><OPTION value="YU">Yugoslavia</OPTION><OPTION value="ZR">Zaire</OPTION><OPTION value="ZM">Zambia</OPTION><OPTION value="ZW">Zimbabwe</OPTION>
+                   </SELECT>
+            </FONT></TD>
+            <TD BGCOLOR="#DDEEFF" ALIGN="center"><font face=Courier size=2>
+                *Phone:<BR>
+                <INPUT NAME="phone" VALUE="" SIZE=28 MAXLENGTH=40>
+            </FONT></TD>
+        </TR>
+        <TR VALIGN="bottom">
+            <TD BGCOLOR="#DDEEFF" ALIGN="center"><font face=Courier size=2>
+                Language:<BR>
+		<select name="lang">
+			<option value="1" selected>English</option>
+			<option value="2">Spanish</option>
+			<option value="3">Russian</option>
+			<option value="4">French</option>
+		</select>
+            </FONT></TD>
+            <TD BGCOLOR="#DDEEFF" ALIGN="center"><font face=Courier size=2>
+                E-mail:<BR>
+                <INPUT NAME="email" VALUE="" SIZE=28 MAXLENGTH=200>
+            </FONT></TD>
+        </TR>
+
+        <TR>
+            <TD BGCOLOR="#DDEEFF" ALIGN="right">
+                <BR>
+                <INPUT TYPE=RESET VALUE=" Reset " style="background-color:#FFFFF8; color: #003399;"><BR></TD><TD BGCOLOR="#DDEEFF" ALIGN="left"><BR>
+                <INPUT TYPE=SUBMIT VALUE=" Register " style="background-color:#FFFFF8; color: #003399;"><BR>
+            </TD>
+        </TR>
+</form>
+        <TR>
+            <TD BGCOLOR="#DDEEFF" COLSPAN="2" ALIGN="center">
+                <font face=verdana size=1>
+                * indicates a required field.<BR></FONT>
+            </FONT></TD>
+        </TR>
+        <TR>
+            <TD COLSPAN="2" align="center">
+<font face=Courier size=2><A HREF="Agreement.html">Agreement</A></font>
+            </TD>
+        </TR>
+
+
+</table>
+
+<!-- End Content -->
+
+<%@ include file="Footer.csp" %>


Index: libui/LoginServlet.h
===================================================================
--- libui/LoginServlet.h	(revision 0)
+++ libui/LoginServlet.h	(revision 0)
@@ -0,0 +1,22 @@
+#ifndef LOGINSERVLET_H
+#define LOGINSERVLET_H
+
+#include "UUServlet.h"
+
+/**
+  *  This servlet: 
+  *  Receives login request.
+  *  Accesses User model object. 
+  *  Stores results in request context.
+  *  Determines the language to render page in based on user preferences.
+  *  Forwards the request to the view object LoginView.csp.
+  */
+
+class LoginServlet : public UUServlet
+{
+public:
+  void service(servlet::HttpServletRequest& request, servlet::HttpServletResponse &response);
+};
+
+#endif//LOGINSERVLET_H
+

Index: libui/LoginServlet.cpp
===================================================================
--- libui/LoginServlet.cpp	(revision 0)
+++ libui/LoginServlet.cpp	(revision 0)
@@ -0,0 +1,56 @@
+#include "LoginServlet.h"
+
+using namespace std;
+using namespace servlet;
+
+void LoginServlet::service(HttpServletRequest& request, HttpServletResponse &response) 
+{
+
+  string csp = "LoginView.csp";
+  try{
+    string newVisit = request.getParameter("new");
+    if(newVisit != "Y"){
+      string login =     request.getParameter("login");
+      string password =  request.getParameter("CustPwd");
+      int server = 1;    //FIXME course_server 
+      string message;
+      user_t user;
+      bool isSuccess = user.isLoginPasswordValid(login, password);
+      if(isSuccess){
+	HttpSession* session = request.getSession(true);
+        if(!session){
+	  throw std::logic_error("No session exist for this request");		
+	} else {
+	  string sessionid = session->getId();
+	  bool isSession = user.setSessionInfo(login, password, server, sessionid);
+	  if(isSession){
+	    vector<SessionInfo> sInfo;
+	    sInfo = user.getSessionInfo(sessionid);
+	    string fullname;
+	    if(!sInfo.empty()){
+	      for(unsigned i=0;i<sInfo.size(); ++i) {
+		const SessionInfo& sinfo = sInfo[i];
+		fullname = sinfo.person_name;
+	      }
+	    }
+	    message = "Welcome back, "+fullname+"!";
+	    csp = "HomeView.csp";
+	  } else {
+	    message = "Registration unsuccessful";
+	  }
+	}
+      } else {
+	message = "Login/password combination is invalid";
+      }
+      request.setAttribute("Message", setAttribute_t(new string(message)));
+    }
+  }catch(const exception& ex) {
+    request.setAttribute("error", setAttribute_t(new string(ex.what())));
+    cerr<<__PRETTY_FUNCTION__<<": "<<ex.what()<<std::endl;
+  }
+  request.getRequestDispatcher(csp)->forward(request,response);
+
+}
+
+EXPORT_SERVLET(LoginServlet);
+

Index: themes/default/LoginView.csp
===================================================================
--- themes/default/LoginView.csp	(revision 0)
+++ themes/default/LoginView.csp	(revision 0)
@@ -0,0 +1,67 @@
+<!-- Login form view CSP -->
+
+<%@ include file="Header.csp" %>
+<%@ include file="Sidebar.csp" %>
+
+
+    <FORM ACTION="LoginServlet" METHOD="GET">
+
+            <TD ALIGN="center" valign="top" BGCOLOR="#DDEEFF"  width="83%">
+
+<% if(request.hasAttribute("Message")) { %>
+<br>
+<font face=Courier size=2 color="#FF0033""><i><%= request.getAttribute<std::string>("Message") %></i></font>
+<% } %>
+
+<!-- Content -->
+
+<table width=100% cellpadding=4 cellspacing=4 border=0>
+<tr><td></td></tr>
+<TR>
+<TD ALIGN="center">
+<font face=Courier size=3 color="#003399"><b>Enter your membership data to login</B>
+</TD>
+</TR>
+<TR>
+<TD ALIGN="center" BGCOLOR="#DDEEFF">
+<table  WIDTH="100%" bordercolor="#FF9900">
+<tr><td colspan="2">&nbsp;</td></tr>      
+<TR>
+<TD ALIGN="right">
+<font face=Courier size=2>Membership name:</font>&nbsp;
+</td>
+<td>
+<INPUT TYPE=TEXT NAME="login" VALUE="" SIZE=20 MAXLENGTH=50>
+</TD>
+</TR>
+<TR>
+<TD ALIGN="right">
+<font face=Courier size=2>Password:</font>&nbsp;
+</td>
+<td>
+<INPUT TYPE=PASSWORD NAME="CustPwd" SIZE=20 MAXLENGTH=50>
+</TD>
+</TR>
+<TR>
+<TD ALIGN="center" colspan="2">
+<BR><INPUT TYPE=SUBMIT NAME="OK" VALUE="Login" SIZE=10 style="background-color:#FFFFF8; color: #003399;">
+</TD>
+</TR>
+<tr><td colspan="2">&nbsp;</td></tr>
+<TR>
+<TD ALIGN="center" colspan="2">
+<font face=verdana size=1><A HREF="#">Forgot Password?</A></font>
+</TD>
+</TR>
+</TABLE>
+</TD>
+</TR>
+
+
+
+</table>
+
+<!-- End Content -->
+
+<%@ include file="Footer.csp" %>
+
   
   
Index: libui/HomeServlet.h
===================================================================
--- libui/HomeServlet.h	(revision 0)
+++ libui/HomeServlet.h	(revision 0)
@@ -0,0 +1,22 @@
+#ifndef HOMESERVLET_H
+#define HOMESERVLET_H
+
+#include "UUServlet.h"
+
+/**
+  *  This servlet: 
+  *  Receives home view request.
+  *  Accesses User model object. 
+  *  Stores results in request context.
+  *  Determines the language to render page in based on user preferences.
+  *  Forwards the request to the view object HomeView.csp.
+  */
+
+class HomeServlet : public UUServlet
+{
+public:
+  void service(servlet::HttpServletRequest& request, servlet::HttpServletResponse &response);
+};
+
+#endif//HOMESERVLET_H
+

Index: libui/HomeServlet.cpp
===================================================================
--- libui/HomeServlet.cpp	(revision 0)
+++ libui/HomeServlet.cpp	(revision 0)
@@ -0,0 +1,32 @@
+#include "HomeServlet.h"
+
+using namespace std;
+using namespace servlet;
+
+void HomeServlet::service(HttpServletRequest& request, HttpServletResponse &response) 
+{
+
+  bool isValidUser;
+  string csp = "HomeView.csp";
+  string message;
+  try{
+    isValidUser = isUserLoggedIn(request);
+    if(isValidUser) {
+      message = "Welcome home!";
+    }
+  }catch(const exception& ex) {
+    request.setAttribute("error", setAttribute_t(new string(ex.what())));
+    cerr<<__PRETTY_FUNCTION__<<": "<<ex.what()<<std::endl;
+  }
+  request.setAttribute("Message", setAttribute_t(new string(message)));
+  if(isValidUser){
+    request.getRequestDispatcher(csp)->forward(request,response);
+  } else {
+    message = "Please login first!";
+    redirectToLogin(request, response);
+  }
+
+}
+
+EXPORT_SERVLET(HomeServlet);
+

Index: themes/default/HomeView.csp
===================================================================
--- themes/default/HomeView.csp	(revision 0)
+++ themes/default/HomeView.csp	(revision 0)
@@ -0,0 +1,80 @@
+<!-- Home view CSP -->
+
+<%@ include file="Header.csp" %>
+<%@ include file="Sidebar.csp" %>
+
+
+            <TD ALIGN="center" valign="top" BGCOLOR="#DDEEFF"  width="83%">
+
+
+<% if(request.hasAttribute("Message")) { %>
+<br>
+<font face=Courier size=2 color="#FF0033""><i><%= request.getAttribute<std::string>("Message") %></i></font>
+<% } %>
+
+
+<table width=100% cellpadding=4 cellspacing=4 border=0>
+<tr>
+<td valign="top" height="100" width="50%">
+<center><font face=Courier size=3 color="#003399"><b>My Courses</b></font></center><br>
+<font face=Courier size=2><A HREF="CourseEdit.html">Calculus</A></font><br>
+<font face=Courier size=2><A HREF="CourseEdit.html">Derivatives</A></font><br>
+<font face=Courier size=2><A HREF="CourseEdit.html">Math</A></font><br>
+<font face=Courier size=2><A HREF="CourseEdit.html">Trigonometry</A></font><br>
+<br>
+<center><font face=verdana size=1><A HREF="RepositoryCourses.html">View All</A></font></center>
+</td>
+</tr>
+
+<tr><td colspan=2><hr color="#99CCFF"></td></tr>
+
+<tr>
+<td valign="top" height="100">
+<center><font face=Courier size=3 color="#003399"><b>Courses I study</b></font></center><br>
+<font face=Courier size=2><A HREF="CourseView1.html">Astronomy</A></font><br>
+<!-- <font face=Courier size=2><A HREF="CourseView1.html">Geology</A></font><br> -->
+<font face=Courier size=2><A HREF="CourseView.html">Theology</A></font><br>
+<br>
+<center><font face=verdana size=1><A HREF="CatalogStudent.html">Get new course</A></font></center>
+<br>
+<br>
+<font face=verdana size=1><A HREF="StudentView.html">My info(as a student)</A></font>
+
+
+</td>
+
+</tr>
+
+<tr><td colspan=2><hr color="#99CCFF"></td></tr>
+
+
+
+<tr>
+<td valign="top" height="100">
+<center><font face=Courier size=3 color="#003399"><b>Courses I teach</b></font></center><br>
+<font face=Courier size=2><A HREF="CourseViewTeach1.html">Math</A></font><br>
+<br>
+<font face=verdana size=1><A HREF="CatalogCoursesTeach.html">Teach new course</A></font>
+<br><br>
+<br>
+<center><font face=Courier size=2 color="#003399"><b>My students</b></font></center><br>
+
+<font face=Courier size=2><A HREF="StudentView.html">Student 1 (359 points)</A></font><br>
+<font face=Courier size=2><A HREF="StudentView.html">Student 2 (412 points)</A></font><br>
+<font face=Courier size=2><A HREF="StudentView.html">Student 3 (87 points)</A></font><br>
+<font face=Courier size=2><A HREF="StudentView.html">Student 4 (210 points)</A></font><br>
+
+<br>
+
+<center><font face=verdana size=1><A HREF="ProblemsList.html">Get list of problems with outstanding solutions</A></font></center>
+<br>
+</td>
+
+</tr>
+
+<tr><td colspan=2><hr color="#99CCFF"></td></tr>
+
+
+</table>
+
+<%@ include file="Footer.csp" %>


   
Index: libui/UUServlet.h
===================================================================
--- libui/UUServlet.h	(revision 0)
+++ libui/UUServlet.h	(revision 0)
@@ -0,0 +1,54 @@
+#ifndef UUSERVLET_H
+#define UUSERVLET_H
+
+#include <servlet/ServletConfig.h>
+#include <servlet/HttpServlet.h>
+#include <servlet/HttpServletRequest.h>
+#include <servlet/HttpServletResponse.h>
+#include <servlet/RequestDispatcher.h>
+#include <string>
+#include <boost/shared_ptr.hpp>
+#include <boost/lexical_cast.hpp>
+#include <stdexcept>
+
+#include "../libdm/User.h"
+
+/**
+  * class UUServlet
+  * This is base class of all UU servlets (both CSP and standard servlets). It
+  * imlements request handling functions (doGet, doPost, etc), which derived
+  * servlets should not touch,
+  * and provides basic login & ACL management.
+  */
+
+class UUServlet : public servlet::HttpServlet
+{
+public:
+  virtual ~UUServlet ( );
+
+  typedef User user_t;
+  typedef boost::shared_ptr<std::string> setAttribute_t;
+
+  /**
+   * Returns true if the request already has valid associated session, and that
+   * session contains valid User object
+   * @return bool
+   * @param  req Request to check
+   */
+  bool isUserLoggedIn (servlet::HttpServletRequest& req ) const;
+
+  /**
+   * Redirects browser to login page
+   * @param  resp send redirect through this response object
+   */
+  void redirectToLogin (servlet::HttpServletRequest& req, servlet::HttpServletResponse& resp);
+
+  /**
+   * @return User
+   * @param  req
+   */
+  User getCurrentUser (servlet::HttpServletRequest& req );
+
+};
+
+#endif // UUSERVLET_H

Index: libui/UUServlet.cpp
===================================================================
--- libui/UUServlet.cpp	(revision 0)
+++ libui/UUServlet.cpp	(revision 0)
@@ -0,0 +1,55 @@
+#include "UUServlet.h"
+
+using namespace std;
+using namespace servlet;
+
+UUServlet::~UUServlet ( ) { }
+
+/**
+ * Returns true if the request already has valid associated session, and that
+ * session contains valid User object
+ * @return bool
+ * @param  req Request to check
+ */
+
+bool UUServlet::isUserLoggedIn (HttpServletRequest& req ) const 
+{
+
+  HttpSession* session = req.getSession(true);
+  if(!session) throw runtime_error("No session exist for this request");
+  string sessionid = session->getId();
+  user_t user;  
+  bool hasValidLogin = user.isSessionInfo(sessionid);
+  return hasValidLogin;
+
+}
+
+
+/**
+ * Redirects browser to login page
+ * @param  resp send redirect through this response object
+ */
+void UUServlet::redirectToLogin (HttpServletRequest& req, HttpServletResponse& resp) 
+{
+  
+  string message = req.getAttribute<string>("Message");
+  if(!message.empty())
+    req.setAttribute("Message", setAttribute_t(new string(message)));
+  req.getRequestDispatcher("LoginView.csp")->forward(req,resp);
+
+}
+
+
+/**
+ * @return User
+ * @param  req
+ */
+User UUServlet::getCurrentUser (HttpServletRequest& req ) 
+{
+
+  user_t user; //FIXME
+  return user;
+  
+}
+
+   


Index: libdm/User.h
===================================================================
--- libdm/User.h	(revision 0)
+++ libdm/User.h	(revision 0)
@@ -0,0 +1,59 @@
+#ifndef USER_H
+#define USER_H
+
+#include <string>
+#include <boost/lexical_cast.hpp>
+#include <map>
+#include <vector>
+
+#include <sptk3/CODBCDatabase.h>
+#include <sptk3/CException.h>
+#include <sptk3/CQuery.h>
+
+#include "uudb.h"
+#include "SessionInfo.h"
+
+/**
+ *This class accesses and alters person_list, city_list tables.
+ */
+
+class User
+{
+public:
+  virtual ~User();
+
+  typedef std::vector<SessionInfo> sessioninfo_t;
+
+  /**
+   * Performs user authentication
+   */
+
+  bool isLoginPasswordValid(std::string login, std::string password);
+
+  /**
+   * Sets data to session_info temp table after successful authentication
+   */
+
+  virtual bool setSessionInfo(std::string login, std::string password, int server, std::string sessionid);
+
+  /**
+   * Gets user data from session_info table. 
+   */
+
+  virtual sessioninfo_t getSessionInfo(std::string sessionid);
+
+  /**
+   * Gets user id from session_info table. Returns true if such user exist
+   */
+
+  virtual bool isSessionInfo(std::string sessionid);
+
+  /**
+   * Sets all user data during a registration process. Calls stored procedure "person_create" to insert user data into "person_list" table. If insert is successful, returns true. Otherwise returns false.
+   */
+
+  virtual bool setUserInfo ( std::string login, std::string password, int language, std::string firstName, std::string lastName, std::string street, std::string city, std::string state, std::string zip, std::string country, std::string email, std::string phone );
+
+};
+
+#endif // USER_H


Index: libdm/User.cpp
===================================================================
--- libdm/User.cpp	(revision 0)
+++ libdm/User.cpp	(revision 0)
@@ -0,0 +1,136 @@
+#include "User.h"
+
+using namespace std;
+using namespace sptk;
+using namespace boost;
+
+User::~User ( ) { }
+
+/**
+ * Performs authentication.
+ * @return bool
+ */
+
+bool User::isLoginPasswordValid(string login, string password) 
+{
+
+  CODBCDatabase db("DSN=PostgreSQL;UID=sergey;PWD=;DATABASE=uu");
+  bool isValid = false;
+  try {
+    CQuery qrySelect(&db,"select pl_id from person_list where pl_login=:login and pl_password=:password");
+    qrySelect.param("login") = login; 
+    qrySelect.param("password") = password; 
+    qrySelect.open();
+    while ( ! qrySelect.eof() ) {
+      isValid = true;
+      qrySelect.fetch();
+    }
+    qrySelect.close();
+  }
+  catch (exception& e) {
+    cout<<"\nError: " <<e.what();
+    return false;
+  }
+  return isValid;
+
+}
+
+/**
+ * Sets data to session_info temp table after successful authentication
+ */
+
+bool User::setSessionInfo(string login, string password, int server, string sessionid) 
+{
+
+  CODBCDatabase db("DSN=PostgreSQL;UID=sergey;PWD=;DATABASE=uu");
+  try {
+    CQuery qryInsert(&db,"select login('"+login+"', '"+password+"', "+lexical_cast<string>(server)+")");
+    qryInsert.exec();
+  }
+  catch (exception& e) {
+    cout<<"\nError: " <<e.what();
+    return false;
+  }
+  return true;
+
+}
+
+/**
+ * Gets user data from session_info table. 
+ */
+
+User::sessioninfo_t User::getSessionInfo(string sessionid) 
+{
+
+  CODBCDatabase db("DSN=PostgreSQL;UID=sergey;PWD=;DATABASE=uu");
+  sessioninfo_t sessioninfo;
+  try {
+    CQuery qrySelect(&db,"select * from session_info where si_session=:sessionid");
+    qrySelect.param("sessionid") = sessionid; 
+    qrySelect.open();
+    CField& idField = qrySelect["si_person"];
+    CField& fnameField = qrySelect["si_person_name"];
+    CField& serverField = qrySelect["si_server"];
+    while ( ! qrySelect.eof() ) {
+      SessionInfo sinfo;
+      sinfo.person_id = idField;
+      sinfo.person_name = fnameField.asString();
+      sinfo.server = serverField;
+      sessioninfo.push_back(sinfo);
+      qrySelect.fetch();
+    }
+    qrySelect.close();
+  }
+  catch (exception& e) {
+    cout<<"\nError: " <<e.what();
+  }
+  return sessioninfo;
+
+}
+
+/**
+ * Gets user id from session_info table. Returns true if such user exist.
+ */
+
+bool User::isSessionInfo(string sessionid) 
+{
+
+  CODBCDatabase db("DSN=PostgreSQL;UID=sergey;PWD=;DATABASE=uu");
+  bool isValid = false;
+  try {
+    CQuery qrySelect(&db,"select si_person from session_info where si_session=:sessionid");
+    qrySelect.param("sessionid") = sessionid; 
+    qrySelect.open();
+    while ( ! qrySelect.eof() ) {
+      isValid = true;
+      qrySelect.fetch();
+    }
+    qrySelect.close();
+  }
+  catch (exception& e) {
+    cout<<"\nError: " <<e.what();
+  }
+  return isValid;
+
+}
+
+/**
+ * Sets all user data during a registration process. Calls stored procedure "person_create" to insert user data into "person_list" table. If insert is successful, returns true. Otherwise returns false.
+ */
+
+bool User::setUserInfo(string login, string password, int language, string firstName, string lastName, string street, string city, string state, string zip, string country, string email, string phone ) 
+{
+
+  CODBCDatabase db("DSN=PostgreSQL;UID=sergey;PWD=;DATABASE=uu");
+  try {
+    CQuery qryInsert(&db,"select person_create('"+firstName+"','"+lastName+"','"+street+"','"+city+"','"+state+"','"+zip+"','"+country+"','"+email+"','"+phone+"','"+login+"','"+password+"')");
+    qryInsert.exec();    
+  }
+  catch (exception& e) {
+    cout<<"\nError: " <<e.what();
+    return false;
+  }
+  return true;
+
+}
+


   
Index: libdm/uudb.h
===================================================================
--- libdm/uudb.h	(revision 0)
+++ libdm/uudb.h	(revision 0)
@@ -0,0 +1,15 @@
+#include <sptk3/CODBCDatabase.h>
+#include <sptk3/CException.h>
+#include <sptk3/CQuery.h>
+
+class uudb 
+{
+ public:
+  uudb();
+  ~uudb();
+
+  sptk::CODBCDatabase handle;
+  void exec(const std::string& query);
+};
+
+extern uudb db;

Index: libdm/uudb.cpp
===================================================================
--- libdm/uudb.cpp	(revision 0)
+++ libdm/uudb.cpp	(revision 0)
@@ -0,0 +1,39 @@
+#include "uudb.h"
+
+uudb db;
+
+using namespace std;
+using namespace sptk;
+
+uudb::uudb() 
+{
+    CODBCDatabase handle("DSN=PostgreSQL;UID=sergey;PWD=;DATABASE=uu");
+    try {
+      cout<<"\nOpening database... \n";
+      handle.open();
+    }
+    catch (exception& e) {
+      cout<<"\nError: " <<e.what();
+      cout<<"\nCan't open the database connection.\n";
+    }    
+}
+
+uudb::~uudb() 
+{
+  try {
+    cout<<"\nClosing database... \n";
+    handle.close();
+  }
+  catch (exception& e) {
+    cout<<"\nError: " <<e.what();
+    cout<<"\nCan't close the database connection\n";
+  }
+}
+
+void uudb::exec(const std::string& query) 
+{
+  CODBCDatabase handle("DSN=PostgreSQL;UID=sergey;PWD=;DATABASE=uu");
+  CQuery qry(&handle, query);
+  qry.exec();
+}
+

   
Index: libdm/SessionInfo.h
===================================================================
--- libdm/SessionInfo.h	(revision 0)
+++ libdm/SessionInfo.h	(revision 0)
@@ -0,0 +1,13 @@
+#ifndef SESSIONINFO_H
+#define SESSIONINFO_H
+
+#include <string>
+
+class SessionInfo {
+ public:
+  long person_id;
+  std::string person_name;
+  int server;
+};
+
+#endif//SESSIONINFO_H

   
   
Index: themes/default/Footer.csp
===================================================================
--- themes/default/Footer.csp	(revision 0)
+++ themes/default/Footer.csp	(revision 0)
@@ -0,0 +1,16 @@
+<!-- Footer -->
+
+</td>
+</tr>
+</table>
+            </TD>
+        </TR>
+    </TABLE>
+
+	    </CENTER><br>
+<P ALIGN="CENTER">
+	<font face=verdana size=1><A HREF="http://www.total-knowledge.com/copyleft.shtml"; TARGET="_new">
+	Authoright  &copy; Total Knowledge: 2001-2007</A></font>
+</P>
+</BODY>
+</HTML>
\ No newline at end of file

Index: themes/default/Header.csp
===================================================================
--- themes/default/Header.csp	(revision 0)
+++ themes/default/Header.csp	(revision 0)
@@ -0,0 +1,47 @@
+
+
+<HTML>
+<HEAD>
+<!-- <link href="styles.css" rel="stylesheet" media="screen"> -->
+<TITLE>TEST</TITLE>
+</HEAD>
+
+<BODY BGCOLOR="#FFFFF8" link="#003399" vlink="#003399">
+<CENTER><br>
+
+<!-- Header -->
+
+<TABLE width="770" border=0>
+<TR>
+<TD BGCOLOR="#3388FF" align="center">
+<table width="100%" border=1 cellpadding=1 cellspacing=0 class="st">
+
+<tr>
+<td align="center" width="16%" height="25">
+<FONT SIZE=2 face=verdana><a href="HomeServlet" class="headerLink"><B>HOME<B></a></FONT>
+</td>
+<td align="center" width="20%">
+<FONT SIZE=2 face=verdana><a href="RegisterServlet?new=Y" class="headerLinkOn"><B>REGISTRATION<B></a></FONT>
+</td>
+<td align="center" width="16%">
+<FONT SIZE=2 face=verdana><a href="LoginServlet?new=Y" class="headerLink"><B>LOGIN<B></a></FONT>
+</td>
+<td align="center" width="16%">
+<FONT SIZE=2 face=verdana><a href="Intro.html" class="headerLink"><B>ABOUT US<B></a></FONT>
+</td>
+
+<td align="center" width="16%">
+<FONT SIZE=2 face=verdana><a href="Policies.html" class="headerLink"><B>POLICIES<B></a></FONT>
+</td>
+<td align="center" width="16%">
+<FONT SIZE=2 face=verdana><a href="Help.html" class="headerLink"><B>HELP<B></a></FONT>
+</td>
+</tr>
+</table>
+
+</TD>
+</TR>
+
+<!-- End Header -->
+
+

Index: themes/default/Sidebar.csp
===================================================================
--- themes/default/Sidebar.csp	(revision 0)
+++ themes/default/Sidebar.csp	(revision 0)
@@ -0,0 +1,87 @@
+<!-- Side Bar -->
+
+        <TR>
+            <TD ALIGN="center" BGCOLOR="#DDEEFF">
+<table  width="770" border=0 cellpadding=4 cellspacing=0>        
+<TR>
+            <TD ALIGN="left" valign="top" BGCOLOR="#99CCFF" width="17%">
+<table width=100% cellpadding=4 cellspacing=4 border=0>
+<tr><form action="SearchResults.html" name="search">
+<td>
+<font face=verdana size=2 color="#003399"><b>Search</b></font><br>
+<font face=verdana size=2><input type="text" name="search" value="" size="4"></font>&nbsp;<font face=verdana size=2><input type="submit" name="go" value="go" style="background-color:#DDEEFF; color: #003399;"></font></td>
+
+</tr>
+<tr>
+<td>
+<font face=verdana size=1><A HREF="AdvancedSearch.html" class="navbarLink">Advanced Search</A></font><br>
+</td></form>
+</tr>
+
+
+<tr><td><hr color="#003399"></td></tr>
+<tr>
+<td>
+<font face=verdana size=2><A HREF="Repository.html" class="navbarLink"><b>My UMOs</b></A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="RepositoryCourses.html" class="navbarLink">Courses</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="RepositoryTopics.html" class="navbarLink">Topics</A></font><br>
+
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="RepositoryProblems.html" class="navbarLink">Problems</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="RepositoryExplanations.html" class="navbarLink">Explanations</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="RepositoryTests.html" class="navbarLink">Tests</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="RepositoryDialogs.html" class="navbarLink">Dialogs</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="RepositoryTexts.html" class="navbarLink">Texts</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="CustomEdit.html" class="navbarLink">Advertising</A></font><br><br>
+<font face=verdana size=2><A HREF="#" class="navbarLink"><b>Create New</b></A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="CourseCreate.html" class="navbarLink">Course</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="TopicCreate.html" class="navbarLink">Topic</A></font><br>
+
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="ProblemCreate.html" class="navbarLink">Problem</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="ExplanationCreate.html" class="navbarLink">Explanation</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="TestCreate.html" class="navbarLink">Test</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="DialogCreate.html" class="navbarLink">Dialog</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="TextCreate.html" class="navbarLink">Text</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="CustomCreate.html" class="navbarLink">Custom UMO</A></font><br></td>
+</tr>
+
+
+<tr><td><hr color="#003399"></td></tr>
+<tr>
+
+<td>
+<font face=verdana size=2><A HREF="RepositoryAll.html" class="navbarLink"><b>All UMOs</b></A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="RepositoryCourses.html" class="navbarLink">Courses</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="RepositoryTopics.html" class="navbarLink">Topics</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="RepositoryProblems.html" class="navbarLink">Problems</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="RepositoryExplanations.html" class="navbarLink">Explanations</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="RepositoryTests.html" class="navbarLink">Tests</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="RepositoryDialogs.html" class="navbarLink">Dialogs</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="RepositoryTexts.html" class="navbarLink">Texts</A></font><br>
+
+<br>
+
+<font face=verdana size=2><A HREF="SearchResults.html" class="navbarLink"><b>Catalog</b></A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="CatalogCourses.html" class="navbarLink">Courses</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="CatalogTopics.html" class="navbarLink">Topics</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="CatalogProblems.html" class="navbarLink">Problems</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="CatalogExplanations.html" class="navbarLink">Explanations</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="CatalogTests.html" class="navbarLink">Tests</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="CatalogDialogs.html" class="navbarLink">Dialogs</A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="CatalogTexts.html" class="navbarLink">Texts</A></font><br>
+
+
+</td>
+</tr>
+
+<tr><td><hr color="#003399"></td></tr>
+<tr>
+<td><font face=verdana size=2><A HREF="Basket.html" class="navbarLink"><b>My Basket</b></A></font><br>
+<font face=verdana size=1 color="#003399">&#149&nbsp;<A HREF="Basket.html" class="navbarLink">3 UMOs</a></font><br><br>
+</td>
+</tr>
+</table>
+            </TD>
+
+<!-- End Side Bar -->
+
+
   

Authoright © Total Knowledge: 2001-2008