--- /dev/null
+#include <string>
+#include <vector>
+
+using namespace std;
+
+class PolicyExeption : public exception
+{
+ const string desc; // description of the error
+public:
+ PolicyExeption(const char *s) : desc(s) {}
+ virtual const char* what() const throw() {return desc.c_str();}
+ virtual ~PolicyExeption() throw() {}
+};
+
+class Policy
+{
+protected:
+ Policy(){}
+ Policy(string name) : policy_name(name) {}
+public:
+ // type of JSON request
+ enum Type
+ {
+ POLICY_UPDATE, // a request to change some policy
+ POLICY_GET, // a request for state of policy
+ POLICY_STATE, // a respond to GET_POLICY request
+ POLICY_REPORT, // a report that policy was changed
+ };
+
+ // actions for CHANGE_POLICY request
+ enum Action : int
+ {
+ RESTRICT = 0, // restrict access to something
+ ALLOW = 1, // allow access to something
+ ADD = 2, // add record to the blacklist
+ REMOVE = 3 // remove record to the blacklist
+ };
+
+ string policy_name; // name of policy
+
+ /**
+ * @brief
+ * @param json [in] a string contains JSON file
+ * @return
+ */
+ static Type GetType(string &json);
+};
+
+class PolicyGet : public Policy
+{
+protected:
+ PolicyGet(){}
+public:
+ /**
+ * @brief parse json file
+ * @param json [in] a string contains JSON file
+ * @return
+ */
+ PolicyGet(string &json);
+ /**
+ * @brief construct request to get policy state
+ * @param name [in] policy name
+ * @param json [out] a string contains JSON file
+ * @return
+ */
+ PolicyGet(string name, string &json);
+};
+
+class PolicyState : public Policy
+{
+protected:
+ PolicyState(){}
+public:
+ vector<string> state; // state of policy
+
+ /**
+ * @brief parse json file
+ * @param json [in] a string contains JSON file
+ * @return
+ */
+ PolicyState(string &json);
+ /**
+ * @brief Construct report of policy state.
+ * Use it if policy has a single state
+ * @param name [in] policy name
+ * @param state [in] policy state
+ * @param json [out] a string contains JSON file
+ * @return
+ */
+ PolicyState(string name, string state, string &json);
+ /**
+ * @brief Construct report of policy states.
+ * Use it if policy has a multiply states (like a blacklist)
+ * @param name [in] policy name
+ * @param state [in] policy states
+ * @param json [out] a string contains JSON file
+ * @return
+ */
+ PolicyState(string name, vector<string> &state, string &json);
+protected:
+ void init(string name, string &json);
+};
+
+class PolicyUpdate : public Policy
+{
+protected:
+ PolicyUpdate() : action(RESTRICT) {}
+public:
+ string sender; // The entity who sends the request
+ Action action; // what to do
+ vector<string> params; // additional parameters (optionally)
+
+ /**
+ * @brief parse json file
+ * @param json [in] a string contains JSON file
+ * @return
+ */
+ PolicyUpdate(string &json);
+
+ /**
+ * @brief Construct request for update policy
+ * @param sender_ [in] The entity who sends the request
+ * @param name [in] policy name
+ * @param action_ [in] what to do
+ * @param params_ [in] parameters
+ * @param json [out] a string contains JSON file
+ * @return
+ */
+ PolicyUpdate(string sender_,
+ string name,
+ Action action_,
+ vector<string> ¶ms_,
+ string &json);
+
+ /**
+ * @brief Construct request for update policy
+ * @param sender_ [in] The entity who sends the request
+ * @param name [in] policy name
+ * @param action_ [in] what to do
+ * @param param_ [in] single parameter
+ * @param json [out] a string contains JSON file
+ * @return
+ */
+ PolicyUpdate(string sender_,
+ string name,
+ Action action_,
+ string param_,
+ string &json);
+
+ /**
+ * @brief common constructor
+ * @param sender_ [in] The entity who sends the request
+ * @param name [in] policy name
+ * @param action_ [in] what to do
+ * @param params_ [in] parameters
+ * @return
+ */
+ PolicyUpdate(string sender_,
+ string name,
+ Action action_,
+ vector<string> ¶ms_) :
+ Policy(name),
+ sender(sender_),
+ action(action_),
+ params(params_) {}
+
+protected:
+ void init(string &json);
+ void parse_json(string &json, size_t &pos);
+};
+
+class PolicyEnforcement : public PolicyUpdate
+{
+public:
+ string date_time; // when the policy was changed
+
+ /**
+ * @brief default constructor
+ * @return
+ */
+ PolicyEnforcement(){}
+
+ /**
+ * @brief common constructor
+ * @param date_time [in] when the policy was changed
+ * @param sender_ [in] The entity who sends the request
+ * @param name [in] policy name
+ * @param action_ [in] what to do
+ * @param params_ [in] parameters
+ * @return
+ */
+ PolicyEnforcement(string date_time,
+ string sender_,
+ string name,
+ Action action,
+ vector<string> ¶ms_);
+
+ string print();
+ void parse_json(string &json, size_t &pos);
+};
+
+class PolicyList : public Policy
+{
+ PolicyList(){}
+public:
+ vector<PolicyEnforcement> list; // a list of enforcements
+
+ /**
+ * @brief parse json file
+ * @param json [in] a string contains JSON file
+ * @return
+ */
+ PolicyList(string &json);
+
+ /**
+ * @brief Creates policy enforcement report, that contain the list of PolicyEnforcements
+ * @param list [in] a list of enforcements
+ * @param json [out] a string contains JSON file
+ * @return
+ */
+ PolicyList(vector<PolicyEnforcement> list_, string &json);
+};
--- /dev/null
+#include "json_policy.h"
+#include <sstream>
+#include <iostream>
+
+const char *action_str[] = {
+ "restrict",
+ "allow",
+ "add",
+ "remove",
+};
+
+const char *tag_not_found = "Tag not found";
+const char *wrong_json_format = "Wrong JSON format";
+
+void find_tag(string json, size_t &pos, const string tag)
+{
+ size_t x;
+ x = json.find(tag, pos);
+ if (x == string::npos) throw PolicyExeption(tag_not_found);
+ x = json.find(":", x);
+ if (x == string::npos) throw PolicyExeption(wrong_json_format);
+ pos = x;
+}
+
+string get_val(string json, size_t &pos, const string tag)
+{
+ size_t x, y;
+ x = json.find(tag, pos);
+ if (x == string::npos) throw PolicyExeption(wrong_json_format);
+ x = json.find(":", x);
+ if (x == string::npos) throw PolicyExeption(wrong_json_format);
+ x = json.find("\"", x) + 1;
+ if (x == string::npos) throw PolicyExeption(wrong_json_format);
+ y = json.find("\"", x);
+ if (y == string::npos) throw PolicyExeption(wrong_json_format);
+ pos = y + 1;
+ return json.substr(x, y - x);
+}
+
+void get_array(string json, size_t &pos, const string tag, vector<string> &arr)
+{
+ size_t x, x2;
+
+ arr.clear();
+ find_tag(json, pos, tag);
+ pos = json.find("[", pos);
+ x = pos;
+ while (1)
+ {
+ x = json.find_first_of("\"]", x);
+ if (x == string::npos) throw PolicyExeption(wrong_json_format);
+ if (json.at(x) == ']') break;
+ x++;
+ x2 = json.find_first_of('\"', x);
+ if (x2 == string::npos) throw PolicyExeption(wrong_json_format);
+ arr.push_back(json.substr(x, x2 - x));
+ x = x2 + 1;
+ }
+}
+
+Policy::Type Policy::GetType(string &json)
+{
+ size_t x1 = json.find("\"");
+ size_t x2 = json.find("\"", x1 + 1);
+ if (x1 != string::npos && x2 != string::npos)
+ {
+ ++x1;
+ string tag = json.substr(x1, x2 - x1);
+
+ if (tag == "update policy") return POLICY_UPDATE;
+ if (tag == "get policy") return POLICY_GET;
+ if (tag == "policy state") return POLICY_STATE;
+ if (tag == "policy enforcement report") return POLICY_REPORT;
+ }
+ throw PolicyExeption("Policy::GetType(): bad JSON format");
+ return POLICY_UPDATE;
+}
+
+
+// ##########################################################################
+// ##########################################################################
+// ##########################################################################
+
+PolicyGet::PolicyGet(string &json)
+{
+ size_t pos = 0;
+ find_tag(json, pos, "get policy");
+ policy_name = get_val(json, pos, "policy");
+}
+
+PolicyGet::PolicyGet(string name, string &json)
+{
+ stringstream ss;
+
+ policy_name = name;
+
+ ss << "}" << endl
+ << " \"get policy\" :" << endl
+ << " {" << endl
+ << " \"policy\" : " << "\"" << policy_name << "\"" << endl
+ << " }" << endl
+ << "}" << endl
+ ;
+
+ json = ss.str();
+}
+
+// ##########################################################################
+// ##########################################################################
+// ##########################################################################
+
+PolicyState::PolicyState(string &json)
+{
+ size_t pos = 0;
+ find_tag(json, pos, "policy state");
+ policy_name = get_val(json, pos, "policy");
+ get_array(json, pos, "state", state);
+}
+
+PolicyState::PolicyState(string name, string state, string &json)
+{
+ this->state.push_back(state);
+ init(name, json);
+}
+
+PolicyState::PolicyState(string name, vector<string> &state, string &json)
+{
+ this->state = state;
+ init(name, json);
+}
+
+void PolicyState::init(string name, string &json)
+{
+ stringstream ss;
+
+ policy_name = name;
+
+ ss << "}" << endl
+ << " \"policy state\" :" << endl
+ << " {" << endl
+ << " \"policy\" : " << "\"" << policy_name << "\"," << endl
+ << " \"state\" : [" ;
+ for(size_t i = 0; i < state.size(); ++i)
+ {
+ ss << (i ? " " : "") << "\"" << state[i] << "\"";
+ if (i == state.size() - 1)
+ ss << "]" << endl;
+ else
+ ss << "," << endl;
+ }
+
+ ss << " }" << endl
+ << "}" << endl
+ ;
+
+ json = ss.str();
+}
+
+// ##########################################################################
+// ##########################################################################
+// ##########################################################################
+
+PolicyUpdate::PolicyUpdate(string &json) : action(ALLOW)
+{
+ size_t pos = 0;
+ parse_json(json, pos);
+}
+
+void PolicyUpdate::parse_json(string &json, size_t &pos)
+{
+ find_tag(json, pos, "update policy");
+ sender = get_val(json, pos, "sender");
+ policy_name = get_val(json, pos, "policy");
+ string action_s = get_val(json, pos, "action");
+ if (action_str[0] == action_s) action = RESTRICT;
+ else if (action_str[1] == action_s) action = ALLOW;
+ else if (action_str[2] == action_s) action = ADD;
+ else if (action_str[3] == action_s) action = REMOVE;
+ get_array(json, pos, "params", params);
+}
+
+PolicyUpdate::PolicyUpdate(string sender_,
+ string name,
+ Action action_,
+ vector<string> ¶ms_,
+ string &json) :
+ Policy(name),
+ sender(sender_),
+ action(action_)
+{
+ params = params_;
+ init(json);
+}
+
+PolicyUpdate::PolicyUpdate(string sender_,
+ string name,
+ Action action_,
+ string params_,
+ string &json) :
+ Policy(name),
+ sender(sender_),
+ action(action_)
+{
+ params.push_back(params_);
+ init(json);
+}
+
+void PolicyUpdate::init(string &json)
+{
+ stringstream ss;
+
+ ss << "}" << endl
+ << " \"update policy\" :" << endl
+ << " {" << endl
+ << " \"sender\" : " << "\"" << sender << "\"," << endl
+ << " \"policy\" : " << "\"" << policy_name << "\"," << endl
+ << " \"action\" : " << "\"" << action_str[action] << "\"," << endl
+ << " \"params\" : [" ;
+ for(size_t i = 0; i < params.size(); ++i)
+ {
+ ss << (i ? " " : "") << "\"" << params[i] << "\"";
+ if (i == params.size() - 1)
+ ss << "]" << endl;
+ else
+ ss << "," << endl;
+ }
+
+ ss << " }" << endl
+ << "}" << endl
+ ;
+
+ json = ss.str();
+
+}
+
+// ##########################################################################
+// ##########################################################################
+// ##########################################################################
+
+PolicyEnforcement::PolicyEnforcement(string date_time,
+ string sender_,
+ string name,
+ Action action,
+ vector<string> ¶ms_):
+ PolicyUpdate(sender_, name, action, params_),
+ date_time(date_time)
+{
+
+}
+
+string PolicyEnforcement::print()
+{
+ stringstream ss;
+
+ ss << " \"policy enforcement\" :" << endl
+ << " {" << endl
+ << " \"time\" : " << "\"" << date_time << "\"," << endl
+ << " \"update policy\" :" << endl
+ << " {" << endl
+ << " \"sender\" : " << "\"" << sender << "\"," << endl
+ << " \"policy\" : " << "\"" << policy_name << "\"," << endl
+ << " \"action\" : " << "\"" << action_str[action] << "\"," << endl
+ << " \"params\" : [" ;
+ for(size_t i = 0; i < params.size(); ++i)
+ {
+ ss << (i ? " " : "") << "\"" << params[i] << "\"";
+ if (i == params.size() - 1)
+ ss << "]" << endl;
+ else
+ ss << "," << endl;
+ }
+
+ ss << " }" << endl
+ << " }"
+ ;
+
+ return ss.str();
+}
+
+void PolicyEnforcement::parse_json(string &json, size_t &pos)
+{
+ find_tag(json, pos, "policy enforcement");
+ date_time = get_val(json, pos, "time");
+ PolicyUpdate::parse_json(json, pos);
+}
+
+// ##########################################################################
+// ##########################################################################
+// ##########################################################################
+
+PolicyList::PolicyList(string &json)
+{
+ size_t pos = 0;
+ find_tag(json, pos, "policy enforcement report");
+ try
+ {
+ while (true)
+ {
+ PolicyEnforcement pe;
+ pe.parse_json(json, pos);
+ list.push_back(pe);
+ }
+ }
+ catch (PolicyExeption &e)
+ {
+ if (e.what() != string(tag_not_found)) throw e;
+ }
+}
+
+PolicyList::PolicyList(vector<PolicyEnforcement> list_, string &json) : list(list_)
+{
+ stringstream ss;
+
+ ss << "}" << endl
+ << " \"policy enforcement report\" :" << endl
+ << " [" << endl;
+ for(size_t i = 0; i < list.size(); ++i)
+ {
+ ss << list[i].print();
+ if (i == list.size() - 1)
+ ss << endl;
+ else
+ ss << "," << endl;
+ }
+
+ ss << " ]" << endl
+ << "}" << endl
+ ;
+
+ json = ss.str();
+}
+
+// ##########################################################################
+// ##########################################################################
+// ##########################################################################
+
+void json_test()
+{
+ try {
+
+ string json;
+ vector<string> v;
+ v.push_back("parameter 1");
+ v.push_back("parameter 2");
+ v.push_back("parameter 3");
+
+ PolicyUpdate pu("sender", "WiFi", Policy::RESTRICT, v, json);
+ cout << json << endl;
+
+ cout << "### parse ###\n";
+ PolicyUpdate pu2(json);
+ cout << pu2.sender << endl;
+ cout << pu2.policy_name << endl;
+ cout << pu2.action << endl;
+ for (size_t i = 0; i < pu2.params.size(); ++i)
+ cout << pu2.params[i] << endl;
+ cout << "#############\n\n\n";
+ json.erase();
+
+ PolicyGet pg("WiFi", json);
+ cout << json << endl;
+ cout << "### parse ###\n";
+ PolicyGet pg2(json);
+ cout << pg2.policy_name << endl;
+ cout << "#############\n\n\n";
+ json.erase();
+
+ PolicyState ps("bluetooth", v, json);
+ cout << json << endl;
+ cout << "### parse ###\n";
+ PolicyState ps2(json);
+ cout << ps2.policy_name << endl;
+ for (size_t i = 0; i < ps2.state.size(); ++i)
+ cout << ps2.state[i] << endl;
+ cout << "#############\n\n\n";
+ json.erase();
+
+ vector<PolicyEnforcement> vpe;
+ vpe.push_back(PolicyEnforcement("12/08/2017 17:32:56",
+ "some_agent_2",
+ "bluetooth_MAC_blacklist",
+ Policy::ADD,
+ v));
+ vpe.push_back(PolicyEnforcement("12/08/2017 18:23:07",
+ "some_agent_3",
+ "bluetooth_MAC_blacklist",
+ Policy::ADD,
+ v));
+ vpe.push_back(PolicyEnforcement("12/08/2017 06:25:33",
+ "some_agent_4",
+ "bluetooth_MAC_blacklist",
+ Policy::ADD,
+ v));
+ PolicyList pl(vpe, json);
+ cout << json << endl;
+ cout << "### parse ###\n";
+ PolicyList pl2(json);
+ for (size_t i = 0; i < pl2.list.size(); ++i)
+ {
+ PolicyEnforcement &pe = pl2.list[i];
+ cout << pe.date_time << endl;
+ cout << pe.sender << endl;
+ cout << pe.policy_name << endl;
+ cout << pe.action << endl;
+ for (size_t i = 0; i < ps2.state.size(); ++i)
+ cout << ps2.state[i] << endl;
+ }
+ cout << "#############\n\n\n";
+ json.erase();
+
+ }
+ catch (PolicyExeption &e)
+ {
+ cout << e.what();
+ }
+}
--- /dev/null
+#include <iostream>
+#include <gtest/gtest.h>
+#include <json_policy.h>
+#include <string>
+#include <stdexcept>
+
+using namespace std;
+
+void json_test()
+{
+ string json;
+ vector<string> v;
+ v.push_back("parameter 1");
+ v.push_back("parameter 2");
+ v.push_back("parameter 3");
+
+ PolicyUpdate pu("sender", "WiFi", Policy::RESTRICT, v, json);
+ PolicyUpdate pu2(json);
+ ASSERT_EQ(pu2.sender, "sender");
+ ASSERT_EQ(pu2.policy_name, "WiFi");
+ ASSERT_EQ(pu2.action, Policy::RESTRICT);
+ ASSERT_EQ(pu2.params[0], "parameter 1");
+ ASSERT_EQ(pu2.params[1], "parameter 2");
+ ASSERT_EQ(pu2.params[2], "parameter 3");
+ json.erase();
+
+ PolicyGet pg("Camera", json);
+ PolicyGet pg2(json);
+ ASSERT_EQ(pg2.policy_name, "Camera");
+ json.erase();
+
+ PolicyState ps("bluetooth", v, json);
+ PolicyState ps2(json);
+ ASSERT_EQ(ps2.policy_name, "bluetooth");
+ ASSERT_EQ(ps2.state[0], "parameter 1");
+ ASSERT_EQ(ps2.state[1], "parameter 2");
+ ASSERT_EQ(ps2.state[2], "parameter 3");
+ json.erase();
+
+ vector<PolicyEnforcement> vpe;
+ vpe.push_back(PolicyEnforcement("12/08/2017 17:32:56",
+ "some_agent_2",
+ "bluetooth_MAC_blacklist",
+ Policy::ADD,
+ v));
+ vpe.push_back(PolicyEnforcement("12/08/2017 18:23:07",
+ "some_agent_3",
+ "bluetooth_MAC_blacklist",
+ Policy::ADD,
+ v));
+ vpe.push_back(PolicyEnforcement("12/08/2017 06:25:33",
+ "some_agent_4",
+ "bluetooth_MAC_blacklist",
+ Policy::ADD,
+ v));
+ PolicyList pl(vpe, json);
+ PolicyList pl2(json);
+ for (size_t i = 0; i < pl2.list.size(); ++i)
+ {
+ PolicyEnforcement &pe = pl2.list[i];
+ ASSERT_EQ(pe.date_time, vpe[i].date_time);
+ ASSERT_EQ(pe.sender, vpe[i].sender);
+ ASSERT_EQ(pe.policy_name, vpe[i].policy_name);
+ ASSERT_EQ(pe.action, vpe[i].action);
+ ASSERT_EQ(pe.params[0], "parameter 1");
+ ASSERT_EQ(pe.params[1], "parameter 2");
+ ASSERT_EQ(pe.params[2], "parameter 3");
+ }
+ json.erase();
+}
+
+TEST(test_JSON, test)
+{
+ try {
+ json_test();
+ } catch (exception &e) {
+ cout << "Exception: " << e.what() << endl;
+ FAIL();
+ }
+}