Wt examples: /home/koen/project/wt/public-git/wt/examples/hangman/Session.C Source File

Wt examples 3.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

/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 }