From 033145b65c543d1d6c0c05ee84c1031fcd5ba3c7 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 26 May 2009 16:13:27 +0200 Subject: UserBackend-Interface erweitert und im Mysql-Backend implementiert --- src/Server/UserBackend.h | 22 +++ src/Server/UserManager.cpp | 80 +++++++++++ src/Server/UserManager.h | 5 + src/mad-server.conf | 10 +- src/modules/UserBackendMysql/UserBackendMysql.cpp | 155 +++++++++++++++++++++- src/modules/UserBackendMysql/UserBackendMysql.h | 5 + 6 files changed, 268 insertions(+), 9 deletions(-) diff --git a/src/Server/UserBackend.h b/src/Server/UserBackend.h index 2a51d1b..001ee49 100644 --- a/src/Server/UserBackend.h +++ b/src/Server/UserBackend.h @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -52,10 +53,31 @@ class UserBackend { throw(Net::Exception(Net::Exception::NOT_IMPLEMENTED)); } + virtual boost::shared_ptr getUserInfoByName(const std::string &name _UNUSED_PARAMETER_) throw(Net::Exception) { + throw(Net::Exception(Net::Exception::NOT_IMPLEMENTED)); + } + + virtual boost::shared_ptr > getUserGroups(unsigned long uid _UNUSED_PARAMETER_) throw(Net::Exception) { + throw(Net::Exception(Net::Exception::NOT_IMPLEMENTED)); + } + + virtual boost::shared_ptr > getGroupList() throw(Net::Exception) { throw(Net::Exception(Net::Exception::NOT_IMPLEMENTED)); } + virtual std::string getGroupName(unsigned long gid _UNUSED_PARAMETER_) throw(Net::Exception) { + throw(Net::Exception(Net::Exception::NOT_IMPLEMENTED)); + } + + virtual unsigned long getGroupId(const std::string &name _UNUSED_PARAMETER_) throw(Net::Exception) { + throw(Net::Exception(Net::Exception::NOT_IMPLEMENTED)); + } + + virtual boost::shared_ptr > getGroupUsers(unsigned long gid _UNUSED_PARAMETER_) throw(Net::Exception) { + throw(Net::Exception(Net::Exception::NOT_IMPLEMENTED)); + } + // TODO Better interface... virtual void setPassword(unsigned long uid _UNUSED_PARAMETER_, const std::string &password _UNUSED_PARAMETER_) throw(Net::Exception) { throw(Net::Exception(Net::Exception::NOT_IMPLEMENTED)); diff --git a/src/Server/UserManager.cpp b/src/Server/UserManager.cpp index 7101b2c..e38f458 100644 --- a/src/Server/UserManager.cpp +++ b/src/Server/UserManager.cpp @@ -66,6 +66,38 @@ boost::shared_ptr UserManager::getUserInfo(unsigned long uid) throw e; } +boost::shared_ptr UserManager::getUserInfoByName(const std::string &name) throw(Net::Exception) { + Net::Exception e(Net::Exception::NOT_IMPLEMENTED); + + for(std::set >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { + try { + return (*backend)->getUserInfoByName(name); + } + catch(Net::Exception e2) { + if(e.getErrorCode() == Net::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Net::Exception::NOT_IMPLEMENTED) + e = e2; + } + } + + throw e; +} + +boost::shared_ptr > UserManager::getUserGroups(unsigned long uid) throw(Net::Exception) { + Net::Exception e(Net::Exception::NOT_IMPLEMENTED); + + for(std::set >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { + try { + return (*backend)->getUserGroups(uid); + } + catch(Net::Exception e2) { + if(e.getErrorCode() == Net::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Net::Exception::NOT_IMPLEMENTED) + e = e2; + } + } + + throw e; +} + boost::shared_ptr > UserManager::getGroupList() throw(Net::Exception) { Net::Exception e(Net::Exception::NOT_IMPLEMENTED); @@ -82,6 +114,54 @@ boost::shared_ptr > UserManager::getG throw e; } +std::string UserManager::getGroupName(unsigned long gid) throw(Net::Exception) { + Net::Exception e(Net::Exception::NOT_IMPLEMENTED); + + for(std::set >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { + try { + return (*backend)->getGroupName(gid); + } + catch(Net::Exception e2) { + if(e.getErrorCode() == Net::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Net::Exception::NOT_IMPLEMENTED) + e = e2; + } + } + + throw e; +} + +unsigned long UserManager::getGroupId(const std::string &name) throw(Net::Exception) { + Net::Exception e(Net::Exception::NOT_IMPLEMENTED); + + for(std::set >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { + try { + return (*backend)->getGroupId(name); + } + catch(Net::Exception e2) { + if(e.getErrorCode() == Net::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Net::Exception::NOT_IMPLEMENTED) + e = e2; + } + } + + throw e; +} + +boost::shared_ptr > UserManager::getGroupUsers(unsigned long gid) throw(Net::Exception) { + Net::Exception e(Net::Exception::NOT_IMPLEMENTED); + + for(std::set >::iterator backend = backends.begin(); backend != backends.end(); ++backend) { + try { + return (*backend)->getGroupUsers(gid); + } + catch(Net::Exception e2) { + if(e.getErrorCode() == Net::Exception::NOT_IMPLEMENTED && e2.getErrorCode() != Net::Exception::NOT_IMPLEMENTED) + e = e2; + } + } + + throw e; +} + void UserManager::setPassword(unsigned long uid, const std::string &password) throw(Net::Exception) { Net::Exception e(Net::Exception::NOT_IMPLEMENTED); diff --git a/src/Server/UserManager.h b/src/Server/UserManager.h index 3377727..fe0ef3f 100644 --- a/src/Server/UserManager.h +++ b/src/Server/UserManager.h @@ -59,8 +59,13 @@ class UserManager : boost::noncopyable { boost::shared_ptr > getUserList() throw(Net::Exception); boost::shared_ptr getUserInfo(unsigned long uid) throw(Net::Exception); + boost::shared_ptr getUserInfoByName(const std::string &name) throw(Net::Exception); + boost::shared_ptr > getUserGroups(unsigned long uid) throw(Net::Exception); boost::shared_ptr > getGroupList() throw(Net::Exception); + std::string getGroupName(unsigned long gid) throw(Net::Exception); + unsigned long getGroupId(const std::string &name) throw(Net::Exception); + boost::shared_ptr > getGroupUsers(unsigned long gid) throw(Net::Exception); void setPassword(unsigned long uid, const std::string &password) throw(Net::Exception); diff --git a/src/mad-server.conf b/src/mad-server.conf index 188833b..09614c4 100644 --- a/src/mad-server.conf +++ b/src/mad-server.conf @@ -18,12 +18,12 @@ UserBackendMysql { Queries { ListUsers "SELECT id, gid, username, fullname FROM users" ListGroups "SELECT id, name FROM groups" - #ListUserGroups - #ListGroupUsers - UserById "SELECT id, gid, username, fullname FROM users WHERE id = {ID}" + ListUserGroups "SELECT gid FROM usergroups WHERE uid = {UID}" + ListGroupUsers "SELECT uid FROM usergroups WHERE gid = {GID}" + UserById "SELECT id, gid, username, fullname FROM users WHERE id = {UID}" UserByName "SELECT id, gid, username, fullname FROM users WHERE username = {USER}" - #GroupById - #GroupByName + GroupById "SELECT id, name FROM groups WHERE id = {GID}" + GroupByName "SELECT id, name FROM groups WHERE name = {GROUP}" } } diff --git a/src/modules/UserBackendMysql/UserBackendMysql.cpp b/src/modules/UserBackendMysql/UserBackendMysql.cpp index 9b960fd..6cc5b2f 100644 --- a/src/modules/UserBackendMysql/UserBackendMysql.cpp +++ b/src/modules/UserBackendMysql/UserBackendMysql.cpp @@ -135,7 +135,8 @@ void UserBackendMysql::configFinished() { boost::shared_ptr > UserBackendMysql::getUserList() throw(Net::Exception) { Net::ThreadManager::get()->detach(); - mysql_ping(mysql); + if(mysql_ping(mysql)) + throw Net::Exception(Net::Exception::NOT_AVAILABLE); mysql_real_query(mysql, queryListUsers.c_str(), queryListUsers.length()); MYSQL_RES *result = mysql_use_result(mysql); @@ -160,7 +161,8 @@ boost::shared_ptr > UserBackendMysql:: boost::shared_ptr UserBackendMysql::getUserInfo(unsigned long uid) throw(Net::Exception) { Net::ThreadManager::get()->detach(); - mysql_ping(mysql); + if(mysql_ping(mysql)) + throw Net::Exception(Net::Exception::NOT_AVAILABLE); std::string query = queryUserById; @@ -169,7 +171,7 @@ boost::shared_ptr UserBackendMysql::getUserInfo(unsigned long tmp << uid; tmp << '"'; - query = boost::regex_replace(query, boost::regex("\\{ID\\}"), tmp.str(), boost::match_default); + query = boost::regex_replace(query, boost::regex("\\{UID\\}"), tmp.str(), boost::match_default); mysql_real_query(mysql, query.c_str(), query.length()); MYSQL_RES *result = mysql_use_result(mysql); @@ -193,10 +195,73 @@ boost::shared_ptr UserBackendMysql::getUserInfo(unsigned long throw Net::Exception(Net::Exception::NOT_AVAILABLE); } +boost::shared_ptr UserBackendMysql::getUserInfoByName(const std::string &name) throw(Net::Exception) { + Net::ThreadManager::get()->detach(); + + if(mysql_ping(mysql)) + throw Net::Exception(Net::Exception::NOT_AVAILABLE); + + boost::scoped_array escapedName(new char[name.length()*2+1]); + + mysql_real_escape_string(mysql, escapedName.get(), name.c_str(), name.length()); + + std::string query = boost::regex_replace(queryUserByName, boost::regex("\\{USER\\}"), "\""+std::string(escapedName.get())+"\"", boost::match_default); + + mysql_real_query(mysql, query.c_str(), query.length()); + MYSQL_RES *result = mysql_use_result(mysql); + + if(!result || mysql_num_fields(result) < 4) + throw Net::Exception(Net::Exception::NOT_AVAILABLE); + + MYSQL_ROW row = mysql_fetch_row(result); + + if(row) { + boost::shared_ptr user(new Common::UserInfo(strtoul(row[0], 0, 10), row[2])); + + user->setGid(strtoul(row[1], 0, 10)); + user->setFullName(row[3]); + + while((row = mysql_fetch_row(result)) != 0) {} + + return user; + } + + throw Net::Exception(Net::Exception::NOT_AVAILABLE); +} + +boost::shared_ptr > UserBackendMysql::getUserGroups(unsigned long uid) throw(Net::Exception) { + Net::ThreadManager::get()->detach(); + + if(mysql_ping(mysql)) + throw Net::Exception(Net::Exception::NOT_AVAILABLE); + + std::ostringstream tmp; + tmp << '"'; + tmp << uid; + tmp << '"'; + + std::string query = boost::regex_replace(queryListUserGroups, boost::regex("\\{UID\\}"), tmp.str(), boost::match_default); + + mysql_real_query(mysql, query.c_str(), query.length()); + MYSQL_RES *result = mysql_use_result(mysql); + + if(!result || mysql_num_fields(result) < 1) + throw Net::Exception(Net::Exception::NOT_AVAILABLE); + + boost::shared_ptr > groups(new std::set); + + while(MYSQL_ROW row = mysql_fetch_row(result)) + groups->insert(strtoul(row[0], 0, 10)); + + return groups; +} + + boost::shared_ptr > UserBackendMysql::getGroupList() throw(Net::Exception) { Net::ThreadManager::get()->detach(); - mysql_ping(mysql); + if(mysql_ping(mysql)) + throw Net::Exception(Net::Exception::NOT_AVAILABLE); mysql_real_query(mysql, queryListGroups.c_str(), queryListGroups.length()); MYSQL_RES *result = mysql_use_result(mysql); @@ -215,6 +280,88 @@ boost::shared_ptr > UserBackendMysql: return groups; } +std::string UserBackendMysql::getGroupName(unsigned long gid) throw(Net::Exception) { + Net::ThreadManager::get()->detach(); + + if(mysql_ping(mysql)) + throw Net::Exception(Net::Exception::NOT_AVAILABLE); + + std::string query = queryGroupById; + + std::ostringstream tmp; + tmp << '"'; + tmp << gid; + tmp << '"'; + + query = boost::regex_replace(query, boost::regex("\\{GID\\}"), tmp.str(), boost::match_default); + + mysql_real_query(mysql, query.c_str(), query.length()); + MYSQL_RES *result = mysql_use_result(mysql); + + if(!result || mysql_num_fields(result) < 2) + throw Net::Exception(Net::Exception::NOT_AVAILABLE); + + MYSQL_ROW row = mysql_fetch_row(result); + + if(row) + return row[1]; + + throw Net::Exception(Net::Exception::NOT_AVAILABLE); +} + +unsigned long UserBackendMysql::getGroupId(const std::string &name) throw(Net::Exception) { + Net::ThreadManager::get()->detach(); + + if(mysql_ping(mysql)) + throw Net::Exception(Net::Exception::NOT_AVAILABLE); + + boost::scoped_array escapedName(new char[name.length()*2+1]); + + mysql_real_escape_string(mysql, escapedName.get(), name.c_str(), name.length()); + + std::string query = boost::regex_replace(queryGroupByName, boost::regex("\\{GROUP\\}"), "\""+std::string(escapedName.get())+"\"", boost::match_default); + + mysql_real_query(mysql, query.c_str(), query.length()); + MYSQL_RES *result = mysql_use_result(mysql); + + if(!result || mysql_num_fields(result) < 2) + throw Net::Exception(Net::Exception::NOT_AVAILABLE); + + MYSQL_ROW row = mysql_fetch_row(result); + + if(row) + return strtoul(row[0], 0, 10); + + throw Net::Exception(Net::Exception::NOT_AVAILABLE); +} + +boost::shared_ptr > UserBackendMysql::getGroupUsers(unsigned long gid) throw(Net::Exception) { + Net::ThreadManager::get()->detach(); + + if(mysql_ping(mysql)) + throw Net::Exception(Net::Exception::NOT_AVAILABLE); + + std::ostringstream tmp; + tmp << '"'; + tmp << gid; + tmp << '"'; + + std::string query = boost::regex_replace(queryListGroupUsers, boost::regex("\\{GID\\}"), tmp.str(), boost::match_default); + + mysql_real_query(mysql, query.c_str(), query.length()); + MYSQL_RES *result = mysql_use_result(mysql); + + if(!result || mysql_num_fields(result) < 1) + throw Net::Exception(Net::Exception::NOT_AVAILABLE); + + boost::shared_ptr > users(new std::set); + + while(MYSQL_ROW row = mysql_fetch_row(result)) + users->insert(strtoul(row[0], 0, 10)); + + return users; +} + void UserBackendMysql::registerBackend() { if(backend) diff --git a/src/modules/UserBackendMysql/UserBackendMysql.h b/src/modules/UserBackendMysql/UserBackendMysql.h index 1bf0f2b..71ee93f 100644 --- a/src/modules/UserBackendMysql/UserBackendMysql.h +++ b/src/modules/UserBackendMysql/UserBackendMysql.h @@ -52,8 +52,13 @@ class UserBackendMysql : public Server::UserBackend, private Common::Configurabl virtual boost::shared_ptr > getUserList() throw(Net::Exception); virtual boost::shared_ptr getUserInfo(unsigned long uid) throw(Net::Exception); + virtual boost::shared_ptr getUserInfoByName(const std::string &name) throw(Net::Exception); + virtual boost::shared_ptr > getUserGroups(unsigned long uid) throw(Net::Exception); virtual boost::shared_ptr > getGroupList() throw(Net::Exception); + virtual std::string getGroupName(unsigned long gid) throw(Net::Exception); + virtual unsigned long getGroupId(const std::string &name) throw(Net::Exception); + virtual boost::shared_ptr > getGroupUsers(unsigned long gid) throw(Net::Exception); public: virtual ~UserBackendMysql() { -- cgit v1.2.3