summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Client/CommandParser.cpp2
-rw-r--r--src/Client/UserCommands.cpp74
-rw-r--r--src/Client/UserCommands.h3
-rw-r--r--src/Common/Backends/NetworkUserBackend.cpp33
-rw-r--r--src/Common/Backends/NetworkUserBackend.h17
-rw-r--r--src/Common/UserBackend.h8
-rw-r--r--src/Common/UserCache.h8
-rw-r--r--src/Common/UserManager.cpp34
-rw-r--r--src/Common/UserManager.h3
-rw-r--r--src/Server/RequestHandlers/UserRequestHandlerGroup.cpp17
-rw-r--r--src/Server/RequestHandlers/UserRequestHandlerGroup.h3
-rw-r--r--src/mad-server.conf2
-rw-r--r--src/modules/UserBackendMysql/UserBackendMysql.cpp46
-rw-r--r--src/modules/UserBackendMysql/UserBackendMysql.h4
14 files changed, 254 insertions, 0 deletions
diff --git a/src/Client/CommandParser.cpp b/src/Client/CommandParser.cpp
index 6e8a7d3..644a392 100644
--- a/src/Client/CommandParser.cpp
+++ b/src/Client/CommandParser.cpp
@@ -54,6 +54,8 @@ const CommandParser::Command CommandParser::commands[] = {
{{"add_user", 0}, "add_user uid gid username full_name", "Add a new user", "Add a new user with the given info to the account database.", &UserCommands::addUserCommand},
{{"update_user", 0}, "update_user uid new_uid gid username full_name", "Update a user", "Update user data in the account database.", &UserCommands::updateUserCommand},
{{"delete_user", 0}, "delete_user uid", "Delete user", "Delete a user from the account database.", &UserCommands::deleteUserCommand},
+ {{"add_user_to_group", 0}, "add_user_to_group uid gid", "Add a user to a group", "Add a user to a group.", &UserCommands::addUserToGroupCommand},
+ {{"delete_user_from_group", 0}, "delete_user_from_group uid gid", "Remove a user from a group", "Remove a user from a group.", &UserCommands::deleteUserFromGroupCommand},
{{"exit", "quit", 0}, "exit", "Close the connection and quit the client", "Close the connection and quit the client.", &CommandParser::exitCommand},
{{0}, 0, 0, 0, 0}
};
diff --git a/src/Client/UserCommands.cpp b/src/Client/UserCommands.cpp
index 96e9cc6..d58eaca 100644
--- a/src/Client/UserCommands.cpp
+++ b/src/Client/UserCommands.cpp
@@ -342,5 +342,79 @@ void UserCommands::deleteUserCommand(CommandParser *commandParser, const std::ve
}
}
+void UserCommands::addUserToGroupCommand(CommandParser *commandParser, const std::vector<std::string> &args) {
+ if(args.size() < 3) {
+ std::cerr << args[0] << ": Too few arguments." << std::endl;
+ commandParser->printUsage("add_user_to_group");
+ return;
+ }
+ if(args.size() > 3) {
+ std::cerr << args[0] << ": Too many arguments." << std::endl;
+ commandParser->printUsage("add_user_to_group");
+ return;
+ }
+
+ char *endptr;
+ unsigned long uid = std::strtoul(args[1].c_str(), &endptr, 10);
+ if(args[1].empty() || *endptr != '\0') {
+ std::cerr << args[0] << ": Unable to parse user id." << std::endl;
+ commandParser->printUsage("add_user_to_group");
+ return;
+ }
+
+ unsigned long gid = std::strtoul(args[2].c_str(), &endptr, 10);
+ if(args[2].empty() || *endptr != '\0') {
+ std::cerr << args[0] << ": Unable to parse group id." << std::endl;
+ commandParser->printUsage("add_user_to_group");
+ return;
+ }
+
+ try {
+ commandParser->application->getUserManager()->addUserToGroup(uid, gid);
+
+ std::cout << "Added." << std::endl;
+ }
+ catch(Core::Exception e) {
+ std::cerr << "An error occurred during your request: " << e.strerror() << "." << std::endl;
+ }
+}
+
+void UserCommands::deleteUserFromGroupCommand(CommandParser *commandParser, const std::vector<std::string> &args) {
+ if(args.size() < 3) {
+ std::cerr << args[0] << ": Too few arguments." << std::endl;
+ commandParser->printUsage("delete_user_from_group");
+ return;
+ }
+ if(args.size() > 3) {
+ std::cerr << args[0] << ": Too many arguments." << std::endl;
+ commandParser->printUsage("delete_user_from_group");
+ return;
+ }
+
+ char *endptr;
+ unsigned long uid = std::strtoul(args[1].c_str(), &endptr, 10);
+ if(args[1].empty() || *endptr != '\0') {
+ std::cerr << args[0] << ": Unable to parse user id." << std::endl;
+ commandParser->printUsage("delete_user_from_group");
+ return;
+ }
+
+ unsigned long gid = std::strtoul(args[2].c_str(), &endptr, 10);
+ if(args[2].empty() || *endptr != '\0') {
+ std::cerr << args[0] << ": Unable to parse group id." << std::endl;
+ commandParser->printUsage("delete_user_from_group");
+ return;
+ }
+
+ try {
+ commandParser->application->getUserManager()->deleteUserFromGroup(uid, gid);
+
+ std::cout << "Removed." << std::endl;
+ }
+ catch(Core::Exception e) {
+ std::cerr << "An error occurred during your request: " << e.strerror() << "." << std::endl;
+ }
+}
+
}
}
diff --git a/src/Client/UserCommands.h b/src/Client/UserCommands.h
index 2feb6a5..b62c8e4 100644
--- a/src/Client/UserCommands.h
+++ b/src/Client/UserCommands.h
@@ -44,6 +44,9 @@ class UserCommands {
static void addUserCommand(CommandParser *commandParser, const std::vector<std::string> &args);
static void updateUserCommand(CommandParser *commandParser, const std::vector<std::string> &args);
static void deleteUserCommand(CommandParser *commandParser, const std::vector<std::string> &args);
+
+ static void addUserToGroupCommand(CommandParser *commandParser, const std::vector<std::string> &args);
+ static void deleteUserFromGroupCommand(CommandParser *commandParser, const std::vector<std::string> &args);
};
}
diff --git a/src/Common/Backends/NetworkUserBackend.cpp b/src/Common/Backends/NetworkUserBackend.cpp
index 1e06a78..6296581 100644
--- a/src/Common/Backends/NetworkUserBackend.cpp
+++ b/src/Common/Backends/NetworkUserBackend.cpp
@@ -83,6 +83,15 @@ void NetworkUserBackend::UserUpdateRequest::sendRequest() {
sendPacket(packet);
}
+void NetworkUserBackend::UserGroupRequest::sendRequest() {
+ XmlPacket packet;
+ packet.setType(type);
+ packet.set("uid", uid);
+ packet.set("gid", gid);
+
+ sendPacket(packet);
+}
+
boost::shared_ptr<const std::map<unsigned long, UserInfo> > NetworkUserBackend::getUserList(boost::posix_time::ptime *timestamp) throw(Core::Exception) {
application->getThreadManager()->detach();
@@ -406,6 +415,30 @@ void NetworkUserBackend::deleteUser(unsigned long uid) throw(Core::Exception) {
throw result.second;
}
+void NetworkUserBackend::addUserToGroup(unsigned long uid, unsigned long gid) throw(Core::Exception) {
+ application->getThreadManager()->detach();
+
+ boost::shared_ptr<UserGroupRequest> request(new UserGroupRequest(application, "AddUserToGroup", uid, gid));
+ 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;
+}
+
+void NetworkUserBackend::deleteUserFromGroup(unsigned long uid, unsigned long gid) throw(Core::Exception) {
+ application->getThreadManager()->detach();
+
+ boost::shared_ptr<UserGroupRequest> request(new UserGroupRequest(application, "DeleteUserFromGroup", uid, gid));
+ 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;
+}
+
}
}
}
diff --git a/src/Common/Backends/NetworkUserBackend.h b/src/Common/Backends/NetworkUserBackend.h
index b932e87..0567514 100644
--- a/src/Common/Backends/NetworkUserBackend.h
+++ b/src/Common/Backends/NetworkUserBackend.h
@@ -96,6 +96,20 @@ class NetworkUserBackend : public UserBackend {
: Request(application), uid(uid0), userInfo(userInfo0) {}
};
+ class UserGroupRequest : public Request {
+ private:
+ std::string type;
+ unsigned long uid;
+ unsigned long gid;
+
+ protected:
+ virtual void sendRequest();
+
+ public:
+ UserGroupRequest(Application *application, const std::string &type0, unsigned long uid0, unsigned long gid0)
+ : Request(application), type(type0), uid(uid0), gid(gid0) {}
+ };
+
Application *application;
Connection *connection;
@@ -118,6 +132,9 @@ class NetworkUserBackend : public UserBackend {
virtual void updateUser(unsigned long uid, const Common::UserInfo &userInfo) throw(Core::Exception);
virtual void deleteUser(unsigned long uid) throw(Core::Exception);
+ virtual void addUserToGroup(unsigned long uid, unsigned long gid) throw(Core::Exception);
+ virtual void deleteUserFromGroup(unsigned long uid, unsigned long gid) throw(Core::Exception);
+
public:
NetworkUserBackend(Application *application0, Connection *connection0) : application(application0), connection(connection0) {}
};
diff --git a/src/Common/UserBackend.h b/src/Common/UserBackend.h
index 2e42e12..9eb59d3 100644
--- a/src/Common/UserBackend.h
+++ b/src/Common/UserBackend.h
@@ -113,6 +113,14 @@ class UserBackend {
throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED));
}
+ virtual void addUserToGroup(unsigned long uid _UNUSED_PARAMETER_, unsigned long gid _UNUSED_PARAMETER_) throw(Core::Exception) {
+ throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED));
+ }
+
+ virtual void deleteUserFromGroup(unsigned long uid _UNUSED_PARAMETER_, unsigned long gid _UNUSED_PARAMETER_) throw(Core::Exception) {
+ throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED));
+ }
+
public:
virtual ~UserBackend() {}
diff --git a/src/Common/UserCache.h b/src/Common/UserCache.h
index e778e24..1425908 100644
--- a/src/Common/UserCache.h
+++ b/src/Common/UserCache.h
@@ -98,6 +98,14 @@ class UserCache : public UserBackend, private boost::noncopyable {
backend->deleteGroup(gid);
}
+ virtual void addUserToGroup(unsigned long uid, unsigned long gid) throw(Core::Exception) {
+ backend->addUserToGroup(uid, gid);
+ }
+
+ virtual void deleteUserFromGroup(unsigned long uid, unsigned long gid) throw(Core::Exception) {
+ backend->deleteUserFromGroup(uid, gid);
+ }
+
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 14451aa..928289b 100644
--- a/src/Common/UserManager.cpp
+++ b/src/Common/UserManager.cpp
@@ -326,5 +326,39 @@ void UserManager::deleteGroup(unsigned long gid) throw(Core::Exception) {
throw Core::Exception(Core::Exception::NOT_IMPLEMENTED);
}
+void UserManager::addUserToGroup(unsigned long uid, unsigned long gid) throw(Core::Exception) {
+ boost::lock_guard<boost::shared_mutex> lock(mutex);
+
+ for(BackendMap::iterator backend = backends.begin(); backend != backends.end(); ++backend) {
+ try {
+ backend->second->addUserToGroup(uid, gid);
+ return;
+ }
+ catch(Core::Exception e) {
+ if(e.getErrorCode() != Core::Exception::NOT_IMPLEMENTED)
+ throw e;
+ }
+ }
+
+ throw Core::Exception(Core::Exception::NOT_IMPLEMENTED);
+}
+
+void UserManager::deleteUserFromGroup(unsigned long uid, unsigned long gid) throw(Core::Exception) {
+ boost::lock_guard<boost::shared_mutex> lock(mutex);
+
+ for(BackendMap::iterator backend = backends.begin(); backend != backends.end(); ++backend) {
+ try {
+ backend->second->deleteUserFromGroup(uid, gid);
+ return;
+ }
+ catch(Core::Exception e) {
+ if(e.getErrorCode() != Core::Exception::NOT_IMPLEMENTED)
+ throw e;
+ }
+ }
+
+ throw Core::Exception(Core::Exception::NOT_IMPLEMENTED);
+}
+
}
}
diff --git a/src/Common/UserManager.h b/src/Common/UserManager.h
index 466b9a9..d2529e7 100644
--- a/src/Common/UserManager.h
+++ b/src/Common/UserManager.h
@@ -90,6 +90,9 @@ class UserManager : private boost::noncopyable {
void addGroup(const GroupInfo &groupInfo) throw(Core::Exception);
void updateGroup(unsigned long gid, const GroupInfo &groupInfo) throw(Core::Exception);
void deleteGroup(unsigned long gid) throw(Core::Exception);
+
+ void addUserToGroup(unsigned long uid, unsigned long gid) throw(Core::Exception);
+ void deleteUserFromGroup(unsigned long uid, unsigned long gid) throw(Core::Exception);
};
}
diff --git a/src/Server/RequestHandlers/UserRequestHandlerGroup.cpp b/src/Server/RequestHandlers/UserRequestHandlerGroup.cpp
index e0c4020..0bb3cfa 100644
--- a/src/Server/RequestHandlers/UserRequestHandlerGroup.cpp
+++ b/src/Server/RequestHandlers/UserRequestHandlerGroup.cpp
@@ -276,6 +276,20 @@ void UserRequestHandlerGroup::handleUserDeleteRequest(boost::shared_ptr<const Co
ret->setType("OK");
}
+void UserRequestHandlerGroup::handleAddUserToGroupRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret,
+ Common::Connection *connection _UNUSED_PARAMETER_) {
+ application->getUserManager()->addUserToGroup(packet->get<unsigned long>("uid"), packet->get<unsigned long>("gid"));
+
+ ret->setType("OK");
+}
+
+void UserRequestHandlerGroup::handleDeleteUserFromGroupRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret,
+ Common::Connection *connection _UNUSED_PARAMETER_) {
+ application->getUserManager()->deleteUserFromGroup(packet->get<unsigned long>("uid"), packet->get<unsigned long>("gid"));
+
+ ret->setType("OK");
+}
+
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));
@@ -290,6 +304,9 @@ UserRequestHandlerGroup::UserRequestHandlerGroup(Application *application0) : ap
registerHandler("AddUser", boost::bind(&UserRequestHandlerGroup::handleUserAddRequest, this, _1, _2, _3));
registerHandler("UpdateUser", boost::bind(&UserRequestHandlerGroup::handleUserUpdateRequest, this, _1, _2, _3));
registerHandler("DeleteUser", boost::bind(&UserRequestHandlerGroup::handleUserDeleteRequest, this, _1, _2, _3));
+
+ registerHandler("AddUserToGroup", boost::bind(&UserRequestHandlerGroup::handleAddUserToGroupRequest, this, _1, _2, _3));
+ registerHandler("DeleteUserFromGroup", boost::bind(&UserRequestHandlerGroup::handleDeleteUserFromGroupRequest, this, _1, _2, _3));
}
}
diff --git a/src/Server/RequestHandlers/UserRequestHandlerGroup.h b/src/Server/RequestHandlers/UserRequestHandlerGroup.h
index 24a689b..6da97a3 100644
--- a/src/Server/RequestHandlers/UserRequestHandlerGroup.h
+++ b/src/Server/RequestHandlers/UserRequestHandlerGroup.h
@@ -47,6 +47,9 @@ class UserRequestHandlerGroup : public Common::RequestHandlers::SimpleRequestHan
void handleUserUpdateRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, Common::Connection *connection);
void handleUserDeleteRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, Common::Connection *connection);
+ void handleAddUserToGroupRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, Common::Connection *connection);
+ void handleDeleteUserFromGroupRequest(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 db51be2..76533cf 100644
--- a/src/mad-server.conf
+++ b/src/mad-server.conf
@@ -28,6 +28,8 @@ UserBackendMysql {
AddUser "INSERT INTO users (id, gid, username, fullname) VALUES ({UID}, {GID}, {USER}, {FULL_NAME})"
UpdateUser "UPDATE users SET id = {UID}, gid = {GID}, username = {USER}, fullname = {FULL_NAME} WHERE id = {ORIG_UID}"
DeleteUser "DELETE FROM users WHERE id = {UID}"
+ AddUserToGroup "INSERT INTO usergroups (uid, gid) VALUES ({UID}, {GID})"
+ DeleteUserFromGroup "DELETE FROM usergroups WHERE uid = {UID} AND gid = {GID}"
}
}
diff --git a/src/modules/UserBackendMysql/UserBackendMysql.cpp b/src/modules/UserBackendMysql/UserBackendMysql.cpp
index f169593..e076b10 100644
--- a/src/modules/UserBackendMysql/UserBackendMysql.cpp
+++ b/src/modules/UserBackendMysql/UserBackendMysql.cpp
@@ -124,6 +124,14 @@ bool UserBackendMysql::handleConfigEntry(const Core::ConfigEntry &entry, bool ha
if(entry[3].empty())
queryDeleteUser = entry[2][0];
}
+ else if(entry[2].getKey().matches("AddUserToGroup")) {
+ if(entry[3].empty())
+ queryAddUserToGroup = entry[2][0];
+ }
+ else if(entry[2].getKey().matches("DeleteUserFromGroup")) {
+ if(entry[3].empty())
+ queryDeleteUserFromGroup = entry[2][0];
+ }
else if(!entry[2].empty())
return false;
}
@@ -529,6 +537,44 @@ void UserBackendMysql::deleteUser(unsigned long uid) throw(Core::Exception) {
lastUpdate = boost::posix_time::microsec_clock::universal_time();
}
+void UserBackendMysql::addUserToGroup(unsigned long uid, unsigned long gid) throw(Core::Exception) {
+ application->getThreadManager()->detach();
+
+ boost::lock_guard<boost::mutex> lock(mutex);
+
+ ArgumentMap args;
+ args.insert(std::make_pair("UID", uid));
+ args.insert(std::make_pair("GID", gid));
+
+ Result result = query(queryAddUserToGroup, args);
+
+ if(result.getErrno()) {
+ if(result.getErrno() == ER_DUP_ENTRY)
+ return;
+ else
+ throw Core::Exception(Core::Exception::NOT_AVAILABLE);
+ }
+
+ lastUpdate = boost::posix_time::microsec_clock::universal_time();
+}
+
+void UserBackendMysql::deleteUserFromGroup(unsigned long uid, unsigned long gid) throw(Core::Exception) {
+ application->getThreadManager()->detach();
+
+ boost::lock_guard<boost::mutex> lock(mutex);
+
+ ArgumentMap args;
+ args.insert(std::make_pair("UID", uid));
+ args.insert(std::make_pair("GID", gid));
+
+ Result result = query(queryDeleteUserFromGroup, args);
+
+ if(result.getErrno())
+ throw Core::Exception(Core::Exception::NOT_AVAILABLE);
+
+ lastUpdate = boost::posix_time::microsec_clock::universal_time();
+}
+
}
}
}
diff --git a/src/modules/UserBackendMysql/UserBackendMysql.h b/src/modules/UserBackendMysql/UserBackendMysql.h
index a1c2bb1..5ed8480 100644
--- a/src/modules/UserBackendMysql/UserBackendMysql.h
+++ b/src/modules/UserBackendMysql/UserBackendMysql.h
@@ -95,6 +95,7 @@ class UserBackendMysql : public Common::UserBackend, private Core::Configurable,
std::string queryGroupById, queryGroupByName;
std::string queryUserGroupTable;
std::string queryAddUser, queryUpdateUser, queryDeleteUser;
+ std::string queryAddUserToGroup, queryDeleteUserFromGroup;
MYSQL *mysql;
@@ -122,6 +123,9 @@ class UserBackendMysql : public Common::UserBackend, private Core::Configurable,
virtual void updateUser(unsigned long uid, const Common::UserInfo &userInfo) throw(Core::Exception);
virtual void deleteUser(unsigned long uid) throw(Core::Exception);
+ virtual void addUserToGroup(unsigned long uid, unsigned long gid) throw(Core::Exception);
+ virtual void deleteUserFromGroup(unsigned long uid, unsigned long gid) throw(Core::Exception);
+
public:
UserBackendMysql(Common::Application *application0) : application(application0), port(0), mysql(0), lastUpdate(boost::posix_time::microsec_clock::universal_time()) {
application->getConfigManager()->registerConfigurable(this);