Rework PrivilegeDb interface for setting application privileges 78/23678/3
authorRafal Krypa <r.krypa@samsung.com>
Tue, 1 Jul 2014 09:39:20 +0000 (11:39 +0200)
committerRafal Krypa <r.krypa@samsung.com>
Tue, 1 Jul 2014 13:00:49 +0000 (15:00 +0200)
While integrating installer code with PrivilegeDb, the existing method for
setting privileges was found to be inadequate. It also would need further
complication to actually do what it was supposed to do.
New UpdateAppPrivileges() method now only updates privileges for application.
To calculate which privileges were added and which removed for the package,
installer will use GetPkgPrivileges() twice: before and after calling
UpdateAppPrivileges(). All three method calls must be done inside transaction.

Change-Id: Ib7e1b8a6b1482c6dcd8b7146c48187797e237bd5
Signed-off-by: Rafal Krypa <r.krypa@samsung.com>
src/server/db/db.sql
src/server/db/include/privilege_db.h
src/server/db/privilege_db.cpp

index d7c6186..cd72162 100644 (file)
@@ -69,11 +69,10 @@ DROP TRIGGER IF EXISTS app_privilege_view_insert_trigger;
 CREATE TRIGGER app_privilege_view_insert_trigger
 INSTEAD OF INSERT ON app_privilege_view
 BEGIN
-       INSERT OR IGNORE INTO pkg(name) VALUES (NEW.pkg_name);
        INSERT OR IGNORE INTO privilege(name) VALUES (NEW.privilege_name);
-       INSERT OR IGNORE INTO app(pkg_id, name) VALUES ((SELECT pkg_id FROM pkg WHERE name=NEW.pkg_name), NEW.app_name);
        INSERT OR IGNORE INTO app_privilege(app_id, privilege_id) VALUES
-               ((SELECT app_id FROM app WHERE name=NEW.app_name), (SELECT privilege_id FROM privilege WHERE name=NEW.privilege_name));
+               ((SELECT app_id FROM app WHERE name=NEW.app_name),
+                (SELECT privilege_id FROM privilege WHERE name=NEW.privilege_name));
 END;
 
 DROP TRIGGER IF EXISTS app_privilege_view_delete_trigger;
index 627c1b6..941380f 100644 (file)
@@ -62,8 +62,8 @@ private:
         { QueryType::EGetPkgPrivileges, "SELECT privilege_name FROM app_privilege_view WHERE pkg_name=?"},
         { QueryType::EAddApplication, "INSERT INTO app_pkg_view (app_name, pkg_name) VALUES (?, ?)" },
         { QueryType::ERemoveApplication, "DELETE FROM app_pkg_view WHERE app_name=? AND pkg_name=?" },
-        { QueryType::EAddAppPrivileges, "INSERT INTO app_privilege_view (app_name, pkg_name, privilege_name) VALUES (?, ?, ?)" },
-        { QueryType::ERemoveAppPrivileges, "DELETE FROM app_privilege_view WHERE app_name=? AND pkg_name=? AND privilege_name=?" },
+        { QueryType::EAddAppPrivileges, "INSERT INTO app_privilege_view (app_name, privilege_name) VALUES (?, ?)" },
+        { QueryType::ERemoveAppPrivileges, "DELETE FROM app_privilege_view WHERE app_name=?" },
         { QueryType::EPkgIdExists, "SELECT * FROM pkg WHERE name=?" }
     };
 
@@ -77,17 +77,6 @@ private:
      */
     bool PkgIdExists(const std::string &pkgId);
 
-    /**
-     * Check if there's a tuple of (appId, packageId) inside the database
-     *
-     * @param appId - application identifier
-     * @param pkgId - package identifier
-     * @param[out] currentPrivileges - list of current privileges assigned to tuple (appId, pkgId)
-     * @exception DB::SqlConnection::Exception::InternalError on internal error
-     */
-    void GetPkgPrivileges(const std::string &pkgId,
-            TPrivilegesList &currentPrivileges);
-
 public:
     class Exception
     {
@@ -127,6 +116,16 @@ public:
     void RollbackTransaction(void);
 
     /**
+     * Retrieve list of privileges assigned to a pkgId
+     *
+     * @param pkgId - package identifier
+     * @param[out] currentPrivileges - list of current privileges assigned to pkgId
+     * @exception DB::SqlConnection::Exception::InternalError on internal error
+     */
+    void GetPkgPrivileges(const std::string &pkgId,
+            TPrivilegesList &currentPrivilege);
+
+    /**
      * Add an application into the database
      *
      * @param appId - application identifier
@@ -149,19 +148,23 @@ public:
             bool &pkgIdIsNoMore);
 
     /**
-     * Update privileges belonging to tuple (appId, pkgId)
+     * Remove privileges assigned to application
+     *
+     * @param appId - application identifier
+     * @exception DB::SqlConnection::Exception::InternalError on internal error
+     */
+    void RemoveAppPrivileges(const std::string &appId);
+
+    /**
+     * Update privileges assigned to application
+     * To assure data integrity this method must be called inside db transaction.
      *
      * @param appId - application identifier
-     * @param pkgId - package identifier
      * @param privileges - list of privileges to assign
-     * @param[out] addedPrivileges - return list of added privileges
-     * @param[out] removedPrivileges - return list of removed privileges
      * @exception DB::SqlConnection::Exception::InternalError on internal error
      */
-    void UpdatePrivileges(const std::string &appId,
-            const std::string &pkgId, const TPrivilegesList &privileges,
-            TPrivilegesList &addedPrivileges,
-            TPrivilegesList &removedPrivileges);
+    void UpdateAppPrivileges(const std::string &appId,
+            const TPrivilegesList &privileges);
 
 };
 
