Wt examples  4.2.2
Session.C
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011 Emweb bv, Herent, Belgium.
3  *
4  * See the LICENSE file for terms of use.
5  */
6 
7 #include "Session.h"
8 
9 #include "Wt/Auth/AuthService.h"
10 #include "Wt/Auth/HashFunction.h"
11 #include "Wt/Auth/PasswordService.h"
12 #include "Wt/Auth/PasswordStrengthValidator.h"
13 #include "Wt/Auth/PasswordVerifier.h"
14 #include "Wt/Auth/GoogleService.h"
15 #include "Wt/Auth/Dbo/AuthInfo.h"
16 #include "Wt/Auth/Dbo/UserDatabase.h"
17 
18 #include <Wt/WApplication.h>
19 #include <Wt/WLogger.h>
20 
21 #ifndef WT_WIN32
22 #include <unistd.h>
23 #endif
24 
25 #if !defined(WT_WIN32) && !defined(__CYGWIN__) && !defined(ANDROID)
26 #define HAVE_CRYPT
27 #ifndef _XOPEN_CRYPT
28 #include <crypt.h>
29 #endif // _XOPEN_CRYPT
30 #endif
31 
32 namespace dbo = Wt::Dbo;
33 
34 namespace {
35 
36 #ifdef HAVE_CRYPT
37 class UnixCryptHashFunction : public Auth::HashFunction
38  {
39  public:
40  virtual std::string compute(const std::string& msg,
41  const std::string& salt) const
42  {
43  std::string md5Salt = "$1$" + salt;
44  return crypt(msg.c_str(), md5Salt.c_str());
45  }
46 
47  virtual bool verify(const std::string& msg,
48  const std::string& salt,
49  const std::string& hash) const
50  {
51  return crypt(msg.c_str(), hash.c_str()) == hash;
52  }
53 
54  virtual std::string name () const {
55  return "crypt";
56  }
57  };
58 #endif // HAVE_CRYPT
59 
60  class MyOAuth : public std::vector<const Auth::OAuthService *>
61  {
62  public:
63  ~MyOAuth()
64  {
65  for (unsigned i = 0; i < size(); ++i)
66  delete (*this)[i];
67  }
68  };
69 
70  Auth::AuthService myAuthService;
71  Auth::PasswordService myPasswordService(myAuthService);
72  MyOAuth myOAuthServices;
73 }
74 
76 {
77  myAuthService.setAuthTokensEnabled(true, "hangmancookie");
78  myAuthService.setEmailVerificationEnabled(true);
79 
80  std::unique_ptr<Auth::PasswordVerifier> verifier
81  = cpp14::make_unique<Auth::PasswordVerifier>();
82  verifier->addHashFunction(cpp14::make_unique<Auth::BCryptHashFunction>(7));
83 
84 #ifdef HAVE_CRYPT
85  // We want to still support users registered in the pre - Wt::Auth
86  // version of the hangman example
87  verifier->addHashFunction(cpp14::make_unique<UnixCryptHashFunction>());
88 #endif
89 
90  myPasswordService.setVerifier(std::move(verifier));
91  myPasswordService.setStrengthValidator(cpp14::make_unique<Auth::PasswordStrengthValidator>());
92  myPasswordService.setAttemptThrottlingEnabled(true);
93 
94  if (Auth::GoogleService::configured())
95  myOAuthServices.push_back(new Auth::GoogleService(myAuthService));
96 }
97 
99 {
100  auto sqlite3 = cpp14::make_unique<Dbo::backend::Sqlite3>(WApplication::instance()->appRoot() + "hangman.db");
101  sqlite3->setProperty("show-queries", "true");
102  session_.setConnection(std::move(sqlite3));
103 
104  session_.mapClass<User>("user");
105  session_.mapClass<AuthInfo>("auth_info");
106  session_.mapClass<AuthInfo::AuthIdentityType>("auth_identity");
108 
109  users_ = cpp14::make_unique<UserDatabase>(session_);
110 
111  dbo::Transaction transaction(session_);
112  try {
114 
115  /*
116  * Add a default guest/guest account
117  */
118  Auth::User guestUser = users_->registerNew();
119  guestUser.addIdentity(Auth::Identity::LoginName, "guest");
120  myPasswordService.updatePassword(guestUser, "guest");
121 
122  log("info") << "Database created";
123  } catch (...) {
124  log("info") << "Using existing database";
125  }
126 
127  transaction.commit();
128 }
129 
131 {
132 }
133 
135 {
136  if (login_.loggedIn()) {
137  dbo::ptr<AuthInfo> authInfo = users_->find(login_.user());
138  dbo::ptr<User> user = authInfo->user();
139 
140  if (!user) {
141  user = session_.add(Wt::cpp14::make_unique<User>());
142  authInfo.modify()->setUser(user);
143  }
144 
145  return user;
146  } else
147  return dbo::ptr<User>();
148 }
149 
150 std::string Session::userName() const
151 {
152  if (login_.loggedIn())
153  return login_.user().identity(Auth::Identity::LoginName).toUTF8();
154  else
155  return std::string();
156 }
157 
159 {
160  dbo::Transaction transaction(session_);
161 
162  dbo::ptr<User> u = user();
163  if (u) {
164  u.modify()->score += s;
165  ++u.modify()->gamesPlayed;
166  u.modify()->lastGame = WDateTime::currentDateTime();
167  }
168 
169  transaction.commit();
170 }
171 
172 std::vector<User> Session::topUsers(int limit)
173 {
174  dbo::Transaction transaction(session_);
175 
176  Users top = session_.find<User>().orderBy("score desc").limit(limit);
177 
178  std::vector<User> result;
179  for (Users::const_iterator i = top.begin(); i != top.end(); ++i) {
180  dbo::ptr<User> user = *i;
181  result.push_back(*user);
182 
183  dbo::ptr<AuthInfo> auth = *user->authInfos.begin();
184  std::string name = auth->identity(Auth::Identity::LoginName).toUTF8();
185 
186  result.back().name = name;
187  }
188 
189  transaction.commit();
190 
191  return result;
192 }
193 
195 {
196  dbo::Transaction transaction(session_);
197 
198  dbo::ptr<User> u = user();
199  int ranking = -1;
200 
201  if (u)
202  ranking = session_.query<int>("select distinct count(score) from user")
203  .where("score > ?").bind(u->score);
204 
205  transaction.commit();
206 
207  return ranking + 1;
208 }
209 
211 {
212  return *users_;
213 }
214 
216 {
217  return myAuthService;
218 }
219 
221 {
222  return myPasswordService;
223 }
224 
225 const std::vector<const Auth::OAuthService *>& Session::oAuth()
226 {
227  return myOAuthServices;
228 }
Session::findRanking
int findRanking()
Definition: Session.C:194
Wt::Dbo::Session::createTables
void createTables()
Session::login_
Auth::Login login_
Definition: Session.h:52
Session::addToScore
void addToScore(int s)
Definition: Session.C:158
Wt::Dbo
Wt::Auth::HashFunction
Session::configureAuth
static void configureAuth()
Definition: Session.C:75
Wt::Auth::User
Session::user
Dbo::ptr< User > user() const
Definition: Session.C:134
Wt::Auth::AbstractUserDatabase
Wt::Auth::Dbo::AuthInfo
Wt::Dbo::collection::end
iterator end()
Session::oAuth
static const std::vector< const Auth::OAuthService * > & oAuth()
Definition: Session.C:225
Wt::Dbo::Session::mapClass
void mapClass(const char *tableName)
Wt::Dbo::collection::begin
iterator begin()
Wt::Dbo::ptr
Wt::Auth::Dbo::AuthToken
Session::users_
std::unique_ptr< UserDatabase > users_
Definition: Session.h:51
Wt::Auth::Login::user
const User & user() const
Session::passwordAuth
static const Auth::AbstractPasswordService & passwordAuth()
Definition: Session.C:220
Wt::Auth::AuthService
Wt::Auth::PasswordService
Session::Session
Session()
Definition: Session.C:98
Wt::Auth::Login::loggedIn
bool loggedIn() const
Wt::Dbo::collection
Wt::Dbo::Session::setConnection
void setConnection(std::unique_ptr< SqlConnection > connection)
Wt::Auth::GoogleService
Session::~Session
~Session()
Definition: Session.C:130
Session::users
Auth::AbstractUserDatabase & users()
Definition: Session.C:210
Wt::Dbo::Transaction
Session::auth
static const Auth::AuthService & auth()
Definition: Session.C:215
Session::topUsers
std::vector< User > topUsers(int limit)
Definition: Session.C:172
Wt::Dbo::ptr::modify
C * modify() const
Wt::Auth::User::identity
WString identity(const std::string &provider) const
Wt::WString::toUTF8
std::string toUTF8() const
Wt::Auth::AbstractPasswordService
Wt::Dbo::Session::query
Query< Result, BindStrategy > query(const std::string &sql)
Wt::Dbo::collection::const_iterator
Wt::Dbo::Session::find
Query< ptr< C >, BindStrategy > find(const std::string &condition=std::string())
Wt::Auth::Dbo::AuthIdentity
Session::session_
Dbo::Session session_
Definition: Session.h:50
Wt::Dbo::Session::add
ptr< C > add(ptr< C > &ptr)
User
Definition: User.h:26
Wt::Auth::User::addIdentity
void addIdentity(const std::string &provider, const WString &identity)
Session.h
Session::userName
std::string userName() const
Definition: Session.C:150
Wt::Dbo::Transaction::commit
bool commit()

Generated on Fri Mar 20 2020 for the C++ Web Toolkit (Wt) by doxygen 1.8.17