summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--src/Common/Backends/NetworkUserBackend.cpp193
-rw-r--r--src/Common/Backends/NetworkUserBackend.h44
-rw-r--r--src/Common/UserBackend.h19
-rw-r--r--src/Common/UserCache.cpp209
-rw-r--r--src/Common/UserCache.h29
-rw-r--r--src/Common/UserManager.cpp36
-rw-r--r--src/Common/UserManager.h18
-rw-r--r--src/Server/RequestHandlers/UserRequestHandlerGroup.cpp191
-rw-r--r--src/modules/UserBackendMysql/UserBackendMysql.cpp81
-rw-r--r--src/modules/UserBackendMysql/UserBackendMysql.h22
11 files changed, 587 insertions, 257 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 50edfaf..d884224 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,7 +8,7 @@ find_package(DL REQUIRED)
find_package(Readline REQUIRED)
#find_package(KRB5 REQUIRED gssapi)
find_package(OpenSSL REQUIRED)
-find_package(Boost REQUIRED regex signals system thread)
+find_package(Boost REQUIRED date_time regex signals system thread)
find_package(MySQL)
configure_file(${MAD_SOURCE_DIR}/config.h.in ${MAD_BINARY_DIR}/config.h)
diff --git a/src/Common/Backends/NetworkUserBackend.cpp b/src/Common/Backends/NetworkUserBackend.cpp
index f75783c..27f65f5 100644
--- a/src/Common/Backends/NetworkUserBackend.cpp
+++ b/src/Common/Backends/NetworkUserBackend.cpp
@@ -20,15 +20,30 @@
#include "NetworkUserBackend.h"
#include "../RequestManager.h"
+#include <boost/date_time/posix_time/posix_time.hpp>
+
namespace Mad {
namespace Common {
namespace Backends {
+void NetworkUserBackend::SimpleUserRequest::sendRequest() {
+ Common::XmlPacket packet;
+ packet.setType(type);
+
+ if(!timestamp.is_not_a_date_time())
+ packet.set("timestamp", boost::posix_time::to_iso_string(timestamp));
+
+ sendPacket(packet);
+}
+
void NetworkUserBackend::IdUserRequest::sendRequest() {
Common::XmlPacket packet;
packet.setType(type);
packet.set(idType, id);
+ if(!timestamp.is_not_a_date_time())
+ packet.set("timestamp", boost::posix_time::to_iso_string(timestamp));
+
sendPacket(packet);
}
@@ -37,22 +52,33 @@ void NetworkUserBackend::NameUserRequest::sendRequest() {
packet.setType(type);
packet.set("name", name);
+ if(!timestamp.is_not_a_date_time())
+ packet.set("timestamp", boost::posix_time::to_iso_string(timestamp));
+
sendPacket(packet);
}
-boost::shared_ptr<const std::map<unsigned long, UserInfo> > NetworkUserBackend::getUserList() throw(Core::Exception) {
- boost::shared_ptr<SimpleUserRequest> request(new SimpleUserRequest(application, "ListUsers"));
+boost::shared_ptr<const std::map<unsigned long, UserInfo> > NetworkUserBackend::getUserList(boost::posix_time::ptime *timestamp) throw(Core::Exception) {
+ boost::shared_ptr<SimpleUserRequest> request(new SimpleUserRequest(application, "ListUsers", timestamp));
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::map<unsigned long, UserInfo> > userList(new std::map<unsigned long, UserInfo>);
+ if(timestamp) {
+ try {
+ *timestamp = boost::posix_time::from_iso_string(result.first->get<const std::string&>("timestamp"));
+ }
+ catch(...) {}
+ }
const XmlPacket::List *users = result.first->getList("users");
if(users) {
+ boost::shared_ptr<std::map<unsigned long, UserInfo> > userList(new std::map<unsigned long, UserInfo>);
+
for(XmlPacket::List::const_iterator user = users->begin(); user != users->end(); ++user) {
UserInfo userInfo(user->get<unsigned long>("uid"), user->get<const std::string&>("username"));
userInfo.setGid(user->get<unsigned long>("gid"));
@@ -60,13 +86,15 @@ boost::shared_ptr<const std::map<unsigned long, UserInfo> > NetworkUserBackend::
userList->insert(std::make_pair(userInfo.getUid(), userInfo));
}
+
+ return userList;
}
- return userList;
+ return boost::shared_ptr<const std::map<unsigned long, UserInfo> >();
}
-boost::shared_ptr<const UserInfo> NetworkUserBackend::getUserInfo(unsigned long uid) throw(Core::Exception) {
- boost::shared_ptr<IdUserRequest> request(new IdUserRequest(application, "GetUserInfo", "uid", uid));
+boost::shared_ptr<const UserInfo> NetworkUserBackend::getUserInfo(unsigned long uid, boost::posix_time::ptime *timestamp) throw(Core::Exception) {
+ boost::shared_ptr<IdUserRequest> request(new IdUserRequest(application, "GetUserInfo", "uid", uid, timestamp));
application->getRequestManager()->sendRequest(connection, request);
request->wait();
@@ -74,15 +102,29 @@ boost::shared_ptr<const UserInfo> NetworkUserBackend::getUserInfo(unsigned long
if(!result.first || result.second)
throw result.second;
- boost::shared_ptr<UserInfo> userInfo(new UserInfo(result.first->get<unsigned long>("uid"), result.first->get<const std::string&>("username")));
- userInfo->setGid(result.first->get<unsigned long>("gid"));
- userInfo->setFullName(result.first->get<const std::string&>("fullName"));
+ if(timestamp) {
+ try {
+ *timestamp = boost::posix_time::from_iso_string(result.first->get<const std::string&>("timestamp"));
+ }
+ catch(...) {}
+ }
+
+ unsigned long uid2 = result.first->get<unsigned long>("uid");
- return userInfo;
+ if(uid2) {
+ boost::shared_ptr<UserInfo> userInfo(new UserInfo(uid2, result.first->get<const std::string&>("username")));
+
+ userInfo->setGid(result.first->get<unsigned long>("gid"));
+ userInfo->setFullName(result.first->get<const std::string&>("fullName"));
+
+ return userInfo;
+ }
+
+ return boost::shared_ptr<const UserInfo>();
}
-boost::shared_ptr<const UserInfo> NetworkUserBackend::getUserInfoByName(const std::string &name) throw(Core::Exception) {
- boost::shared_ptr<NameUserRequest> request(new NameUserRequest(application, "GetUserInfo", name));
+boost::shared_ptr<const UserInfo> NetworkUserBackend::getUserInfoByName(const std::string &name, boost::posix_time::ptime *timestamp) throw(Core::Exception) {
+ boost::shared_ptr<NameUserRequest> request(new NameUserRequest(application, "GetUserInfo", name, timestamp));
application->getRequestManager()->sendRequest(connection, request);
request->wait();
@@ -90,15 +132,29 @@ boost::shared_ptr<const UserInfo> NetworkUserBackend::getUserInfoByName(const st
if(!result.first || result.second)
throw result.second;
- boost::shared_ptr<UserInfo> userInfo(new UserInfo(result.first->get<unsigned long>("uid"), result.first->get<const std::string&>("username")));
- userInfo->setGid(result.first->get<unsigned long>("gid"));
- userInfo->setFullName(result.first->get<const std::string&>("fullName"));
+ if(timestamp) {
+ try {
+ *timestamp = boost::posix_time::from_iso_string(result.first->get<const std::string&>("timestamp"));
+ }
+ catch(...) {}
+ }
+
+ unsigned long uid = result.first->get<unsigned long>("uid");
+
+ if(uid) {
+ boost::shared_ptr<UserInfo> userInfo(new UserInfo(uid, result.first->get<const std::string&>("username")));
+
+ userInfo->setGid(result.first->get<unsigned long>("gid"));
+ userInfo->setFullName(result.first->get<const std::string&>("fullName"));
- return userInfo;
+ return userInfo;
+ }
+
+ return boost::shared_ptr<const UserInfo>();
}
-boost::shared_ptr<const std::set<unsigned long> > NetworkUserBackend::getUserGroupList(unsigned long uid) throw(Core::Exception) {
- boost::shared_ptr<IdUserRequest> request(new IdUserRequest(application, "ListUserGroups", "uid", uid));
+boost::shared_ptr<const std::set<unsigned long> > NetworkUserBackend::getUserGroupList(unsigned long uid, boost::posix_time::ptime *timestamp) throw(Core::Exception) {
+ boost::shared_ptr<IdUserRequest> request(new IdUserRequest(application, "ListUserGroups", "uid", uid, timestamp));
application->getRequestManager()->sendRequest(connection, request);
request->wait();
@@ -106,19 +162,29 @@ boost::shared_ptr<const std::set<unsigned long> > NetworkUserBackend::getUserGro
if(!result.first || result.second)
throw result.second;
- boost::shared_ptr<std::set<unsigned long> > groupList(new std::set<unsigned long>);
+ if(timestamp) {
+ try {
+ *timestamp = boost::posix_time::from_iso_string(result.first->get<const std::string&>("timestamp"));
+ }
+ catch(...) {}
+ }
const XmlPacket::List *groups = result.first->getList("groups");
+
if(groups) {
+ boost::shared_ptr<std::set<unsigned long> > groupList(new std::set<unsigned long>);
+
for(XmlPacket::List::const_iterator group = groups->begin(); group != groups->end(); ++group)
groupList->insert(group->get<unsigned long>("gid"));
+
+ return groupList;
}
- return groupList;
+ return boost::shared_ptr<const std::set<unsigned long> >();
}
-boost::shared_ptr<const std::map<unsigned long, GroupInfo> > NetworkUserBackend::getGroupList() throw(Core::Exception) {
- boost::shared_ptr<SimpleUserRequest> request(new SimpleUserRequest(application, "ListGroups"));
+boost::shared_ptr<const std::map<unsigned long, GroupInfo> > NetworkUserBackend::getGroupList(boost::posix_time::ptime *timestamp) throw(Core::Exception) {
+ boost::shared_ptr<SimpleUserRequest> request(new SimpleUserRequest(application, "ListGroups", timestamp));
application->getRequestManager()->sendRequest(connection, request);
request->wait();
@@ -126,21 +192,30 @@ boost::shared_ptr<const std::map<unsigned long, GroupInfo> > NetworkUserBackend:
if(!result.first || result.second)
throw result.second;
- boost::shared_ptr<std::map<unsigned long, GroupInfo> > groupList(new std::map<unsigned long, GroupInfo>);
+ if(timestamp) {
+ try {
+ *timestamp = boost::posix_time::from_iso_string(result.first->get<const std::string&>("timestamp"));
+ }
+ catch(...) {}
+ }
const XmlPacket::List *groups = result.first->getList("groups");
if(groups) {
+ boost::shared_ptr<std::map<unsigned long, GroupInfo> > groupList(new std::map<unsigned long, GroupInfo>);
+
for(XmlPacket::List::const_iterator group = groups->begin(); group != groups->end(); ++group) {
GroupInfo groupInfo(group->get<unsigned long>("gid"), group->get<const std::string&>("name"));
groupList->insert(std::make_pair(groupInfo.getGid(), groupInfo));
}
+
+ return groupList;
}
- return groupList;
+ return boost::shared_ptr<const std::map<unsigned long, GroupInfo> >();
}
-boost::shared_ptr<const GroupInfo> NetworkUserBackend::getGroupInfo(unsigned long gid) throw(Core::Exception) {
- boost::shared_ptr<IdUserRequest> request(new IdUserRequest(application, "GetGroupInfo", "gid", gid));
+boost::shared_ptr<const GroupInfo> NetworkUserBackend::getGroupInfo(unsigned long gid, boost::posix_time::ptime *timestamp) throw(Core::Exception) {
+ boost::shared_ptr<IdUserRequest> request(new IdUserRequest(application, "GetGroupInfo", "gid", gid, timestamp));
application->getRequestManager()->sendRequest(connection, request);
request->wait();
@@ -148,13 +223,23 @@ boost::shared_ptr<const GroupInfo> NetworkUserBackend::getGroupInfo(unsigned lon
if(!result.first || result.second)
throw result.second;
- boost::shared_ptr<GroupInfo> groupInfo(new GroupInfo(result.first->get<unsigned long>("gid"), result.first->get<const std::string&>("name")));
+ if(timestamp) {
+ try {
+ *timestamp = boost::posix_time::from_iso_string(result.first->get<const std::string&>("timestamp"));
+ }
+ catch(...) {}
+ }
+
+ unsigned long gid2 = result.first->get<unsigned long>("gid");
- return groupInfo;
+ if(gid2)
+ return boost::shared_ptr<GroupInfo>(new GroupInfo(gid2, result.first->get<const std::string&>("name")));
+
+ return boost::shared_ptr<const GroupInfo>();
}
-boost::shared_ptr<const GroupInfo> NetworkUserBackend::getGroupInfoByName(const std::string &name) throw(Core::Exception) {
- boost::shared_ptr<NameUserRequest> request(new NameUserRequest(application, "GetGroupInfo", name));
+boost::shared_ptr<const GroupInfo> NetworkUserBackend::getGroupInfoByName(const std::string &name, boost::posix_time::ptime *timestamp) throw(Core::Exception) {
+ boost::shared_ptr<NameUserRequest> request(new NameUserRequest(application, "GetGroupInfo", name, timestamp));
application->getRequestManager()->sendRequest(connection, request);
request->wait();
@@ -162,13 +247,23 @@ boost::shared_ptr<const GroupInfo> NetworkUserBackend::getGroupInfoByName(const
if(!result.first || result.second)
throw result.second;
- boost::shared_ptr<GroupInfo> groupInfo(new GroupInfo(result.first->get<unsigned long>("gid"), result.first->get<const std::string&>("name")));
+ if(timestamp) {
+ try {
+ *timestamp = boost::posix_time::from_iso_string(result.first->get<const std::string&>("timestamp"));
+ }
+ catch(...) {}
+ }
+
+ unsigned long gid = result.first->get<unsigned long>("gid");
- return groupInfo;
+ if(gid)
+ return boost::shared_ptr<GroupInfo>(new GroupInfo(gid, result.first->get<const std::string&>("name")));
+
+ return boost::shared_ptr<const GroupInfo>();
}
-boost::shared_ptr<const std::set<unsigned long> > NetworkUserBackend::getGroupUserList(unsigned long gid) throw(Core::Exception) {
- boost::shared_ptr<IdUserRequest> request(new IdUserRequest(application, "ListGroupUsers", "gid", gid));
+boost::shared_ptr<const std::set<unsigned long> > NetworkUserBackend::getGroupUserList(unsigned long gid, boost::posix_time::ptime *timestamp) throw(Core::Exception) {
+ boost::shared_ptr<IdUserRequest> request(new IdUserRequest(application, "ListGroupUsers", "gid", gid, timestamp));
application->getRequestManager()->sendRequest(connection, request);
request->wait();
@@ -176,20 +271,29 @@ boost::shared_ptr<const std::set<unsigned long> > NetworkUserBackend::getGroupUs
if(!result.first || result.second)
throw result.second;
- boost::shared_ptr<std::set<unsigned long> > userList(new std::set<unsigned long>);
+ if(timestamp) {
+ try {
+ *timestamp = boost::posix_time::from_iso_string(result.first->get<const std::string&>("timestamp"));
+ }
+ catch(...) {}
+ }
const XmlPacket::List *users = result.first->getList("users");
if(users) {
+ boost::shared_ptr<std::set<unsigned long> > userList(new std::set<unsigned long>);
+
for(XmlPacket::List::const_iterator user = users->begin(); user != users->end(); ++user) {
userList->insert(user->get<unsigned long>("uid"));
}
+
+ return userList;
}
- return userList;
+ return boost::shared_ptr<const std::set<unsigned long> >();
}
-boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > NetworkUserBackend::getFullUserGroupList() throw(Core::Exception) {
- boost::shared_ptr<SimpleUserRequest> request(new SimpleUserRequest(application, "GetFullUserGroupList"));
+boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > NetworkUserBackend::getFullUserGroupList(boost::posix_time::ptime *timestamp) throw(Core::Exception) {
+ boost::shared_ptr<SimpleUserRequest> request(new SimpleUserRequest(application, "GetFullUserGroupList", timestamp));
application->getRequestManager()->sendRequest(connection, request);
request->wait();
@@ -197,15 +301,24 @@ boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > NetworkUse
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>);
+ if(timestamp) {
+ try {
+ *timestamp = boost::posix_time::from_iso_string(result.first->get<const std::string&>("timestamp"));
+ }
+ catch(...) {}
+ }
const XmlPacket::List *list = result.first->getList("userGroupList");
if(list) {
+ boost::shared_ptr<std::multimap<unsigned long, unsigned long> > ret(new std::multimap<unsigned long, unsigned long>);
+
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;
}
- return ret;
+ return boost::shared_ptr<const std::multimap<unsigned long, unsigned long> >();
}
diff --git a/src/Common/Backends/NetworkUserBackend.h b/src/Common/Backends/NetworkUserBackend.h
index 66be909..8faa8e3 100644
--- a/src/Common/Backends/NetworkUserBackend.h
+++ b/src/Common/Backends/NetworkUserBackend.h
@@ -21,7 +21,7 @@
#define MAD_COMMON_BACKENDS_NETWORKUSERBACKEND_H_
#include "../UserBackend.h"
-#include "../Requests/SimpleRequest.h"
+#include "../Request.h"
namespace Mad {
namespace Common {
@@ -29,9 +29,17 @@ namespace Backends {
class NetworkUserBackend : public UserBackend {
private:
- class SimpleUserRequest : public Requests::SimpleRequest {
+ class SimpleUserRequest : public Request {
+ private:
+ std::string type;
+ boost::posix_time::ptime timestamp;
+
+ protected:
+ virtual void sendRequest();
+
public:
- SimpleUserRequest(Application *application, const std::string &type) : SimpleRequest(application, type) {}
+ SimpleUserRequest(Application *application, const std::string &type0, boost::posix_time::ptime *timestamp0)
+ : Request(application), type(type0), timestamp(timestamp0 ? *timestamp0 : boost::posix_time::not_a_date_time) {}
};
class IdUserRequest : public Request {
@@ -39,45 +47,45 @@ class NetworkUserBackend : public UserBackend {
std::string type;
std::string idType;
unsigned long id;
-
+ boost::posix_time::ptime timestamp;
protected:
virtual void sendRequest();
public:
- IdUserRequest(Application *application, const std::string &type0, const std::string &idType0, unsigned long id0)
- : Request(application), type(type0), idType(idType0), id(id0) {}
+ IdUserRequest(Application *application, const std::string &type0, const std::string &idType0, unsigned long id0, boost::posix_time::ptime *timestamp0)
+ : Request(application), type(type0), idType(idType0), id(id0), timestamp(timestamp0 ? *timestamp0 : boost::posix_time::not_a_date_time) {}
};
class NameUserRequest : public Request {
private:
std::string type;
std::string name;
-
+ boost::posix_time::ptime timestamp;
protected:
virtual void sendRequest();
public:
- NameUserRequest(Application *application, const std::string &type0, const std::string &name0)
- : Request(application), type(type0), name(name0) {}
+ NameUserRequest(Application *application, const std::string &type0, const std::string &name0, boost::posix_time::ptime *timestamp0)
+ : Request(application), type(type0), name(name0), timestamp(timestamp0 ? *timestamp0 : boost::posix_time::not_a_date_time) {}
};
Application *application;
Connection *connection;
protected:
- virtual boost::shared_ptr<const std::map<unsigned long, UserInfo> > getUserList() throw(Core::Exception);
- virtual boost::shared_ptr<const UserInfo> getUserInfo(unsigned long uid) throw(Core::Exception);
- virtual boost::shared_ptr<const UserInfo> getUserInfoByName(const std::string &name) throw(Core::Exception);
- virtual boost::shared_ptr<const std::set<unsigned long> > getUserGroupList(unsigned long uid) throw(Core::Exception);
+ virtual boost::shared_ptr<const std::map<unsigned long, Common::UserInfo> > getUserList(boost::posix_time::ptime *timestamp) throw(Core::Exception);
+ virtual boost::shared_ptr<const Common::UserInfo> getUserInfo(unsigned long uid, boost::posix_time::ptime *timestamp) throw(Core::Exception);
+ virtual boost::shared_ptr<const Common::UserInfo> getUserInfoByName(const std::string &name, boost::posix_time::ptime *timestamp) throw(Core::Exception);
+ virtual boost::shared_ptr<const std::set<unsigned long> > getUserGroupList(unsigned long uid, boost::posix_time::ptime *timestamp) throw(Core::Exception);
- virtual boost::shared_ptr<const std::map<unsigned long, GroupInfo> > getGroupList() throw(Core::Exception);
- virtual boost::shared_ptr<const GroupInfo> getGroupInfo(unsigned long gid) throw(Core::Exception);
- 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::map<unsigned long, Common::GroupInfo> > getGroupList(boost::posix_time::ptime *timestamp) throw(Core::Exception);
+ virtual boost::shared_ptr<const Common::GroupInfo> getGroupInfo(unsigned long gid, boost::posix_time::ptime *timestamp) throw(Core::Exception);
+ virtual boost::shared_ptr<const Common::GroupInfo> getGroupInfoByName(const std::string &name, boost::posix_time::ptime *timestamp) throw(Core::Exception);
+ virtual boost::shared_ptr<const std::set<unsigned long> > getGroupUserList(unsigned long gid, boost::posix_time::ptime *timestamp) throw(Core::Exception);
- virtual boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > getFullUserGroupList() throw(Core::Exception);
+ virtual boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > getFullUserGroupList(boost::posix_time::ptime *timestamp) 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 829aae7..4004dbc 100644
--- a/src/Common/UserBackend.h
+++ b/src/Common/UserBackend.h
@@ -31,6 +31,7 @@
#include <set>
#include <string>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/smart_ptr.hpp>
@@ -47,40 +48,40 @@ class UserBackend {
UserBackend() {}
- virtual boost::shared_ptr<const std::map<unsigned long, UserInfo> > getUserList() throw(Core::Exception) {
+ virtual boost::shared_ptr<const std::map<unsigned long, UserInfo> > getUserList(boost::posix_time::ptime *timestamp _UNUSED_PARAMETER_) throw(Core::Exception) {
throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED));
}
- virtual boost::shared_ptr<const UserInfo> getUserInfo(unsigned long uid _UNUSED_PARAMETER_) throw(Core::Exception) {
+ virtual boost::shared_ptr<const UserInfo> getUserInfo(unsigned long uid _UNUSED_PARAMETER_, boost::posix_time::ptime *timestamp _UNUSED_PARAMETER_) throw(Core::Exception) {
throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED));
}
- virtual boost::shared_ptr<const UserInfo> getUserInfoByName(const std::string &name _UNUSED_PARAMETER_) throw(Core::Exception) {
+ virtual boost::shared_ptr<const UserInfo> getUserInfoByName(const std::string &name _UNUSED_PARAMETER_, boost::posix_time::ptime *timestamp _UNUSED_PARAMETER_) throw(Core::Exception) {
throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED));
}
- virtual boost::shared_ptr<const std::set<unsigned long> > getUserGroupList(unsigned long uid _UNUSED_PARAMETER_) throw(Core::Exception) {
+ virtual boost::shared_ptr<const std::set<unsigned long> > getUserGroupList(unsigned long uid _UNUSED_PARAMETER_, boost::posix_time::ptime *timestamp _UNUSED_PARAMETER_) throw(Core::Exception) {
throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED));
}
- virtual boost::shared_ptr<const std::map<unsigned long, GroupInfo> > getGroupList() throw(Core::Exception) {
+ virtual boost::shared_ptr<const std::map<unsigned long, GroupInfo> > getGroupList(boost::posix_time::ptime *timestamp _UNUSED_PARAMETER_) throw(Core::Exception) {
throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED));
}
- virtual boost::shared_ptr<const GroupInfo> getGroupInfo(unsigned long gid _UNUSED_PARAMETER_) throw(Core::Exception) {
+ virtual boost::shared_ptr<const GroupInfo> getGroupInfo(unsigned long gid _UNUSED_PARAMETER_, boost::posix_time::ptime *timestamp _UNUSED_PARAMETER_) throw(Core::Exception) {
throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED));
}
- virtual boost::shared_ptr<const GroupInfo> getGroupInfoByName(const std::string &name _UNUSED_PARAMETER_) throw(Core::Exception) {
+ virtual boost::shared_ptr<const GroupInfo> getGroupInfoByName(const std::string &name _UNUSED_PARAMETER_, boost::posix_time::ptime *timestamp _UNUSED_PARAMETER_) throw(Core::Exception) {
throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED));
}
- virtual boost::shared_ptr<const std::set<unsigned long> > getGroupUserList(unsigned long gid _UNUSED_PARAMETER_) throw(Core::Exception) {
+ virtual boost::shared_ptr<const std::set<unsigned long> > getGroupUserList(unsigned long gid _UNUSED_PARAMETER_, boost::posix_time::ptime *timestamp _UNUSED_PARAMETER_) throw(Core::Exception) {
throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED));
}
- virtual boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > getFullUserGroupList() throw(Core::Exception) {
+ virtual boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > getFullUserGroupList(boost::posix_time::ptime *timestamp _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 887e375..a32bcd3 100644
--- a/src/Common/UserCache.cpp
+++ b/src/Common/UserCache.cpp
@@ -23,40 +23,50 @@
namespace Mad {
namespace Common {
-boost::shared_ptr<const std::map<unsigned long, UserInfo> > UserCache::getUserList() throw(Core::Exception) {
- boost::lock_guard<boost::shared_mutex> lock(mutex);
-
- if(users) {
- application->log(Core::LoggerBase::USER, Core::LoggerBase::DEBUG, "Using cached user list");
- return users;
- }
- else if(userException) {
- application->log(Core::LoggerBase::USER, Core::LoggerBase::DEBUG, "Error cached");
- throw userException;
- }
+boost::shared_ptr<const std::map<unsigned long, UserInfo> > UserCache::getUserList(boost::posix_time::ptime *timestamp) throw(Core::Exception) {
+ boost::lock_guard<boost::recursive_mutex> lock(mutex);
try {
- users = backend->getUserList();
-
- userNames.reset(new std::map<std::string, unsigned long>);
- for(std::map<unsigned long, UserInfo>::const_iterator user = users->begin(); user != users->end(); ++user)
- userNames->insert(std::make_pair(user->second.getUsername(), user->first));
-
- return users;
+ boost::shared_ptr<const std::map<unsigned long, UserInfo> > newUsers = backend->getUserList(&userTime);
+
+ if(newUsers) {
+ users = newUsers;
+ userException = Core::Exception();
+
+ userNames.reset(new std::map<std::string, unsigned long>);
+ for(std::map<unsigned long, UserInfo>::const_iterator user = users->begin(); user != users->end(); ++user)
+ userNames->insert(std::make_pair(user->second.getUsername(), user->first));
+ }
+ else {
+ if(users)
+ application->log(Core::LoggerBase::USER, Core::LoggerBase::DEBUG, "Using cached user list");
+ else
+ application->log(Core::LoggerBase::USER, Core::LoggerBase::DEBUG, "Error cached");
+ }
}
catch(Core::Exception e) {
+ users.reset();
userException = e;
- throw userException;
}
-}
-boost::shared_ptr<const UserInfo> UserCache::getUserInfo(unsigned long uid) throw(Core::Exception) {
- getUserList();
+ if((!timestamp) || timestamp->is_not_a_date_time() || (*timestamp < userTime)) {
+ if(timestamp)
+ *timestamp = userTime;
+
+ if(users)
+ return users;
+ else
+ throw userException;
+ }
+
+ return boost::shared_ptr<const std::map<unsigned long, UserInfo> >();
+}
- boost::lock_guard<boost::shared_mutex> lock(mutex);
+boost::shared_ptr<const UserInfo> UserCache::getUserInfo(unsigned long uid, boost::posix_time::ptime *timestamp) throw(Core::Exception) {
+ boost::lock_guard<boost::recursive_mutex> lock(mutex);
- if(!users)
- throw userException;
+ if(!getUserList(timestamp))
+ return boost::shared_ptr<const UserInfo>();
std::map<unsigned long, UserInfo>::const_iterator user = users->find(uid);
@@ -66,13 +76,11 @@ boost::shared_ptr<const UserInfo> UserCache::getUserInfo(unsigned long uid) thro
return boost::shared_ptr<UserInfo>(new UserInfo(user->second));
}
-boost::shared_ptr<const UserInfo> UserCache::getUserInfoByName(const std::string &name) throw(Core::Exception) {
- getUserList();
+boost::shared_ptr<const UserInfo> UserCache::getUserInfoByName(const std::string &name, boost::posix_time::ptime *timestamp) throw(Core::Exception) {
+ boost::lock_guard<boost::recursive_mutex> lock(mutex);
- boost::lock_guard<boost::shared_mutex> lock(mutex);
-
- if(!users)
- throw userException;
+ if(!getUserList(timestamp))
+ return boost::shared_ptr<const UserInfo>();
std::map<std::string, unsigned long>::const_iterator uid = userNames->find(name);
if(uid == userNames->end())
@@ -83,13 +91,11 @@ boost::shared_ptr<const UserInfo> UserCache::getUserInfoByName(const std::string
return boost::shared_ptr<UserInfo>(new UserInfo(user->second));
}
-boost::shared_ptr<const std::set<unsigned long> > UserCache::getUserGroupList(unsigned long uid) throw(Core::Exception) {
- getFullUserGroupList();
-
- boost::lock_guard<boost::shared_mutex> lock(mutex);
+boost::shared_ptr<const std::set<unsigned long> > UserCache::getUserGroupList(unsigned long uid, boost::posix_time::ptime *timestamp) throw(Core::Exception) {
+ boost::lock_guard<boost::recursive_mutex> lock(mutex);
- if(!userGroups)
- throw userGroupException;
+ if(!getFullUserGroupList(timestamp))
+ return boost::shared_ptr<const std::set<unsigned long> >();
std::pair<std::multimap<unsigned long, unsigned long>::const_iterator, std::multimap<unsigned long, unsigned long>::const_iterator> range = userGroups->equal_range(uid);
@@ -102,40 +108,50 @@ boost::shared_ptr<const std::set<unsigned long> > UserCache::getUserGroupList(un
}
-boost::shared_ptr<const std::map<unsigned long, GroupInfo> > UserCache::getGroupList() throw(Core::Exception) {
- boost::lock_guard<boost::shared_mutex> lock(mutex);
-
- if(groups) {
- application->log(Core::LoggerBase::USER, Core::LoggerBase::DEBUG, "Using cached group list");
- return groups;
- }
- else if(groupException) {
- application->log(Core::LoggerBase::USER, Core::LoggerBase::DEBUG, "Error cached");
- throw groupException;
- }
+boost::shared_ptr<const std::map<unsigned long, GroupInfo> > UserCache::getGroupList(boost::posix_time::ptime *timestamp) throw(Core::Exception) {
+ boost::lock_guard<boost::recursive_mutex> lock(mutex);
try {
- groups = backend->getGroupList();
-
- groupNames.reset(new std::map<std::string, unsigned long>);
- for(std::map<unsigned long, GroupInfo>::const_iterator group = groups->begin(); group != groups->end(); ++group)
- groupNames->insert(std::make_pair(group->second.getName(), group->first));
-
- return groups;
+ boost::shared_ptr<const std::map<unsigned long, GroupInfo> > newGroups = backend->getGroupList(&groupTime);
+
+ if(newGroups) {
+ groups = newGroups;
+ groupException = Core::Exception();
+
+ groupNames.reset(new std::map<std::string, unsigned long>);
+ for(std::map<unsigned long, GroupInfo>::const_iterator group = groups->begin(); group != groups->end(); ++group)
+ groupNames->insert(std::make_pair(group->second.getName(), group->first));
+ }
+ else {
+ if(groups)
+ application->log(Core::LoggerBase::USER, Core::LoggerBase::DEBUG, "Using cached group list");
+ else
+ application->log(Core::LoggerBase::USER, Core::LoggerBase::DEBUG, "Error cached");
+ }
}
catch(Core::Exception e) {
+ groups.reset();
groupException = e;
- throw groupException;
}
-}
-boost::shared_ptr<const GroupInfo> UserCache::getGroupInfo(unsigned long gid) throw(Core::Exception) {
- getGroupList();
+ if((!timestamp) || timestamp->is_not_a_date_time() || (*timestamp < groupTime)) {
+ if(timestamp)
+ *timestamp = groupTime;
+
+ if(groups)
+ return groups;
+ else
+ throw groupException;
+ }
+
+ return boost::shared_ptr<const std::map<unsigned long, GroupInfo> >();
+}
- boost::lock_guard<boost::shared_mutex> lock(mutex);
+boost::shared_ptr<const GroupInfo> UserCache::getGroupInfo(unsigned long gid, boost::posix_time::ptime *timestamp) throw(Core::Exception) {
+ boost::lock_guard<boost::recursive_mutex> lock(mutex);
- if(!groups)
- throw groupException;
+ if(!getGroupList(timestamp))
+ return boost::shared_ptr<const GroupInfo>();
std::map<unsigned long, GroupInfo>::const_iterator group = groups->find(gid);
@@ -145,13 +161,11 @@ boost::shared_ptr<const GroupInfo> UserCache::getGroupInfo(unsigned long gid) th
return boost::shared_ptr<GroupInfo>(new GroupInfo(group->second));
}
-boost::shared_ptr<const GroupInfo> UserCache::getGroupInfoByName(const std::string &name) throw(Core::Exception) {
- getGroupList();
+boost::shared_ptr<const GroupInfo> UserCache::getGroupInfoByName(const std::string &name, boost::posix_time::ptime *timestamp) throw(Core::Exception) {
+ boost::lock_guard<boost::recursive_mutex> lock(mutex);
- boost::lock_guard<boost::shared_mutex> lock(mutex);
-
- if(!groups)
- throw groupException;
+ if(!getGroupList(timestamp))
+ return boost::shared_ptr<const GroupInfo>();
std::map<std::string, unsigned long>::const_iterator gid = groupNames->find(name);
if(gid == groupNames->end())
@@ -162,13 +176,11 @@ 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 gid) throw(Core::Exception) {
- getFullUserGroupList();
-
- boost::lock_guard<boost::shared_mutex> lock(mutex);
+boost::shared_ptr<const std::set<unsigned long> > UserCache::getGroupUserList(unsigned long gid, boost::posix_time::ptime *timestamp) throw(Core::Exception) {
+ boost::lock_guard<boost::recursive_mutex> lock(mutex);
- if(!userGroups)
- throw userGroupException;
+ if(!getFullUserGroupList(timestamp))
+ return boost::shared_ptr<const std::set<unsigned long> >();
std::pair<std::multimap<unsigned long, unsigned long>::iterator, std::multimap<unsigned long, unsigned long>::iterator> range = groupUsers->equal_range(gid);
@@ -180,30 +192,43 @@ boost::shared_ptr<const std::set<unsigned long> > UserCache::getGroupUserList(un
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);
+boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > UserCache::getFullUserGroupList(boost::posix_time::ptime *timestamp) throw(Core::Exception) {
+ boost::lock_guard<boost::recursive_mutex> lock(mutex);
- if(userGroups) {
- application->log(Core::LoggerBase::USER, Core::LoggerBase::DEBUG, "Using cached user-group table");
- return userGroups;
- }
- else if(userGroupException) {
- application->log(Core::LoggerBase::USER, Core::LoggerBase::DEBUG, "Error cached");
- 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;
+ boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > newUserGroups = backend->getFullUserGroupList(&userGroupTime);
+
+ if(newUserGroups) {
+ userGroups = newUserGroups;
+ userGroupException = Core::Exception();
+
+ 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));
+ }
+ else {
+ if(userGroups)
+ application->log(Core::LoggerBase::USER, Core::LoggerBase::DEBUG, "Using cached user-group table");
+ else
+ application->log(Core::LoggerBase::USER, Core::LoggerBase::DEBUG, "Error cached");
+ }
}
catch(Core::Exception e) {
+ userGroups.reset();
userGroupException = e;
- throw userGroupException;
}
+
+ if((!timestamp) || timestamp->is_not_a_date_time() || (*timestamp < userTime)) {
+ if(timestamp)
+ *timestamp = userGroupTime;
+
+ if(userGroups)
+ return userGroups;
+ else
+ throw userGroupException;
+ }
+
+ return boost::shared_ptr<const std::multimap<unsigned long, unsigned long> >();
}
}
diff --git a/src/Common/UserCache.h b/src/Common/UserCache.h
index 548be2e..0fe26be 100644
--- a/src/Common/UserCache.h
+++ b/src/Common/UserCache.h
@@ -24,7 +24,7 @@
#include <limits>
-#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/recursive_mutex.hpp>
namespace Mad {
namespace Common {
@@ -40,32 +40,35 @@ class UserCache : public UserBackend, private boost::noncopyable {
boost::shared_ptr<UserBackend> backend;
- boost::shared_mutex mutex;
+ boost::recursive_mutex mutex;
boost::shared_ptr<const std::map<unsigned long, UserInfo> > users;
boost::shared_ptr<std::map<std::string, unsigned long> > userNames;
Core::Exception userException;
+ boost::posix_time::ptime userTime;
boost::shared_ptr<const std::map<unsigned long, GroupInfo> > groups;
boost::shared_ptr<std::map<std::string, unsigned long> > groupNames;
Core::Exception groupException;
+ boost::posix_time::ptime groupTime;
boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > userGroups;
boost::shared_ptr<std::multimap<unsigned long, unsigned long> > groupUsers;
Core::Exception userGroupException;
+ boost::posix_time::ptime userGroupTime;
protected:
- virtual boost::shared_ptr<const std::map<unsigned long, UserInfo> > getUserList() throw(Core::Exception);
- virtual boost::shared_ptr<const UserInfo> getUserInfo(unsigned long uid) throw(Core::Exception);
- virtual boost::shared_ptr<const UserInfo> getUserInfoByName(const std::string &name) throw(Core::Exception);
- virtual boost::shared_ptr<const std::set<unsigned long> > getUserGroupList(unsigned long uid) throw(Core::Exception);
+ virtual boost::shared_ptr<const std::map<unsigned long, UserInfo> > getUserList(boost::posix_time::ptime *timestamp) throw(Core::Exception);
+ virtual boost::shared_ptr<const UserInfo> getUserInfo(unsigned long uid, boost::posix_time::ptime *timestamp) throw(Core::Exception);
+ virtual boost::shared_ptr<const UserInfo> getUserInfoByName(const std::string &name, boost::posix_time::ptime *timestamp) throw(Core::Exception);
+ virtual boost::shared_ptr<const std::set<unsigned long> > getUserGroupList(unsigned long uid, boost::posix_time::ptime *timestamp) throw(Core::Exception);
- virtual boost::shared_ptr<const std::map<unsigned long, GroupInfo> > getGroupList() throw(Core::Exception);
- virtual boost::shared_ptr<const GroupInfo> getGroupInfo(unsigned long gid) throw(Core::Exception);
- 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::map<unsigned long, GroupInfo> > getGroupList(boost::posix_time::ptime *timestamp) throw(Core::Exception);
+ virtual boost::shared_ptr<const GroupInfo> getGroupInfo(unsigned long gid, boost::posix_time::ptime *timestamp) throw(Core::Exception);
+ virtual boost::shared_ptr<const GroupInfo> getGroupInfoByName(const std::string &name, boost::posix_time::ptime *timestamp) throw(Core::Exception);
+ virtual boost::shared_ptr<const std::set<unsigned long> > getGroupUserList(unsigned long gid, boost::posix_time::ptime *timestamp) throw(Core::Exception);
- virtual boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > getFullUserGroupList() throw(Core::Exception);
+ virtual boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > getFullUserGroupList(boost::posix_time::ptime *timestamp) throw(Core::Exception);
virtual void setPassword(unsigned long uid, const std::string &password) throw(Core::Exception) {
backend->setPassword(uid, password);
@@ -75,7 +78,9 @@ class UserCache : public UserBackend, private boost::noncopyable {
backend->addUser(userInfo);
}
- UserCache(Application *application0, boost::shared_ptr<UserBackend> backend0) : application(application0), backend(backend0) {}
+ UserCache(Application *application0, boost::shared_ptr<UserBackend> backend0) : application(application0), backend(backend0),
+ userTime(boost::posix_time::not_a_date_time), groupTime(boost::posix_time::not_a_date_time),
+ userGroupTime(boost::posix_time::not_a_date_time) {}
};
}
diff --git a/src/Common/UserManager.cpp b/src/Common/UserManager.cpp
index 1b20395..4031140 100644
--- a/src/Common/UserManager.cpp
+++ b/src/Common/UserManager.cpp
@@ -41,14 +41,14 @@ void UserManager::registerBackendCached(boost::shared_ptr<UserBackend> backend)
}
-boost::shared_ptr<const std::map<unsigned long, UserInfo> > UserManager::getUserList() throw(Core::Exception) {
+boost::shared_ptr<const std::map<unsigned long, UserInfo> > UserManager::getUserList(boost::posix_time::ptime *timestamp) 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->getUserList();
+ return backend->second->getUserList(timestamp);
}
catch(Core::Exception e2) {
if(e.getErrorCode() == Core::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Core::Exception::NOT_IMPLEMENTED)
@@ -59,14 +59,14 @@ boost::shared_ptr<const std::map<unsigned long, UserInfo> > UserManager::getUser
throw e;
}
-boost::shared_ptr<const UserInfo> UserManager::getUserInfo(unsigned long uid) throw(Core::Exception) {
+boost::shared_ptr<const UserInfo> UserManager::getUserInfo(unsigned long uid, boost::posix_time::ptime *timestamp) 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->getUserInfo(uid);
+ return backend->second->getUserInfo(uid, timestamp);
}
catch(Core::Exception e2) {
if(e.getErrorCode() == Core::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Core::Exception::NOT_IMPLEMENTED)
@@ -77,14 +77,14 @@ boost::shared_ptr<const UserInfo> UserManager::getUserInfo(unsigned long uid) th
throw e;
}
-boost::shared_ptr<const UserInfo> UserManager::getUserInfoByName(const std::string &name) throw(Core::Exception) {
+boost::shared_ptr<const UserInfo> UserManager::getUserInfoByName(const std::string &name, boost::posix_time::ptime *timestamp) 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->getUserInfoByName(name);
+ return backend->second->getUserInfoByName(name, timestamp);
}
catch(Core::Exception e2) {
if(e.getErrorCode() == Core::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Core::Exception::NOT_IMPLEMENTED)
@@ -95,14 +95,14 @@ boost::shared_ptr<const UserInfo> UserManager::getUserInfoByName(const std::stri
throw e;
}
-boost::shared_ptr<const std::set<unsigned long> > UserManager::getUserGroupList(unsigned long uid) throw(Core::Exception) {
+boost::shared_ptr<const std::set<unsigned long> > UserManager::getUserGroupList(unsigned long uid, boost::posix_time::ptime *timestamp) 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->getUserGroupList(uid);
+ return backend->second->getUserGroupList(uid, timestamp);
}
catch(Core::Exception e2) {
if(e.getErrorCode() == Core::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Core::Exception::NOT_IMPLEMENTED)
@@ -113,7 +113,7 @@ boost::shared_ptr<const std::set<unsigned long> > UserManager::getUserGroupList(
throw e;
}
-boost::shared_ptr<const std::map<unsigned long, GroupInfo> > UserManager::getGroupList() throw(Core::Exception) {
+boost::shared_ptr<const std::map<unsigned long, GroupInfo> > UserManager::getGroupList(boost::posix_time::ptime *timestamp) throw(Core::Exception) {
Core::Exception e(Core::Exception::NOT_IMPLEMENTED);
boost::shared_ptr<const std::map<unsigned long, GroupInfo> > ret;
@@ -123,7 +123,7 @@ boost::shared_ptr<const std::map<unsigned long, GroupInfo> > UserManager::getGro
for(BackendMap::iterator backend = backends.begin(); backend != backends.end(); ++backend) {
try {
- return backend->second->getGroupList();
+ return backend->second->getGroupList(timestamp);
}
catch(Core::Exception e2) {
if(e.getErrorCode() == Core::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Core::Exception::NOT_IMPLEMENTED)
@@ -135,14 +135,14 @@ boost::shared_ptr<const std::map<unsigned long, GroupInfo> > UserManager::getGro
throw e;
}
-boost::shared_ptr<const GroupInfo> UserManager::getGroupInfo(unsigned long gid) throw(Core::Exception) {
+boost::shared_ptr<const GroupInfo> UserManager::getGroupInfo(unsigned long gid, boost::posix_time::ptime *timestamp) 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->getGroupInfo(gid);
+ return backend->second->getGroupInfo(gid, timestamp);
}
catch(Core::Exception e2) {
if(e.getErrorCode() == Core::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Core::Exception::NOT_IMPLEMENTED)
@@ -153,14 +153,14 @@ boost::shared_ptr<const GroupInfo> UserManager::getGroupInfo(unsigned long gid)
throw e;
}
-boost::shared_ptr<const GroupInfo> UserManager::getGroupInfoByName(const std::string &name) throw(Core::Exception) {
+boost::shared_ptr<const GroupInfo> UserManager::getGroupInfoByName(const std::string &name, boost::posix_time::ptime *timestamp) 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->getGroupInfoByName(name);
+ return backend->second->getGroupInfoByName(name, timestamp);
}
catch(Core::Exception e2) {
if(e.getErrorCode() == Core::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Core::Exception::NOT_IMPLEMENTED)
@@ -171,14 +171,14 @@ boost::shared_ptr<const GroupInfo> UserManager::getGroupInfoByName(const std::st
throw e;
}
-boost::shared_ptr<const std::set<unsigned long> > UserManager::getGroupUserList(unsigned long gid) throw(Core::Exception) {
+boost::shared_ptr<const std::set<unsigned long> > UserManager::getGroupUserList(unsigned long gid, boost::posix_time::ptime *timestamp) 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->getGroupUserList(gid);
+ return backend->second->getGroupUserList(gid, timestamp);
}
catch(Core::Exception e2) {
if(e.getErrorCode() == Core::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Core::Exception::NOT_IMPLEMENTED)
@@ -189,14 +189,14 @@ 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) {
+boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > UserManager::getFullUserGroupList(boost::posix_time::ptime *timestamp) 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();
+ return backend->second->getFullUserGroupList(timestamp);
}
catch(Core::Exception e2) {
if(e.getErrorCode() == Core::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Core::Exception::NOT_IMPLEMENTED)
diff --git a/src/Common/UserManager.h b/src/Common/UserManager.h
index c545f01..5877bac 100644
--- a/src/Common/UserManager.h
+++ b/src/Common/UserManager.h
@@ -69,17 +69,17 @@ class UserManager : private boost::noncopyable {
backends.erase(backend);
}
- boost::shared_ptr<const std::map<unsigned long, UserInfo> > getUserList() throw(Core::Exception);
- boost::shared_ptr<const UserInfo> getUserInfo(unsigned long uid) throw(Core::Exception);
- boost::shared_ptr<const UserInfo> getUserInfoByName(const std::string &name) throw(Core::Exception);
- boost::shared_ptr<const std::set<unsigned long> > getUserGroupList(unsigned long uid) throw(Core::Exception);
+ boost::shared_ptr<const std::map<unsigned long, UserInfo> > getUserList(boost::posix_time::ptime *timestamp = 0) throw(Core::Exception);
+ boost::shared_ptr<const UserInfo> getUserInfo(unsigned long uid, boost::posix_time::ptime *timestamp = 0) throw(Core::Exception);
+ boost::shared_ptr<const UserInfo> getUserInfoByName(const std::string &name, boost::posix_time::ptime *timestamp = 0) throw(Core::Exception);
+ boost::shared_ptr<const std::set<unsigned long> > getUserGroupList(unsigned long uid, boost::posix_time::ptime *timestamp = 0) throw(Core::Exception);
- boost::shared_ptr<const std::map<unsigned long, GroupInfo> > getGroupList() throw(Core::Exception);
- boost::shared_ptr<const GroupInfo> getGroupInfo(unsigned long gid) throw(Core::Exception);
- 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::map<unsigned long, GroupInfo> > getGroupList(boost::posix_time::ptime *timestamp = 0) throw(Core::Exception);
+ boost::shared_ptr<const GroupInfo> getGroupInfo(unsigned long gid, boost::posix_time::ptime *timestamp = 0) throw(Core::Exception);
+ boost::shared_ptr<const GroupInfo> getGroupInfoByName(const std::string &name, boost::posix_time::ptime *timestamp = 0) throw(Core::Exception);
+ boost::shared_ptr<const std::set<unsigned long> > getGroupUserList(unsigned long gid, boost::posix_time::ptime *timestamp = 0) throw(Core::Exception);
- boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > getFullUserGroupList() throw(Core::Exception);
+ boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > getFullUserGroupList(boost::posix_time::ptime *timestamp = 0) throw(Core::Exception);
void setPassword(unsigned long uid, const std::string &password) throw(Core::Exception);
diff --git a/src/Server/RequestHandlers/UserRequestHandlerGroup.cpp b/src/Server/RequestHandlers/UserRequestHandlerGroup.cpp
index d579480..292e887 100644
--- a/src/Server/RequestHandlers/UserRequestHandlerGroup.cpp
+++ b/src/Server/RequestHandlers/UserRequestHandlerGroup.cpp
@@ -17,99 +17,196 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <config.h>
+
#include "UserRequestHandlerGroup.h"
#include "../Application.h"
+
#include <Common/UserManager.h>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
namespace Mad {
namespace Server {
namespace RequestHandlers {
-void UserRequestHandlerGroup::handleUserListRequest(boost::shared_ptr<const Common::XmlPacket> packet _UNUSED_PARAMETER_, Common::XmlPacket *ret,
+void UserRequestHandlerGroup::handleUserListRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret,
Common::Connection *connection _UNUSED_PARAMETER_) {
- boost::shared_ptr<const std::map<unsigned long, Common::UserInfo> > info = application->getUserManager()->getUserList();
+ boost::posix_time::ptime timestamp(boost::posix_time::not_a_date_time);
+
+ const std::string &timestr = packet->get<const std::string&>("timestamp");
+ if(!timestr.empty()) {
+ try {
+ timestamp = boost::posix_time::from_iso_string(timestr);
+ }
+ catch(...) {}
+ }
+
+ boost::shared_ptr<const std::map<unsigned long, Common::UserInfo> > users = application->getUserManager()->getUserList(&timestamp);
ret->setType("OK");
- Common::XmlPacket::List *list = ret->createList("users");
- for(std::map<unsigned long, Common::UserInfo>::const_iterator user = info->begin(); user != info->end(); ++user) {
- Common::XmlPacket::List::iterator entry = list->addEntry();
+ if(!timestamp.is_not_a_date_time())
+ ret->set("timestamp", boost::posix_time::to_iso_string(timestamp));
+
+ if(users) {
+ Common::XmlPacket::List *list = ret->createList("users");
+
+ for(std::map<unsigned long, Common::UserInfo>::const_iterator user = users->begin(); user != users->end(); ++user) {
+ Common::XmlPacket::List::iterator entry = list->addEntry();
- entry->set("uid", user->second.getUid());
- entry->set("gid", user->second.getGid());
- entry->set("username", user->second.getUsername());
- entry->set("fullName", user->second.getFullName());
+ entry->set("uid", user->second.getUid());
+ entry->set("gid", user->second.getGid());
+ entry->set("username", user->second.getUsername());
+ entry->set("fullName", user->second.getFullName());
+ }
}
}
void UserRequestHandlerGroup::handleUserInfoRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret,
Common::Connection *connection _UNUSED_PARAMETER_) {
+ boost::posix_time::ptime timestamp(boost::posix_time::not_a_date_time);
+
+ const std::string &timestr = packet->get<const std::string&>("timestamp");
+ if(!timestr.empty()) {
+ try {
+ timestamp = boost::posix_time::from_iso_string(timestr);
+ }
+ catch(...) {}
+ }
+
boost::shared_ptr<const Common::UserInfo> info;
unsigned long uid = packet->get<unsigned long>("uid");
if(uid)
- info = application->getUserManager()->getUserInfo(uid);
+ info = application->getUserManager()->getUserInfo(uid, &timestamp);
else
- info = application->getUserManager()->getUserInfoByName(packet->get<const std::string&>("name"));
+ info = application->getUserManager()->getUserInfoByName(packet->get<const std::string&>("name"), &timestamp);
ret->setType("OK");
- ret->set("uid", info->getUid());
- ret->set("gid", info->getGid());
- ret->set("username", info->getUsername());
- ret->set("fullName", info->getFullName());
+ if(!timestamp.is_not_a_date_time())
+ ret->set("timestamp", boost::posix_time::to_iso_string(timestamp));
+
+ if(info) {
+ ret->set("uid", info->getUid());
+ ret->set("gid", info->getGid());
+ ret->set("username", info->getUsername());
+ ret->set("fullName", info->getFullName());
+ }
}
void UserRequestHandlerGroup::handleUserGroupListRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret,
Common::Connection *connection _UNUSED_PARAMETER_) {
- boost::shared_ptr<const std::set<unsigned long> > groups = application->getUserManager()->getUserGroupList(packet->get<unsigned long>("uid"));
+ boost::posix_time::ptime timestamp(boost::posix_time::not_a_date_time);
+
+ const std::string &timestr = packet->get<const std::string&>("timestamp");
+ if(!timestr.empty()) {
+ try {
+ timestamp = boost::posix_time::from_iso_string(timestr);
+ }
+ catch(...) {}
+ }
+
+ boost::shared_ptr<const std::set<unsigned long> > groups = application->getUserManager()->getUserGroupList(packet->get<unsigned long>("uid"), &timestamp);
ret->setType("OK");
- Common::XmlPacket::List *list = ret->createList("groups");
- for(std::set<unsigned long>::const_iterator group = groups->begin(); group != groups->end(); ++group) {
- Common::XmlPacket::List::iterator entry = list->addEntry();
+ if(!timestamp.is_not_a_date_time())
+ ret->set("timestamp", boost::posix_time::to_iso_string(timestamp));
+
+ if(groups) {
+ Common::XmlPacket::List *list = ret->createList("groups");
+
+ for(std::set<unsigned long>::const_iterator group = groups->begin(); group != groups->end(); ++group) {
+ Common::XmlPacket::List::iterator entry = list->addEntry();
- entry->set("gid", *group);
+ entry->set("gid", *group);
+ }
}
}
-void UserRequestHandlerGroup::handleGroupListRequest(boost::shared_ptr<const Common::XmlPacket> packet _UNUSED_PARAMETER_, Common::XmlPacket *ret,
+void UserRequestHandlerGroup::handleGroupListRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret,
Common::Connection *connection _UNUSED_PARAMETER_) {
- boost::shared_ptr<const std::map<unsigned long, Common::GroupInfo> > info = application->getUserManager()->getGroupList();
+ boost::posix_time::ptime timestamp(boost::posix_time::not_a_date_time);
+
+ const std::string &timestr = packet->get<const std::string&>("timestamp");
+ if(!timestr.empty()) {
+ try {
+ timestamp = boost::posix_time::from_iso_string(timestr);
+ }
+ catch(...) {}
+ }
+
+ boost::shared_ptr<const std::map<unsigned long, Common::GroupInfo> > groups = application->getUserManager()->getGroupList(&timestamp);
ret->setType("OK");
- Common::XmlPacket::List *list = ret->createList("groups");
- for(std::map<unsigned long, Common::GroupInfo>::const_iterator group = info->begin(); group != info->end(); ++group) {
- Common::XmlPacket::List::iterator entry = list->addEntry();
+ if(!timestamp.is_not_a_date_time())
+ ret->set("timestamp", boost::posix_time::to_iso_string(timestamp));
+
+ if(groups) {
+ Common::XmlPacket::List *list = ret->createList("groups");
+
+ for(std::map<unsigned long, Common::GroupInfo>::const_iterator group = groups->begin(); group != groups->end(); ++group) {
+ Common::XmlPacket::List::iterator entry = list->addEntry();
- entry->set("gid", group->second.getGid());
- entry->set("name", group->second.getName());
+ entry->set("gid", group->second.getGid());
+ entry->set("name", group->second.getName());
+ }
}
}
void UserRequestHandlerGroup::handleGroupInfoRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret,
Common::Connection *connection _UNUSED_PARAMETER_) {
+ boost::posix_time::ptime timestamp(boost::posix_time::not_a_date_time);
+
+ const std::string &timestr = packet->get<const std::string&>("timestamp");
+ if(!timestr.empty()) {
+ try {
+ timestamp = boost::posix_time::from_iso_string(timestr);
+ }
+ catch(...) {}
+ }
+
boost::shared_ptr<const Common::GroupInfo> info;
unsigned long gid = packet->get<unsigned long>("gid");
if(gid)
- info = application->getUserManager()->getGroupInfo(gid);
+ info = application->getUserManager()->getGroupInfo(gid, &timestamp);
else
- info = application->getUserManager()->getGroupInfoByName(packet->get<const std::string&>("name"));
+ info = application->getUserManager()->getGroupInfoByName(packet->get<const std::string&>("name"), &timestamp);
ret->setType("OK");
- ret->set("gid", info->getGid());
- ret->set("name", info->getName());
+ if(!timestamp.is_not_a_date_time())
+ ret->set("timestamp", boost::posix_time::to_iso_string(timestamp));
+
+ if(info) {
+ ret->set("gid", info->getGid());
+ ret->set("name", info->getName());
+ }
}
void UserRequestHandlerGroup::handleGroupUserListRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret,
Common::Connection *connection _UNUSED_PARAMETER_) {
- boost::shared_ptr<const std::set<unsigned long> > users = application->getUserManager()->getGroupUserList(packet->get<unsigned long>("gid"));
+ boost::posix_time::ptime timestamp(boost::posix_time::not_a_date_time);
+
+ const std::string &timestr = packet->get<const std::string&>("timestamp");
+ if(!timestr.empty()) {
+ try {
+ timestamp = boost::posix_time::from_iso_string(timestr);
+ }
+ catch(...) {}
+ }
+
+ boost::shared_ptr<const std::set<unsigned long> > users = application->getUserManager()->getGroupUserList(packet->get<unsigned long>("gid"), &timestamp);
ret->setType("OK");
+
+ if(!timestamp.is_not_a_date_time())
+ ret->set("timestamp", boost::posix_time::to_iso_string(timestamp));
+
Common::XmlPacket::List *list = ret->createList("users");
for(std::set<unsigned long>::const_iterator user = users->begin(); user != users->end(); ++user) {
@@ -119,18 +216,34 @@ void UserRequestHandlerGroup::handleGroupUserListRequest(boost::shared_ptr<const
}
}
-void UserRequestHandlerGroup::handleFullUserGroupListRequest(boost::shared_ptr<const Common::XmlPacket> packet _UNUSED_PARAMETER_, Common::XmlPacket *ret,
+void UserRequestHandlerGroup::handleFullUserGroupListRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret,
Common::Connection *connection _UNUSED_PARAMETER_) {
- boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > userGroups = application->getUserManager()->getFullUserGroupList();
+ boost::posix_time::ptime timestamp(boost::posix_time::not_a_date_time);
+
+ const std::string &timestr = packet->get<const std::string&>("timestamp");
+ if(!timestr.empty()) {
+ try {
+ timestamp = boost::posix_time::from_iso_string(timestr);
+ }
+ catch(...) {}
+ }
+
+ boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > userGroups = application->getUserManager()->getFullUserGroupList(&timestamp);
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();
+ if(!timestamp.is_not_a_date_time())
+ ret->set("timestamp", boost::posix_time::to_iso_string(timestamp));
+
+ if(userGroups) {
+ 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);
+ entry->set("uid", userGroup->first);
+ entry->set("gid", userGroup->second);
+ }
}
}
diff --git a/src/modules/UserBackendMysql/UserBackendMysql.cpp b/src/modules/UserBackendMysql/UserBackendMysql.cpp
index 6d64a51..82258e8 100644
--- a/src/modules/UserBackendMysql/UserBackendMysql.cpp
+++ b/src/modules/UserBackendMysql/UserBackendMysql.cpp
@@ -134,11 +134,18 @@ void UserBackendMysql::configFinished() {
}
-boost::shared_ptr<const std::map<unsigned long, Common::UserInfo> > UserBackendMysql::getUserList() throw(Core::Exception) {
+boost::shared_ptr<const std::map<unsigned long, Common::UserInfo> > UserBackendMysql::getUserList(boost::posix_time::ptime *timestamp) throw(Core::Exception) {
application->getThreadManager()->detach();
boost::unique_lock<boost::mutex> lock(mutex);
+ if(timestamp) {
+ if(timestamp->is_not_a_date_time() || *timestamp < lastUpdate)
+ *timestamp = lastUpdate;
+ else
+ return boost::shared_ptr<const std::map<unsigned long, Common::UserInfo> >();
+ }
+
if(!mysql || mysql_ping(mysql))
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -164,11 +171,18 @@ boost::shared_ptr<const std::map<unsigned long, Common::UserInfo> > UserBackendM
return users;
}
-boost::shared_ptr<const Common::UserInfo> UserBackendMysql::getUserInfo(unsigned long uid) throw(Core::Exception) {
+boost::shared_ptr<const Common::UserInfo> UserBackendMysql::getUserInfo(unsigned long uid, boost::posix_time::ptime *timestamp) throw(Core::Exception) {
application->getThreadManager()->detach();
boost::unique_lock<boost::mutex> lock(mutex);
+ if(timestamp) {
+ if(timestamp->is_not_a_date_time() || *timestamp < lastUpdate)
+ *timestamp = lastUpdate;
+ else
+ return boost::shared_ptr<const Common::UserInfo>();
+ }
+
if(!mysql || mysql_ping(mysql))
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -205,11 +219,18 @@ boost::shared_ptr<const Common::UserInfo> UserBackendMysql::getUserInfo(unsigned
throw Core::Exception(Core::Exception::NOT_FOUND);
}
-boost::shared_ptr<const Common::UserInfo> UserBackendMysql::getUserInfoByName(const std::string &name) throw(Core::Exception) {
+boost::shared_ptr<const Common::UserInfo> UserBackendMysql::getUserInfoByName(const std::string &name, boost::posix_time::ptime *timestamp) throw(Core::Exception) {
application->getThreadManager()->detach();
boost::unique_lock<boost::mutex> lock(mutex);
+ if(timestamp) {
+ if(timestamp->is_not_a_date_time() || *timestamp < lastUpdate)
+ *timestamp = lastUpdate;
+ else
+ return boost::shared_ptr<const Common::UserInfo>();
+ }
+
if(!mysql || mysql_ping(mysql))
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -243,11 +264,18 @@ boost::shared_ptr<const Common::UserInfo> UserBackendMysql::getUserInfoByName(co
throw Core::Exception(Core::Exception::NOT_FOUND);
}
-boost::shared_ptr<const std::set<unsigned long> > UserBackendMysql::getUserGroupList(unsigned long uid) throw(Core::Exception) {
+boost::shared_ptr<const std::set<unsigned long> > UserBackendMysql::getUserGroupList(unsigned long uid, boost::posix_time::ptime *timestamp) throw(Core::Exception) {
application->getThreadManager()->detach();
boost::unique_lock<boost::mutex> lock(mutex);
+ if(timestamp) {
+ if(timestamp->is_not_a_date_time() || *timestamp < lastUpdate)
+ *timestamp = lastUpdate;
+ else
+ return boost::shared_ptr<const std::set<unsigned long> >();
+ }
+
if(!mysql || mysql_ping(mysql))
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -275,11 +303,18 @@ 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) {
+boost::shared_ptr<const std::map<unsigned long, Common::GroupInfo> > UserBackendMysql::getGroupList(boost::posix_time::ptime *timestamp) throw(Core::Exception) {
application->getThreadManager()->detach();
boost::unique_lock<boost::mutex> lock(mutex);
+ if(timestamp) {
+ if(timestamp->is_not_a_date_time() || *timestamp < lastUpdate)
+ *timestamp = lastUpdate;
+ else
+ return boost::shared_ptr<const std::map<unsigned long, Common::GroupInfo> >();
+ }
+
if(!mysql || mysql_ping(mysql))
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -302,11 +337,18 @@ boost::shared_ptr<const std::map<unsigned long, Common::GroupInfo> > UserBackend
return groups;
}
-boost::shared_ptr<const Common::GroupInfo> UserBackendMysql::getGroupInfo(unsigned long gid) throw(Core::Exception) {
+boost::shared_ptr<const Common::GroupInfo> UserBackendMysql::getGroupInfo(unsigned long gid, boost::posix_time::ptime *timestamp) throw(Core::Exception) {
application->getThreadManager()->detach();
boost::unique_lock<boost::mutex> lock(mutex);
+ if(timestamp) {
+ if(timestamp->is_not_a_date_time() || *timestamp < lastUpdate)
+ *timestamp = lastUpdate;
+ else
+ return boost::shared_ptr<const Common::GroupInfo>();
+ }
+
if(!mysql || mysql_ping(mysql))
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -335,11 +377,18 @@ boost::shared_ptr<const Common::GroupInfo> UserBackendMysql::getGroupInfo(unsign
throw Core::Exception(Core::Exception::NOT_FOUND);
}
-boost::shared_ptr<const Common::GroupInfo> UserBackendMysql::getGroupInfoByName(const std::string &name) throw(Core::Exception) {
+boost::shared_ptr<const Common::GroupInfo> UserBackendMysql::getGroupInfoByName(const std::string &name, boost::posix_time::ptime *timestamp) throw(Core::Exception) {
application->getThreadManager()->detach();
boost::unique_lock<boost::mutex> lock(mutex);
+ if(timestamp) {
+ if(timestamp->is_not_a_date_time() || *timestamp < lastUpdate)
+ *timestamp = lastUpdate;
+ else
+ return boost::shared_ptr<const Common::GroupInfo>();
+ }
+
if(!mysql || mysql_ping(mysql))
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -365,11 +414,18 @@ boost::shared_ptr<const Common::GroupInfo> UserBackendMysql::getGroupInfoByName(
throw Core::Exception(Core::Exception::NOT_FOUND);
}
-boost::shared_ptr<const std::set<unsigned long> > UserBackendMysql::getGroupUserList(unsigned long gid) throw(Core::Exception) {
+boost::shared_ptr<const std::set<unsigned long> > UserBackendMysql::getGroupUserList(unsigned long gid, boost::posix_time::ptime *timestamp) throw(Core::Exception) {
application->getThreadManager()->detach();
boost::unique_lock<boost::mutex> lock(mutex);
+ if(timestamp) {
+ if(timestamp->is_not_a_date_time() || *timestamp < lastUpdate)
+ *timestamp = lastUpdate;
+ else
+ return boost::shared_ptr<const std::set<unsigned long> >();
+ }
+
if(!mysql || mysql_ping(mysql))
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
@@ -396,11 +452,18 @@ 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) {
+boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > UserBackendMysql::getFullUserGroupList(boost::posix_time::ptime *timestamp) throw(Core::Exception) {
application->getThreadManager()->detach();
boost::unique_lock<boost::mutex> lock(mutex);
+ if(timestamp) {
+ if(timestamp->is_not_a_date_time() || *timestamp < lastUpdate)
+ *timestamp = lastUpdate;
+ else
+ return boost::shared_ptr<const std::multimap<unsigned long, unsigned long> >();
+ }
+
if(!mysql || mysql_ping(mysql))
throw Core::Exception(Core::Exception::NOT_AVAILABLE);
diff --git a/src/modules/UserBackendMysql/UserBackendMysql.h b/src/modules/UserBackendMysql/UserBackendMysql.h
index eadbf3b..52a134a 100644
--- a/src/modules/UserBackendMysql/UserBackendMysql.h
+++ b/src/modules/UserBackendMysql/UserBackendMysql.h
@@ -49,26 +49,28 @@ class UserBackendMysql : public Common::UserBackend, private Core::Configurable
MYSQL *mysql;
+ boost::posix_time::ptime lastUpdate;
+
boost::mutex mutex;
protected:
virtual bool handleConfigEntry(const Core::ConfigEntry &entry, bool);
virtual void configFinished();
- virtual boost::shared_ptr<const std::map<unsigned long, Common::UserInfo> > getUserList() throw(Core::Exception);
- virtual boost::shared_ptr<const Common::UserInfo> getUserInfo(unsigned long uid) throw(Core::Exception);
- virtual boost::shared_ptr<const Common::UserInfo> getUserInfoByName(const std::string &name) throw(Core::Exception);
- virtual boost::shared_ptr<const std::set<unsigned long> > getUserGroupList(unsigned long uid) throw(Core::Exception);
+ virtual boost::shared_ptr<const std::map<unsigned long, Common::UserInfo> > getUserList(boost::posix_time::ptime *timestamp) throw(Core::Exception);
+ virtual boost::shared_ptr<const Common::UserInfo> getUserInfo(unsigned long uid, boost::posix_time::ptime *timestamp) throw(Core::Exception);
+ virtual boost::shared_ptr<const Common::UserInfo> getUserInfoByName(const std::string &name, boost::posix_time::ptime *timestamp) throw(Core::Exception);
+ virtual boost::shared_ptr<const std::set<unsigned long> > getUserGroupList(unsigned long uid, boost::posix_time::ptime *timestamp) throw(Core::Exception);
- virtual boost::shared_ptr<const std::map<unsigned long, Common::GroupInfo> > getGroupList() throw(Core::Exception);
- virtual boost::shared_ptr<const Common::GroupInfo> getGroupInfo(unsigned long gid) throw(Core::Exception);
- 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::map<unsigned long, Common::GroupInfo> > getGroupList(boost::posix_time::ptime *timestamp) throw(Core::Exception);
+ virtual boost::shared_ptr<const Common::GroupInfo> getGroupInfo(unsigned long gid, boost::posix_time::ptime *timestamp) throw(Core::Exception);
+ virtual boost::shared_ptr<const Common::GroupInfo> getGroupInfoByName(const std::string &name, boost::posix_time::ptime *timestamp) throw(Core::Exception);
+ virtual boost::shared_ptr<const std::set<unsigned long> > getGroupUserList(unsigned long gid, boost::posix_time::ptime *timestamp) throw(Core::Exception);
- virtual boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > getFullUserGroupList() throw(Core::Exception);
+ virtual boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > getFullUserGroupList(boost::posix_time::ptime *timestamp) throw(Core::Exception);
public:
- UserBackendMysql(Common::Application *application0) : application(application0), port(0), mysql(0) {
+ UserBackendMysql(Common::Application *application0) : application(application0), port(0), mysql(0), lastUpdate(boost::posix_time::microsec_clock::universal_time()) {
application->getConfigManager()->registerConfigurable(this);
}