Wt examples  4.0.5
Session.C
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011 Emweb bvba, Heverlee, 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 }
C * modify() const
ptr< C > add(ptr< C > &ptr)
Query< ptr< C >, BindStrategy > find(const std::string &condition=std::string())
Dbo::Session session_
Definition: Session.h:50
bool loggedIn() const
WString identity(const std::string &provider) const
std::string userName() const
Definition: Session.C:150
Auth::AbstractUserDatabase & users()
Definition: Session.C:210
Session()
Definition: Session.C:98
int findRanking()
Definition: Session.C:194
Definition: User.h:26
static const Auth::AuthService & auth()
Definition: Session.C:215
std::string toUTF8() const
int gamesPlayed
Definition: User.h:32
long long score
Definition: User.h:33
void setUser(Wt::Dbo::ptr< UserType > user)
static const std::vector< const Auth::OAuthService * > & oAuth()
Definition: Session.C:225
WDateTime lastGame
Definition: User.h:34
static void configureAuth()
Definition: Session.C:75
const User & user() const
Wt::Dbo::ptr< UserType > user() const
void addIdentity(const std::string &provider, const WString &identity)
Dbo::ptr< User > user() const
Definition: Session.C:134
std::unique_ptr< UserDatabase > users_
Definition: Session.h:51
void mapClass(const char *tableName)
std::vector< User > topUsers(int limit)
Definition: Session.C:172
~Session()
Definition: Session.C:130
static const Auth::AbstractPasswordService & passwordAuth()
Definition: Session.C:220
void addToScore(int s)
Definition: Session.C:158
void setConnection(std::unique_ptr< SqlConnection > connection)
Query< Result, BindStrategy > query(const std::string &sql)
Auth::Login login_
Definition: Session.h:52

Generated on Mon May 20 2019 for the C++ Web Toolkit (Wt) by doxygen 1.8.14