API for policy management in JSON format
authorAndrey Zabolotnyi <a.zabolotnyi@samsung.com>
Fri, 28 Apr 2017 10:28:33 +0000 (13:28 +0300)
committerAndrey Zabolotnyi <a.zabolotnyi@samsung.com>
Fri, 28 Apr 2017 10:28:33 +0000 (13:28 +0300)
network-manager/nmlib/CMakeLists.txt
network-manager/nmlib/json_policy/.gitignore [new file with mode: 0644]
network-manager/nmlib/json_policy/inc/json_policy.h [new file with mode: 0644]
network-manager/nmlib/json_policy/src/json_policy.cpp [new file with mode: 0644]
network-manager/test/CMakeLists.txt
network-manager/test/test_json.cpp [new file with mode: 0644]

index d8b74ab..25ff013 100644 (file)
@@ -10,6 +10,7 @@ include_directories(
        ctrl_app/inc
        easy-setup/inc
        easy-setup/enrollee/inc
+       json_policy/inc
 )
 
 add_subdirectory(easy-setup/enrollee)
@@ -19,6 +20,7 @@ add_subdirectory(easy-setup/mediator/richsdk)
 FILE(GLOB CTRL_APP_SUPPORT_SRCS ctrl_app/src/*.cpp)
 
 FILE(GLOB IOT_SRC IoT/src/*.cpp IoT/src/*.c)
+FILE(GLOB JSON_POLICY_SRC json_policy/src/*.cpp)
 
 if(NOT "${FLAVOR}" STREQUAL "UBUNTU")
        FILE(GLOB DPM_SRCS dpm/src/*.cpp)
@@ -29,6 +31,7 @@ SET( LIB_SOURCES
        ${DPM_SRCS}
     ${CTRL_APP_SUPPORT_SRCS}
        ${IOT_SRC}
+       ${JSON_POLICY_SRC}
 )
 
 add_library(${PROJECT_NAME} SHARED ${LIB_SOURCES})
diff --git a/network-manager/nmlib/json_policy/.gitignore b/network-manager/nmlib/json_policy/.gitignore
new file mode 100644 (file)
index 0000000..b4b939f
--- /dev/null
@@ -0,0 +1,4 @@
+Release
+.cproject
+.project
+
diff --git a/network-manager/nmlib/json_policy/inc/json_policy.h b/network-manager/nmlib/json_policy/inc/json_policy.h
new file mode 100644 (file)
index 0000000..b4b4217
--- /dev/null
@@ -0,0 +1,222 @@
+#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> &params_,
+                                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> &params_) :
+                                        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> &params_);
+
+       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);
+};
diff --git a/network-manager/nmlib/json_policy/src/json_policy.cpp b/network-manager/nmlib/json_policy/src/json_policy.cpp
new file mode 100644 (file)
index 0000000..59fac2c
--- /dev/null
@@ -0,0 +1,416 @@
+#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> &params_,
+                                                  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> &params_):
+                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();
+       }
+}
index 79f223f..1749265 100644 (file)
@@ -5,6 +5,7 @@ project(${ProjectId})
 include_directories (
     ${NETWORK_MANAGER_LIB}/IoT/inc
     ${NETWORK_MANAGER_LIB}/REST/inc
+    ${NETWORK_MANAGER_LIB}/json_policy/inc
        ${NETWORK_MANAGER_LIB}/include
        ${NETWORK_MANAGER_LIB}/easy-setup/inc
        ${NETWORK_MANAGER_LIB}/easy-setup/enrollee/inc
diff --git a/network-manager/test/test_json.cpp b/network-manager/test/test_json.cpp
new file mode 100644 (file)
index 0000000..d844be6
--- /dev/null
@@ -0,0 +1,80 @@
+#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();
+       }
+}