diff options
Diffstat (limited to 'src/Common/UserManager.cpp')
-rw-r--r-- | src/Common/UserManager.cpp | 226 |
1 files changed, 210 insertions, 16 deletions
diff --git a/src/Common/UserManager.cpp b/src/Common/UserManager.cpp index 66cbbf4..342d4bf 100644 --- a/src/Common/UserManager.cpp +++ b/src/Common/UserManager.cpp @@ -20,6 +20,8 @@ #include "UserManager.h" #include "UserBackend.h" +#include <iostream> + namespace Mad { namespace Common { @@ -32,24 +34,90 @@ bool UserManager::Compare::operator() (boost::shared_ptr<UserBackend> b1, boost: boost::shared_ptr<const std::map<unsigned long, UserInfo> > UserManager::getUserList() throw(Core::Exception) { + { + boost::shared_lock<boost::shared_mutex> lock(mutex); + + if(caching) { + if(users) + return users; + else if(userException) + throw *userException; + } + } + Core::Exception e(Core::Exception::NOT_IMPLEMENTED); - for(std::set<boost::shared_ptr<UserBackend> >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { - try { - return (*backend)->getUserList(); + boost::shared_ptr<const std::map<unsigned long, UserInfo> > ret; + + { + boost::lock_guard<boost::shared_mutex> backendLock(backendMutex); + + for(std::set<boost::shared_ptr<UserBackend> >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { + try { + ret = (*backend)->getUserList(); + break; + } + catch(Core::Exception e2) { + if(e.getErrorCode() == Core::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Core::Exception::NOT_IMPLEMENTED) + e = e2; + } } - catch(Core::Exception e2) { - if(e.getErrorCode() == Core::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Core::Exception::NOT_IMPLEMENTED) - e = e2; + } + + { + boost::upgrade_lock<boost::shared_mutex> lock(mutex); + + if(caching) { + if(ret) { + boost::upgrade_to_unique_lock<boost::shared_mutex> upgradeLock(lock); + users = ret; + + boost::shared_ptr<std::map<std::string, unsigned long> > names(new std::map<std::string, unsigned long>); + for(std::map<unsigned long, UserInfo>::const_iterator user = users->begin(); user != users->end(); ++user) + names->insert(std::make_pair(user->second.getUsername(), user->first)); + + userNames = names; + } + else + userException.reset(new Core::Exception(e)); } } - throw e; + if(ret) + return ret; + else + throw e; } boost::shared_ptr<const UserInfo> UserManager::getUserInfo(unsigned long uid) throw(Core::Exception) { + { + boost::shared_lock<boost::shared_mutex> lock(mutex); + + if(caching) { + if(!users && !userException) { + lock.unlock(); + getUserList(); + lock.lock(); + } + + if(caching) { + if(users) { + std::map<unsigned long, UserInfo>::const_iterator user = users->find(uid); + if(user != users->end()) + return boost::shared_ptr<UserInfo>(new UserInfo(user->second)); + else + throw Core::Exception(Core::Exception::NOT_FOUND); + } + else if(userException) + throw *userException; + } + } + } + Core::Exception e(Core::Exception::NOT_IMPLEMENTED); + boost::lock_guard<boost::shared_mutex> backendLock(backendMutex); + for(std::set<boost::shared_ptr<UserBackend> >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { try { return (*backend)->getUserInfo(uid); @@ -64,8 +132,34 @@ boost::shared_ptr<const UserInfo> UserManager::getUserInfo(unsigned long uid) th } boost::shared_ptr<const UserInfo> UserManager::getUserInfoByName(const std::string &name) throw(Core::Exception) { + { + boost::shared_lock<boost::shared_mutex> lock(mutex); + + if(caching) { + if(!users && !userException) { + lock.unlock(); + getUserList(); + lock.lock(); + } + + if(caching) { + if(userNames) { + std::map<std::string, unsigned long>::const_iterator user = userNames->find(name); + if(user != userNames->end()) + return boost::shared_ptr<UserInfo>(new UserInfo(users->find(user->second)->second)); + else + throw Core::Exception(Core::Exception::NOT_FOUND); + } + else if(userException) + throw *userException; + } + } + } + Core::Exception e(Core::Exception::NOT_IMPLEMENTED); + boost::lock_guard<boost::shared_mutex> backendLock(backendMutex); + for(std::set<boost::shared_ptr<UserBackend> >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { try { return (*backend)->getUserInfoByName(name); @@ -82,6 +176,8 @@ boost::shared_ptr<const UserInfo> UserManager::getUserInfoByName(const std::stri boost::shared_ptr<const std::set<unsigned long> > UserManager::getUserGroupList(unsigned long uid) throw(Core::Exception) { Core::Exception e(Core::Exception::NOT_IMPLEMENTED); + boost::lock_guard<boost::shared_mutex> backendLock(backendMutex); + for(std::set<boost::shared_ptr<UserBackend> >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { try { return (*backend)->getUserGroupList(uid); @@ -96,24 +192,90 @@ boost::shared_ptr<const std::set<unsigned long> > UserManager::getUserGroupList( } boost::shared_ptr<const std::map<unsigned long, GroupInfo> > UserManager::getGroupList() throw(Core::Exception) { + { + boost::shared_lock<boost::shared_mutex> lock(mutex); + + if(caching) { + if(groups) + return groups; + else if(groupException) + throw *groupException; + } + } + Core::Exception e(Core::Exception::NOT_IMPLEMENTED); - for(std::set<boost::shared_ptr<UserBackend> >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { - try { - return (*backend)->getGroupList(); + boost::shared_ptr<const std::map<unsigned long, GroupInfo> > ret; + + { + boost::lock_guard<boost::shared_mutex> backendLock(backendMutex); + + for(std::set<boost::shared_ptr<UserBackend> >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { + try { + ret = (*backend)->getGroupList(); + break; + } + catch(Core::Exception e2) { + if(e.getErrorCode() == Core::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Core::Exception::NOT_IMPLEMENTED) + e = e2; + } } - catch(Core::Exception e2) { - if(e.getErrorCode() == Core::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Core::Exception::NOT_IMPLEMENTED) - e = e2; + } + + { + boost::upgrade_lock<boost::shared_mutex> lock(mutex); + + if(caching) { + if(ret) { + boost::upgrade_to_unique_lock<boost::shared_mutex> upgradeLock(lock); + groups = ret; + + boost::shared_ptr<std::map<std::string, unsigned long> > names(new std::map<std::string, unsigned long>); + for(std::map<unsigned long, GroupInfo>::const_iterator group = groups->begin(); group != groups->end(); ++group) + names->insert(std::make_pair(group->second.getName(), group->first)); + + groupNames = names; + } + else + groupException.reset(new Core::Exception(e)); } } - throw e; + if(ret) + return ret; + else + throw e; } boost::shared_ptr<const GroupInfo> UserManager::getGroupInfo(unsigned long gid) throw(Core::Exception) { + { + boost::shared_lock<boost::shared_mutex> lock(mutex); + + if(caching) { + if(!groups && !groupException) { + lock.unlock(); + getGroupList(); + lock.lock(); + } + + if(caching) { + if(groups) { + std::map<unsigned long, GroupInfo>::const_iterator group = groups->find(gid); + if(group != groups->end()) + return boost::shared_ptr<GroupInfo>(new GroupInfo(group->second)); + else + throw Core::Exception(Core::Exception::NOT_FOUND); + } + else if(groupException) + throw *groupException; + } + } + } + Core::Exception e(Core::Exception::NOT_IMPLEMENTED); + boost::lock_guard<boost::shared_mutex> backendLock(backendMutex); + for(std::set<boost::shared_ptr<UserBackend> >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { try { return (*backend)->getGroupInfo(gid); @@ -128,8 +290,34 @@ boost::shared_ptr<const GroupInfo> UserManager::getGroupInfo(unsigned long gid) } boost::shared_ptr<const GroupInfo> UserManager::getGroupInfoByName(const std::string &name) throw(Core::Exception) { + { + boost::shared_lock<boost::shared_mutex> lock(mutex); + + if(caching) { + if(!groups && !groupException) { + lock.unlock(); + getGroupList(); + lock.lock(); + } + + if(caching) { + if(groupNames) { + std::map<std::string, unsigned long>::const_iterator group = groupNames->find(name); + if(group != groupNames->end()) + return boost::shared_ptr<GroupInfo>(new GroupInfo(groups->find(group->second)->second)); + else + throw Core::Exception(Core::Exception::NOT_FOUND); + } + else if(groupException) + throw *groupException; + } + } + } + Core::Exception e(Core::Exception::NOT_IMPLEMENTED); + boost::lock_guard<boost::shared_mutex> backendLock(backendMutex); + for(std::set<boost::shared_ptr<UserBackend> >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { try { return (*backend)->getGroupInfoByName(name); @@ -146,6 +334,8 @@ boost::shared_ptr<const GroupInfo> UserManager::getGroupInfoByName(const std::st boost::shared_ptr<const std::set<unsigned long> > UserManager::getGroupUserList(unsigned long gid) throw(Core::Exception) { Core::Exception e(Core::Exception::NOT_IMPLEMENTED); + boost::lock_guard<boost::shared_mutex> backendLock(backendMutex); + for(std::set<boost::shared_ptr<UserBackend> >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { try { return (*backend)->getGroupUserList(gid); @@ -162,9 +352,11 @@ boost::shared_ptr<const std::set<unsigned long> > UserManager::getGroupUserList( void UserManager::setPassword(unsigned long uid, const std::string &password) throw(Core::Exception) { Core::Exception e(Core::Exception::NOT_IMPLEMENTED); + boost::lock_guard<boost::shared_mutex> backendLock(backendMutex); + for(std::set<boost::shared_ptr<UserBackend> >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { try { - return (*backend)->setPassword(uid, password); + (*backend)->setPassword(uid, password); } catch(Core::Exception e2) { if(e.getErrorCode() == Core::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Core::Exception::NOT_IMPLEMENTED) @@ -178,9 +370,11 @@ void UserManager::setPassword(unsigned long uid, const std::string &password) th void UserManager::addUser(const UserInfo &userInfo) throw(Core::Exception) { Core::Exception e(Core::Exception::NOT_IMPLEMENTED); + boost::lock_guard<boost::shared_mutex> backendLock(backendMutex); + for(std::set<boost::shared_ptr<UserBackend> >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { try { - return (*backend)->addUser(userInfo); + (*backend)->addUser(userInfo); } catch(Core::Exception e2) { if(e.getErrorCode() == Core::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Core::Exception::NOT_IMPLEMENTED) |