pion-net  4.0.9
PionUser.hpp
1 // ------------------------------------------------------------------
2 // pion-net: a C++ framework for building lightweight HTTP interfaces
3 // ------------------------------------------------------------------
4 // Copyright (C) 2007-2008 Atomic Labs, Inc. (http://www.atomiclabs.com)
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // See http://www.boost.org/LICENSE_1_0.txt
8 //
9 
10 #ifndef __PION_PIONUSER_HEADER__
11 #define __PION_PIONUSER_HEADER__
12 
13 #include <map>
14 #include <string>
15 #include <cstring>
16 #include <boost/shared_ptr.hpp>
17 #include <boost/noncopyable.hpp>
18 #include <boost/thread/mutex.hpp>
19 #include <boost/numeric/conversion/cast.hpp>
20 #include <pion/PionConfig.hpp>
21 #include <pion/PionException.hpp>
22 
23 #ifdef PION_HAVE_SSL
24  #include <openssl/sha.h>
25 #endif
26 
27 namespace pion { // begin namespace pion
28 namespace net { // begin namespace net (Pion Network Library)
29 
30 
34 class PionUser :
35  private boost::noncopyable
36 {
37 public:
38 
40  class BadPasswordHash : public std::exception {
41  public:
42  virtual const char* what() const throw() {
43  return "Invalid password hash provided";
44  }
45  };
46 
47 
49  PionUser(std::string const &username) :
50  m_username(username)
51  {}
52 
54  PionUser(std::string const &username, std::string const &password) :
55  m_username(username)
56  {
57  setPassword(password);
58  }
59 
61  virtual ~PionUser() {}
62 
64  std::string const & getUsername() const { return m_username; }
65 
67  std::string const & getPassword() const { return m_password; }
68 
74  virtual bool matchPassword(const std::string& password) const {
75 #ifdef PION_HAVE_SSL
76  unsigned char sha1_hash[SHA_DIGEST_LENGTH];
77  SHA1(reinterpret_cast<const unsigned char *>(password.data()), password.size(), sha1_hash);
78  return (memcmp(sha1_hash, m_password_hash, SHA_DIGEST_LENGTH) == 0);
79 #else
80  return m_password == password;
81 #endif
82  }
83 
85  virtual void setPassword(const std::string& password) {
86 #ifdef PION_HAVE_SSL
87  // store encrypted hash value
88  SHA1((const unsigned char *)password.data(), password.size(), m_password_hash);
89 
90  // update password string (convert binary to hex)
91  m_password.clear();
92  char buf[3];
93  for (unsigned int n = 0; n < SHA_DIGEST_LENGTH; ++n) {
94  sprintf(buf, "%.2x", static_cast<unsigned int>(m_password_hash[n]));
95  m_password += buf;
96  }
97 #else
98  m_password = password;
99 #endif
100  }
101 
102 #ifdef PION_HAVE_SSL
103  virtual void setPasswordHash(const std::string& password_hash) {
105  // update password string representation
106  if (password_hash.size() != SHA_DIGEST_LENGTH*2)
107  throw BadPasswordHash();
108  m_password = password_hash;
109 
110  // convert string from hex to binary value
111  char buf[3];
112  buf[2] = '\0';
113  unsigned int hash_pos = 0;
114  std::string::iterator str_it = m_password.begin();
115  while (str_it != m_password.end()) {
116  buf[0] = *str_it;
117  ++str_it;
118  buf[1] = *str_it;
119  ++str_it;
120  m_password_hash[hash_pos++] = boost::numeric_cast<unsigned char>(strtoul(buf, 0, 16));
121  }
122  }
123 #endif
124 
125 
126 protected:
127 
129  const std::string m_username;
130 
132  std::string m_password;
133 
134 #ifdef PION_HAVE_SSL
135  unsigned char m_password_hash[SHA_DIGEST_LENGTH];
137 #endif
138 };
139 
141 typedef boost::shared_ptr<PionUser> PionUserPtr;
142 
143 
148  private boost::noncopyable
149 {
150 public:
151 
154 
156  virtual ~PionUserManager() {}
157 
159  inline bool empty(void) const {
160  boost::mutex::scoped_lock lock(m_mutex);
161  return m_users.empty();
162  }
163 
172  virtual bool addUser(const std::string &username,
173  const std::string &password)
174  {
175  boost::mutex::scoped_lock lock(m_mutex);
176  UserMap::iterator i = m_users.find(username);
177  if (i!=m_users.end())
178  return false;
179  PionUserPtr user(new PionUser(username, password));
180  m_users.insert(std::make_pair(username, user));
181  return true;
182  }
183 
192  virtual bool updateUser(const std::string &username,
193  const std::string &password)
194  {
195  boost::mutex::scoped_lock lock(m_mutex);
196  UserMap::iterator i = m_users.find(username);
197  if (i==m_users.end())
198  return false;
199  i->second->setPassword(password);
200  return true;
201  }
202 
203 #ifdef PION_HAVE_SSL
204 
212  virtual bool addUserHash(const std::string &username,
213  const std::string &password_hash)
214  {
215  boost::mutex::scoped_lock lock(m_mutex);
216  UserMap::iterator i = m_users.find(username);
217  if (i!=m_users.end())
218  return false;
219  PionUserPtr user(new PionUser(username));
220  user->setPasswordHash(password_hash);
221  m_users.insert(std::make_pair(username, user));
222  return true;
223  }
224 
233  virtual bool updateUserHash(const std::string &username,
234  const std::string &password_hash)
235  {
236  boost::mutex::scoped_lock lock(m_mutex);
237  UserMap::iterator i = m_users.find(username);
238  if (i==m_users.end())
239  return false;
240  i->second->setPasswordHash(password_hash);
241  return true;
242  }
243 #endif
244 
250  virtual bool removeUser(const std::string &username) {
251  boost::mutex::scoped_lock lock(m_mutex);
252  UserMap::iterator i = m_users.find(username);
253  if (i==m_users.end())
254  return false;
255  m_users.erase(i);
256  return true;
257  }
258 
262  virtual PionUserPtr getUser(const std::string &username) {
263  boost::mutex::scoped_lock lock(m_mutex);
264  UserMap::const_iterator i = m_users.find(username);
265  if (i==m_users.end())
266  return PionUserPtr();
267  else
268  return i->second;
269  }
270 
274  virtual PionUserPtr getUser(const std::string& username, const std::string& password) {
275  boost::mutex::scoped_lock lock(m_mutex);
276  UserMap::const_iterator i = m_users.find(username);
277  if (i==m_users.end() || !i->second->matchPassword(password))
278  return PionUserPtr();
279  else
280  return i->second;
281  }
282 
283 
284 protected:
285 
287  typedef std::map<std::string, PionUserPtr> UserMap;
288 
289 
291  mutable boost::mutex m_mutex;
292 
295 };
296 
298 typedef boost::shared_ptr<PionUserManager> PionUserManagerPtr;
299 
300 
301 } // end namespace net
302 } // end namespace pion
303 
304 #endif
virtual bool addUser(const std::string &username, const std::string &password)
Definition: PionUser.hpp:172
std::string const & getUsername() const
returns user name as a string
Definition: PionUser.hpp:64
virtual bool removeUser(const std::string &username)
Definition: PionUser.hpp:250
virtual bool updateUser(const std::string &username, const std::string &password)
Definition: PionUser.hpp:192
bool empty(void) const
returns true if no users are defined
Definition: PionUser.hpp:159
std::string m_password
password string (actual contents depends on implementation)
Definition: PionUser.hpp:132
UserMap m_users
user records container
Definition: PionUser.hpp:294
PionUser(std::string const &username)
construct a new PionUser object
Definition: PionUser.hpp:49
boost::mutex m_mutex
mutex used to protect access to the user list
Definition: PionUser.hpp:291
virtual void setPassword(const std::string &password)
sets password credentials for given user
Definition: PionUser.hpp:85
std::string const & getPassword() const
returns password for the user (encrypted if SSL is enabled)
Definition: PionUser.hpp:67
virtual PionUserPtr getUser(const std::string &username)
Definition: PionUser.hpp:262
virtual bool matchPassword(const std::string &password) const
Definition: PionUser.hpp:74
virtual ~PionUserManager()
virtual destructor
Definition: PionUser.hpp:156
std::map< std::string, PionUserPtr > UserMap
data type for a map of usernames to user objects
Definition: PionUser.hpp:287
virtual PionUserPtr getUser(const std::string &username, const std::string &password)
Definition: PionUser.hpp:274
PionUser(std::string const &username, std::string const &password)
construct a new PionUser object
Definition: PionUser.hpp:54
PionUserManager(void)
construct a new PionUserManager object
Definition: PionUser.hpp:153
exception thrown if a bad password hash is given to setPasswordHash()
Definition: PionUser.hpp:40
virtual ~PionUser()
virtual destructor
Definition: PionUser.hpp:61
const std::string m_username
username string
Definition: PionUser.hpp:129