summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Common/Backends/NetworkUserBackend.cpp20
-rw-r--r--src/Common/Backends/NetworkUserBackend.h2
-rw-r--r--src/Common/UserBackend.h4
-rw-r--r--src/Common/UserCache.cpp59
-rw-r--r--src/Common/UserCache.h8
-rw-r--r--src/Common/UserManager.cpp18
-rw-r--r--src/Common/UserManager.h2
-rw-r--r--src/Server/RequestHandlers/UserRequestHandlerGroup.cpp16
-rw-r--r--src/Server/RequestHandlers/UserRequestHandlerGroup.h2
-rw-r--r--src/mad-server.conf1
-rw-r--r--src/modules/UserBackendMysql/UserBackendMysql.cpp71
-rw-r--r--src/modules/UserBackendMysql/UserBackendMysql.h7
12 files changed, 199 insertions, 11 deletions
diff --git a/src/Common/Backends/NetworkUserBackend.cpp b/src/Common/Backends/NetworkUserBackend.cpp
index 81fc94a..f75783c 100644
--- a/src/Common/Backends/NetworkUserBackend.cpp
+++ b/src/Common/Backends/NetworkUserBackend.cpp
@@ -188,6 +188,26 @@ boost::shared_ptr<const std::set<unsigned long> > NetworkUserBackend::getGroupUs
return userList;
}
+boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > NetworkUserBackend::getFullUserGroupList() throw(Core::Exception) {
+ boost::shared_ptr<SimpleUserRequest> request(new SimpleUserRequest(application, "GetFullUserGroupList"));
+ application->getRequestManager()->sendRequest(connection, request);
+ request->wait();
+
+ std::pair<boost::shared_ptr<const XmlPacket>, Core::Exception> result = request->getResult();
+ if(!result.first || result.second)
+ throw result.second;
+
+ boost::shared_ptr<std::multimap<unsigned long, unsigned long> > ret(new std::multimap<unsigned long, unsigned long>);
+
+ const XmlPacket::List *list = result.first->getList("userGroupList");
+ if(list) {
+ for(XmlPacket::List::const_iterator entry = list->begin(); entry != list->end(); ++entry)
+ ret->insert(std::make_pair(entry->get<unsigned long>("uid"), entry->get<unsigned long>("gid")));
+ }
+
+ return ret;
+}
+
/*void NetworkUserBackend::setPassword(unsigned long uid, const std::string &password) throw(Core::Exception) {
diff --git a/src/Common/Backends/NetworkUserBackend.h b/src/Common/Backends/NetworkUserBackend.h
index c569ab6..66be909 100644
--- a/src/Common/Backends/NetworkUserBackend.h
+++ b/src/Common/Backends/NetworkUserBackend.h
@@ -77,6 +77,8 @@ class NetworkUserBackend : public UserBackend {
virtual boost::shared_ptr<const GroupInfo> getGroupInfoByName(const std::string &name) throw(Core::Exception);
virtual boost::shared_ptr<const std::set<unsigned long> > getGroupUserList(unsigned long gid) throw(Core::Exception);
+ virtual boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > getFullUserGroupList() throw(Core::Exception);
+
//virtual void setPassword(unsigned long uid, const std::string &password) throw(Core::Exception);
//virtual void addUser(const UserInfo &userInfo) throw(Core::Exception);
diff --git a/src/Common/UserBackend.h b/src/Common/UserBackend.h
index 9983ee0..829aae7 100644
--- a/src/Common/UserBackend.h
+++ b/src/Common/UserBackend.h
@@ -80,6 +80,10 @@ class UserBackend {
throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED));
}
+ virtual boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > getFullUserGroupList() throw(Core::Exception) {
+ throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED));
+ }
+
virtual void setPassword(unsigned long uid _UNUSED_PARAMETER_, const std::string &password _UNUSED_PARAMETER_) throw(Core::Exception) {
throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED));
}
diff --git a/src/Common/UserCache.cpp b/src/Common/UserCache.cpp
index 63f72dd..79f27c7 100644
--- a/src/Common/UserCache.cpp
+++ b/src/Common/UserCache.cpp
@@ -83,7 +83,21 @@ boost::shared_ptr<const UserInfo> UserCache::getUserInfoByName(const std::string
}
boost::shared_ptr<const std::set<unsigned long> > UserCache::getUserGroupList(unsigned long uid) throw(Core::Exception) {
- return backend->getUserGroupList(uid);
+ getFullUserGroupList();
+
+ boost::lock_guard<boost::shared_mutex> lock(mutex);
+
+ if(!userGroups)
+ throw userGroupException;
+
+ std::pair<std::multimap<unsigned long, unsigned long>::const_iterator, std::multimap<unsigned long, unsigned long>::const_iterator> range = userGroups->equal_range(uid);
+
+ boost::shared_ptr<std::set<unsigned long> > groups(new std::set<unsigned long>);
+
+ for(std::multimap<unsigned long, unsigned long>::const_iterator group = range.first; group != range.second; ++group)
+ groups->insert(group->second);
+
+ return groups;
}
@@ -145,8 +159,47 @@ boost::shared_ptr<const GroupInfo> UserCache::getGroupInfoByName(const std::stri
return boost::shared_ptr<GroupInfo>(new GroupInfo(group->second));
}
-boost::shared_ptr<const std::set<unsigned long> > UserCache::getGroupUserList(unsigned long uid) throw(Core::Exception) {
- return backend->getGroupUserList(uid);
+boost::shared_ptr<const std::set<unsigned long> > UserCache::getGroupUserList(unsigned long gid) throw(Core::Exception) {
+ getFullUserGroupList();
+
+ boost::lock_guard<boost::shared_mutex> lock(mutex);
+
+ if(!userGroups)
+ throw userGroupException;
+
+ std::pair<std::multimap<unsigned long, unsigned long>::iterator, std::multimap<unsigned long, unsigned long>::iterator> range = groupUsers->equal_range(gid);
+
+ boost::shared_ptr<std::set<unsigned long> > users(new std::set<unsigned long>);
+
+ for(std::multimap<unsigned long, unsigned long>::iterator user = range.first; user != range.second; ++user)
+ users->insert(user->second);
+
+ return users;
+}
+
+boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > UserCache::getFullUserGroupList() throw(Core::Exception) {
+ boost::lock_guard<boost::shared_mutex> lock(mutex);
+
+ if(userGroups) {
+ std::cerr << "Cached" << std::endl;
+ return userGroups;
+ }
+ else if(userGroupException)
+ throw userGroupException;
+
+ try {
+ userGroups = backend->getFullUserGroupList();
+
+ groupUsers.reset(new std::multimap<unsigned long, unsigned long>);
+ for(std::multimap<unsigned long, unsigned long>::const_iterator usergroup = userGroups->begin(); usergroup != userGroups->end(); ++usergroup)
+ groupUsers->insert(std::make_pair(usergroup->second, usergroup->first));
+
+ return userGroups;
+ }
+ catch(Core::Exception e) {
+ userGroupException = e;
+ throw userGroupException;
+ }
}
}
diff --git a/src/Common/UserCache.h b/src/Common/UserCache.h
index 1e432fd..cec5ea5 100644
--- a/src/Common/UserCache.h
+++ b/src/Common/UserCache.h
@@ -47,9 +47,9 @@ class UserCache : public UserBackend, private boost::noncopyable {
boost::shared_ptr<std::map<std::string, unsigned long> > groupNames;
Core::Exception groupException;
- /*boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > userGroups;
- boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > groupUsers;
- Core::Exception userGroupException;*/
+ boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > userGroups;
+ boost::shared_ptr<std::multimap<unsigned long, unsigned long> > groupUsers;
+ Core::Exception userGroupException;
protected:
virtual boost::shared_ptr<const std::map<unsigned long, UserInfo> > getUserList() throw(Core::Exception);
@@ -62,6 +62,8 @@ class UserCache : public UserBackend, private boost::noncopyable {
virtual boost::shared_ptr<const GroupInfo> getGroupInfoByName(const std::string &name) throw(Core::Exception);
virtual boost::shared_ptr<const std::set<unsigned long> > getGroupUserList(unsigned long gid) throw(Core::Exception);
+ virtual boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > getFullUserGroupList() throw(Core::Exception);
+
virtual void setPassword(unsigned long uid, const std::string &password) throw(Core::Exception) {
backend->setPassword(uid, password);
}
diff --git a/src/Common/UserManager.cpp b/src/Common/UserManager.cpp
index 253466e..c56195d 100644
--- a/src/Common/UserManager.cpp
+++ b/src/Common/UserManager.cpp
@@ -189,6 +189,24 @@ boost::shared_ptr<const std::set<unsigned long> > UserManager::getGroupUserList(
throw e;
}
+boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > UserManager::getFullUserGroupList() throw(Core::Exception) {
+ Core::Exception e(Core::Exception::NOT_IMPLEMENTED);
+
+ boost::lock_guard<boost::shared_mutex> lock(mutex);
+
+ for(BackendMap::iterator backend = backends.begin(); backend != backends.end(); ++backend) {
+ try {
+ return backend->second->getFullUserGroupList();
+ }
+ catch(Core::Exception e2) {
+ if(e.getErrorCode() == Core::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Core::Exception::NOT_IMPLEMENTED)
+ e = e2;
+ }
+ }
+
+ throw e;
+}
+
void UserManager::setPassword(unsigned long uid, const std::string &password) throw(Core::Exception) {
Core::Exception e(Core::Exception::NOT_IMPLEMENTED);
diff --git a/src/Common/UserManager.h b/src/Common/UserManager.h
index 7413970..1ba051f 100644
--- a/src/Common/UserManager.h
+++ b/src/Common/UserManager.h
@@ -77,6 +77,8 @@ class UserManager : boost::noncopyable {
boost::shared_ptr<const GroupInfo> getGroupInfoByName(const std::string &name) throw(Core::Exception);
boost::shared_ptr<const std::set<unsigned long> > getGroupUserList(unsigned long gid) throw(Core::Exception);
+ boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > getFullUserGroupList() throw(Core::Exception);
+
void setPassword(unsigned long uid, const std::string &password) throw(Core::Exception);
void addUser(const UserInfo &userInfo) throw(Core::Exception);
diff --git a/src/Server/RequestHandlers/UserRequestHandlerGroup.cpp b/src/Server/RequestHandlers/UserRequestHandlerGroup.cpp
index 31d2c16..9e4d23c 100644
--- a/src/Server/RequestHandlers/UserRequestHandlerGroup.cpp
+++ b/src/Server/RequestHandlers/UserRequestHandlerGroup.cpp
@@ -119,6 +119,20 @@ void UserRequestHandlerGroup::handleGroupUserListRequest(boost::shared_ptr<const
}
}
+void UserRequestHandlerGroup::handleFullUserGroupListRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, Common::Connection *connection) {
+ boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > userGroups = application->getUserManager()->getFullUserGroupList();
+
+ ret->setType("OK");
+ Common::XmlPacket::List *list = ret->createList("userGroupList");
+
+ for(std::map<unsigned long, unsigned long>::const_iterator userGroup = userGroups->begin(); userGroup != userGroups->end(); ++userGroup) {
+ Common::XmlPacket::List::iterator entry = list->addEntry();
+
+ entry->set("uid", userGroup->first);
+ entry->set("gid", userGroup->second);
+ }
+}
+
UserRequestHandlerGroup::UserRequestHandlerGroup(Application *application0) : application(application0) {
registerHandler("ListUsers", boost::bind(&UserRequestHandlerGroup::handleUserListRequest, this, _1, _2, _3));
registerHandler("GetUserInfo", boost::bind(&UserRequestHandlerGroup::handleUserInfoRequest, this, _1, _2, _3));
@@ -127,6 +141,8 @@ UserRequestHandlerGroup::UserRequestHandlerGroup(Application *application0) : ap
registerHandler("ListGroups", boost::bind(&UserRequestHandlerGroup::handleGroupListRequest, this, _1, _2, _3));
registerHandler("GetGroupInfo", boost::bind(&UserRequestHandlerGroup::handleGroupInfoRequest, this, _1, _2, _3));
registerHandler("ListGroupUsers", boost::bind(&UserRequestHandlerGroup::handleGroupUserListRequest, this, _1, _2, _3));
+
+ registerHandler("GetFullUserGroupList", boost::bind(&UserRequestHandlerGroup::handleFullUserGroupListRequest, this, _1, _2, _3));
}
}
diff --git a/src/Server/RequestHandlers/UserRequestHandlerGroup.h b/src/Server/RequestHandlers/UserRequestHandlerGroup.h
index 744f895..a55a34f 100644
--- a/src/Server/RequestHandlers/UserRequestHandlerGroup.h
+++ b/src/Server/RequestHandlers/UserRequestHandlerGroup.h
@@ -41,6 +41,8 @@ class UserRequestHandlerGroup : public Common::RequestHandlers::SimpleRequestHan
void handleGroupInfoRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, Common::Connection *connection);
void handleGroupUserListRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, Common::Connection *connection);
+ void handleFullUserGroupListRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, Common::Connection *connection);
+
public:
UserRequestHandlerGroup(Application *application0);
};
diff --git a/src/mad-server.conf b/src/mad-server.conf
index 09614c4..8ab08cc 100644
--- a/src/mad-server.conf
+++ b/src/mad-server.conf
@@ -24,6 +24,7 @@ UserBackendMysql {
UserByName "SELECT id, gid, username, fullname FROM users WHERE username = {USER}"
GroupById "SELECT id, name FROM groups WHERE id = {GID}"
GroupByName "SELECT id, name FROM groups WHERE name = {GROUP}"
+ UserGroupTable "SELECT uid, gid FROM usergroups"
}
}
diff --git a/src/modules/UserBackendMysql/UserBackendMysql.cpp b/src/modules/UserBackendMysql/UserBackendMysql.cpp
index e6e6dda..6d64a51 100644
--- a/src/modules/UserBackendMysql/UserBackendMysql.cpp
+++ b/src/modules/UserBackendMysql/UserBackendMysql.cpp
@@ -28,7 +28,7 @@
#include <boost/bind.hpp>
#include <boost/regex.hpp>
-
+#include <boost/thread/locks.hpp>
namespace Mad {
namespace Modules {
@@ -106,6 +106,10 @@ bool UserBackendMysql::handleConfigEntry(const Core::ConfigEntry &entry, bool ha
if(entry[3].empty())
queryGroupByName = entry[2][0];
}
+ else if(entry[2].getKey().matches("UserGroupTable")) {
+ if(entry[3].empty())
+ queryUserGroupTable = entry[2][0];
+ }
else if(!entry[2].empty())
return false;
}
@@ -124,6 +128,7 @@ void UserBackendMysql::configFinished() {
return;
}
+ boost::lock_guard<boost::mutex> lock(mutex);
mysql = mysql_init(0);
mysql_real_connect(mysql, host.c_str(), username.c_str(), passwd.c_str(), db.c_str(), port, unixSocket.empty() ? 0 : unixSocket.c_str(), 0);
}
@@ -132,12 +137,16 @@ void UserBackendMysql::configFinished() {
boost::shared_ptr<const std::map<unsigned long, Common::UserInfo> > UserBackendMysql::getUserList() throw(Core::Exception) {
application->getThreadManager()->detach();
+ boost::unique_lock<boost::mutex> lock(mutex);
+
if(!mysql || mysql_ping(mysql))
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
mysql_real_query(mysql, queryListUsers.c_str(), queryListUsers.length());
MYSQL_RES *result = mysql_store_result(mysql);
+ lock.unlock();
+
if(!result || mysql_num_fields(result) < 4)
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -158,6 +167,8 @@ boost::shared_ptr<const std::map<unsigned long, Common::UserInfo> > UserBackendM
boost::shared_ptr<const Common::UserInfo> UserBackendMysql::getUserInfo(unsigned long uid) throw(Core::Exception) {
application->getThreadManager()->detach();
+ boost::unique_lock<boost::mutex> lock(mutex);
+
if(!mysql || mysql_ping(mysql))
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -173,6 +184,8 @@ boost::shared_ptr<const Common::UserInfo> UserBackendMysql::getUserInfo(unsigned
mysql_real_query(mysql, query.c_str(), query.length());
MYSQL_RES *result = mysql_store_result(mysql);
+ lock.unlock();
+
if(!result || mysql_num_fields(result) < 4)
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -189,12 +202,14 @@ boost::shared_ptr<const Common::UserInfo> UserBackendMysql::getUserInfo(unsigned
return user;
}
- throw Core::Exception(Core::Exception::NOT_AVAILABLE);
+ throw Core::Exception(Core::Exception::NOT_FOUND);
}
boost::shared_ptr<const Common::UserInfo> UserBackendMysql::getUserInfoByName(const std::string &name) throw(Core::Exception) {
application->getThreadManager()->detach();
+ boost::unique_lock<boost::mutex> lock(mutex);
+
if(!mysql || mysql_ping(mysql))
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -207,6 +222,8 @@ boost::shared_ptr<const Common::UserInfo> UserBackendMysql::getUserInfoByName(co
mysql_real_query(mysql, query.c_str(), query.length());
MYSQL_RES *result = mysql_store_result(mysql);
+ lock.unlock();
+
if(!result || mysql_num_fields(result) < 4)
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -223,12 +240,14 @@ boost::shared_ptr<const Common::UserInfo> UserBackendMysql::getUserInfoByName(co
return user;
}
- throw Core::Exception(Core::Exception::NOT_AVAILABLE);
+ throw Core::Exception(Core::Exception::NOT_FOUND);
}
boost::shared_ptr<const std::set<unsigned long> > UserBackendMysql::getUserGroupList(unsigned long uid) throw(Core::Exception) {
application->getThreadManager()->detach();
+ boost::unique_lock<boost::mutex> lock(mutex);
+
if(!mysql || mysql_ping(mysql))
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -242,6 +261,8 @@ boost::shared_ptr<const std::set<unsigned long> > UserBackendMysql::getUserGroup
mysql_real_query(mysql, query.c_str(), query.length());
MYSQL_RES *result = mysql_store_result(mysql);
+ lock.unlock();
+
if(!result || mysql_num_fields(result) < 1)
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -257,12 +278,16 @@ boost::shared_ptr<const std::set<unsigned long> > UserBackendMysql::getUserGroup
boost::shared_ptr<const std::map<unsigned long, Common::GroupInfo> > UserBackendMysql::getGroupList() throw(Core::Exception) {
application->getThreadManager()->detach();
+ boost::unique_lock<boost::mutex> lock(mutex);
+
if(!mysql || mysql_ping(mysql))
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
mysql_real_query(mysql, queryListGroups.c_str(), queryListGroups.length());
MYSQL_RES *result = mysql_store_result(mysql);
+ lock.unlock();
+
if(!result || mysql_num_fields(result) < 2)
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -280,6 +305,8 @@ boost::shared_ptr<const std::map<unsigned long, Common::GroupInfo> > UserBackend
boost::shared_ptr<const Common::GroupInfo> UserBackendMysql::getGroupInfo(unsigned long gid) throw(Core::Exception) {
application->getThreadManager()->detach();
+ boost::unique_lock<boost::mutex> lock(mutex);
+
if(!mysql || mysql_ping(mysql))
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -295,6 +322,8 @@ boost::shared_ptr<const Common::GroupInfo> UserBackendMysql::getGroupInfo(unsign
mysql_real_query(mysql, query.c_str(), query.length());
MYSQL_RES *result = mysql_store_result(mysql);
+ lock.unlock();
+
if(!result || mysql_num_fields(result) < 2)
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -303,12 +332,14 @@ boost::shared_ptr<const Common::GroupInfo> UserBackendMysql::getGroupInfo(unsign
if(row)
return boost::shared_ptr<Common::GroupInfo>(new Common::GroupInfo(strtoul(row[0], 0, 10), row[1]));
- throw Core::Exception(Core::Exception::NOT_AVAILABLE);
+ throw Core::Exception(Core::Exception::NOT_FOUND);
}
boost::shared_ptr<const Common::GroupInfo> UserBackendMysql::getGroupInfoByName(const std::string &name) throw(Core::Exception) {
application->getThreadManager()->detach();
+ boost::unique_lock<boost::mutex> lock(mutex);
+
if(!mysql || mysql_ping(mysql))
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -321,6 +352,8 @@ boost::shared_ptr<const Common::GroupInfo> UserBackendMysql::getGroupInfoByName(
mysql_real_query(mysql, query.c_str(), query.length());
MYSQL_RES *result = mysql_store_result(mysql);
+ lock.unlock();
+
if(!result || mysql_num_fields(result) < 2)
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -329,12 +362,14 @@ boost::shared_ptr<const Common::GroupInfo> UserBackendMysql::getGroupInfoByName(
if(row)
return boost::shared_ptr<Common::GroupInfo>(new Common::GroupInfo(strtoul(row[0], 0, 10), row[1]));
- throw Core::Exception(Core::Exception::NOT_AVAILABLE);
+ throw Core::Exception(Core::Exception::NOT_FOUND);
}
boost::shared_ptr<const std::set<unsigned long> > UserBackendMysql::getGroupUserList(unsigned long gid) throw(Core::Exception) {
application->getThreadManager()->detach();
+ boost::unique_lock<boost::mutex> lock(mutex);
+
if(!mysql || mysql_ping(mysql))
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -348,6 +383,8 @@ boost::shared_ptr<const std::set<unsigned long> > UserBackendMysql::getGroupUser
mysql_real_query(mysql, query.c_str(), query.length());
MYSQL_RES *result = mysql_store_result(mysql);
+ lock.unlock();
+
if(!result || mysql_num_fields(result) < 1)
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -359,6 +396,30 @@ boost::shared_ptr<const std::set<unsigned long> > UserBackendMysql::getGroupUser
return users;
}
+boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > UserBackendMysql::getFullUserGroupList() throw(Core::Exception) {
+ application->getThreadManager()->detach();
+
+ boost::unique_lock<boost::mutex> lock(mutex);
+
+ if(!mysql || mysql_ping(mysql))
+ throw Core::Exception(Core::Exception::NOT_AVAILABLE);
+
+ mysql_real_query(mysql, queryUserGroupTable.c_str(), queryUserGroupTable.length());
+ MYSQL_RES *result = mysql_store_result(mysql);
+
+ lock.unlock();
+
+ if(!result || mysql_num_fields(result) < 2)
+ throw Core::Exception(Core::Exception::NOT_AVAILABLE);
+
+ boost::shared_ptr<std::multimap<unsigned long, unsigned long> > usergroups(new std::multimap<unsigned long, unsigned long>);
+
+ while(MYSQL_ROW row = mysql_fetch_row(result))
+ usergroups->insert(std::make_pair(strtoul(row[0], 0, 10), strtoul(row[1], 0, 10)));
+
+ return usergroups;
+}
+
}
}
}
diff --git a/src/modules/UserBackendMysql/UserBackendMysql.h b/src/modules/UserBackendMysql/UserBackendMysql.h
index 7832e95..eadbf3b 100644
--- a/src/modules/UserBackendMysql/UserBackendMysql.h
+++ b/src/modules/UserBackendMysql/UserBackendMysql.h
@@ -28,6 +28,8 @@
#include <mysql/mysql.h>
+#include <boost/thread/mutex.hpp>
+
namespace Mad {
namespace Modules {
namespace UserBackendMysql {
@@ -43,9 +45,12 @@ class UserBackendMysql : public Common::UserBackend, private Core::Configurable
std::string queryListUserGroups, queryListGroupUsers;
std::string queryUserById, queryUserByName;
std::string queryGroupById, queryGroupByName;
+ std::string queryUserGroupTable;
MYSQL *mysql;
+ boost::mutex mutex;
+
protected:
virtual bool handleConfigEntry(const Core::ConfigEntry &entry, bool);
virtual void configFinished();
@@ -60,6 +65,8 @@ class UserBackendMysql : public Common::UserBackend, private Core::Configurable
virtual boost::shared_ptr<const Common::GroupInfo> getGroupInfoByName(const std::string &name) throw(Core::Exception);
virtual boost::shared_ptr<const std::set<unsigned long> > getGroupUserList(unsigned long gid) throw(Core::Exception);
+ virtual boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > getFullUserGroupList() throw(Core::Exception);
+
public:
UserBackendMysql(Common::Application *application0) : application(application0), port(0), mysql(0) {
application->getConfigManager()->registerConfigurable(this);