Wt examples  4.10.4
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 using namespace Wt;
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  Auth::AuthService myAuthService;
61  Auth::PasswordService myPasswordService(myAuthService);
62  std::vector<std::unique_ptr<const Auth::OAuthService>> myOAuthServices;
63 }
64 
66 {
67  myAuthService.setAuthTokensEnabled(true, "hangmancookie");
68  myAuthService.setEmailVerificationEnabled(true);
69 
70  auto verifier = std::make_unique<Auth::PasswordVerifier>();
71  verifier->addHashFunction(std::make_unique<Auth::BCryptHashFunction>(7));
72 
73 #ifdef HAVE_CRYPT
74  // We want to still support users registered in the pre - Wt::Auth
75  // version of the hangman example
76  verifier->addHashFunction(std::make_unique<UnixCryptHashFunction>());
77 #endif
78 
79  myPasswordService.setVerifier(std::move(verifier));
80  myPasswordService.setStrengthValidator(std::make_unique<Auth::PasswordStrengthValidator>());
81  myPasswordService.setAttemptThrottlingEnabled(true);
82 
84  myOAuthServices.push_back(std::make_unique<Auth::GoogleService>(myAuthService));
85  }
86 }
87 
89 {
90  auto sqlite3 = std::make_unique<Dbo::backend::Sqlite3>(WApplication::instance()->appRoot() + "hangman.db");
91  sqlite3->setProperty("show-queries", "true");
92  session_.setConnection(std::move(sqlite3));
93 
94  session_.mapClass<User>("user");
95  session_.mapClass<AuthInfo>("auth_info");
96  session_.mapClass<AuthInfo::AuthIdentityType>("auth_identity");
97  session_.mapClass<AuthInfo::AuthTokenType>("auth_token");
98 
99  users_ = std::make_unique<UserDatabase>(session_);
100 
101  dbo::Transaction transaction(session_);
102  try {
103  session_.createTables();
104 
105  /*
106  * Add a default guest/guest account
107  */
108  Auth::User guestUser = users_->registerNew();
109  guestUser.addIdentity(Auth::Identity::LoginName, "guest");
110  myPasswordService.updatePassword(guestUser, "guest");
111 
112  log("info") << "Database created";
113  } catch (...) {
114  log("info") << "Using existing database";
115  }
116 
117  transaction.commit();
118 }
119 
121 {
122  if (login_.loggedIn()) {
123  dbo::ptr<AuthInfo> authInfo = users_->find(login_.user());
124  dbo::ptr<User> user = authInfo->user();
125 
126  if (!user) {
127  user = session_.add(std::make_unique<User>());
128  authInfo.modify()->setUser(user);
129  }
130 
131  return user;
132  } else
133  return dbo::ptr<User>();
134 }
135 
136 std::string Session::userName() const
137 {
138  if (login_.loggedIn())
139  return login_.user().identity(Auth::Identity::LoginName).toUTF8();
140  else
141  return std::string();
142 }
143 
145 {
146  dbo::Transaction transaction(session_);
147 
148  dbo::ptr<User> u = user();
149  if (u) {
150  u.modify()->score += s;
151  ++u.modify()->gamesPlayed;
152  u.modify()->lastGame = WDateTime::currentDateTime();
153  }
154 
155  transaction.commit();
156 }
157 
158 std::vector<User> Session::topUsers(int limit)
159 {
160  dbo::Transaction transaction(session_);
161 
162  Users top = session_.find<User>().orderBy("score desc").limit(limit);
163 
164  std::vector<User> result;
165  for (Users::const_iterator i = top.begin(); i != top.end(); ++i) {
166  dbo::ptr<User> user = *i;
167  result.push_back(*user);
168 
169  dbo::ptr<AuthInfo> auth = user->authInfo;
170  std::string name = auth->identity(Auth::Identity::LoginName).toUTF8();
171 
172  result.back().name = name;
173  }
174 
175  transaction.commit();
176 
177  return result;
178 }
179 
181 {
182  dbo::Transaction transaction(session_);
183 
184  dbo::ptr<User> u = user();
185  int ranking = -1;
186 
187  if (u)
188  ranking = session_.query<int>("select distinct count(score) from user")
189  .where("score > ?").bind(u->score);
190 
191  transaction.commit();
192 
193  return ranking + 1;
194 }
195 
197 {
198  return *users_;
199 }
200 
202 {
203  return myAuthService;
204 }
205 
207 {
208  return myPasswordService;
209 }
210 
211 std::vector<const Auth::OAuthService *> Session::oAuth()
212 {
213  std::vector<const Auth::OAuthService *> result;
214  result.reserve(myOAuthServices.size());
215  for (const auto& service : myOAuthServices) {
216  result.push_back(service.get());
217  }
218  return result;
219 }
static void configureAuth()
Definition: Session.C:65
static const Wt::Auth::AbstractPasswordService & passwordAuth()
Definition: Session.C:206
std::vector< User > topUsers(int limit)
Definition: Session.C:158
std::string userName() const
Definition: Session.C:136
static const Wt::Auth::AuthService & auth()
Definition: Session.C:201
Wt::Dbo::ptr< User > user() const
Definition: Session.C:120
int findRanking()
Definition: Session.C:180
Session()
Definition: Session.C:88
static std::vector< const Wt::Auth::OAuthService * > oAuth()
Definition: Session.C:211
Wt::Auth::AbstractUserDatabase & users()
Definition: Session.C:196
void addToScore(int s)
Definition: Session.C:144
Definition: User.h:25
static bool configured()
static const std::string LoginName
void addIdentity(const std::string &provider, const WString &identity)
Query< C, DynamicBinding > find() const
C * modify() const
static WApplication * instance()
static WDateTime currentDateTime()