diff --git a/include/maxscale/users.h b/include/maxscale/users.h index 787017569..8bdf7a7ef 100644 --- a/include/maxscale/users.h +++ b/include/maxscale/users.h @@ -88,6 +88,36 @@ bool users_auth(USERS* users, const char* user, const char* password); */ bool users_find(USERS* users, const char* user); +/** + * Check if user is an administrator + * + * @param users The users table + * @param user User to check + * + * @return True if user is an administrator + */ +bool users_is_admin(USERS* users, const char* user); + +/** + * Promote a user to an administrator + * + * @param users The users table + * @param user User to promote + * + * @return True if user was found and promoted + */ +bool users_promote(USERS* users, const char* user); + +/** + * Demote an administrative user to a normal user + * + * @param users The users table + * @param user User to demote + * + * @return True if user was found and demoted + */ +bool users_demote(USERS* users, const char* user); + /** * @brief Default user loading function * diff --git a/server/core/users.cc b/server/core/users.cc index 43c28540d..bc4c1e2b9 100644 --- a/server/core/users.cc +++ b/server/core/users.cc @@ -22,13 +22,33 @@ namespace { + +enum permission_type +{ + PERM_READ, + PERM_WRITE +}; + +struct UserInfo +{ + UserInfo(std::string pw = "", permission_type perm = PERM_WRITE): // TODO: Change default to PERM_READ + password(pw), + permissions(perm) + { + } + + std::string password; + permission_type permissions; +}; + + class Users { Users(const Users&); Users& operator=(const Users&); public: - typedef std::tr1::unordered_map UserMap; + typedef std::tr1::unordered_map UserMap; Users() { @@ -40,7 +60,7 @@ public: bool add(std::string user, std::string password) { - return m_data.insert(std::make_pair(user, password)).second; + return m_data.insert(std::make_pair(user, UserInfo(password))).second; } bool remove(std::string user) @@ -56,7 +76,7 @@ public: return rval; } - bool get(std::string user, std::string* output = NULL) const + bool get(std::string user, UserInfo* output = NULL) const { UserMap::const_iterator it = m_data.find(user); bool rval = false; @@ -74,6 +94,33 @@ public: return rval; } + bool check_permissions(std::string user, permission_type perm) const + { + UserMap::const_iterator it = m_data.find(user); + bool rval = false; + + if (it != m_data.end() && it->second.permissions == perm) + { + rval = true; + } + + return rval; + } + + bool set_permissions(std::string user, permission_type perm) + { + UserMap::iterator it = m_data.find(user); + bool rval = false; + + if (it != m_data.end()) + { + rval = true; + it->second.permissions = perm; + } + + return rval; + } + json_t* diagnostic_json() const { json_t* rval = json_array(); @@ -147,16 +194,34 @@ bool users_auth(USERS* users, const char* user, const char* password) { Users* u = reinterpret_cast(users); bool rval = false; - std::string str; + UserInfo info; - if (u->get(user, &str)) + if (u->get(user, &info)) { - rval = strcmp(password, str.c_str()) == 0; + rval = strcmp(password, info.password.c_str()) == 0; } return rval; } +bool users_is_admin(USERS* users, const char* user) +{ + Users* u = reinterpret_cast(users); + return u->check_permissions(user, PERM_WRITE); +} + +bool users_promote(USERS* users, const char* user) +{ + Users* u = reinterpret_cast(users); + return u->set_permissions(user, PERM_WRITE); +} + +bool users_demote(USERS* users, const char* user) +{ + Users* u = reinterpret_cast(users); + return u->set_permissions(user, PERM_READ); +} + void users_diagnostic(DCB* dcb, USERS* users) { Users* u = reinterpret_cast(users);