diff options
author | Krzysztof Sasiak <k.sasiak@samsung.com> | 2014-06-06 16:11:08 +0200 |
---|---|---|
committer | Krzysztof Sasiak <k.sasiak@samsung.com> | 2014-06-27 22:38:10 +0200 |
commit | 664fec5054ca386f240e13c3d7846f65adae8777 (patch) | |
tree | 3ebebacabeae9f187f5f18b21d074d3920b99ccc /src/server/db | |
parent | dc1616e930b963b13c701c0571c841dd0eff911b (diff) | |
download | security-manager-664fec5054ca386f240e13c3d7846f65adae8777.tar.gz security-manager-664fec5054ca386f240e13c3d7846f65adae8777.tar.bz2 security-manager-664fec5054ca386f240e13c3d7846f65adae8777.zip |
Privilege database access implementation
Adding convenience methods for accessing privilege
database and performing queries on it.
Change-Id: I34d8986ec1315ce46f7f5bc462d746df81e7e432
Signed-off-by: Krzysztof Sasiak <k.sasiak@samsung.com>
Diffstat (limited to 'src/server/db')
-rw-r--r-- | src/server/db/include/privilege_db.h | 174 | ||||
-rw-r--r-- | src/server/db/privilege_db.cpp | 257 |
2 files changed, 431 insertions, 0 deletions
diff --git a/src/server/db/include/privilege_db.h b/src/server/db/include/privilege_db.h new file mode 100644 index 00000000..94f41f7a --- /dev/null +++ b/src/server/db/include/privilege_db.h @@ -0,0 +1,174 @@ +/* + * security-manager, database access + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Rafal Krypa <r.krypa@samsung.com> + * + * 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. + * + */ + +/* + * @file privilege_db.h + * @author Krzysztof Sasiak <k.sasiak@samsung.com> + * @version 1.0 + * @brief This file contains declaration of the API to privilges database. + */ + +#include <cstdio> +#include <list> +#include <map> +#include <stdbool.h> +#include <string> + +#include <dpl/db/sql_connection.h> + +#ifndef PRIVILEGE_DB_H_ +#define PRIVILEGE_DB_H_ + +namespace SecurityManager { + +typedef std::vector<std::string> TPermissionsList; + +enum class QueryType { + EGetPkgPermissions, + EAddApplication, + ERemoveApplication, + EAddAppPermissions, + ERemoveAppPermissions, + EPkgIdExists, +}; + +class PrivilegeDb { + /** + * PrivilegeDb database class + */ + +private: + SecurityManager::DB::SqlConnection *mSqlConnection; + const std::map<QueryType, const char * const > Queries = { + { QueryType::EGetPkgPermissions, "SELECT permission_name FROM app_permission_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::EAddAppPermissions, "INSERT INTO app_permission_view (app_name, pkg_name, permission_name) VALUES (?, ?, ?)" }, + { QueryType::ERemoveAppPermissions, "DELETE FROM app_permission_view WHERE app_name=? AND pkg_name=? AND permission_name=?" }, + { QueryType::EPkgIdExists, "SELECT * FROM pkg WHERE name=?" } + }; + + /** + * Check if pkgId is already registered in database + * + * @param pkgId - package identifier + * @exception DB::SqlConnection::Exception::InternalError on internal error + * @return true if pkgId exists in the database + * + */ + 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] currentPermissions - list of current permissions assigned to tuple (appId, pkgId) + * @exception DB::SqlConnection::Exception::InternalError on internal error + * @return true on success, false on failure + */ + bool GetPkgPermissions(const std::string &pkgId, + TPermissionsList ¤tPermission); + +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(SecurityManager::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, IOError) + DECLARE_EXCEPTION_TYPE(Base, InternalError) + }; + + /** + * Constructor + * @exception DB::SqlConnection::Exception::IOError on problems with database access + * + */ + PrivilegeDb(const std::string &path); + ~PrivilegeDb(void); + + /** + * Begin transaction + * @exception DB::SqlConnection::Exception::InternalError on internal error + * + */ + void BeginTransaction(void); + + /** + * Commit transaction + * @exception DB::SqlConnection::Exception::InternalError on internal error + * + */ + void CommitTransaction(void); + + /** + * Rollback transaction + * @exception DB::SqlConnection::Exception::InternalError on internal error + * + */ + void RollbackTransaction(void); + + /** + * Add an application into the database + * + * @param appId - application identifier + * @param pkgId - package identifier + * @param[out] pkgIdIsNew - return info if pkgId is new to the database + * @exception DB::SqlConnection::Exception::InternalError on internal error + * @return true on success, false on failure + */ + bool AddApplication(const std::string &appId, const std::string &pkgId, + bool &pkgIdIsNew); + + /** + * Remove an application from the database + * + * @param appId - application identifier + * @param pkgId - package identifier + * @param[out] pkgIdIsNoMore - return info if pkgId is in the database + * @exception DB::SqlConnection::Exception::InternalError on internal error + * @return true on success, false on failure + */ + bool RemoveApplication(const std::string &appId, const std::string &pkgId, + bool &pkgIdIsNoMore); + + /** + * Update permissions belonging to tuple (appId, pkgId) + * + * @param appId - application identifier + * @param pkgId - package identifier + * @param permissions - list of permissions to assign + * @param[out] addedPermissions - return list of added permissions + * @param[out] removedPermissions - return list of removed permissions + * @exception DB::SqlConnection::Exception::InternalError on internal error + * @return - true on success, false on failure + */ + bool UpdatePermissions(const std::string &appId, + const std::string &pkgId, const TPermissionsList &permissions, + TPermissionsList &addedPermissions, + TPermissionsList &removedPermissions); + +}; +} +; +//namespace SecurityManager + +#endif // PRIVILEGE_DB_H_ diff --git a/src/server/db/privilege_db.cpp b/src/server/db/privilege_db.cpp new file mode 100644 index 00000000..2fcad749 --- /dev/null +++ b/src/server/db/privilege_db.cpp @@ -0,0 +1,257 @@ +/* + * security-manager, database access + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Rafal Krypa <r.krypa@samsung.com> + * + * 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. + * + */ + +/* + * @file privilege_db.cpp + * @author Krzysztof Sasiak <k.sasiak@samsung.com> + * @version 0.1 + * @brief This file contains declaration of the API to privileges database. + */ + +#include <cstdio> +#include <set> +#include <list> +#include <string> +#include <iostream> + +#include <dpl/log/log.h> +#include "privilege_db.h" + +#define SET_CONTAINS(set,value) set.find(value)!=set.end() +#define CATCH_STANDARD_EXCEPTIONS \ + catch (DB::SqlConnection::Exception::SyntaxError &e) { \ + LogDebug("Syntax error in command: " << e.DumpToString()); \ + ThrowMsg(PrivilegeDb::Exception::InternalError, \ + "Syntax error in command: " << e.DumpToString()); \ + } catch (DB::SqlConnection::Exception::InternalError &e) { \ + LogDebug("Mysterious internal error in SqlConnection class" << e.DumpToString()); \ + ThrowMsg(PrivilegeDb::Exception::InternalError, \ + "Mysterious internal error in SqlConnection class: " << e.DumpToString()); \ + } + +namespace SecurityManager { + +PrivilegeDb::PrivilegeDb(const std::string &path) { + try { + mSqlConnection = new DB::SqlConnection(path, + DB::SqlConnection::Flag::None, + DB::SqlConnection::Flag::RW); + } catch (DB::SqlConnection::Exception::Base &e) { + LogError("Database initialization error: " << e.DumpToString()); + ThrowMsg(PrivilegeDb::Exception::IOError, + "Database initialization error:" << e.DumpToString()); + + }; +} + +PrivilegeDb::~PrivilegeDb() { + delete mSqlConnection; +} +; + +void PrivilegeDb::BeginTransaction(void) { + try { + mSqlConnection->BeginTransaction(); + }CATCH_STANDARD_EXCEPTIONS; +} + +void PrivilegeDb::CommitTransaction(void) { + try { + mSqlConnection->CommitTransaction(); + }CATCH_STANDARD_EXCEPTIONS; +} + +void PrivilegeDb::RollbackTransaction(void) { + try { + mSqlConnection->RollbackTransaction(); + }CATCH_STANDARD_EXCEPTIONS; +} + +bool PrivilegeDb::PkgIdExists(const std::string &pkgId) { + + try { + DB::SqlConnection::DataCommandAutoPtr command = + mSqlConnection->PrepareDataCommand( + Queries.at(QueryType::EPkgIdExists)); + command->BindString(1, pkgId.c_str()); + if (command->Step()) { + LogPedantic("PkgId: " << pkgId << " found in database"); + command->Reset(); + return true; + }; + + }CATCH_STANDARD_EXCEPTIONS; + + return false; +} + +bool PrivilegeDb::AddApplication(const std::string &appId, + const std::string &pkgId, bool &pkgIdIsNew) { + + pkgIdIsNew = !(this->PkgIdExists(pkgId)); + + try { + DB::SqlConnection::DataCommandAutoPtr command = + mSqlConnection->PrepareDataCommand( + Queries.at(QueryType::EAddApplication)); + + command->BindString(1, appId.c_str()); + command->BindString(2, pkgId.c_str()); + + if (command->Step()) { + LogPedantic("Unexpected SQLITE_ROW answer to query: " << + Queries.at(QueryType::EAddApplication)); + }; + + command->Reset(); + LogPedantic( "Added appId: " << appId << ", pkgId: " << pkgId); + + return true; + + }CATCH_STANDARD_EXCEPTIONS; + return false; + +} + +bool PrivilegeDb::RemoveApplication(const std::string &appId, + const std::string &pkgId, bool &pkgIdIsNoMore) { + + try { + DB::SqlConnection::DataCommandAutoPtr command = + mSqlConnection->PrepareDataCommand( + Queries.at(QueryType::ERemoveApplication)); + + command->BindString(1, appId.c_str()); + command->BindString(2, pkgId.c_str()); + + if (command->Step()) { + LogPedantic("Unexpected SQLITE_ROW answer to query: " << + Queries.at(QueryType::ERemoveApplication)); + }; + + command->Reset(); + LogPedantic( "Removed appId: " << appId << ", pkgId: " << pkgId); + + pkgIdIsNoMore = !(this->PkgIdExists(pkgId)); + + return true; + + }CATCH_STANDARD_EXCEPTIONS; + return false; + +} + +bool PrivilegeDb::GetPkgPermissions(const std::string &pkgId, + TPermissionsList ¤tPermissions) { + try { + DB::SqlConnection::DataCommandAutoPtr command = + mSqlConnection->PrepareDataCommand( + Queries.at(QueryType::EGetPkgPermissions)); + command->BindString(1, pkgId.c_str()); + + while (command->Step()) { + std::string permission = command->GetColumnString(0); + LogPedantic ("Got permission: "<< permission); + currentPermissions.push_back(permission); + }; + + return true; + }CATCH_STANDARD_EXCEPTIONS; + + return false; + +} + +bool PrivilegeDb::UpdatePermissions(const std::string &appId, + const std::string &pkgId, const TPermissionsList &permissions, + TPermissionsList &addedPermissions, + TPermissionsList &removedPermissions) { + + DB::SqlConnection::DataCommandAutoPtr command; + + TPermissionsList curPermissions = TPermissionsList(); + if (!this->GetPkgPermissions(pkgId, curPermissions)) + return false; + + try { + //Data compilation + std::set<std::string> permissionsSet = std::set< + std::string>(permissions.begin(), permissions.end()); + std::set<std::string> curPermissionsSet = std::set< + std::string>(curPermissions.begin(), curPermissions.end()); + + std::list < std::string > tmpPermissions = std::list < std::string + > (permissions.begin(), permissions.end()); + tmpPermissions.merge (std::list < std::string + >(curPermissions.begin(), curPermissions.end())); + tmpPermissions.unique (); + + for (auto permission : tmpPermissions) { + if ((SET_CONTAINS(permissionsSet, permission)) && !(SET_CONTAINS(curPermissionsSet, permission))) { + addedPermissions.push_back(permission); + } + if (!(SET_CONTAINS(permissionsSet, permission)) && (SET_CONTAINS(curPermissionsSet, permission))) { + removedPermissions.push_back(permission); + } + + } + + //adding missing permissions + for (auto addedPermission : addedPermissions) { + command = mSqlConnection->PrepareDataCommand( + Queries.at(QueryType::EAddAppPermissions)); + command->BindString(1, appId.c_str()); + command->BindString(2, pkgId.c_str()); + command->BindString(3, addedPermission.c_str()); + + if (command->Step()) + LogPedantic("Unexpected SQLITE_ROW answer to query: " << + Queries.at(QueryType::EAddAppPermissions)); + + command->Reset(); + LogPedantic( + "Added appId: " << appId << ", pkgId: " << pkgId << ", permission: " << addedPermission); + + } + + //removing unwanted permissions + for (auto removedPermission : removedPermissions) { + command = mSqlConnection->PrepareDataCommand( + Queries.at(QueryType::ERemoveAppPermissions)); + command->BindString(1, appId.c_str()); + command->BindString(2, pkgId.c_str()); + command->BindString(3, removedPermission.c_str()); + + if (command->Step()) + LogPedantic("Unexpected SQLITE_ROW answer to query: " << + Queries.at(QueryType::EAddAppPermissions)); + + LogPedantic( + "Removed appId: " << appId << ", pkgId: " << pkgId << ", permission: " << removedPermission); + } + + return true; + + }CATCH_STANDARD_EXCEPTIONS; + + return false; +} +} //namespace SecurityManager |