diff options
-rw-r--r-- | src/Client/CommandParser.cpp | 4 | ||||
-rw-r--r-- | src/Client/UserCommands.cpp | 78 | ||||
-rw-r--r-- | src/Client/UserCommands.h | 2 | ||||
-rw-r--r-- | src/Common/Backends/NetworkUserBackend.cpp | 33 | ||||
-rw-r--r-- | src/Common/Backends/NetworkUserBackend.h | 17 | ||||
-rw-r--r-- | src/Server/RequestHandlers/UserRequestHandlerGroup.cpp | 20 | ||||
-rw-r--r-- | src/Server/RequestHandlers/UserRequestHandlerGroup.h | 2 | ||||
-rw-r--r-- | src/mad-server.conf | 2 | ||||
-rw-r--r-- | src/modules/UserBackendMysql/UserBackendMysql.cpp | 51 | ||||
-rw-r--r-- | src/modules/UserBackendMysql/UserBackendMysql.h | 4 |
10 files changed, 207 insertions, 6 deletions
diff --git a/src/Client/CommandParser.cpp b/src/Client/CommandParser.cpp index efa48b9..6e8a7d3 100644 --- a/src/Client/CommandParser.cpp +++ b/src/Client/CommandParser.cpp @@ -51,7 +51,9 @@ const CommandParser::Command CommandParser::commands[] = { {{"list_groups", "groups", 0}, "list_groups", "Show the user group database", "Show the user group database.", &UserCommands::listGroupsCommand}, {{"group_info", "group", 0}, "group_info gid|name", "Search for a group id", "Search for a group.", &UserCommands::groupInfoCommand}, {{"list_group_users", "group_users", 0}, "list_group_users gid", "List group's users", "List the users that are members of the group.", &UserCommands::listGroupUsersCommand}, - {{"add_user", 0}, "add_user uid gid username full_name", "Add a new user", "Adds a new user with the given info to the account database.", &UserCommands::addUserCommand}, + {{"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}, {{"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 6bc2c11..96e9cc6 100644 --- a/src/Client/UserCommands.cpp +++ b/src/Client/UserCommands.cpp @@ -264,5 +264,83 @@ void UserCommands::addUserCommand(CommandParser *commandParser, const std::vecto } } +void UserCommands::updateUserCommand(CommandParser *commandParser, const std::vector<std::string> &args) { + if(args.size() < 6) { + std::cerr << args[0] << ": Too few arguments." << std::endl; + commandParser->printUsage("update_user"); + return; + } + if(args.size() > 6) { + std::cerr << args[0] << ": Too many arguments." << std::endl; + commandParser->printUsage("update_user"); + return; + } + + char *endptr; + unsigned long origUid = std::strtoul(args[1].c_str(), &endptr, 10); + if(args[1].empty() || *endptr != '\0') { + std::cerr << args[0] << ": Unable to parse the old user id." << std::endl; + commandParser->printUsage("update_user"); + return; + } + + unsigned long uid = std::strtoul(args[2].c_str(), &endptr, 10); + if(args[2].empty() || *endptr != '\0') { + std::cerr << args[0] << ": Unable to parse the new user id." << std::endl; + commandParser->printUsage("update_user"); + return; + } + + unsigned long gid = std::strtoul(args[3].c_str(), &endptr, 10); + if(args[3].empty() || *endptr != '\0') { + std::cerr << args[0] << ": Unable to parse group id." << std::endl; + commandParser->printUsage("update_user"); + return; + } + + try { + Common::UserInfo user(uid, args[4]); + user.setGid(gid); + user.setFullName(args[5]); + + commandParser->application->getUserManager()->updateUser(origUid, user); + + std::cout << "User updated." << std::endl; + } + catch(Core::Exception e) { + std::cerr << "An error occurred during your request: " << e.strerror() << "." << std::endl; + } +} + +void UserCommands::deleteUserCommand(CommandParser *commandParser, const std::vector<std::string> &args) { + if(args.size() < 2) { + std::cerr << args[0] << ": No user id given." << std::endl; + commandParser->printUsage("delete_user"); + return; + } + if(args.size() > 2) { + std::cerr << args[0] << ": Too many arguments." << std::endl; + commandParser->printUsage("delete_user"); + 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"); + return; + } + + try { + commandParser->application->getUserManager()->deleteUser(uid); + + std::cout << "User deleted." << 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 0dc008d..2feb6a5 100644 --- a/src/Client/UserCommands.h +++ b/src/Client/UserCommands.h @@ -42,6 +42,8 @@ class UserCommands { static void listGroupUsersCommand(CommandParser *commandParser, const std::vector<std::string> &args); 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); }; } diff --git a/src/Common/Backends/NetworkUserBackend.cpp b/src/Common/Backends/NetworkUserBackend.cpp index 7e77253..20deba6 100644 --- a/src/Common/Backends/NetworkUserBackend.cpp +++ b/src/Common/Backends/NetworkUserBackend.cpp @@ -70,6 +70,19 @@ void NetworkUserBackend::UserAddRequest::sendRequest() { sendPacket(packet); } +void NetworkUserBackend::UserUpdateRequest::sendRequest() { + XmlPacket packet; + packet.setType("UpdateUser"); + + packet.set("origUid", uid); + packet.set("uid", userInfo.getUid()); + packet.set("gid", userInfo.getGid()); + packet.set("username", userInfo.getUsername()); + packet.set("fullName", userInfo.getFullName()); + + sendPacket(packet); +} + 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); @@ -349,6 +362,26 @@ void NetworkUserBackend::addUser(const UserInfo &userInfo) throw(Core::Exception throw result.second; } +void NetworkUserBackend::updateUser(unsigned long uid, const Common::UserInfo &userInfo) throw(Core::Exception) { + boost::shared_ptr<UserUpdateRequest> request(new UserUpdateRequest(application, uid, userInfo)); + 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::deleteUser(unsigned long uid) throw(Core::Exception) { + boost::shared_ptr<IdUserRequest> request(new IdUserRequest(application, "DeleteUser", "uid", uid)); + 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 939c3b1..b932e87 100644 --- a/src/Common/Backends/NetworkUserBackend.h +++ b/src/Common/Backends/NetworkUserBackend.h @@ -53,7 +53,7 @@ class NetworkUserBackend : public UserBackend { virtual void sendRequest(); public: - IdUserRequest(Application *application, const std::string &type0, const std::string &idType0, unsigned long id0, boost::posix_time::ptime *timestamp0) + IdUserRequest(Application *application, const std::string &type0, const std::string &idType0, unsigned long id0, boost::posix_time::ptime *timestamp0 = 0) : Request(application), type(type0), idType(idType0), id(id0), timestamp(timestamp0 ? *timestamp0 : boost::posix_time::not_a_date_time) {} }; @@ -83,6 +83,19 @@ class NetworkUserBackend : public UserBackend { : Request(application), userInfo(userInfo0) {} }; + class UserUpdateRequest : public Request { + private: + unsigned long uid; + UserInfo userInfo; + + protected: + virtual void sendRequest(); + + public: + UserUpdateRequest(Application *application, unsigned long uid0, const UserInfo &userInfo0) + : Request(application), uid(uid0), userInfo(userInfo0) {} + }; + Application *application; Connection *connection; @@ -102,6 +115,8 @@ class NetworkUserBackend : public UserBackend { //virtual void setPassword(unsigned long uid, const std::string &password) throw(Core::Exception); virtual void addUser(const UserInfo &userInfo) throw(Core::Exception); + virtual void updateUser(unsigned long uid, const Common::UserInfo &userInfo) throw(Core::Exception); + virtual void deleteUser(unsigned long uid) throw(Core::Exception); public: NetworkUserBackend(Application *application0, Connection *connection0) : application(application0), connection(connection0) {} diff --git a/src/Server/RequestHandlers/UserRequestHandlerGroup.cpp b/src/Server/RequestHandlers/UserRequestHandlerGroup.cpp index 43d6bc4..e0c4020 100644 --- a/src/Server/RequestHandlers/UserRequestHandlerGroup.cpp +++ b/src/Server/RequestHandlers/UserRequestHandlerGroup.cpp @@ -258,6 +258,24 @@ void UserRequestHandlerGroup::handleUserAddRequest(boost::shared_ptr<const Commo ret->setType("OK"); } +void UserRequestHandlerGroup::handleUserUpdateRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, + Common::Connection *connection _UNUSED_PARAMETER_) { + Common::UserInfo userInfo(packet->get<unsigned long>("uid"), packet->get<const std::string&>("username")); + userInfo.setGid(packet->get<unsigned long>("gid")); + userInfo.setFullName(packet->get<const std::string&>("fullName")); + + application->getUserManager()->updateUser(packet->get<unsigned long>("origUid"), userInfo); + + ret->setType("OK"); +} + +void UserRequestHandlerGroup::handleUserDeleteRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, + Common::Connection *connection _UNUSED_PARAMETER_) { + application->getUserManager()->deleteUser(packet->get<unsigned long>("uid")); + + 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)); @@ -270,6 +288,8 @@ UserRequestHandlerGroup::UserRequestHandlerGroup(Application *application0) : ap registerHandler("GetFullUserGroupList", boost::bind(&UserRequestHandlerGroup::handleFullUserGroupListRequest, this, _1, _2, _3)); 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)); } } diff --git a/src/Server/RequestHandlers/UserRequestHandlerGroup.h b/src/Server/RequestHandlers/UserRequestHandlerGroup.h index f39754e..24a689b 100644 --- a/src/Server/RequestHandlers/UserRequestHandlerGroup.h +++ b/src/Server/RequestHandlers/UserRequestHandlerGroup.h @@ -44,6 +44,8 @@ class UserRequestHandlerGroup : public Common::RequestHandlers::SimpleRequestHan void handleFullUserGroupListRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, Common::Connection *connection); void handleUserAddRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, Common::Connection *connection); + 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); public: UserRequestHandlerGroup(Application *application0); diff --git a/src/mad-server.conf b/src/mad-server.conf index 5c21bff..db51be2 100644 --- a/src/mad-server.conf +++ b/src/mad-server.conf @@ -26,6 +26,8 @@ UserBackendMysql { GroupByName "SELECT id, name FROM groups WHERE name = {GROUP}" UserGroupTable "SELECT uid, gid FROM usergroups" 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}" } } diff --git a/src/modules/UserBackendMysql/UserBackendMysql.cpp b/src/modules/UserBackendMysql/UserBackendMysql.cpp index 015c5a1..f169593 100644 --- a/src/modules/UserBackendMysql/UserBackendMysql.cpp +++ b/src/modules/UserBackendMysql/UserBackendMysql.cpp @@ -116,6 +116,14 @@ bool UserBackendMysql::handleConfigEntry(const Core::ConfigEntry &entry, bool ha if(entry[3].empty()) queryAddUser = entry[2][0]; } + else if(entry[2].getKey().matches("UpdateUser")) { + if(entry[3].empty()) + queryUpdateUser = entry[2][0]; + } + else if(entry[2].getKey().matches("DeleteUser")) { + if(entry[3].empty()) + queryDeleteUser = entry[2][0]; + } else if(!entry[2].empty()) return false; } @@ -463,9 +471,6 @@ void UserBackendMysql::addUser(const Common::UserInfo &userInfo) throw(Core::Exc boost::lock_guard<boost::mutex> lock(mutex); - if(!mysql || mysql_ping(mysql)) - throw Core::Exception(Core::Exception::NOT_AVAILABLE); - ArgumentMap args; args.insert(std::make_pair("UID", userInfo.getUid())); args.insert(std::make_pair("GID", userInfo.getGid())); @@ -484,6 +489,46 @@ void UserBackendMysql::addUser(const Common::UserInfo &userInfo) throw(Core::Exc lastUpdate = boost::posix_time::microsec_clock::universal_time(); } +void UserBackendMysql::updateUser(unsigned long uid, const Common::UserInfo &userInfo) throw(Core::Exception) { + application->getThreadManager()->detach(); + + boost::lock_guard<boost::mutex> lock(mutex); + + ArgumentMap args; + args.insert(std::make_pair("ORIG_UID", uid)); + args.insert(std::make_pair("UID", userInfo.getUid())); + args.insert(std::make_pair("GID", userInfo.getGid())); + args.insert(std::make_pair("USER", userInfo.getUsername())); + args.insert(std::make_pair("FULL_NAME", userInfo.getFullName())); + + Result result = query(queryUpdateUser, args); + + if(result.getErrno()) { + if(result.getErrno() == ER_DUP_ENTRY) + throw Core::Exception(Core::Exception::DUPLICATE_ENTRY); + else + throw Core::Exception(Core::Exception::NOT_AVAILABLE); + } + + lastUpdate = boost::posix_time::microsec_clock::universal_time(); +} + +void UserBackendMysql::deleteUser(unsigned long uid) throw(Core::Exception) { + application->getThreadManager()->detach(); + + boost::lock_guard<boost::mutex> lock(mutex); + + ArgumentMap args; + args.insert(std::make_pair("UID", uid)); + + Result result = query(queryDeleteUser, 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 78926b9..a1c2bb1 100644 --- a/src/modules/UserBackendMysql/UserBackendMysql.h +++ b/src/modules/UserBackendMysql/UserBackendMysql.h @@ -94,7 +94,7 @@ class UserBackendMysql : public Common::UserBackend, private Core::Configurable, std::string queryUserById, queryUserByName; std::string queryGroupById, queryGroupByName; std::string queryUserGroupTable; - std::string queryAddUser; + std::string queryAddUser, queryUpdateUser, queryDeleteUser; MYSQL *mysql; @@ -119,6 +119,8 @@ class UserBackendMysql : public Common::UserBackend, private Core::Configurable, virtual boost::shared_ptr<const std::multimap<unsigned long, unsigned long> > getFullUserGroupList(boost::posix_time::ptime *timestamp) throw(Core::Exception); virtual void addUser(const Common::UserInfo &userInfo) throw(Core::Exception); + virtual void updateUser(unsigned long uid, const Common::UserInfo &userInfo) throw(Core::Exception); + virtual void deleteUser(unsigned long uid) throw(Core::Exception); public: UserBackendMysql(Common::Application *application0) : application(application0), port(0), mysql(0), lastUpdate(boost::posix_time::microsec_clock::universal_time()) { |