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 <sangwan.kwon@samsung.com>
CREATE TABLE IF NOT EXISTS admin (
id INTEGER PRIMARY KEY AUTOINCREMENT,
pkg TEXT NOT NULL,
- uid INTEGER,
key TEXT,
removable INTEGER
);
CREATE TABLE IF NOT EXISTS policy_definition (
id INTEGER PRIMARY KEY AUTOINCREMENT,
- scope INTEGER,
name TEXT NOT NULL,
ivalue INTEGER
);
#include <bluetooth-api.h>
#include <bluetooth_internal.h>
-#include <vist/policy/sdk/global-policy.h>
+#include <vist/policy/sdk/policy-model.h>
#include <vist/policy/sdk/policy-provider.h>
#include <memory>
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
{
}
};
-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
{
}
};
-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
{
}
};
-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&) {}
};
#include <arpa/inet.h>
#include <wifi-manager.h>
-#include <vist/policy/sdk/global-policy.h>
+#include <vist/policy/sdk/policy-model.h>
#include <vist/policy/sdk/policy-provider.h>
#include <klay/dbus/connection.h>
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
{
}
};
-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
{
}
};
-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
{
}
};
-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
{
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")
return std::string();
}
-std::pair<std::string, int> 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
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));
}
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";
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";
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);
}
-DSCRIPT_INSTALL_DIR="${SCRIPT_INSTALL_DIR}")
ADD_SUBDIRECTORY(client)
-ADD_SUBDIRECTORY(common)
ADD_SUBDIRECTORY(notification)
ADD_SUBDIRECTORY(policy)
ADD_SUBDIRECTORY(service)
}
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);
}
#include <vist/policy/sdk/policy-value.h>
#include <string>
-#include <map>
#include <unordered_map>
+#include <vector>
namespace vist {
namespace policy {
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<std::string, int> GetAll();
+ static std::vector<std::string> GetAll();
};
};
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<std::string, int> API::Admin::GetAll()
+std::vector<std::string> API::Admin::GetAll()
{
return PolicyManager::Instance().getAdmins();
}
struct Admin {
int id = -1;
std::string pkg;
- int uid = -1;
std::string key;
int removable = -1;
};
struct PolicyDefinition {
int id = -1;
- int scope = -1;
std::string name;
int ivalue = -1;
};
/// 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;
}
}
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<std::string, PolicyValue> PolicyManager::getAll(uid_t uid)
+std::unordered_map<std::string, PolicyValue> PolicyManager::getAll()
{
- return storage.strictest(uid);
+ return storage.strictest();
}
-std::multimap<std::string, int> PolicyManager::getAdmins()
+std::vector<std::string> PolicyManager::getAdmins()
{
return storage.getAdmins();
}
#include "policy-storage.h"
#include <exception>
-#include <map>
#include <memory>
#include <string>
#include <unordered_map>
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<std::string, PolicyValue> 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<std::string, PolicyValue> getAll();
- std::multimap<std::string, int> getAdmins();
+ std::vector<std::string> getAdmins();
private:
explicit PolicyManager();
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));
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
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));
}
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));
}
}
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);
}
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<int>(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);
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<int>(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);
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);
if (managedPolicies.size() == 0)
return PolicyValue(definitions[policy].ivalue);
- std::shared_ptr<PolicyValue> strictest = nullptr;
+ std::shared_ptr<PolicyValue> 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<int>(uid))
- continue;
- }
-
int value = iter->second.value;
- if (strictest == nullptr)
- strictest = std::make_shared<PolicyValue>(value);
+ if (strictestPtr == nullptr)
+ strictestPtr = std::make_shared<PolicyValue>(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<std::string, PolicyValue> PolicyStorage::strictest(uid_t uid)
+std::unordered_map<std::string, PolicyValue> PolicyStorage::strictest()
{
std::unordered_map<std::string, PolicyValue> 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));
}
return policies;
}
-std::multimap<std::string, int> PolicyStorage::getAdmins()
+std::vector<std::string> PolicyStorage::getAdmins()
{
- std::multimap<std::string, int> admins;
+ std::vector<std::string> 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
#include "db-schema.h"
-#include <map>
#include <memory>
#include <unordered_map>
#include <vector>
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<std::string, PolicyValue> strictest(uid_t uid = 0);
+ std::unordered_map<std::string, PolicyValue> strictest();
- /// Admin name can be duplicated
- std::multimap<std::string, int> getAdmins();
+ std::vector<std::string> 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<klay::database::Connection> database;
/// TODO(Sangwan): add locking mechanism
std::unordered_map<std::string, PolicyDefinition> definitions;
std::unordered_map<std::string, Admin> admins;
- std::unordered_multimap<int, ManagedPolicy> managedPolicies;
+ std::unordered_map<int, ManagedPolicy> managedPolicies;
};
} // namespace policy
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
class PolicyStorageTests : public testing::Test {
public:
- void SetUp() override {
- /// TODO(Sangwan KWon): Change to test db
+ void SetUp() override
+ {
this->storage = std::make_shared<PolicyStorage>(DB_PATH);
}
- std::shared_ptr<PolicyStorage> getStorage() {
+ std::shared_ptr<PolicyStorage> getStorage()
+ {
return this->storage;
}
std::shared_ptr<PolicyStorage> storage = nullptr;
};
-TEST_F(PolicyStorageTests, initialize) {
+TEST_F(PolicyStorageTests, initialize)
+{
bool isRaised = false;
try {
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;
}
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);
}
+++ /dev/null
-/*
- * 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 <exception>
-#include <string>
-#include <unordered_map>
-
-#include <sys/types.h>
-
-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<uid_t, PolicyValue> current;
-};
-
-} // namespace policy
-} // namespace vist
+++ /dev/null
-/*
- * 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 <stdexcept>
-#include <string>
-
-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
#pragma once
-#include"policy-value.h"
+#include <vist/policy/sdk/policy-value.h>
#include <string>
+#include <stdexcept>
namespace vist {
namespace policy {
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
#pragma once
-#include "domain-policy.h"
-#include "global-policy.h"
+#include <vist/policy/sdk/policy-model.h>
#include <cstddef>
#include <memory>
explicit PolicyProvider(std::string name) noexcept : name(std::move(name)) {}
virtual ~PolicyProvider() = default;
- inline void add(const std::shared_ptr<GlobalPolicy>& policy) {
- global[policy->getName()] = policy;
- }
-
- inline void add(const std::shared_ptr<DomainPolicy>& policy) {
- domain[policy->getName()] = policy;
+ inline void add(const std::shared_ptr<PolicyModel>& 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<std::string, std::shared_ptr<GlobalPolicy>> global;
- std::unordered_map<std::string, std::shared_ptr<DomainPolicy>> domain;
+ std::unordered_map<std::string, std::shared_ptr<PolicyModel>> policies;
friend class PolicyManager;
};
#include <gtest/gtest.h>
-#include "../domain-policy.h"
-#include "../global-policy.h"
+#include "../policy-model.h"
#include "../policy-provider.h"
#include <exception>
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);
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<TestGlobalPolicy>());
- provider.add(std::make_shared<TestDomainPolicy>());
+ provider.add(std::make_shared<TestPolicyModel>());
+ provider.add(std::make_shared<TestPolicyModelFailed>());
- EXPECT_EQ(1, provider.gsize());
- EXPECT_EQ(1, provider.dsize());
+ EXPECT_EQ(2, provider.size());
}
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);
rows = Vist::Query(statement);
EXPECT_EQ(rows[0]["value"], std::to_string(3));
- manager.disenroll("admin", 0);
+ manager.disenroll("admin");
}