From: Sangwan Kwon Date: Thu, 31 Oct 2019 00:54:05 +0000 (+0900) Subject: Redesign vist-policy except for multi-user concept X-Git-Tag: accepted/tizen/unified/20200810.122954~169 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=be1bc95d2cb9cd0804c75e6626b205e672ba10fb;p=platform%2Fcore%2Fsecurity%2Fvist.git Redesign vist-policy except for multi-user concept Tizen originally intended to support multiuser platform. As a result, the logic is complicated to support multi-users. In practice, However, the multiuser concept is excluded on Tizen. So we redesign except for the multi-user concept. Signed-off-by: Sangwan Kwon --- diff --git a/data/script/create_schema.sql b/data/script/create-schema.sql similarity index 97% rename from data/script/create_schema.sql rename to data/script/create-schema.sql index 9aa918d..3266cc8 100644 --- a/data/script/create_schema.sql +++ b/data/script/create-schema.sql @@ -17,7 +17,6 @@ CREATE TABLE IF NOT EXISTS admin ( id INTEGER PRIMARY KEY AUTOINCREMENT, pkg TEXT NOT NULL, - uid INTEGER, key TEXT, removable INTEGER ); @@ -31,7 +30,6 @@ CREATE TABLE IF NOT EXISTS managed_policy ( CREATE TABLE IF NOT EXISTS policy_definition ( id INTEGER PRIMARY KEY AUTOINCREMENT, - scope INTEGER, name TEXT NOT NULL, ivalue INTEGER ); diff --git a/plugins/bluetooth/bluetooth.cpp b/plugins/bluetooth/bluetooth.cpp index aca5c24..eafbc65 100644 --- a/plugins/bluetooth/bluetooth.cpp +++ b/plugins/bluetooth/bluetooth.cpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include @@ -39,9 +39,9 @@ using namespace vist::policy; -class ModeChange : public GlobalPolicy { +class ModeChange : public PolicyModel { public: - ModeChange() : GlobalPolicy("bluetooth", PolicyValue(1)) {} + ModeChange() : PolicyModel("bluetooth", PolicyValue(1)) {} void onChanged(const PolicyValue& value) override { @@ -51,10 +51,10 @@ public: } }; -class DesktopConnectivity : public GlobalPolicy { +class DesktopConnectivity : public PolicyModel { public: DesktopConnectivity() : - GlobalPolicy("bluetooth-desktop-connectivity", PolicyValue(1)) {} + PolicyModel("bluetooth-desktop-connectivity", PolicyValue(1)) {} void onChanged(const PolicyValue& value) override { @@ -64,9 +64,9 @@ public: } }; -class Pairing: public GlobalPolicy { +class Pairing: public PolicyModel { public: - Pairing() : GlobalPolicy("bluetooth-pairing", PolicyValue(1)) {} + Pairing() : PolicyModel("bluetooth-pairing", PolicyValue(1)) {} void onChanged(const PolicyValue& value) override { @@ -76,9 +76,9 @@ public: } }; -class Tethering: public GlobalPolicy { +class Tethering: public PolicyModel { public: - Tethering() : GlobalPolicy("bluetooth-tethering", PolicyValue(1)) {} + Tethering() : PolicyModel("bluetooth-tethering", PolicyValue(1)) {} void onChanged(const PolicyValue&) {} }; diff --git a/plugins/wifi/wifi.cpp b/plugins/wifi/wifi.cpp index 3714fa8..b8d8aa5 100644 --- a/plugins/wifi/wifi.cpp +++ b/plugins/wifi/wifi.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include @@ -33,9 +33,9 @@ using namespace vist::policy; -class ModeChange : public GlobalPolicy { +class ModeChange : public PolicyModel { public: - ModeChange() : GlobalPolicy("wifi", PolicyValue(1)) {} + ModeChange() : PolicyModel("wifi", PolicyValue(1)) {} void onChanged(const PolicyValue& value) override { @@ -50,9 +50,9 @@ public: } }; -class ProfileChange : public GlobalPolicy { +class ProfileChange : public PolicyModel { public: - ProfileChange() : GlobalPolicy("wifi-profile-change", PolicyValue(1)) {} + ProfileChange() : PolicyModel("wifi-profile-change", PolicyValue(1)) {} void onChanged(const PolicyValue& value) override { @@ -67,9 +67,9 @@ public: } }; -class Hotspot : public GlobalPolicy { +class Hotspot : public PolicyModel { public: - Hotspot() : GlobalPolicy("wifi-hotspot", PolicyValue(1)) {} + Hotspot() : PolicyModel("wifi-hotspot", PolicyValue(1)) {} void onChanged(const PolicyValue&) override { @@ -77,9 +77,9 @@ public: } }; -class SsidRestriction : public GlobalPolicy { +class SsidRestriction : public PolicyModel { public: - SsidRestriction() : GlobalPolicy("wifi-ssid-restriction", PolicyValue(0)) {} + SsidRestriction() : PolicyModel("wifi-ssid-restriction", PolicyValue(0)) {} void onChanged(const PolicyValue&) override { diff --git a/specs/tizen/policy_admin.table b/specs/tizen/policy_admin.table index 03622f8..3cd3227 100644 --- a/specs/tizen/policy_admin.table +++ b/specs/tizen/policy_admin.table @@ -2,7 +2,6 @@ table_name("policy_admin") description("Policy administrator.") schema([ Column("name", TEXT, "Policy admin name"), - Column("uid", INTEGER, "Policy admin uid"), ]) implementation("tizen/policy_admin@genPolicyAdmin") implementation_delete("tizen/policy_admin@deletePolicyAdmin") diff --git a/src/osquery/tables/tizen/policy_admin.cpp b/src/osquery/tables/tizen/policy_admin.cpp index e3e47da..a831701 100644 --- a/src/osquery/tables/tizen/policy_admin.cpp +++ b/src/osquery/tables/tizen/policy_admin.cpp @@ -37,31 +37,20 @@ std::string getValue(std::string&& alias, const std::string& key) return std::string(); } -std::pair parseAdmin(const std::string& request, bool insert = true) +std::string parseAdmin(const std::string& request, bool insert = true) { rapidjson::Document document; document.Parse(request.c_str()); if (document.HasParseError() || !document.IsArray()) throw std::runtime_error("Cannot parse request."); - if (document.Size() != 2) + if (document.Size() != 1) throw std::runtime_error("Wrong request format."); - if (insert) { - return std::make_pair(document[0].GetString(), document[1].GetInt()); - } else { /// osquery transforms int to string in 'where clause' internally. - std::string name, uid; - std::string value = getValue(document[0].GetString(), "name"); - if (!value.empty()) { - name = value; - uid = getValue(document[1].GetString(), "uid"); - } else { - name = getValue(document[1].GetString(), "name"); - uid = getValue(document[0].GetString(), "uid"); - } - - return std::make_pair(name, std::stoi(uid)); - } + if (insert) + return std::string(document[0].GetString()); + else + return getValue(document[0].GetString(), "name"); } } // anonymous namespace @@ -77,10 +66,9 @@ QueryData genPolicyAdmin(QueryContext& context) try { for (auto& admin : admins) { Row r; - r["name"] = SQL_TEXT(admin.first); - r["uid"] = INTEGER(admin.second); + r["name"] = SQL_TEXT(admin); - DEBUG(VIST, "Admin info [name]: " << r["name"] << ", [uid]: " << r["uid"]); + DEBUG(VIST, "Admin info [name]: " << r["name"]); results.emplace_back(std::move(r)); } @@ -97,8 +85,8 @@ QueryData insertPolicyAdmin(QueryContext& context, const PluginRequest& request) throw std::runtime_error("Wrong request format. Not found json value."); auto admin = parseAdmin(request.at("json_value_array")); - DEBUG(VIST, "Admin info [name]: " << admin.first << ", [uid]: " << admin.second); - vist::policy::API::Admin::Enroll(admin.first, admin.second); + DEBUG(VIST, "Admin info [name]: " << admin); + vist::policy::API::Admin::Enroll(admin); Row r; r["status"] = "success"; @@ -115,8 +103,8 @@ QueryData deletePolicyAdmin(QueryContext& context, const PluginRequest& request) throw std::runtime_error("Wrong request format. Not found json value."); auto admin = parseAdmin(request.at("json_value_array"), false); - DEBUG(VIST, "Admin info [name]: " << admin.first << ", [uid]: " << admin.second); - vist::policy::API::Admin::Disenroll(admin.first, admin.second); + DEBUG(VIST, "Admin info [name]: " << admin); + vist::policy::API::Admin::Disenroll(admin); Row r; r["status"] = "success"; diff --git a/src/osquery/tables/tizen/tests/policy_tests.cpp b/src/osquery/tables/tizen/tests/policy_tests.cpp index f31d527..e7cb5b2 100644 --- a/src/osquery/tables/tizen/tests/policy_tests.cpp +++ b/src/osquery/tables/tizen/tests/policy_tests.cpp @@ -32,19 +32,19 @@ TEST_F(PolicyTests, get_admin_all) { auto admins = policy::API::Admin::GetAll(); EXPECT_EQ(admins.size(), 0); - policy::API::Admin::Enroll("testAdmin", 0); + policy::API::Admin::Enroll("testAdmin"); admins = policy::API::Admin::GetAll(); EXPECT_EQ(admins.size(), 1); - policy::API::Admin::Enroll("testAdmin", 1); + policy::API::Admin::Enroll("testAdmin1"); admins = policy::API::Admin::GetAll(); EXPECT_EQ(admins.size(), 2); - policy::API::Admin::Disenroll("testAdmin", 0); + policy::API::Admin::Disenroll("testAdmin"); admins = policy::API::Admin::GetAll(); EXPECT_EQ(admins.size(), 1); - policy::API::Admin::Disenroll("testAdmin", 1); + policy::API::Admin::Disenroll("testAdmin1"); admins = policy::API::Admin::GetAll(); EXPECT_EQ(admins.size(), 0); } diff --git a/src/vist/CMakeLists.txt b/src/vist/CMakeLists.txt index 73f9be1..8f71945 100644 --- a/src/vist/CMakeLists.txt +++ b/src/vist/CMakeLists.txt @@ -29,7 +29,6 @@ ADD_DEFINITIONS(-DDB_PATH="${DB_INSTALL_DIR}/.vist.db" -DSCRIPT_INSTALL_DIR="${SCRIPT_INSTALL_DIR}") ADD_SUBDIRECTORY(client) -ADD_SUBDIRECTORY(common) ADD_SUBDIRECTORY(notification) ADD_SUBDIRECTORY(policy) ADD_SUBDIRECTORY(service) diff --git a/src/vist/client/tests/client-tests.cpp b/src/vist/client/tests/client-tests.cpp index d48b003..f7bc148 100644 --- a/src/vist/client/tests/client-tests.cpp +++ b/src/vist/client/tests/client-tests.cpp @@ -32,24 +32,23 @@ TEST_F(ClientTests, query) { } TEST_F(ClientTests, admin_enrollment) { - auto rows = Query::Execute("INSERT INTO policy_admin (name, uid) " - "VALUES ('testAdmin', 0)"); + auto rows = Query::Execute("INSERT INTO policy_admin (name) VALUES ('testAdmin')"); EXPECT_EQ(rows.size(), 0); rows = Query::Execute("SELECT * FROM policy_admin"); EXPECT_EQ(rows.size(), 1); - Query::Execute("INSERT INTO policy_admin (name, uid) VALUES ('testAdmin', 1)"); + Query::Execute("INSERT INTO policy_admin (name) VALUES ('testAdmin2')"); rows = Query::Execute("SELECT * FROM policy_admin"); EXPECT_EQ(rows.size(), 2); - rows = Query::Execute("DELETE FROM policy_admin WHERE uid = 0 AND name = 'testAdmin'"); + rows = Query::Execute("DELETE FROM policy_admin WHERE name = 'testAdmin'"); EXPECT_EQ(rows.size(), 0); rows = Query::Execute("SELECT * FROM policy_admin"); EXPECT_EQ(rows.size(), 1); - Query::Execute("DELETE FROM policy_admin WHERE name = 'testAdmin' AND uid = 1"); + Query::Execute("DELETE FROM policy_admin WHERE name = 'testAdmin2'"); rows = Query::Execute("SELECT * FROM policy_admin"); EXPECT_EQ(rows.size(), 0); } diff --git a/src/vist/policy/api.h b/src/vist/policy/api.h index 33b54f3..6fd3d06 100644 --- a/src/vist/policy/api.h +++ b/src/vist/policy/api.h @@ -19,8 +19,8 @@ #include #include -#include #include +#include namespace vist { namespace policy { @@ -32,10 +32,10 @@ struct API { struct Admin { static void Set(const std::string& policy, const PolicyValue& value); - static void Enroll(const std::string& admin, uid_t uid); - static void Disenroll(const std::string& admin, uid_t uid); + static void Enroll(const std::string& admin); + static void Disenroll(const std::string& admin); - static std::multimap GetAll(); + static std::vector GetAll(); }; }; diff --git a/src/vist/policy/core/api.cpp b/src/vist/policy/core/api.cpp index 7a5a8e0..2277cb4 100644 --- a/src/vist/policy/core/api.cpp +++ b/src/vist/policy/core/api.cpp @@ -37,17 +37,17 @@ void API::Admin::Set(const std::string& policy, const PolicyValue& value) PolicyManager::Instance().set(policy, value, "admin"); } -void API::Admin::Enroll(const std::string& admin, uid_t uid) +void API::Admin::Enroll(const std::string& admin) { - PolicyManager::Instance().enroll(admin, uid); + PolicyManager::Instance().enroll(admin); } -void API::Admin::Disenroll(const std::string& admin, uid_t uid) +void API::Admin::Disenroll(const std::string& admin) { - PolicyManager::Instance().disenroll(admin, uid); + PolicyManager::Instance().disenroll(admin); } -std::multimap API::Admin::GetAll() +std::vector API::Admin::GetAll() { return PolicyManager::Instance().getAdmins(); } diff --git a/src/vist/policy/core/db-schema.h b/src/vist/policy/core/db-schema.h index c2facea..6d41ccd 100644 --- a/src/vist/policy/core/db-schema.h +++ b/src/vist/policy/core/db-schema.h @@ -24,7 +24,6 @@ namespace schema { struct Admin { int id = -1; std::string pkg; - int uid = -1; std::string key; int removable = -1; }; @@ -38,7 +37,6 @@ struct ManagedPolicy { struct PolicyDefinition { int id = -1; - int scope = -1; std::string name; int ivalue = -1; }; diff --git a/src/vist/policy/core/policy-manager.cpp b/src/vist/policy/core/policy-manager.cpp index 0def919..2ec9ab6 100644 --- a/src/vist/policy/core/policy-manager.cpp +++ b/src/vist/policy/core/policy-manager.cpp @@ -77,23 +77,13 @@ int PolicyManager::loadPolicies() /// Make policy-provider map for performance for (const auto& provider : providers) { - for (const auto& pair : provider->global) { + for (const auto& pair : provider->policies) { policies[pair.first] = provider->getName(); /// Check the policy is defined on policy-storage if (!storage.exists(pair.first)) { - INFO(VIST, "Define global policy: " << pair.first); - storage.define(0, pair.first, pair.second->getInitial().value); - changed = true; - } - } - - for (const auto& pair : provider->domain) { - policies[pair.first] = provider->getName(); - - if (!storage.exists(pair.first)) { - INFO(VIST, "Define domain policy: " << pair.first); - storage.define(1, pair.first, pair.second->getInitial().value); + INFO(VIST, "Define policy: " << pair.first); + storage.define(pair.first, pair.second->getInitial().value); changed = true; } } @@ -105,51 +95,47 @@ int PolicyManager::loadPolicies() return policies.size(); } -void PolicyManager::enroll(const std::string& admin, uid_t uid) +void PolicyManager::enroll(const std::string& admin) { - this->storage.enroll(admin, uid); + this->storage.enroll(admin); } -void PolicyManager::disenroll(const std::string& admin, uid_t uid) +void PolicyManager::disenroll(const std::string& admin) { - this->storage.disenroll(admin, uid); + this->storage.disenroll(admin); } -void PolicyManager::set(const std::string& policy, const PolicyValue& value, - const std::string& admin, uid_t uid) +void PolicyManager::set(const std::string& policy, + const PolicyValue& value, + const std::string& admin) { - if (policies.find(policy) == policies.end()) + if (this->policies.find(policy) == this->policies.end()) std::runtime_error("Not exist policy: " + policy); - storage.update(admin, uid, policy, value); + storage.update(admin, policy, value); for (auto& p : providers) { - if (p->getName() != policies[policy]) + if (p->getName() != this->policies[policy]) continue; - if (p->global.find(policy) != p->global.end()) { - p->global[policy]->set(value); - return; - } - - if (p->domain.find(policy) != p->domain.end()) { - p->domain[policy]->set(uid, value); + if (p->policies.find(policy) != p->policies.end()) { + p->policies[policy]->set(value); return; } } } -PolicyValue PolicyManager::get(const std::string& policy, uid_t uid) +PolicyValue PolicyManager::get(const std::string& policy) { - return storage.strictest(policy, uid); + return storage.strictest(policy); } -std::unordered_map PolicyManager::getAll(uid_t uid) +std::unordered_map PolicyManager::getAll() { - return storage.strictest(uid); + return storage.strictest(); } -std::multimap PolicyManager::getAdmins() +std::vector PolicyManager::getAdmins() { return storage.getAdmins(); } diff --git a/src/vist/policy/core/policy-manager.h b/src/vist/policy/core/policy-manager.h index feff66e..7e81c18 100644 --- a/src/vist/policy/core/policy-manager.h +++ b/src/vist/policy/core/policy-manager.h @@ -22,7 +22,6 @@ #include "policy-storage.h" #include -#include #include #include #include @@ -41,20 +40,22 @@ public: PolicyManager(PolicyManager&&) = delete; PolicyManager& operator=(PolicyManager&&) = delete; - static PolicyManager& Instance() { + static PolicyManager& Instance() + { static PolicyManager manager; return manager; } - void enroll(const std::string& admin, uid_t uid); - void disenroll(const std::string& admin, uid_t uid); + void enroll(const std::string& admin); + void disenroll(const std::string& admin); - void set(const std::string& policy, const PolicyValue& value, - const std::string& admin, uid_t uid = 0); - PolicyValue get(const std::string& policy, uid_t uid = 0); - std::unordered_map getAll(uid_t uid = 0); + void set(const std::string& policy, + const PolicyValue& value, + const std::string& admin); + PolicyValue get(const std::string& policy); + std::unordered_map getAll(); - std::multimap getAdmins(); + std::vector getAdmins(); private: explicit PolicyManager(); diff --git a/src/vist/policy/core/policy-storage.cpp b/src/vist/policy/core/policy-storage.cpp index e7a6cb5..c8668a0 100644 --- a/src/vist/policy/core/policy-storage.cpp +++ b/src/vist/policy/core/policy-storage.cpp @@ -33,7 +33,6 @@ namespace { auto adminTable = make_table("admin", make_column("id", &Admin::id), make_column("pkg", &Admin::pkg), - make_column("uid", &Admin::uid), make_column("key", &Admin::key), make_column("removable", &Admin::removable)); @@ -45,12 +44,11 @@ auto managedPolTable = make_table("managed_policy", auto definitionTable = make_table("policy_definition", make_column("id", &PolicyDefinition::id), - make_column("scope", &PolicyDefinition::scope), make_column("name", &PolicyDefinition::name), make_column("ivalue", &PolicyDefinition::ivalue)); const std::string SCRIPT_BASE = SCRIPT_INSTALL_DIR; -const std::string SCRIPT_CREATE_SCHEMA = "create_schema"; +const std::string SCRIPT_CREATE_SCHEMA = "create-schema"; } // anonymous namespace @@ -85,9 +83,8 @@ void PolicyStorage::syncPolicyDefinition() while (stmt.step()) { PolicyDefinition pd; pd.id = stmt.getColumn(0); - pd.scope = stmt.getColumn(1); - pd.name = std::string(stmt.getColumn(2)); - pd.ivalue = stmt.getColumn(3); + pd.name = std::string(stmt.getColumn(1)); + pd.ivalue = stmt.getColumn(2); DEBUG(VIST, "Defined policy:" + pd.name); this->definitions.emplace(pd.name, std::move(pd)); } @@ -103,12 +100,10 @@ void PolicyStorage::syncAdmin() Admin admin; admin.id = stmt.getColumn(0); admin.pkg = std::string(stmt.getColumn(1)); - admin.uid = stmt.getColumn(2); - admin.key = std::string(stmt.getColumn(3)); - admin.removable = stmt.getColumn(4); + admin.key = std::string(stmt.getColumn(2)); + admin.removable = stmt.getColumn(3); - std::string alias = getAlias(admin.pkg, admin.uid); - this->admins.emplace(alias, std::move(admin)); + this->admins.emplace(admin.pkg, std::move(admin)); } } @@ -143,7 +138,7 @@ std::string PolicyStorage::getScript(const std::string& name) return content; } -void PolicyStorage::define(int scope, const std::string& policy, int ivalue) +void PolicyStorage::define(const std::string& policy, int ivalue) { if (definitions.find(policy) != definitions.end()) { INFO(VIST, "Policy is already defined: " + policy); @@ -151,43 +146,38 @@ void PolicyStorage::define(int scope, const std::string& policy, int ivalue) } PolicyDefinition pd; - pd.scope = scope; pd.name = policy; pd.ivalue = ivalue; - std::string insertQuery = definitionTable.insert(&PolicyDefinition::scope, - &PolicyDefinition::name, + std::string insertQuery = definitionTable.insert(&PolicyDefinition::name, &PolicyDefinition::ivalue); database::Statement stmt(*database, insertQuery); - stmt.bind(1, pd.scope); - stmt.bind(2, pd.name); - stmt.bind(3, pd.ivalue); + stmt.bind(1, pd.name); + stmt.bind(2, pd.ivalue); if (!stmt.exec()) throw std::runtime_error("Failed to define policy: " + pd.name); } -void PolicyStorage::enroll(const std::string& name, uid_t uid) +void PolicyStorage::enroll(const std::string& name) { - std::string alias = getAlias(name, uid); - INFO(VIST, "Enroll admin: " + alias); - if (admins.find(alias) != admins.end()) { - ERROR(VIST, "Admin is aleady enrolled.: " + alias); + INFO(VIST, "Enroll admin: " + name); + if (admins.find(name) != admins.end()) { + ERROR(VIST, "Admin is aleady enrolled.: " + name); return; } Admin admin; admin.pkg = name; - admin.uid = static_cast(uid); admin.key = "Not supported"; admin.removable = true; - std::string insertQuery = adminTable.insert(&Admin::pkg, &Admin::uid, - &Admin::key, &Admin::removable); + std::string insertQuery = adminTable.insert(&Admin::pkg, + &Admin::key, + &Admin::removable); database::Statement stmt(*database, insertQuery); stmt.bind(1, admin.pkg); - stmt.bind(2, admin.uid); - stmt.bind(3, admin.key); - stmt.bind(4, admin.removable); + stmt.bind(2, admin.key); + stmt.bind(3, admin.removable); if (!stmt.exec()) throw std::runtime_error("Failed to enroll admin: " + admin.pkg); @@ -197,46 +187,42 @@ void PolicyStorage::enroll(const std::string& name, uid_t uid) syncManagedPolicy(); int count = managedPolicies.size() / admins.size(); - INFO(VIST, "Admin[" + alias + "] manages " + std::to_string(count) + "-policies."); + INFO(VIST, "Admin[" + name + "] manages " + std::to_string(count) + "-policies."); } -void PolicyStorage::disenroll(const std::string& name, uid_t uid) +void PolicyStorage::disenroll(const std::string& name) { - std::string alias = getAlias(name, uid); - INFO(VIST, "Disenroll admin: " + alias); - if (admins.find(alias) == admins.end()) { - ERROR(VIST, "Not exist admin: " + alias); + INFO(VIST, "Disenroll admin: " + name); + if (admins.find(name) == admins.end()) { + ERROR(VIST, "Not exist admin: " + name); return; } else { - admins.erase(alias); + admins.erase(name); } - int iUid = static_cast(uid); - std::string query = adminTable.remove().where(expr(&Admin::pkg) == name && - expr(&Admin::uid) == iUid); + std::string query = adminTable.remove().where(expr(&Admin::pkg) == name); database::Statement stmt(*database, query); stmt.bind(1, name); - stmt.bind(2, iUid); if (!stmt.exec()) throw std::runtime_error("Failed to disenroll admin: " + name); } -void PolicyStorage::update(const std::string& name, uid_t uid, - const std::string& policy, const PolicyValue& value) +void PolicyStorage::update(const std::string& admin, + const std::string& policy, + const PolicyValue& value) { - std::string alias = getAlias(name, uid); - if (admins.find(alias) == admins.end()) - throw std::runtime_error("Not exist admin: " + alias); + if (admins.find(admin) == admins.end()) + throw std::runtime_error("Not exist admin: " + admin); if (definitions.find(policy) == definitions.end()) throw std::runtime_error("Not exist policy: " + policy); - DEBUG(VIST, "Policy-update is called by admin: " + alias + ", about: " + policy + - ", value: " + std::to_string(value)); + DEBUG(VIST, "Policy-update is called by admin: " + admin + ", about: " + policy + + ", value: " + std::to_string(value)); int policyId = definitions[policy].id; int policyValue = value; - int adminId = admins[alias].id; + int adminId = admins[admin].id; std::string query = managedPolTable.update(&ManagedPolicy::value) .where(expr(&ManagedPolicy::pid) == policyId && expr(&ManagedPolicy::aid) == adminId); @@ -250,7 +236,7 @@ void PolicyStorage::update(const std::string& name, uid_t uid, syncManagedPolicy(); } -PolicyValue PolicyStorage::strictest(const std::string& policy, uid_t uid) +PolicyValue PolicyStorage::strictest(const std::string& policy) { if (definitions.find(policy) == definitions.end()) throw std::runtime_error("Not exist policy: " + policy); @@ -259,38 +245,32 @@ PolicyValue PolicyStorage::strictest(const std::string& policy, uid_t uid) if (managedPolicies.size() == 0) return PolicyValue(definitions[policy].ivalue); - std::shared_ptr strictest = nullptr; + std::shared_ptr strictestPtr = nullptr; int policyId = definitions[policy].id; auto range = managedPolicies.equal_range(policyId); for (auto iter = range.first; iter != range.second; iter++) { - if (uid != 0) { - int ret = getUid(iter->second.aid); - if (ret == -1 || ret != static_cast(uid)) - continue; - } - int value = iter->second.value; - if (strictest == nullptr) - strictest = std::make_shared(value); + if (strictestPtr == nullptr) + strictestPtr = std::make_shared(value); else - strictest->value = (*strictest < value) ? strictest->value : value; + strictestPtr->value = (*strictestPtr < value) ? strictestPtr->value : value; DEBUG(VIST, "The strictest of policy[" + policy + - "] : " + std::to_string(strictest->value)); + "] : " + std::to_string(strictestPtr->value)); } - if (strictest == nullptr) + if (strictestPtr == nullptr) throw std::runtime_error("Not exist managed policy: " + policy); - return std::move(*strictest); + return std::move(*strictestPtr); } -std::unordered_map PolicyStorage::strictest(uid_t uid) +std::unordered_map PolicyStorage::strictest() { std::unordered_map policies; for (const auto& pair : definitions) { std::string name = pair.first; - auto value = this->strictest(name, uid); + auto value = this->strictest(name); policies.emplace(std::move(name), std::move(value)); } @@ -298,35 +278,16 @@ std::unordered_map PolicyStorage::strictest(uid_t uid) return policies; } -std::multimap PolicyStorage::getAdmins() +std::vector PolicyStorage::getAdmins() { - std::multimap admins; + std::vector admins; for (const auto& pair : this->admins) { - std::string alias = pair.first; - int uid = pair.second.uid; - /// Erase uid from alias(name + uid) - std::size_t pos = alias.rfind(std::to_string(uid)); - alias.erase(pos, std::to_string(uid).size()); - - admins.emplace(std::move(alias), uid); + std::string name = pair.first; + admins.emplace_back(std::move(name)); } return admins; } -std::string PolicyStorage::getAlias(const std::string& name, uid_t uid) const noexcept -{ - return name + std::to_string(uid); -} - -int PolicyStorage::getUid(int adminId) const noexcept -{ - for (const auto& a : admins) - if (a.second.id == adminId) - return a.second.uid; - - return -1; -} - } // namespace policy } // namespace vist diff --git a/src/vist/policy/core/policy-storage.h b/src/vist/policy/core/policy-storage.h index 49a4283..a725f41 100644 --- a/src/vist/policy/core/policy-storage.h +++ b/src/vist/policy/core/policy-storage.h @@ -20,7 +20,6 @@ #include "db-schema.h" -#include #include #include #include @@ -43,32 +42,32 @@ public: void syncAdmin(); void syncManagedPolicy(); - inline bool exists(const std::string& policy) const noexcept { + inline bool exists(const std::string& policy) const noexcept + { return definitions.find(policy) != definitions.end(); } - inline bool isActivated() const noexcept { + inline bool isActivated() const noexcept + { return admins.size() > 0 && managedPolicies.size() > 0; } - void enroll(const std::string& admin, uid_t uid); - void disenroll(const std::string& admin, uid_t uid); + void enroll(const std::string& admin); + void disenroll(const std::string& admin); - void define(int scope, const std::string& policy, int ivalue); - void update(const std::string& admin, uid_t uid, - const std::string& policy, const PolicyValue& value); + void define(const std::string& policy, int ivalue); + void update(const std::string& admin, + const std::string& policy, + const PolicyValue& value); - PolicyValue strictest(const std::string& policy, uid_t uid = 0); + PolicyValue strictest(const std::string& policy); /// Return all strictest policy values - std::unordered_map strictest(uid_t uid = 0); + std::unordered_map strictest(); - /// Admin name can be duplicated - std::multimap getAdmins(); + std::vector getAdmins(); private: std::string getScript(const std::string& name); - std::string getAlias(const std::string& name, uid_t uid) const noexcept; - int getUid(int adminId) const noexcept; std::shared_ptr database; @@ -76,7 +75,7 @@ private: /// TODO(Sangwan): add locking mechanism std::unordered_map definitions; std::unordered_map admins; - std::unordered_multimap managedPolicies; + std::unordered_map managedPolicies; }; } // namespace policy diff --git a/src/vist/policy/core/tests/core-tests.cpp b/src/vist/policy/core/tests/core-tests.cpp index 46afc70..4a30c19 100644 --- a/src/vist/policy/core/tests/core-tests.cpp +++ b/src/vist/policy/core/tests/core-tests.cpp @@ -32,21 +32,21 @@ TEST_F(PolicyCoreTests, policy_loader) { TEST_F(PolicyCoreTests, policy_set_get) { auto& manager = PolicyManager::Instance(); - manager.enroll("testAdmin", 0); - manager.set("bluetooth", PolicyValue(5), "testAdmin", 0); + manager.enroll("testAdmin"); + manager.set("bluetooth", PolicyValue(5), "testAdmin"); - auto policy = manager.get("bluetooth", 0); + auto policy = manager.get("bluetooth"); EXPECT_EQ(policy.value, 5); - manager.enroll("testAdmin1", 0); - manager.set("bluetooth", PolicyValue(10), "testAdmin1", 0); + manager.enroll("testAdmin1"); + manager.set("bluetooth", PolicyValue(10), "testAdmin1"); /// Manager should return the strongest policy. - policy = manager.get("bluetooth", 0); + policy = manager.get("bluetooth"); EXPECT_EQ(policy.value, 5); - manager.disenroll("testAdmin", 0); - manager.disenroll("testAdmin1", 0); + manager.disenroll("testAdmin"); + manager.disenroll("testAdmin1"); } } // namespace policy diff --git a/src/vist/policy/core/tests/storage-tests.cpp b/src/vist/policy/core/tests/storage-tests.cpp index 5249395..1fd0579 100644 --- a/src/vist/policy/core/tests/storage-tests.cpp +++ b/src/vist/policy/core/tests/storage-tests.cpp @@ -24,12 +24,13 @@ using namespace vist::policy; class PolicyStorageTests : public testing::Test { public: - void SetUp() override { - /// TODO(Sangwan KWon): Change to test db + void SetUp() override + { this->storage = std::make_shared(DB_PATH); } - std::shared_ptr getStorage() { + std::shared_ptr getStorage() + { return this->storage; } @@ -37,7 +38,8 @@ private: std::shared_ptr storage = nullptr; }; -TEST_F(PolicyStorageTests, initialize) { +TEST_F(PolicyStorageTests, initialize) +{ bool isRaised = false; try { @@ -50,35 +52,37 @@ TEST_F(PolicyStorageTests, initialize) { EXPECT_FALSE(isRaised); } -TEST_F(PolicyStorageTests, enrollment) { +TEST_F(PolicyStorageTests, enrollment) +{ auto storage = getStorage(); EXPECT_FALSE(storage->isActivated()); - storage->enroll("testAdmin", 0); - storage->enroll("testAdmin", 1); + storage->enroll("testAdmin0"); + storage->enroll("testAdmin1"); EXPECT_TRUE(storage->isActivated()); - storage->disenroll("testAdmin", 0); + storage->disenroll("testAdmin0"); EXPECT_TRUE(storage->isActivated()); - storage->disenroll("testAdmin", 1); + storage->disenroll("testAdmin1"); EXPECT_FALSE(storage->isActivated()); } -TEST_F(PolicyStorageTests, update) { +TEST_F(PolicyStorageTests, update) +{ auto storage = getStorage(); - storage->enroll("testAdmin", 0); + storage->enroll("testAdmin"); bool isRaised = false; try { - storage->update("testAdmin", 1, "bluetooth", PolicyValue(0)); + storage->update("fakeAdmin", "bluetooth", PolicyValue(0)); } catch (const std::exception&) { isRaised = true; } isRaised = false; try { - storage->update("testAdmin", 0, "bluetooth", PolicyValue(0)); + storage->update("testAdmin", "bluetooth", PolicyValue(0)); } catch (const std::exception&) { isRaised = true; } @@ -86,77 +90,70 @@ TEST_F(PolicyStorageTests, update) { isRaised = false; try { - storage->update("testAdmin", 0, "FakePolicy", PolicyValue(0)); + storage->update("testAdmin", "FakePolicy", PolicyValue(0)); } catch (const std::exception&) { isRaised = true; } EXPECT_TRUE(isRaised); - storage->disenroll("testAdmin", 0); + storage->disenroll("testAdmin"); } -TEST_F(PolicyStorageTests, strictest) { +TEST_F(PolicyStorageTests, strictest) +{ auto storage = getStorage(); - storage->enroll("testAdmin", 0); - storage->enroll("testAdmin", 1); + storage->enroll("testAdmin0"); + storage->enroll("testAdmin1"); - storage->update("testAdmin", 0, "bluetooth", PolicyValue(3)); - storage->update("testAdmin", 1, "bluetooth", PolicyValue(6)); + storage->update("testAdmin0", "bluetooth", PolicyValue(3)); + storage->update("testAdmin1", "bluetooth", PolicyValue(6)); bool isRaised = false; try { - auto value = storage->strictest("FakePolicy", 3); + auto value = storage->strictest("FakePolicy"); } catch (const std::exception&) { isRaised = true; } EXPECT_TRUE(isRaised); - /// as global policy auto policy = storage->strictest("bluetooth"); EXPECT_EQ(policy.value, 3); - /// as domain policy - policy = storage->strictest("bluetooth", 1); - EXPECT_EQ(policy.value, 6); - - storage->disenroll("testAdmin", 0); - storage->disenroll("testAdmin", 1); + storage->disenroll("testAdmin0"); + storage->disenroll("testAdmin1"); } -TEST_F(PolicyStorageTests, strictest_all) { +TEST_F(PolicyStorageTests, strictest_all) +{ auto storage = getStorage(); - storage->enroll("testAdmin", 1); + storage->enroll("testAdmin"); - /// as global policy auto policies = storage->strictest(); EXPECT_TRUE(policies.size() > 0); - /// as domain policy - policies = storage->strictest(1); - EXPECT_TRUE(policies.size() > 0); - - storage->disenroll("testAdmin", 1); + storage->disenroll("testAdmin"); } -TEST_F(PolicyStorageTests, admin_list) { +TEST_F(PolicyStorageTests, admin_list) +{ auto storage = getStorage(); auto admins = storage->getAdmins(); EXPECT_EQ(admins.size(), 0); - storage->enroll("testAdmin", 1); + storage->enroll("testAdmin1"); admins = storage->getAdmins(); EXPECT_EQ(admins.size(), 1); - storage->enroll("testAdmin", 2); + storage->enroll("testAdmin2"); admins = storage->getAdmins(); EXPECT_EQ(admins.size(), 2); - storage->disenroll("testAdmin", 2); + storage->disenroll("testAdmin2"); admins = storage->getAdmins(); EXPECT_EQ(admins.size(), 1); - storage->disenroll("testAdmin", 1); + storage->disenroll("testAdmin1"); admins = storage->getAdmins(); EXPECT_EQ(admins.size(), 0); } diff --git a/src/vist/policy/sdk/domain-policy.h b/src/vist/policy/sdk/domain-policy.h deleted file mode 100644 index 6992f8c..0000000 --- a/src/vist/policy/sdk/domain-policy.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -#pragma once - -#include "policy-model.h" - -#include -#include -#include - -#include - -namespace vist { -namespace policy { - -class DomainPolicy : public PolicyModel { -public: - explicit DomainPolicy(std::string name, PolicyValue initial) noexcept : - PolicyModel(std::move(name), std::move(initial)) {} - virtual ~DomainPolicy() = default; - - DomainPolicy(DomainPolicy&&) = default; - DomainPolicy& operator=(DomainPolicy&&) = default; - - inline void set(uid_t domain, const PolicyValue& value) { - current[domain] = value; - - try { - this->onChanged(domain, value); - } catch (const std::exception& e) { - current.erase(domain); - std::rethrow_exception(std::current_exception()); - } - } - - inline const PolicyValue& get(uid_t domain) const { - if (!current.count(domain)) - throw std::runtime_error("Policy value should be set once before use."); - - return current.at(domain); - } - - virtual void onChanged(uid_t domain, const PolicyValue& value) = 0; - -private: - std::unordered_map current; -}; - -} // namespace policy -} // namespace vist diff --git a/src/vist/policy/sdk/global-policy.h b/src/vist/policy/sdk/global-policy.h deleted file mode 100644 index 88d94c9..0000000 --- a/src/vist/policy/sdk/global-policy.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -#pragma once - -#include "policy-model.h" - -#include -#include - -namespace vist { -namespace policy { - -class GlobalPolicy : public PolicyModel { -public: - explicit GlobalPolicy(std::string name, PolicyValue initial) noexcept : - PolicyModel(std::move(name), std::move(initial)) {} - virtual ~GlobalPolicy() = default; - - GlobalPolicy(GlobalPolicy&&) = default; - GlobalPolicy& operator=(GlobalPolicy&&) = default; - - inline void set(const PolicyValue& value) { - current = value; - ready = true; - - try { - this->onChanged(value); - } catch (const std::exception& e) { - ready = false; - std::rethrow_exception(std::current_exception()); - } - } - - inline const PolicyValue& get() const { - if (!ready) - throw std::runtime_error("Policy value should be set once before use."); - - return current; - } - - virtual void onChanged(const PolicyValue& value) = 0; - -private: - PolicyValue current; - bool ready = false; -}; - -} // namespace policy -} // namespace vist diff --git a/src/vist/policy/sdk/policy-model.h b/src/vist/policy/sdk/policy-model.h index 09df30a..8dd0392 100644 --- a/src/vist/policy/sdk/policy-model.h +++ b/src/vist/policy/sdk/policy-model.h @@ -16,9 +16,10 @@ #pragma once -#include"policy-value.h" +#include #include +#include namespace vist { namespace policy { @@ -35,12 +36,39 @@ public: PolicyModel(PolicyModel&&) = default; PolicyModel& operator=(PolicyModel&&) = default; + inline void set(const PolicyValue& value) + { + auto rollback = current; + current = value; + ready = true; + + try { + this->onChanged(value); + } catch (const std::exception& e) { + current = rollback; + ready = false; + std::rethrow_exception(std::current_exception()); + } + } + + inline const PolicyValue& get() const + { + if (!ready) + throw std::runtime_error("Policy value should be set once before use."); + + return current; + } + + virtual void onChanged(const PolicyValue& value) = 0; + const std::string& getName() const noexcept { return name; } const PolicyValue& getInitial() const noexcept { return initial; } protected: std::string name; PolicyValue initial; + PolicyValue current; + bool ready = false; }; } // namespace policy diff --git a/src/vist/policy/sdk/policy-provider.h b/src/vist/policy/sdk/policy-provider.h index 75a996a..ff79099 100644 --- a/src/vist/policy/sdk/policy-provider.h +++ b/src/vist/policy/sdk/policy-provider.h @@ -16,8 +16,7 @@ #pragma once -#include "domain-policy.h" -#include "global-policy.h" +#include #include #include @@ -33,27 +32,23 @@ public: explicit PolicyProvider(std::string name) noexcept : name(std::move(name)) {} virtual ~PolicyProvider() = default; - inline void add(const std::shared_ptr& policy) { - global[policy->getName()] = policy; - } - - inline void add(const std::shared_ptr& policy) { - domain[policy->getName()] = policy; + inline void add(const std::shared_ptr& policy) + { + policies[policy->getName()] = policy; } inline const std::string& getName() const noexcept { return name; } - static const std::string& getFactoryName() noexcept { + static const std::string& getFactoryName() noexcept + { static std::string name = "PolicyFactory"; return name; } - std::size_t gsize() { return global.size(); } - std::size_t dsize() { return domain.size(); } + inline std::size_t size() const noexcept { return policies.size(); } private: std::string name; - std::unordered_map> global; - std::unordered_map> domain; + std::unordered_map> policies; friend class PolicyManager; }; diff --git a/src/vist/policy/sdk/tests/sdk-tests.cpp b/src/vist/policy/sdk/tests/sdk-tests.cpp index b6fb906..656e29d 100644 --- a/src/vist/policy/sdk/tests/sdk-tests.cpp +++ b/src/vist/policy/sdk/tests/sdk-tests.cpp @@ -16,33 +16,42 @@ #include -#include "../domain-policy.h" -#include "../global-policy.h" +#include "../policy-model.h" #include "../policy-provider.h" #include namespace { int g_value = -1; - int d_value = -1; - uid_t d_uid = 0; } // anonymous namespace using namespace vist::policy; class PolicySDKTests : public testing::Test {}; -class TestGlobalPolicy : public GlobalPolicy { +class TestPolicyModel : public PolicyModel { public: - TestGlobalPolicy() : GlobalPolicy("test_policy", PolicyValue(1)) {} + TestPolicyModel() : PolicyModel("test_policy", PolicyValue(1)) {} - virtual void onChanged(const PolicyValue& value) { + virtual void onChanged(const PolicyValue& value) + { g_value = value; } }; -TEST_F(PolicySDKTests, global_policy) { - TestGlobalPolicy policy; +class TestPolicyModelFailed : public PolicyModel { +public: + TestPolicyModelFailed() : PolicyModel("test_policy_failed", PolicyValue(1)) {} + + virtual void onChanged(const PolicyValue& value) + { + throw std::runtime_error("Intended exception for test."); + } +}; + +TEST_F(PolicySDKTests, policy_model) +{ + TestPolicyModel policy; EXPECT_EQ(policy.getName(), "test_policy"); EXPECT_EQ(policy.getInitial(), 1); @@ -62,43 +71,28 @@ TEST_F(PolicySDKTests, global_policy) { EXPECT_EQ(3, policy.get()); } -class TestDomainPolicy : public DomainPolicy { -public: - TestDomainPolicy() : DomainPolicy("test_policy", PolicyValue(1)) {} - - virtual void onChanged(uid_t domain, const PolicyValue& value) { - d_uid = domain; - d_value = value; - } -}; +TEST_F(PolicySDKTests, policy_model_failed) +{ + TestPolicyModelFailed policy; -TEST_F(PolicySDKTests, domain_policy) { - TestDomainPolicy policy; - uid_t domain = 5001; - - EXPECT_EQ(policy.getName(), "test_policy"); + EXPECT_EQ(policy.getName(), "test_policy_failed"); EXPECT_EQ(policy.getInitial(), 1); - // Policy value should be set once before use - bool isRaised = false; + bool isRaised = true; try { - auto value = policy.get(domain); + policy.set(PolicyValue(3)); } catch (const std::exception&) { isRaised = true; } EXPECT_TRUE(isRaised); - - policy.set(domain, PolicyValue(3)); - EXPECT_EQ(d_uid, domain); - EXPECT_EQ(3, policy.get(domain)); } -TEST_F(PolicySDKTests, policy_provider) { +TEST_F(PolicySDKTests, policy_provider) +{ PolicyProvider provider("testProvider"); - provider.add(std::make_shared()); - provider.add(std::make_shared()); + provider.add(std::make_shared()); + provider.add(std::make_shared()); - EXPECT_EQ(1, provider.gsize()); - EXPECT_EQ(1, provider.dsize()); + EXPECT_EQ(2, provider.size()); } diff --git a/src/vist/service/tests/core-tests.cpp b/src/vist/service/tests/core-tests.cpp index 62edf79..f60e602 100644 --- a/src/vist/service/tests/core-tests.cpp +++ b/src/vist/service/tests/core-tests.cpp @@ -42,7 +42,7 @@ TEST_F(CoreTests, query_select) { TEST_F(CoreTests, query_update) { auto& manager = policy::PolicyManager::Instance(); - manager.enroll("admin", 0); + manager.enroll("admin"); std::string statement = "SELECT * FROM policy WHERE name = 'bluetooth'"; auto rows = Vist::Query(statement); @@ -57,5 +57,5 @@ TEST_F(CoreTests, query_update) { rows = Vist::Query(statement); EXPECT_EQ(rows[0]["value"], std::to_string(3)); - manager.disenroll("admin", 0); + manager.disenroll("admin"); }