From bf4c6ec2b7694f1a844eef5989b77e83a8cab362 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 11 Jul 2009 01:11:21 +0200 Subject: Befehle add_user_to_group und delete_user_from_group implementiert --- src/Client/CommandParser.cpp | 2 + src/Client/UserCommands.cpp | 74 ++++++++++++++++++++++ src/Client/UserCommands.h | 3 + src/Common/Backends/NetworkUserBackend.cpp | 33 ++++++++++ src/Common/Backends/NetworkUserBackend.h | 17 +++++ src/Common/UserBackend.h | 8 +++ src/Common/UserCache.h | 8 +++ src/Common/UserManager.cpp | 34 ++++++++++ src/Common/UserManager.h | 3 + .../RequestHandlers/UserRequestHandlerGroup.cpp | 17 +++++ .../RequestHandlers/UserRequestHandlerGroup.h | 3 + src/mad-server.conf | 2 + src/modules/UserBackendMysql/UserBackendMysql.cpp | 46 ++++++++++++++ src/modules/UserBackendMysql/UserBackendMysql.h | 4 ++ 14 files changed, 254 insertions(+) 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 &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 &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 &args); static void updateUserCommand(CommandParser *commandParser, const std::vector &args); static void deleteUserCommand(CommandParser *commandParser, const std::vector &args); + + static void addUserToGroupCommand(CommandParser *commandParser, const std::vector &args); + static void deleteUserFromGroupCommand(CommandParser *commandParser, const std::vector &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 > 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 request(new UserGroupRequest(application, "AddUserToGroup", uid, gid)); + application->getRequestManager()->sendRequest(connection, request); + request->wait(); + + std::pair, 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 request(new UserGroupRequest(application, "DeleteUserFromGroup", uid, gid)); + application->getRequestManager()->sendRequest(connection, request); + request->wait(); + + std::pair, 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 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 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 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_ptrsetType("OK"); } +void UserRequestHandlerGroup::handleAddUserToGroupRequest(boost::shared_ptr packet, Common::XmlPacket *ret, + Common::Connection *connection _UNUSED_PARAMETER_) { + application->getUserManager()->addUserToGroup(packet->get("uid"), packet->get("gid")); + + ret->setType("OK"); +} + +void UserRequestHandlerGroup::handleDeleteUserFromGroupRequest(boost::shared_ptr packet, Common::XmlPacket *ret, + Common::Connection *connection _UNUSED_PARAMETER_) { + application->getUserManager()->deleteUserFromGroup(packet->get("uid"), packet->get("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 packet, Common::XmlPacket *ret, Common::Connection *connection); void handleUserDeleteRequest(boost::shared_ptr packet, Common::XmlPacket *ret, Common::Connection *connection); + void handleAddUserToGroupRequest(boost::shared_ptr packet, Common::XmlPacket *ret, Common::Connection *connection); + void handleDeleteUserFromGroupRequest(boost::shared_ptr 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 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 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); -- cgit v1.2.3