Wt examples  3.2.1
/home/koen/project/wt/public-git/wt/examples/hangman/Session.C
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2011 Emweb bvba, Heverlee, Belgium.
00003  *
00004  * See the LICENSE file for terms of use.
00005  */
00006 
00007 #include "Session.h"
00008 
00009 #include "Wt/Auth/AuthService"
00010 #include "Wt/Auth/HashFunction"
00011 #include "Wt/Auth/PasswordService"
00012 #include "Wt/Auth/PasswordStrengthValidator"
00013 #include "Wt/Auth/PasswordVerifier"
00014 #include "Wt/Auth/GoogleService"
00015 #include "Wt/Auth/Dbo/AuthInfo"
00016 #include "Wt/Auth/Dbo/UserDatabase"
00017 
00018 #include <Wt/WApplication>
00019 #include <Wt/WLogger>
00020 
00021 #ifndef WIN32
00022 #include <unistd.h>
00023 #endif
00024 
00025 #if !defined(WIN32) && !defined(__CYGWIN__) && !defined(ANDROID)
00026 #define HAVE_CRYPT
00027 #endif
00028 
00029 using namespace Wt;
00030 namespace dbo = Wt::Dbo;
00031 
00032 namespace {
00033 
00034 #ifdef HAVE_CRYPT
00035 class UnixCryptHashFunction : public Auth::HashFunction
00036   {
00037   public:
00038     virtual std::string compute(const std::string& msg, 
00039                                 const std::string& salt) const
00040     {
00041       std::string md5Salt = "$1$" + salt;
00042       return crypt(msg.c_str(), md5Salt.c_str());
00043     }
00044 
00045     virtual bool verify(const std::string& msg,
00046                         const std::string& salt,
00047                         const std::string& hash) const
00048     {
00049       return crypt(msg.c_str(), hash.c_str()) == hash;
00050     }
00051 
00052     virtual std::string name () const {
00053       return "crypt";
00054     }
00055   };
00056 #endif // HAVE_CRYPT
00057 
00058   class MyOAuth : public std::vector<const Auth::OAuthService *>
00059   {
00060   public:
00061     ~MyOAuth()
00062     {
00063       for (unsigned i = 0; i < size(); ++i)
00064         delete (*this)[i];
00065     }
00066   };
00067 
00068   Auth::AuthService myAuthService;
00069   Auth::PasswordService myPasswordService(myAuthService);
00070   MyOAuth myOAuthServices;
00071 }
00072 
00073 void Session::configureAuth()
00074 {
00075   myAuthService.setAuthTokensEnabled(true, "hangmancookie");
00076   myAuthService.setEmailVerificationEnabled(true);
00077 
00078   Auth::PasswordVerifier *verifier = new Auth::PasswordVerifier();
00079   verifier->addHashFunction(new Auth::BCryptHashFunction(7));
00080 
00081 #ifdef HAVE_CRYPT
00082   // We want to still support users registered in the pre - Wt::Auth
00083   // version of the hangman example
00084   verifier->addHashFunction(new UnixCryptHashFunction());
00085 #endif
00086 
00087   myPasswordService.setVerifier(verifier);
00088   myPasswordService.setStrengthValidator(new Auth::PasswordStrengthValidator());
00089   myPasswordService.setAttemptThrottlingEnabled(true);
00090 
00091   if (Auth::GoogleService::configured())
00092     myOAuthServices.push_back(new Auth::GoogleService(myAuthService));
00093 }
00094 
00095 Session::Session()
00096   : sqlite3_(WApplication::instance()->appRoot() + "hangman.db")
00097 {
00098   session_.setConnection(sqlite3_);
00099   sqlite3_.setProperty("show-queries", "true");
00100 
00101   session_.mapClass<User>("user");
00102   session_.mapClass<AuthInfo>("auth_info");
00103   session_.mapClass<AuthInfo::AuthIdentityType>("auth_identity");
00104   session_.mapClass<AuthInfo::AuthTokenType>("auth_token");
00105 
00106   users_ = new UserDatabase(session_);
00107 
00108   dbo::Transaction transaction(session_);
00109   try {
00110     session_.createTables();
00111 
00112     /*
00113      * Add a default guest/guest account
00114      */
00115     Auth::User guestUser = users_->registerNew();
00116     guestUser.addIdentity(Auth::Identity::LoginName, "guest");
00117     myPasswordService.updatePassword(guestUser, "guest");
00118 
00119     Wt::log("info") << "Database created";
00120   } catch (...) {
00121     Wt::log("info") << "Using existing database";
00122   }
00123 
00124   transaction.commit();
00125 }
00126 
00127 Session::~Session()
00128 {
00129   delete users_;
00130 }
00131 
00132 dbo::ptr<User> Session::user() const
00133 {
00134   if (login_.loggedIn()) {
00135     dbo::ptr<AuthInfo> authInfo = users_->find(login_.user());
00136     dbo::ptr<User> user = authInfo->user();
00137 
00138     if (!user) {
00139       user = session_.add(new User());
00140       authInfo.modify()->setUser(user);
00141     }
00142 
00143     return user;
00144   } else
00145     return dbo::ptr<User>();
00146 }
00147 
00148 std::string Session::userName() const
00149 {
00150   if (login_.loggedIn())
00151     return login_.user().identity(Auth::Identity::LoginName).toUTF8();
00152   else
00153     return std::string();
00154 }
00155 
00156 void Session::addToScore(int s)
00157 {
00158   dbo::Transaction transaction(session_);
00159 
00160   dbo::ptr<User> u = user();
00161   if (u) {
00162     u.modify()->score += s;
00163     ++u.modify()->gamesPlayed;
00164     u.modify()->lastGame = WDateTime::currentDateTime();
00165   }
00166 
00167   transaction.commit();
00168 }
00169 
00170 std::vector<User> Session::topUsers(int limit)
00171 {
00172   dbo::Transaction transaction(session_);
00173 
00174   Users top = session_.find<User>().orderBy("score desc").limit(20);
00175 
00176   std::vector<User> result;
00177   for (Users::const_iterator i = top.begin(); i != top.end(); ++i) {
00178     dbo::ptr<User> user = *i;
00179     result.push_back(*user);
00180  
00181     dbo::ptr<AuthInfo> auth = *user->authInfos.begin();
00182     std::string name = auth->identity(Auth::Identity::LoginName).toUTF8();
00183 
00184     result.back().name = name;
00185   }
00186 
00187   transaction.commit();
00188 
00189   return result;
00190 }
00191 
00192 int Session::findRanking()
00193 {
00194   dbo::Transaction transaction(session_);
00195   
00196   dbo::ptr<User> u = user();
00197   int ranking = -1;
00198 
00199   if (u)
00200     ranking = session_.query<int>("select distinct count(score) from user")
00201       .where("score > ?").bind(u->score);
00202 
00203   transaction.commit();
00204   
00205   return ranking + 1;
00206 }
00207 
00208 Auth::AbstractUserDatabase& Session::users()
00209 {
00210   return *users_;
00211 }
00212 
00213 const Auth::AuthService& Session::auth()
00214 {
00215   return myAuthService;
00216 }
00217 
00218 const Auth::AbstractPasswordService& Session::passwordAuth()
00219 {
00220   return myPasswordService;
00221 }
00222 
00223 const std::vector<const Auth::OAuthService *>& Session::oAuth()
00224 {
00225   return myOAuthServices;
00226 }

Generated on Fri Mar 30 2012 for the C++ Web Toolkit (Wt) by doxygen 1.7.5.1