index ff86d50..0b9335d 100644 (file)
@@ -28,7 +28,6 @@
  */
 
 #include <cstdio>
-#include <set>
 #include <list>
 #include <string>
 #include <iostream>
@@ -36,8 +35,6 @@
 #include <dpl/log/log.h>
 #include "privilege_db.h"
 
-#define SET_CONTAINS(set,value) set.find(value)!=set.end()
-
 namespace SecurityManager {
 
 /* Common code for handling SqlConnection exceptions */
@@ -177,70 +174,31 @@ void PrivilegeDb::GetPkgPrivileges(const std::string &pkgId,
     });
 }
 
-void PrivilegeDb::UpdatePrivileges(const std::string &appId,
-        const std::string &pkgId, const TPrivilegesList &privileges,
-        TPrivilegesList &addedPrivileges,
-        TPrivilegesList &removedPrivileges)
+void PrivilegeDb::RemoveAppPrivileges(const std::string &appId)
 {
     try_catch<void>([&] {
-        DB::SqlConnection::DataCommandAutoPtr command;
-        TPrivilegesList curPrivileges = TPrivilegesList();
-        GetPkgPrivileges(pkgId, curPrivileges);
-
-        //Data compilation
-        std::set<std::string> privilegesSet = std::set<
-                std::string>(privileges.begin(), privileges.end());
-        std::set<std::string> curPrivilegesSet = std::set<
-                std::string>(curPrivileges.begin(), curPrivileges.end());
-
-        std::list < std::string > tmpPrivileges = std::list < std::string
-                > (privileges.begin(), privileges.end());
-        tmpPrivileges.merge (std::list < std::string
-                >(curPrivileges.begin(), curPrivileges.end()));
-        tmpPrivileges.unique ();
-
-        for (auto privilege : tmpPrivileges) {
-            if ((SET_CONTAINS(privilegesSet, privilege)) && !(SET_CONTAINS(curPrivilegesSet, privilege))) {
-                addedPrivileges.push_back(privilege);
-            }
-            if (!(SET_CONTAINS(privilegesSet, privilege)) && (SET_CONTAINS(curPrivilegesSet, privilege))) {
-                removedPrivileges.push_back(privilege);
-            }
+        DB::SqlConnection::DataCommandAutoPtr command =
+            mSqlConnection->PrepareDataCommand(Queries.at(QueryType::ERemoveAppPrivileges));
 
-        }
+        command->BindString(1, appId.c_str());
+        command->Step();
+    });
+}
 
-        //adding missing privileges
-        for (auto addedPrivilege : addedPrivileges) {
-            command = mSqlConnection->PrepareDataCommand(
-                    Queries.at(QueryType::EAddAppPrivileges));
-            command->BindString(1, appId.c_str());
-            command->BindString(2, pkgId.c_str());
-            command->BindString(3, addedPrivilege.c_str());
+void PrivilegeDb::UpdateAppPrivileges(const std::string &appId,
+        const TPrivilegesList &privileges)
+{
+    try_catch<void>([&] {
+        DB::SqlConnection::DataCommandAutoPtr command =
+            mSqlConnection->PrepareDataCommand(Queries.at(QueryType::EAddAppPrivileges));
+        command->BindString(1, appId.c_str());
 
-            if (command->Step())
-                LogPedantic("Unexpected SQLITE_ROW answer to query: " <<
-                        Queries.at(QueryType::EAddAppPrivileges));
+        RemoveAppPrivileges(appId);
 
+        for (const auto &privilege : privileges) {
+            command->BindString(2, privilege.c_str());
+            command->Step();
             command->Reset();
-            LogPedantic(
-                    "Added appId: " << appId << ", pkgId: " << pkgId << ", privilege: " << addedPrivilege);
-
-        }
-
-        //removing unwanted privileges
-        for (auto removedPrivilege : removedPrivileges) {
-            command = mSqlConnection->PrepareDataCommand(
-                    Queries.at(QueryType::ERemoveAppPrivileges));
-            command->BindString(1, appId.c_str());
-            command->BindString(2, pkgId.c_str());
-            command->BindString(3, removedPrivilege.c_str());
-
-            if (command->Step())
-                LogPedantic("Unexpected SQLITE_ROW answer to query: " <<
-                        Queries.at(QueryType::EAddAppPrivileges));
-
-            LogPedantic(
-                    "Removed appId: " << appId << ", pkgId: " << pkgId << ", privilege: " << removedPrivilege);
         }
     });
 }