From 14d1fb229ad782830543cb3ac04b58a46c67f504 Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Tue, 23 Dec 2014 14:21:47 +0100 Subject: [PATCH 01/16] Implement detection of online/offline mode in admin Change-Id: I93a2af08266d7606491abf4f89bf16663c7d0e15 --- src/admin/CMakeLists.txt | 4 ++ src/admin/api/admin-api.cpp | 10 ++- src/admin/logic/Logic.cpp | 95 ++++++++++++++++++++++++++++ src/admin/logic/Logic.h | 67 ++++++++++++++++++++ src/admin/logic/OfflineLogic.cpp | 133 +++++++++++++++++++++++++++++++++++++++ src/admin/logic/OfflineLogic.h | 68 ++++++++++++++++++++ 6 files changed, 375 insertions(+), 2 deletions(-) create mode 100644 src/admin/logic/Logic.cpp create mode 100644 src/admin/logic/Logic.h create mode 100644 src/admin/logic/OfflineLogic.cpp create mode 100644 src/admin/logic/OfflineLogic.h diff --git a/src/admin/CMakeLists.txt b/src/admin/CMakeLists.txt index 321ca92..3cbff78 100644 --- a/src/admin/CMakeLists.txt +++ b/src/admin/CMakeLists.txt @@ -23,10 +23,13 @@ SET(CYNARA_LIB_CYNARA_ADMIN_PATH ${CYNARA_PATH}/admin) SET(LIB_CYNARA_ADMIN_SOURCES ${CYNARA_LIB_CYNARA_ADMIN_PATH}/api/admin-api.cpp + ${CYNARA_LIB_CYNARA_ADMIN_PATH}/logic/Logic.cpp + ${CYNARA_LIB_CYNARA_ADMIN_PATH}/logic/OfflineLogic.cpp ${CYNARA_LIB_CYNARA_ADMIN_PATH}/logic/OnlineLogic.cpp ) INCLUDE_DIRECTORIES( + ${CYNARA_PATH} ${CYNARA_PATH}/include ${CYNARA_LIB_CYNARA_ADMIN_PATH} ) @@ -43,6 +46,7 @@ SET_TARGET_PROPERTIES( TARGET_LINK_LIBRARIES(${TARGET_LIB_CYNARA_ADMIN} ${CYNARA_DEP_LIBRARIES} ${TARGET_CYNARA_COMMON} + ${TARGET_LIB_CYNARA_STORAGE} ) INSTALL(TARGETS ${TARGET_LIB_CYNARA_ADMIN} DESTINATION ${LIB_INSTALL_DIR}) diff --git a/src/admin/api/admin-api.cpp b/src/admin/api/admin-api.cpp index 1dfeb90..d3b6a36 100644 --- a/src/admin/api/admin-api.cpp +++ b/src/admin/api/admin-api.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -43,7 +44,7 @@ #include #include -#include +#include struct cynara_admin { Cynara::ApiInterface *impl; @@ -61,7 +62,12 @@ int cynara_admin_initialize(struct cynara_admin **pp_cynara_admin) { return CYNARA_API_INVALID_PARAM; return Cynara::tryCatch([&]() { - *pp_cynara_admin = new cynara_admin(new Cynara::OnlineLogic); + try { + *pp_cynara_admin = new cynara_admin(new Cynara::Logic); + } catch (const Cynara::FileLockAcquiringException &ex) { + LOGE("%s", ex.what()); + return CYNARA_API_OPERATION_FAILED; + } init_log(); diff --git a/src/admin/logic/Logic.cpp b/src/admin/logic/Logic.cpp new file mode 100644 index 0000000..57fc0b5 --- /dev/null +++ b/src/admin/logic/Logic.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2014 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 + */ +/** + * @file src/admin/logic/Logic.cpp + * @author Lukasz Wojciechowski + * @author Aleksander Zdyb + * @version 1.0 + * @brief This file contains implementation of Logic class - main libcynara-admin class + */ + +#include +#include +#include + +#include "Logic.h" +#include "OfflineLogic.h" +#include "OnlineLogic.h" + +namespace Cynara { + +Logic::Logic() : m_onlineLogic(new OnlineLogic()), m_offlineLogic(new OfflineLogic()), + m_lockable(PathConfig::StoragePath::lockFile) {} + +Logic::~Logic() { + delete m_onlineLogic; + delete m_offlineLogic; +} + +int Logic::setPolicies(const ApiInterface::PoliciesByBucket &insertOrUpdate, + const ApiInterface::KeysByBucket &remove) { + using std::placeholders::_1; + return callApiFunction(std::bind(&ApiInterface::setPolicies, _1, + std::cref(insertOrUpdate), std::cref(remove))); +} + +int Logic::insertOrUpdateBucket(const PolicyBucketId &bucket, + const PolicyResult &policyResult) { + using std::placeholders::_1; + auto f = std::bind(&ApiInterface::insertOrUpdateBucket, _1, + std::cref(bucket), std::cref(policyResult)); + return callApiFunction(f); +} + +int Logic::removeBucket(const PolicyBucketId &bucket) { + using std::placeholders::_1; + return callApiFunction(std::bind(&ApiInterface::removeBucket, _1, std::cref(bucket))); +} + +int Logic::adminCheck(const PolicyBucketId &startBucket, bool recursive, const PolicyKey &key, + PolicyResult &result) { + using std::placeholders::_1; + return callApiFunction(std::bind(&ApiInterface::adminCheck, _1, std::cref(startBucket), + recursive, std::cref(key), std::ref(result))); +} + +int Logic::listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter, + std::vector &policies) { + using std::placeholders::_1; + return callApiFunction(std::bind(&ApiInterface::listPolicies, _1, std::cref(bucket), + std::cref(filter), std::ref(policies))); +} + +int Logic::erasePolicies(const PolicyBucketId &startBucket, bool recursive, + const PolicyKey &filter) { + using std::placeholders::_1; + return callApiFunction(std::bind(&ApiInterface::erasePolicies, _1, std::cref(startBucket), + recursive, std::cref(filter))); +} + +int Logic::callApiFunction(std::function apiCall) { + FileLock lock(m_lockable); + if (lock.tryLock() == true) { + m_offlineLogic->acquireDatabase(); + LOGI("Admin uses offline API"); + return apiCall(m_offlineLogic); + } else { + LOGI("Admin uses online API"); + return apiCall(m_onlineLogic); + } +} + +} // namespace Cynara diff --git a/src/admin/logic/Logic.h b/src/admin/logic/Logic.h new file mode 100644 index 0000000..9a24de7 --- /dev/null +++ b/src/admin/logic/Logic.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014 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 + */ +/** + * @file src/admin/logic/Logic.h + * @author Lukasz Wojciechowski + * @author Aleksander Zdyb + * @version 1.0 + * @brief This file contains definition of Logic class - main libcynara-admin class + */ + +#ifndef SRC_ADMIN_LOGIC_LOGIC_H_ +#define SRC_ADMIN_LOGIC_LOGIC_H_ + +#include + +#include + +#include + +namespace Cynara { + +class OnlineLogic; +class OfflineLogic; + +class Logic : public ApiInterface { + +public: + Logic(); + virtual ~Logic(); + + virtual int setPolicies(const ApiInterface::PoliciesByBucket &insertOrUpdate, + const ApiInterface::KeysByBucket &remove); + virtual int insertOrUpdateBucket(const PolicyBucketId &bucket, + const PolicyResult &policyResult); + virtual int removeBucket(const PolicyBucketId &bucket); + virtual int adminCheck(const PolicyBucketId &startBucket, bool recursive, + const PolicyKey &key, PolicyResult &result); + virtual int listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter, + std::vector &policies); + virtual int erasePolicies(const PolicyBucketId &startBucket, bool recursive, + const PolicyKey &filter); + +protected: + int callApiFunction(std::function apiCall); + +private: + OnlineLogic *m_onlineLogic; + OfflineLogic *m_offlineLogic; + Lockable m_lockable; +}; + +} // namespace Cynara + +#endif /* SRC_ADMIN_LOGIC_LOGIC_H_ */ diff --git a/src/admin/logic/OfflineLogic.cpp b/src/admin/logic/OfflineLogic.cpp new file mode 100644 index 0000000..a52a0fe --- /dev/null +++ b/src/admin/logic/OfflineLogic.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2014 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. + */ +/** + * @file src/admin/logic/OfflineLogic.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief This file contains implementation of OfflineLogic class + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "OfflineLogic.h" + +namespace Cynara { + +OfflineLogic::OfflineLogic() {} + +void OfflineLogic::acquireDatabase(void) { + m_storageBackend.reset(new InMemoryStorageBackend(PathConfig::StoragePath::dbDir)); + m_storage.reset(new Storage(*m_storageBackend)); + m_storage->load(); +} + +int OfflineLogic::setPolicies(const ApiInterface::PoliciesByBucket &insertOrUpdate, + const ApiInterface::KeysByBucket &remove) { + try { + m_storage->insertPolicies(insertOrUpdate); + m_storage->deletePolicies(remove); + onPoliciesChanged(); + } catch (const BucketNotExistsException &) { + return CYNARA_API_BUCKET_NOT_FOUND; + } catch (const DatabaseException &) { + return CYNARA_API_OPERATION_FAILED; + } + + return CYNARA_API_SUCCESS; +} + +int OfflineLogic::insertOrUpdateBucket(const PolicyBucketId &bucket, + const PolicyResult &policyResult) { + try { + m_storage->addOrUpdateBucket(bucket, policyResult); + onPoliciesChanged(); + } catch (const DefaultBucketSetNoneException &) { + return CYNARA_API_OPERATION_NOT_ALLOWED; + } catch (const InvalidBucketIdException &ex) { + return CYNARA_API_OPERATION_NOT_ALLOWED; + } catch (const DatabaseException &) { + return CYNARA_API_OPERATION_FAILED; + } + + return CYNARA_API_SUCCESS; +} + +int OfflineLogic::removeBucket(const PolicyBucketId &bucket) { + try { + m_storage->deleteBucket(bucket); + onPoliciesChanged(); + } catch (const BucketNotExistsException &) { + return CYNARA_API_BUCKET_NOT_FOUND; + } catch (const DefaultBucketDeletionException &) { + return CYNARA_API_OPERATION_NOT_ALLOWED; + } catch (const DatabaseException &) { + return CYNARA_API_OPERATION_FAILED; + } + + return CYNARA_API_SUCCESS; +} + +int OfflineLogic::adminCheck(const PolicyBucketId &startBucket, bool recursive, + const PolicyKey &key, PolicyResult &result) { + try { + result = m_storage->checkPolicy(key, startBucket, recursive); + } catch (const BucketNotExistsException &ex) { + return CYNARA_API_BUCKET_NOT_FOUND; + } + + return CYNARA_API_SUCCESS; +} + +int OfflineLogic::listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter, + std::vector &policies) { + try { + policies = m_storage->listPolicies(bucket, filter); + } catch (const BucketNotExistsException &ex) { + return CYNARA_API_BUCKET_NOT_FOUND; + } + + return CYNARA_API_SUCCESS; +} + +int OfflineLogic::erasePolicies(const PolicyBucketId &startBucket, bool recursive, + const PolicyKey &filter) { + try { + m_storage->erasePolicies(startBucket, recursive, filter); + onPoliciesChanged(); + } catch (const BucketNotExistsException &) { + return CYNARA_API_BUCKET_NOT_FOUND; + } + + return CYNARA_API_SUCCESS; +} + +void OfflineLogic::onPoliciesChanged(void) { + m_storage->save(); +} + +} /* namespace Cynara */ diff --git a/src/admin/logic/OfflineLogic.h b/src/admin/logic/OfflineLogic.h new file mode 100644 index 0000000..ec180f2 --- /dev/null +++ b/src/admin/logic/OfflineLogic.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2014 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. + */ +/** + * @file src/admin/logic/OfflineLogic.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief This file contains definition of OfflineLogic class + */ + +#ifndef SRC_ADMIN_LOGIC_OFFLINELOGIC_H_ +#define SRC_ADMIN_LOGIC_OFFLINELOGIC_H_ + +#include + +#include + +#include +#include + +#include + +namespace Cynara { + +class OfflineLogic : public ApiInterface { +public: + OfflineLogic(); + + void acquireDatabase(void); + + int setPolicies(const ApiInterface::PoliciesByBucket &insertOrUpdate, + const ApiInterface::KeysByBucket &remove); + int insertOrUpdateBucket(const PolicyBucketId &bucket, + const PolicyResult &policyResult); + int removeBucket(const PolicyBucketId &bucket); + int adminCheck(const PolicyBucketId &startBucket, bool recursive, + const PolicyKey &key, PolicyResult &result); + int listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter, + std::vector &policies); + int erasePolicies(const PolicyBucketId &startBucket, bool recursive, + const PolicyKey &filter); + +protected: + void onPoliciesChanged(void); + +private: + typedef std::unique_ptr StorageUniquePtr; + typedef std::unique_ptr StorageBackendUniquePtr; + + StorageUniquePtr m_storage; + StorageBackendUniquePtr m_storageBackend; +}; + +} /* namespace Cynara */ + +#endif /* SRC_ADMIN_LOGIC_OFFLINELOGIC_H_ */ -- 2.7.4 From 582e79ea7c430629a9ee5fa432839956174c736d Mon Sep 17 00:00:00 2001 From: Zofia Abramowska Date: Tue, 16 Dec 2014 16:48:58 +0100 Subject: [PATCH 02/16] Add listing types of policies Change-Id: Iab51f7ec232fb711ac6945be1ce71effa7e59ef1 --- src/client-async/logic/Logic.cpp | 4 +-- src/client-common/CMakeLists.txt | 1 - src/client-common/cache/CacheInterface.h | 8 ++--- src/client-common/plugins/NaiveInterpreter.cpp | 30 ---------------- src/client-common/plugins/NaiveInterpreter.h | 7 ++-- src/client/logic/Logic.cpp | 4 +-- src/common/CMakeLists.txt | 2 ++ src/common/plugin/ExternalPluginInterface.h | 7 ++-- src/common/plugin/PluginManager.cpp | 18 +++++++--- src/common/plugin/PluginManager.h | 5 ++- src/common/types/PolicyDescription.cpp | 36 +++++++++++++++++++ src/common/types/PolicyDescription.h | 48 ++++++++++++++++++++++++++ src/include/cynara-client-plugin.h | 3 +- 13 files changed, 119 insertions(+), 54 deletions(-) delete mode 100644 src/client-common/plugins/NaiveInterpreter.cpp create mode 100644 src/common/types/PolicyDescription.cpp create mode 100644 src/common/types/PolicyDescription.h diff --git a/src/client-async/logic/Logic.cpp b/src/client-async/logic/Logic.cpp index 48b8bad..7504c7e 100644 --- a/src/client-async/logic/Logic.cpp +++ b/src/client-async/logic/Logic.cpp @@ -50,8 +50,8 @@ Logic::Logic(cynara_status_callback callback, void *userStatusData) m_cache = std::make_shared(); auto naiveInterpreter = std::make_shared(); - for (auto &type : naiveInterpreter->getSupportedPolicyTypes()) { - m_cache->registerPlugin(type, naiveInterpreter); + for (auto &descr : naiveInterpreter->getSupportedPolicyDescr()) { + m_cache->registerPlugin(descr, naiveInterpreter); } } diff --git a/src/client-common/CMakeLists.txt b/src/client-common/CMakeLists.txt index bb02eca..2c60ca9 100644 --- a/src/client-common/CMakeLists.txt +++ b/src/client-common/CMakeLists.txt @@ -28,7 +28,6 @@ INCLUDE_DIRECTORIES( SET(LIB_CYNARA_COMMON_SOURCES ${LIB_CYNARA_COMMON_PATH}/cache/CapacityCache.cpp - ${LIB_CYNARA_COMMON_PATH}/plugins/NaiveInterpreter.cpp ) ADD_DEFINITIONS("-fvisibility=default") diff --git a/src/client-common/cache/CacheInterface.h b/src/client-common/cache/CacheInterface.h index 03b7624..bbd18c8 100644 --- a/src/client-common/cache/CacheInterface.h +++ b/src/client-common/cache/CacheInterface.h @@ -31,9 +31,9 @@ #include #include #include +#include #include #include -#include namespace Cynara { @@ -48,8 +48,8 @@ public: const PolicyKey &key, const PolicyResult &result) = 0; - void registerPlugin(const PolicyType policyType, ClientPluginInterfacePtr plugin) { - m_plugins[policyType] = plugin; + void registerPlugin(const PolicyDescription &policyDescr, ClientPluginInterfacePtr plugin) { + m_plugins[policyDescr] = plugin; } virtual void clear(void) { @@ -59,7 +59,7 @@ public: virtual ~PluginCache() {}; protected: - std::map m_plugins; + std::map m_plugins; }; } // namespace Cynara diff --git a/src/client-common/plugins/NaiveInterpreter.cpp b/src/client-common/plugins/NaiveInterpreter.cpp deleted file mode 100644 index 7141cb7..0000000 --- a/src/client-common/plugins/NaiveInterpreter.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2014 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 - */ -/** - * @file src/client-common/plugins/NaiveInterpreter.cpp - * @author Zofia Abramowska - * @version 1.0 - * @brief This file contains NaiveInterpreter supported types definition. - */ - -#include - -namespace Cynara { - - const std::vector NaiveInterpreter::s_supportedTypes = - {PredefinedPolicyType::ALLOW, PredefinedPolicyType::DENY}; - -} diff --git a/src/client-common/plugins/NaiveInterpreter.h b/src/client-common/plugins/NaiveInterpreter.h index 059554d..a0e2d67 100644 --- a/src/client-common/plugins/NaiveInterpreter.h +++ b/src/client-common/plugins/NaiveInterpreter.h @@ -25,6 +25,7 @@ #include #include #include +#include namespace Cynara { @@ -45,13 +46,11 @@ public: return CYNARA_API_ACCESS_DENIED; } - const std::vector &getSupportedPolicyTypes(void) { - return s_supportedTypes; + const std::vector &getSupportedPolicyDescr(void) { + return predefinedPolicyDescr; } void invalidate(void) {} -private: - static const std::vector s_supportedTypes; }; } // namespace Cynara diff --git a/src/client/logic/Logic.cpp b/src/client/logic/Logic.cpp index 498e53c..f8fc543 100644 --- a/src/client/logic/Logic.cpp +++ b/src/client/logic/Logic.cpp @@ -52,8 +52,8 @@ Logic::Logic() { std::make_shared()); m_cache = std::make_shared(); auto naiveInterpreter = std::make_shared(); - for (auto &type : naiveInterpreter->getSupportedPolicyTypes()) { - m_cache->registerPlugin(type, naiveInterpreter); + for (auto &descr : naiveInterpreter->getSupportedPolicyDescr()) { + m_cache->registerPlugin(descr, naiveInterpreter); } } diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 37073ad..fe2f727 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -62,9 +62,11 @@ SET(COMMON_SOURCES ${COMMON_PATH}/sockets/Socket.cpp ${COMMON_PATH}/sockets/SocketClient.cpp ${COMMON_PATH}/types/PolicyBucket.cpp + ${COMMON_PATH}/types/PolicyDescription.cpp ${COMMON_PATH}/types/PolicyKey.cpp ${COMMON_PATH}/types/PolicyKeyHelpers.cpp ${COMMON_PATH}/types/PolicyResult.cpp + ${COMMON_PATH}/types/PolicyType.cpp ) IF (CMAKE_BUILD_TYPE MATCHES "DEBUG") diff --git a/src/common/plugin/ExternalPluginInterface.h b/src/common/plugin/ExternalPluginInterface.h index ddd8363..f4e8a63 100644 --- a/src/common/plugin/ExternalPluginInterface.h +++ b/src/common/plugin/ExternalPluginInterface.h @@ -25,7 +25,7 @@ #include -#include +#include namespace Cynara { @@ -47,11 +47,10 @@ typedef void (*destroy_t)(ExternalPluginInterface *); class ExternalPluginInterface { public: - /** - * Policy type supported by plugin. + * Policy types supported by plugin. */ - virtual const std::vector &getSupportedPolicyTypes(void) = 0; + virtual const std::vector &getSupportedPolicyDescr(void) = 0; /** * Informs, that every data stored based on previously given input diff --git a/src/common/plugin/PluginManager.cpp b/src/common/plugin/PluginManager.cpp index c8a38c5..300dc7f 100644 --- a/src/common/plugin/PluginManager.cpp +++ b/src/common/plugin/PluginManager.cpp @@ -65,6 +65,15 @@ ExternalPluginPtr PluginManager::getPlugin(PolicyType pType) { return m_plugins[pType]; } +std::vector PluginManager::getPolicyDescriptions(void) const { + std::vector descriptions; + descriptions.reserve(m_plugins.size()); + for (auto &plugin : m_plugins) { + descriptions.push_back(plugin.first); + } + return descriptions; +} + void PluginManager::invalidateAll(void) { for (auto &plugin : m_plugins) { plugin.second->invalidate(); @@ -125,14 +134,15 @@ void PluginManager::openPlugin(const std::string &path) { return; } - auto policies = pluginPtr->getSupportedPolicyTypes(); + auto policies = pluginPtr->getSupportedPolicyDescr(); if (policies.empty()) { LOGE("Plugin <%s> does not support any type!", path.c_str()); return; } - for (auto type : policies) { - if (!m_plugins.insert(std::make_pair(type, pluginPtr)).second) { - LOGW("policyType [%" PRIu16 "] was already supported.", type); + for (auto &desc : policies) { + if (!m_plugins.insert(std::make_pair(desc, pluginPtr)).second) { + LOGW("policy type: [%" PRIu16 "] name: <%s> was already supported.", + desc.type, desc.name.c_str()); } } diff --git a/src/common/plugin/PluginManager.h b/src/common/plugin/PluginManager.h index 8de33ae..87b0597 100644 --- a/src/common/plugin/PluginManager.h +++ b/src/common/plugin/PluginManager.h @@ -28,8 +28,10 @@ #include #include #include +#include #include +#include namespace Cynara { typedef std::shared_ptr ExternalPluginPtr; @@ -38,6 +40,7 @@ class PluginManager { public: PluginManager(const std::string &pluginDir); ExternalPluginPtr getPlugin(PolicyType pType); + std::vector getPolicyDescriptions(void) const; void invalidateAll(void); ~PluginManager(); @@ -46,7 +49,7 @@ private: typedef std::list PluginLibs; std::string m_dir; - std::map m_plugins; + std::map m_plugins; PluginLibs m_pluginLibs; void loadPlugins(void); diff --git a/src/common/types/PolicyDescription.cpp b/src/common/types/PolicyDescription.cpp new file mode 100644 index 0000000..1c06137 --- /dev/null +++ b/src/common/types/PolicyDescription.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014 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. + */ +/** + * @file src/common/types/PolicyDescription.cpp + * @author Zofia Abramowska + * @version 1.0 + * @brief Implementation of functions for Cynara::PolicyDescription + */ + +#include "PolicyDescription.h" + +namespace Cynara { + +const std::vector predefinedPolicyDescr = { + PolicyDescription(PredefinedPolicyType::ALLOW, "Allow"), + PolicyDescription(PredefinedPolicyType::DENY, "Deny") +}; + +bool operator<(const PolicyDescription &left, const PolicyDescription &right) { + return left.type < right.type; +} + +} // namespace Cynara diff --git a/src/common/types/PolicyDescription.h b/src/common/types/PolicyDescription.h new file mode 100644 index 0000000..b4d27d5 --- /dev/null +++ b/src/common/types/PolicyDescription.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014 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. + */ +/** + * @file src/common/types/PolicyDescription.h + * @author Zofia Abramowska + * @version 1.0 + * @brief This file defines PolicyDescription for storing policy type + * description. + */ + +#ifndef SRC_COMMON_TYPES_POLICYDESCRIPTION_H_ +#define SRC_COMMON_TYPES_POLICYDESCRIPTION_H_ + +#include + +#include +#include + +namespace Cynara { + +struct PolicyDescription { + PolicyDescription(const PolicyType &pType, const std::string &pName) : type(pType), name(pName) + {}; + PolicyDescription(const PolicyType &pType) : type(pType) {}; + PolicyType type; + std::string name; +}; + +extern const std::vector predefinedPolicyDescr; + +bool operator<(const PolicyDescription &left, const PolicyDescription &right); + +} // namespace Cynara + +#endif /* SRC_COMMON_TYPES_POLICYDESCRIPTION_H_ */ diff --git a/src/include/cynara-client-plugin.h b/src/include/cynara-client-plugin.h index 3d39ad7..29e32ce 100644 --- a/src/include/cynara-client-plugin.h +++ b/src/include/cynara-client-plugin.h @@ -51,13 +51,12 @@ typedef std::shared_ptr ClientPluginInterfacePtr; */ class ClientPluginInterface : public ExternalPluginInterface { public: - /** * Return entry cacheability */ virtual bool isCacheable(const ClientSession &session, const PolicyResult &result) = 0; /** - * Return entry cacheability + * Return entry usability */ virtual bool isUsable(const ClientSession &session, const ClientSession &prevSession, bool &updateSession, PolicyResult &result) = 0; -- 2.7.4 From c58b6587a522499aac183ea5116d3ce69462b0f7 Mon Sep 17 00:00:00 2001 From: Zofia Abramowska Date: Fri, 19 Dec 2014 10:52:22 +0100 Subject: [PATCH 03/16] Add api side implementation of plugin descriptions listing Add: * description of api function cynara_admin_list_policies_descriptions * implementation in admin-api * utilities for creating null terminated array Change-Id: I4b7d56757e22fab4cce81665f16ceef61f3a0e2c --- src/admin/api/ApiInterface.h | 2 + src/admin/api/admin-api.cpp | 116 +++++++++++++++++++++++---------------- src/admin/logic/Logic.cpp | 5 ++ src/admin/logic/Logic.h | 1 + src/admin/logic/OfflineLogic.cpp | 5 ++ src/admin/logic/OfflineLogic.h | 1 + src/admin/logic/OnlineLogic.cpp | 5 ++ src/admin/logic/OnlineLogic.h | 2 +- src/admin/logic/Utility.h | 69 +++++++++++++++++++++++ src/include/cynara-admin-types.h | 13 +++++ src/include/cynara-admin.h | 49 +++++++++++++++++ 11 files changed, 219 insertions(+), 49 deletions(-) create mode 100644 src/admin/logic/Utility.h diff --git a/src/admin/api/ApiInterface.h b/src/admin/api/ApiInterface.h index 89ac978..9484b7f 100644 --- a/src/admin/api/ApiInterface.h +++ b/src/admin/api/ApiInterface.h @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -56,6 +57,7 @@ public: std::vector &policies) = 0; virtual int erasePolicies(const PolicyBucketId &startBucket, bool recursive, const PolicyKey &filter) = 0; + virtual int listDescriptions(std::vector &descriptions) = 0; }; diff --git a/src/admin/api/admin-api.cpp b/src/admin/api/admin-api.cpp index d3b6a36..10077df 100644 --- a/src/admin/api/admin-api.cpp +++ b/src/admin/api/admin-api.cpp @@ -22,11 +22,9 @@ #include #include -#include -#include #include #include -#include +#include #include #include @@ -36,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -45,6 +44,8 @@ #include #include +#include +#include struct cynara_admin { Cynara::ApiInterface *impl; @@ -228,59 +229,40 @@ int cynara_admin_check(struct cynara_admin *p_cynara_admin, }); } -static int createPoliciesArray(const char *bucket, - const std::vector &policiesVector, - struct cynara_admin_policy ***policies) { - typedef struct cynara_admin_policy Elem; - size_t elems = policiesVector.size(); - - Elem **tab = reinterpret_cast(calloc(elems + 1U, sizeof(Elem*))); - if (!tab) +static int copyPolicy(const char *bucket, const Cynara::Policy &from, cynara_admin_policy *&to) { + to = reinterpret_cast(calloc(1, sizeof(cynara_admin_policy))); + if (!to) return CYNARA_API_OUT_OF_MEMORY; - std::unique_ptr> plumber(tab, - [](Elem **tab) { - for (int i = 0; tab[i] != nullptr; i++) { - free(tab[i]->bucket); - free(tab[i]->client); - free(tab[i]->user); - free(tab[i]->privilege); - free(tab[i]->result_extra); - free(tab[i]); - } - free(tab); - }); - - for (size_t i = 0U; i < elems; ++i) { - tab[i] = reinterpret_cast(calloc(1U, sizeof(Elem))); - if (!tab[i]) - return CYNARA_API_OUT_OF_MEMORY; - - tab[i]->bucket = strdup(bucket); - if (!tab[i]->bucket) + to->bucket = strdup(bucket); + if (!to->bucket) + return CYNARA_API_OUT_OF_MEMORY; + to->client = strdup(from.key().client().value().c_str()); + if (!to->client) return CYNARA_API_OUT_OF_MEMORY; - - tab[i]->client = strdup(policiesVector[i].key().client().value().c_str()); - if (!tab[i]->client) + to->user = strdup(from.key().user().value().c_str()); + if (!to->user) return CYNARA_API_OUT_OF_MEMORY; - tab[i]->user = strdup(policiesVector[i].key().user().value().c_str()); - if (!tab[i]->user) + to->privilege = strdup(from.key().privilege().value().c_str()); + if (!to->privilege) return CYNARA_API_OUT_OF_MEMORY; - tab[i]->privilege = strdup(policiesVector[i].key().privilege().value().c_str()); - if (!tab[i]->privilege) + to->result = static_cast(from.result().policyType()); + if (!from.result().metadata().empty()) { + to->result_extra = strdup(from.result().metadata().c_str()); + if (!to->result_extra) return CYNARA_API_OUT_OF_MEMORY; - - tab[i]->result = static_cast(policiesVector[i].result().policyType()); - if (!policiesVector[i].result().metadata().empty()) { - tab[i]->result_extra = strdup(policiesVector[i].result().metadata().c_str()); - if (!tab[i]->result_extra) - return CYNARA_API_OUT_OF_MEMORY; - } } - *policies = tab; - plumber.release(); return CYNARA_API_SUCCESS; } +static void freeElem(struct cynara_admin_policy *policyPtr) { + free(policyPtr->bucket); + free(policyPtr->client); + free(policyPtr->user); + free(policyPtr->privilege); + free(policyPtr->result_extra); + free(policyPtr); +} + CYNARA_API int cynara_admin_list_policies(struct cynara_admin *p_cynara_admin, const char *bucket, const char *client, const char *user, const char *privilege, @@ -313,7 +295,45 @@ int cynara_admin_list_policies(struct cynara_admin *p_cynara_admin, const char * if (ret != CYNARA_API_SUCCESS) return ret; - return createPoliciesArray(bucket, policiesVector, policies); + auto copyFun = std::bind(copyPolicy, bucket, std::placeholders::_1, std::placeholders::_2); + return Cynara::createNullTerminatedArray + (policiesVector, policies, copyFun); + }); +} + +static int copyDescr(const Cynara::PolicyDescription &from, cynara_admin_policy_descr *&to) { + to = reinterpret_cast(calloc(1, sizeof(cynara_admin_policy_descr))); + if (!to) + return CYNARA_API_OUT_OF_MEMORY; + to->result = static_cast(from.type); + to->name = strdup(from.name.c_str()); + if (!to->name) + return CYNARA_API_OUT_OF_MEMORY; + return CYNARA_API_SUCCESS; +} + +static void freeElem(struct cynara_admin_policy_descr *descrPtr) { + free(descrPtr->name); + free(descrPtr); +} + +CYNARA_API +int cynara_admin_list_policies_descriptions(struct cynara_admin *p_cynara_admin, + struct cynara_admin_policy_descr ***descriptions) { + if (!p_cynara_admin || !p_cynara_admin->impl) + return CYNARA_API_INVALID_PARAM; + if (!descriptions) + return CYNARA_API_INVALID_PARAM; + + return Cynara::tryCatch([&p_cynara_admin, &descriptions] () { + std::vector descriptionsVector; + int ret = p_cynara_admin->impl->listDescriptions(descriptionsVector); + + if (ret != CYNARA_API_SUCCESS) + return ret; + return Cynara::createNullTerminatedArray + (descriptionsVector, descriptions, copyDescr); }); } diff --git a/src/admin/logic/Logic.cpp b/src/admin/logic/Logic.cpp index 57fc0b5..3f23370 100644 --- a/src/admin/logic/Logic.cpp +++ b/src/admin/logic/Logic.cpp @@ -66,6 +66,11 @@ int Logic::adminCheck(const PolicyBucketId &startBucket, bool recursive, const P recursive, std::cref(key), std::ref(result))); } +int Logic::listDescriptions(std::vector &descriptions) { + using std::placeholders::_1; + return callApiFunction(std::bind(&ApiInterface::listDescriptions, _1, std::ref(descriptions))); +} + int Logic::listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter, std::vector &policies) { using std::placeholders::_1; diff --git a/src/admin/logic/Logic.h b/src/admin/logic/Logic.h index 9a24de7..e9c7774 100644 --- a/src/admin/logic/Logic.h +++ b/src/admin/logic/Logic.h @@ -48,6 +48,7 @@ public: virtual int removeBucket(const PolicyBucketId &bucket); virtual int adminCheck(const PolicyBucketId &startBucket, bool recursive, const PolicyKey &key, PolicyResult &result); + virtual int listDescriptions(std::vector &descriptions); virtual int listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter, std::vector &policies); virtual int erasePolicies(const PolicyBucketId &startBucket, bool recursive, diff --git a/src/admin/logic/OfflineLogic.cpp b/src/admin/logic/OfflineLogic.cpp index a52a0fe..c860ad8 100644 --- a/src/admin/logic/OfflineLogic.cpp +++ b/src/admin/logic/OfflineLogic.cpp @@ -103,6 +103,11 @@ int OfflineLogic::adminCheck(const PolicyBucketId &startBucket, bool recursive, return CYNARA_API_SUCCESS; } +int OfflineLogic::listDescriptions(std::vector &descriptions) { + (void) descriptions; + return CYNARA_API_SUCCESS; +} + int OfflineLogic::listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter, std::vector &policies) { try { diff --git a/src/admin/logic/OfflineLogic.h b/src/admin/logic/OfflineLogic.h index ec180f2..fc04d5e 100644 --- a/src/admin/logic/OfflineLogic.h +++ b/src/admin/logic/OfflineLogic.h @@ -47,6 +47,7 @@ public: int removeBucket(const PolicyBucketId &bucket); int adminCheck(const PolicyBucketId &startBucket, bool recursive, const PolicyKey &key, PolicyResult &result); + int listDescriptions(std::vector &descriptions); int listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter, std::vector &policies); int erasePolicies(const PolicyBucketId &startBucket, bool recursive, diff --git a/src/admin/logic/OnlineLogic.cpp b/src/admin/logic/OnlineLogic.cpp index 9aa1831..6626a77 100644 --- a/src/admin/logic/OnlineLogic.cpp +++ b/src/admin/logic/OnlineLogic.cpp @@ -205,4 +205,9 @@ int OnlineLogic::erasePolicies(const PolicyBucketId &startBucket, bool recursive return askCynaraAndInterpreteCodeResponse(startBucket, recursive, filter); } +int OnlineLogic::listDescriptions(std::vector &descriptions) { + (void) descriptions; + return CYNARA_API_SUCCESS; +} + } // namespace Cynara diff --git a/src/admin/logic/OnlineLogic.h b/src/admin/logic/OnlineLogic.h index 19e3304..84becd7 100644 --- a/src/admin/logic/OnlineLogic.h +++ b/src/admin/logic/OnlineLogic.h @@ -52,7 +52,7 @@ public: std::vector &policies); virtual int erasePolicies(const PolicyBucketId &startBucket, bool recursive, const PolicyKey &filter); - + virtual int listDescriptions(std::vector &descriptions); }; } // namespace Cynara diff --git a/src/admin/logic/Utility.h b/src/admin/logic/Utility.h new file mode 100644 index 0000000..10e62da --- /dev/null +++ b/src/admin/logic/Utility.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co. + * + * 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 src/admin/logic/Utility.h + * @author Zofia Abramowska + * @version 1.0 + * @brief This file contains implementation of utility function for managing null pointer + * terminated lists. + */ + +#ifndef SRC_ADMIN_LOGIC_UTILITY_H_ +#define SRC_ADMIN_LOGIC_UTILITY_H_ + +#include +#include +#include +#include + +#include + +namespace Cynara { + +//This function requires proper freeElem function for given type T. +template +static void freeNullTerminatedList(T **list) { + for (int i = 0; list[i]; i++) { + freeElem(list[i]); + } + free(list); +} + +template +static int createNullTerminatedArray(const std::vector &vectorized, T ***array, + std::function copyFun) { + size_t elems = vectorized.size(); + + T **tab = reinterpret_cast(calloc(elems + 1U, sizeof(T*))); + if (!tab) + return CYNARA_API_OUT_OF_MEMORY; + + std::unique_ptr> plumber(tab, freeNullTerminatedList); + + for (size_t i = 0; i < elems; i++) { + int ret = copyFun(vectorized[i], tab[i]); + if (ret != CYNARA_API_SUCCESS) + return ret; + } + + *array = tab; + plumber.release(); + return CYNARA_API_SUCCESS; +} + +} // namespace Cynara + +#endif /* SRC_ADMIN_LOGIC_UTILITY_H_ */ diff --git a/src/include/cynara-admin-types.h b/src/include/cynara-admin-types.h index b83c81d..bb4c1bf 100644 --- a/src/include/cynara-admin-types.h +++ b/src/include/cynara-admin-types.h @@ -17,6 +17,7 @@ * \file src/include/cynara-admin-types.h * \author Lukasz Wojciechowski * \author Aleksander Zdyb + * \author Zofia Abramowska * \version 1.0 * \brief This file contains structs and consts for cynara admin. */ @@ -49,6 +50,18 @@ struct cynara_admin_policy { }; /** + * \name cynara_admin_policy_descr + * describes policy of type given with result + * result - result of policy to describe + * name - name of given policy result + */ + +struct cynara_admin_policy_descr { + int result; + char *name; +}; + +/** * \name Wildcard * definition of WILDCARD, that can replace client, user or privilege name. * WILDCARD matches any string during check procedure from libcynara-client. diff --git a/src/include/cynara-admin.h b/src/include/cynara-admin.h index bb1b8d1..0d958f8 100644 --- a/src/include/cynara-admin.h +++ b/src/include/cynara-admin.h @@ -16,6 +16,7 @@ /** * @file src/include/cynara-admin.h * \author Lukasz Wojciechowski + * \author Zofia Abramowska * \version 1.0 * \brief This file contains administration APIs of cynara available with libcynara-admin. */ @@ -358,6 +359,54 @@ int cynara_admin_list_policies(struct cynara_admin *p_cynara_admin, const char * int cynara_admin_erase(struct cynara_admin *p_cynara_admin, const char *start_bucket, int recursive, const char *client, const char *user, const char *privilege); + +/** + * \par Description: + * + * Lists available cynara policy results with name description. + * + * \par Purpose: + * This API should be used to list all available policy results + * (also from cynara extension plugins). + * + * \par Typical use case: + * Gathering information about possible policy results and presenting them to user (using name + * attribute of description). Result can be passed to cynara_admin_set_policies(). + * + * \par Method of function operation: + * Policies are based on policy result number. Policies can be built in (like primitives: ALLOW, + * DENY...) or can be loaded from cynara plugin extensions. This API gives possibility of checking, + * which of these result exist in current cynara server and can be presented to user in a readable + * way (of course additional translation may be needed). + * + * Descriptions of existing policy results are returned as NULL terminated array of pointers of + * cynara_admin_policy_descr structures. + * + * Example output could be {{0, "Deny"}, {11, "AskUser"}, {65535, "Allow"}, NULL} + * + * In case of successful call CYNARA_API_SUCCESS is returned and *descriptions points + * to newly created array of pointers to struct cynara_admin_policy_descr. It is responsibility + * of caller to release: + * * all non-NULL char* pointers in all cynara_admin_policy_descr structures; + * * all pointers to cynara_admin_policy_descr structures kept in *descriptions array; + * * *descriptions array itself. + * All allocation made by cynara admin library are done with malloc(3) function and must be released + * with free(3) function. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \param[in] p_cynara_admin cynara admin structure. + * \param[out] descriptions placeholder for NULL terminated array of pointers of + * description structures. + * + * \return CYNARA_API_SUCCESS on success, or error code otherwise. + * + * \brief Lists available policies with their name description. + */ +int cynara_admin_list_policies_descriptions(struct cynara_admin *p_cynara_admin, + struct cynara_admin_policy_descr ***descriptions); + #ifdef __cplusplus } #endif -- 2.7.4 From c7f9108b6fd36daaccbe0218b0ea708c955b0713 Mon Sep 17 00:00:00 2001 From: Zofia Abramowska Date: Mon, 22 Dec 2014 13:19:15 +0100 Subject: [PATCH 04/16] Add classes for plugin description listing request and response DescritpionListRequest used for asking cynara for list of internal and external plugin description. DescriptionListResponse used for sending this list back to client. Change-Id: I047747efcf69ecf7f15747e890ffe1b2b98132f1 --- src/common/CMakeLists.txt | 2 + src/common/request/DescriptionListRequest.cpp | 36 ++++++++++++++++ src/common/request/DescriptionListRequest.h | 44 +++++++++++++++++++ src/common/request/RequestTaker.cpp | 5 +++ src/common/request/RequestTaker.h | 1 + src/common/request/pointers.h | 3 ++ src/common/response/DescriptionListResponse.cpp | 36 ++++++++++++++++ src/common/response/DescriptionListResponse.h | 56 +++++++++++++++++++++++++ src/common/response/ResponseTaker.cpp | 5 +++ src/common/response/ResponseTaker.h | 1 + src/common/response/pointers.h | 3 ++ 11 files changed, 192 insertions(+) create mode 100644 src/common/request/DescriptionListRequest.cpp create mode 100644 src/common/request/DescriptionListRequest.h create mode 100644 src/common/response/DescriptionListResponse.cpp create mode 100644 src/common/response/DescriptionListResponse.h diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index fe2f727..feb7e80 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -44,6 +44,7 @@ SET(COMMON_SOURCES ${COMMON_PATH}/request/AgentRegisterRequest.cpp ${COMMON_PATH}/request/CancelRequest.cpp ${COMMON_PATH}/request/CheckRequest.cpp + ${COMMON_PATH}/request/DescriptionListRequest.cpp ${COMMON_PATH}/request/EraseRequest.cpp ${COMMON_PATH}/request/InsertOrUpdateBucketRequest.cpp ${COMMON_PATH}/request/ListRequest.cpp @@ -57,6 +58,7 @@ SET(COMMON_SOURCES ${COMMON_PATH}/response/CancelResponse.cpp ${COMMON_PATH}/response/CheckResponse.cpp ${COMMON_PATH}/response/CodeResponse.cpp + ${COMMON_PATH}/response/DescriptionListResponse.cpp ${COMMON_PATH}/response/ListResponse.cpp ${COMMON_PATH}/response/ResponseTaker.cpp ${COMMON_PATH}/sockets/Socket.cpp diff --git a/src/common/request/DescriptionListRequest.cpp b/src/common/request/DescriptionListRequest.cpp new file mode 100644 index 0000000..1cea6f5 --- /dev/null +++ b/src/common/request/DescriptionListRequest.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014 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. + */ +/** + * @file src/common/request/DescriptionListRequest.cpp + * @author Zofia Abramowska + * @version 1.0 + * @brief This file implements plugin description list request class + */ + +#include + +#include + +#include "DescriptionListRequest.h" + +namespace Cynara { + +void DescriptionListRequest::execute(RequestPtr self, RequestTakerPtr taker, + RequestContextPtr context) const { + taker->execute(context, std::dynamic_pointer_cast(self)); +} + +} // namespace Cynara diff --git a/src/common/request/DescriptionListRequest.h b/src/common/request/DescriptionListRequest.h new file mode 100644 index 0000000..53e14ef --- /dev/null +++ b/src/common/request/DescriptionListRequest.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014 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. + */ +/** + * @file src/common/request/DescriptionListRequest.h + * @author Zofia Abramowska + * @version 1.0 + * @brief This file defines plugin description list request class + */ + +#ifndef SRC_COMMON_REQUEST_DESCRIPTIONLISTREQUEST_H_ +#define SRC_COMMON_REQUEST_DESCRIPTIONLISTREQUEST_H_ + +#include +#include + +namespace Cynara { + +class DescriptionListRequest : public Request { +public: + DescriptionListRequest(ProtocolFrameSequenceNumber sequenceNumber) : + Request(sequenceNumber) { + } + + virtual ~DescriptionListRequest() {}; + + virtual void execute(RequestPtr self, RequestTakerPtr taker, RequestContextPtr context) const; +}; + +} // namespace Cynara + +#endif /* SRC_COMMON_REQUEST_DESCRIPTIONLISTREQUEST_H_ */ diff --git a/src/common/request/RequestTaker.cpp b/src/common/request/RequestTaker.cpp index 1233f17..ea25f16 100644 --- a/src/common/request/RequestTaker.cpp +++ b/src/common/request/RequestTaker.cpp @@ -55,6 +55,11 @@ void RequestTaker::execute(RequestContextPtr context UNUSED, EraseRequestPtr req } void RequestTaker::execute(RequestContextPtr context UNUSED, + DescriptionListRequestPtr request UNUSED) { + throw NotImplementedException(); +} + +void RequestTaker::execute(RequestContextPtr context UNUSED, InsertOrUpdateBucketRequestPtr request UNUSED) { throw NotImplementedException(); } diff --git a/src/common/request/RequestTaker.h b/src/common/request/RequestTaker.h index 9d929d9..e6e3f08 100644 --- a/src/common/request/RequestTaker.h +++ b/src/common/request/RequestTaker.h @@ -37,6 +37,7 @@ public: virtual void execute(RequestContextPtr context, AgentRegisterRequestPtr request); virtual void execute(RequestContextPtr context, CancelRequestPtr request); virtual void execute(RequestContextPtr context, CheckRequestPtr request); + virtual void execute(RequestContextPtr context, DescriptionListRequestPtr request); virtual void execute(RequestContextPtr context, EraseRequestPtr request); virtual void execute(RequestContextPtr context, InsertOrUpdateBucketRequestPtr request); virtual void execute(RequestContextPtr context, ListRequestPtr request); diff --git a/src/common/request/pointers.h b/src/common/request/pointers.h index 865a4c4..be1fdeb 100644 --- a/src/common/request/pointers.h +++ b/src/common/request/pointers.h @@ -42,6 +42,9 @@ typedef std::shared_ptr CancelRequestPtr; class CheckRequest; typedef std::shared_ptr CheckRequestPtr; +class DescriptionListRequest; +typedef std::shared_ptr DescriptionListRequestPtr; + class EraseRequest; typedef std::shared_ptr EraseRequestPtr; diff --git a/src/common/response/DescriptionListResponse.cpp b/src/common/response/DescriptionListResponse.cpp new file mode 100644 index 0000000..481913a --- /dev/null +++ b/src/common/response/DescriptionListResponse.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014 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. + */ +/** + * @file src/common/response/DescriptionListResponse.cpp + * @author Zofia Abramowska + * @version 1.0 + * @brief This file implements plugins description list response class + */ + +#include + +#include + +#include "DescriptionListResponse.h" + +namespace Cynara { + +void DescriptionListResponse::execute(ResponsePtr self, ResponseTakerPtr taker, + RequestContextPtr context) const { + taker->execute(context, std::dynamic_pointer_cast(self)); +} + +} // namespace Cynara diff --git a/src/common/response/DescriptionListResponse.h b/src/common/response/DescriptionListResponse.h new file mode 100644 index 0000000..a963775 --- /dev/null +++ b/src/common/response/DescriptionListResponse.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2014 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. + */ +/** + * @file src/common/response/DescriptionListResponse.h + * @author Zofia Abramowska + * @version 1.0 + * @brief This file defines response class for plugins description list response + */ + +#ifndef SRC_COMMON_RESPONSE_DESCRIPTIONLISTRESPONSE_H_ +#define SRC_COMMON_RESPONSE_DESCRIPTIONLISTRESPONSE_H_ + +#include + +#include +#include +#include +#include + +namespace Cynara { + +class DescriptionListResponse : public Response { +public: + DescriptionListResponse(const std::vector &descriptions, + ProtocolFrameSequenceNumber sequenceNumber) : + Response(sequenceNumber), m_descriptions(descriptions) { + } + + virtual ~DescriptionListResponse() {}; + + virtual void execute(ResponsePtr self, ResponseTakerPtr taker, RequestContextPtr context) const; + + const std::vector &descriptions(void) const { + return m_descriptions; + } + +private: + std::vector m_descriptions; +}; + +} // namespace Cynara + +#endif /* SRC_COMMON_RESPONSE_DESCRIPTIONLISTRESPONSE_H_ */ diff --git a/src/common/response/ResponseTaker.cpp b/src/common/response/ResponseTaker.cpp index af47659..492af6e 100644 --- a/src/common/response/ResponseTaker.cpp +++ b/src/common/response/ResponseTaker.cpp @@ -55,6 +55,11 @@ void ResponseTaker::execute(RequestContextPtr context UNUSED, CodeResponsePtr re throw NotImplementedException(); } +void ResponseTaker::execute(RequestContextPtr context UNUSED, + DescriptionListResponsePtr response UNUSED) { + throw NotImplementedException(); +} + void ResponseTaker::execute(RequestContextPtr context UNUSED, ListResponsePtr response UNUSED) { throw NotImplementedException(); } diff --git a/src/common/response/ResponseTaker.h b/src/common/response/ResponseTaker.h index 20296af..c642b4f 100644 --- a/src/common/response/ResponseTaker.h +++ b/src/common/response/ResponseTaker.h @@ -39,6 +39,7 @@ public: virtual void execute(RequestContextPtr context, CancelResponsePtr response); virtual void execute(RequestContextPtr context, CheckResponsePtr response); virtual void execute(RequestContextPtr context, CodeResponsePtr response); + virtual void execute(RequestContextPtr context, DescriptionListResponsePtr response); virtual void execute(RequestContextPtr context, ListResponsePtr response); }; diff --git a/src/common/response/pointers.h b/src/common/response/pointers.h index 5e26929..5e90289 100644 --- a/src/common/response/pointers.h +++ b/src/common/response/pointers.h @@ -45,6 +45,9 @@ typedef std::shared_ptr CheckResponsePtr; class CodeResponse; typedef std::shared_ptr CodeResponsePtr; +class DescriptionListResponse; +typedef std::shared_ptr DescriptionListResponsePtr; + class ListResponse; typedef std::shared_ptr ListResponsePtr; -- 2.7.4 From bb718b1017aacdd44d9301831b1e60111cb9867b Mon Sep 17 00:00:00 2001 From: Zofia Abramowska Date: Mon, 22 Dec 2014 16:40:16 +0100 Subject: [PATCH 05/16] Redo admin logic template Template askCynaraAndInterpreteCodeResponse replaced with more general getResponse. Change-Id: I3d4ba04ebc5fb279a4eefbe9657a627822c39fc2 --- src/admin/logic/OnlineLogic.cpp | 110 ++++++++++++++++++---------------------- src/admin/logic/OnlineLogic.h | 4 +- 2 files changed, 52 insertions(+), 62 deletions(-) diff --git a/src/admin/logic/OnlineLogic.cpp b/src/admin/logic/OnlineLogic.cpp index 6626a77..d27681b 100644 --- a/src/admin/logic/OnlineLogic.cpp +++ b/src/admin/logic/OnlineLogic.cpp @@ -64,8 +64,8 @@ bool OnlineLogic::ensureConnection(void) { return m_socketClient->isConnected() || m_socketClient->connect(); } -template -int OnlineLogic::askCynaraAndInterpreteCodeResponse(Args... args) { +template +int OnlineLogic::getResponse(std::shared_ptr &retResponse, ReqArgs... args) { if (!ensureConnection()) { LOGE("Cannot connect to cynara. Service not available."); return CYNARA_API_SERVICE_NOT_AVAILABLE; @@ -73,24 +73,25 @@ int OnlineLogic::askCynaraAndInterpreteCodeResponse(Args... args) { ProtocolFrameSequenceNumber sequenceNumber = generateSequenceNumber(); - //Ask cynara service - CodeResponsePtr codeResponse; - - RequestPtr request = std::make_shared(args..., sequenceNumber); + RequestPtr request = std::make_shared(args..., sequenceNumber); ResponsePtr response; while (!(response = m_socketClient->askCynaraServer(request))) { if (!m_socketClient->connect()) return CYNARA_API_SERVICE_NOT_AVAILABLE; } - codeResponse = std::dynamic_pointer_cast(response); - if (!codeResponse) { - LOGC("Critical error. Casting Response to CodeResponse failed."); + retResponse = std::dynamic_pointer_cast(response); + if (!retResponse) { + LOGC("Critical error. Casting Response failed."); return CYNARA_API_UNKNOWN_ERROR; } - LOGD("codeResponse: code [%" PRIu16 "]", codeResponse->m_code); - switch (codeResponse->m_code) { + return CYNARA_API_SUCCESS; +} + +static int interpretCodeResponse(const CodeResponse::Code &code) { + LOGD("codeResponse: code [%" PRIu16 "]", code); + switch (code) { case CodeResponse::Code::OK: LOGI("Cynara command finished successfully."); return CYNARA_API_SUCCESS; @@ -105,49 +106,49 @@ int OnlineLogic::askCynaraAndInterpreteCodeResponse(Args... args) { return CYNARA_API_OPERATION_FAILED; default: LOGE("Unexpected response code from server: [%d]", - static_cast(codeResponse->m_code)); + static_cast(code)); return CYNARA_API_UNKNOWN_ERROR; } } int OnlineLogic::setPolicies(const ApiInterface::PoliciesByBucket &insertOrUpdate, - const ApiInterface::KeysByBucket &remove) { - return askCynaraAndInterpreteCodeResponse(insertOrUpdate, remove); + const ApiInterface::KeysByBucket &remove) { + CodeResponsePtr codeResponse; + int ret = getResponse(codeResponse, insertOrUpdate, remove); + if (ret != CYNARA_API_SUCCESS) { + return ret; + } + + return interpretCodeResponse(codeResponse->m_code); } int OnlineLogic::insertOrUpdateBucket(const PolicyBucketId &bucket, - const PolicyResult &policyResult) { - return askCynaraAndInterpreteCodeResponse(bucket, policyResult); -} + const PolicyResult &policyResult) { + CodeResponsePtr codeResponse; + int ret = getResponse(codeResponse, bucket, policyResult); + if (ret != CYNARA_API_SUCCESS) { + return ret; + } -int OnlineLogic::removeBucket(const PolicyBucketId &bucket) { - return askCynaraAndInterpreteCodeResponse(bucket); + return interpretCodeResponse(codeResponse->m_code); } -int OnlineLogic::adminCheck(const PolicyBucketId &startBucket, bool recursive, const PolicyKey &key, - PolicyResult &result) { - if (!ensureConnection()) { - LOGE("Cannot connect to cynara. Service not available."); - return CYNARA_API_SERVICE_NOT_AVAILABLE; +int OnlineLogic::removeBucket(const PolicyBucketId &bucket) { + CodeResponsePtr codeResponse; + int ret = getResponse(codeResponse, bucket); + if (ret != CYNARA_API_SUCCESS) { + return ret; } - ProtocolFrameSequenceNumber sequenceNumber = generateSequenceNumber(); + return interpretCodeResponse(codeResponse->m_code); +} - //Ask cynara service +int OnlineLogic::adminCheck(const PolicyBucketId &startBucket, bool recursive, const PolicyKey &key, + PolicyResult &result) { AdminCheckResponsePtr adminCheckResponse; - - RequestPtr request = std::make_shared(key, startBucket, recursive, - sequenceNumber); - ResponsePtr response; - while (!(response = m_socketClient->askCynaraServer(request))) { - if (!m_socketClient->connect()) - return CYNARA_API_SERVICE_NOT_AVAILABLE; - } - - adminCheckResponse = std::dynamic_pointer_cast(response); - if (!adminCheckResponse) { - LOGC("Casting Response to AdminCheckResponse failed."); - return CYNARA_API_UNKNOWN_ERROR; + int ret = getResponse(adminCheckResponse, key, startBucket, recursive); + if (ret != CYNARA_API_SUCCESS) { + return ret; } LOGD("AdminCheckResponse: policyType [%" PRIu16 "], metadata <%s>, bucketValid [%d]", @@ -166,27 +167,10 @@ int OnlineLogic::adminCheck(const PolicyBucketId &startBucket, bool recursive, c int OnlineLogic::listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter, std::vector &policies) { - if (!ensureConnection()) { - LOGE("Cannot connect to cynara. Service not available."); - return CYNARA_API_SERVICE_NOT_AVAILABLE; - } - - ProtocolFrameSequenceNumber sequenceNumber = generateSequenceNumber(); - - //Ask cynara service ListResponsePtr listResponse; - - RequestPtr request = std::make_shared(bucket, filter, sequenceNumber); - ResponsePtr response; - while (!(response = m_socketClient->askCynaraServer(request))) { - if (!m_socketClient->connect()) - return CYNARA_API_SERVICE_NOT_AVAILABLE; - } - - listResponse = std::dynamic_pointer_cast(response); - if (!listResponse) { - LOGC("Casting Response to ListResponse failed."); - return CYNARA_API_UNKNOWN_ERROR; + int ret = getResponse(listResponse, bucket, filter); + if (ret != CYNARA_API_SUCCESS) { + return ret; } LOGD("listResponse: number of policies [%zu], bucketValid [%d]", @@ -202,7 +186,13 @@ int OnlineLogic::listPolicies(const PolicyBucketId &bucket, const PolicyKey &fil int OnlineLogic::erasePolicies(const PolicyBucketId &startBucket, bool recursive, const PolicyKey &filter) { - return askCynaraAndInterpreteCodeResponse(startBucket, recursive, filter); + CodeResponsePtr codeResponse; + int ret = getResponse(codeResponse, startBucket, recursive, filter); + if (ret != CYNARA_API_SUCCESS) { + return ret; + } + + return interpretCodeResponse(codeResponse->m_code); } int OnlineLogic::listDescriptions(std::vector &descriptions) { diff --git a/src/admin/logic/OnlineLogic.h b/src/admin/logic/OnlineLogic.h index 84becd7..fbcbc48 100644 --- a/src/admin/logic/OnlineLogic.h +++ b/src/admin/logic/OnlineLogic.h @@ -34,8 +34,8 @@ private: SocketClientPtr m_socketClient; bool ensureConnection(void); - template - int askCynaraAndInterpreteCodeResponse(Args... args); + template + int getResponse(std::shared_ptr &retResponse, ReqArgs... args); public: OnlineLogic(); -- 2.7.4 From 58dcbfa29d996c3e6c3c291432d8d7925cc424e0 Mon Sep 17 00:00:00 2001 From: Zofia Abramowska Date: Mon, 22 Dec 2014 17:27:21 +0100 Subject: [PATCH 06/16] Implement plugin description listing in admin logic Change-Id: I82f82a7dc31cad4349c91ac61a36b70e00c2929a --- src/admin/logic/OnlineLogic.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/admin/logic/OnlineLogic.cpp b/src/admin/logic/OnlineLogic.cpp index d27681b..b9be92d 100644 --- a/src/admin/logic/OnlineLogic.cpp +++ b/src/admin/logic/OnlineLogic.cpp @@ -17,6 +17,7 @@ * @file src/admin/logic/OnlineLogic.cpp * @author Lukasz Wojciechowski * @author Aleksander Zdyb + * @author Zofia Abramowska * @version 1.0 * @brief This file contains implementation of online version of Logic class */ @@ -33,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -196,7 +199,16 @@ int OnlineLogic::erasePolicies(const PolicyBucketId &startBucket, bool recursive } int OnlineLogic::listDescriptions(std::vector &descriptions) { - (void) descriptions; + DescriptionListResponsePtr descrResponse; + int ret = getResponse(descrResponse); + if (ret != CYNARA_API_SUCCESS) { + return ret; + } + + LOGD("descriptionListResponse: number of plugin descriptions [%zu]", + descrResponse->descriptions().size()); + + descriptions = descrResponse->descriptions(); return CYNARA_API_SUCCESS; } -- 2.7.4 From c6b77d8b0f195bc70efe737ac67701a9c91dd8f9 Mon Sep 17 00:00:00 2001 From: Zofia Abramowska Date: Mon, 22 Dec 2014 18:03:21 +0100 Subject: [PATCH 07/16] Implement plugin description listing in service logic Change-Id: I426edc48d77768b2841fb96ee35eb6eb01cfae11 --- src/service/logic/Logic.cpp | 11 +++++++++++ src/service/logic/Logic.h | 1 + 2 files changed, 12 insertions(+) diff --git a/src/service/logic/Logic.cpp b/src/service/logic/Logic.cpp index 75c94ca..4a547a0 100644 --- a/src/service/logic/Logic.cpp +++ b/src/service/logic/Logic.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,7 @@ #include #include #include +#include #include #include @@ -271,6 +273,15 @@ bool Logic::update(const PolicyKey &key, ProtocolFrameSequenceNumber checkId, return false; } +void Logic::execute(RequestContextPtr context, DescriptionListRequestPtr request) { + auto descriptions = m_pluginManager->getPolicyDescriptions(); + descriptions.insert(descriptions.begin(), predefinedPolicyDescr.begin(), + predefinedPolicyDescr.end()); + + context->returnResponse(context, std::make_shared(descriptions, + request->sequenceNumber())); +} + void Logic::execute(RequestContextPtr context, EraseRequestPtr request) { auto code = CodeResponse::Code::OK; diff --git a/src/service/logic/Logic.h b/src/service/logic/Logic.h index 71c5d01..a0ea510 100644 --- a/src/service/logic/Logic.h +++ b/src/service/logic/Logic.h @@ -69,6 +69,7 @@ public: virtual void execute(RequestContextPtr context, AgentRegisterRequestPtr request); virtual void execute(RequestContextPtr context, CancelRequestPtr request); virtual void execute(RequestContextPtr context, CheckRequestPtr request); + virtual void execute(RequestContextPtr context, DescriptionListRequestPtr request); virtual void execute(RequestContextPtr context, EraseRequestPtr request); virtual void execute(RequestContextPtr context, InsertOrUpdateBucketRequestPtr request); virtual void execute(RequestContextPtr context, ListRequestPtr request); -- 2.7.4 From 901e1a401e6a1bd00577307bb4685a43baed80cb Mon Sep 17 00:00:00 2001 From: Zofia Abramowska Date: Tue, 23 Dec 2014 13:51:36 +0100 Subject: [PATCH 08/16] Implement plugin description listing in admin protocol layer Change-Id: Id8de44b255234fec8a4bd85091283db2f00be205 --- src/common/protocol/ProtocolAdmin.cpp | 57 +++++++++++++++++++++++++++++++++++ src/common/protocol/ProtocolAdmin.h | 4 +++ src/common/protocol/ProtocolOpCode.h | 4 ++- src/service/logic/Logic.cpp | 1 - test/CMakeLists.txt | 3 ++ 5 files changed, 67 insertions(+), 2 deletions(-) diff --git a/src/common/protocol/ProtocolAdmin.cpp b/src/common/protocol/ProtocolAdmin.cpp index ccbf589..238374b 100644 --- a/src/common/protocol/ProtocolAdmin.cpp +++ b/src/common/protocol/ProtocolAdmin.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,7 @@ #include #include #include +#include #include #include @@ -74,6 +76,11 @@ RequestPtr ProtocolAdmin::deserializeAdminCheckRequest(void) { m_frameHeader.sequenceNumber()); } +RequestPtr ProtocolAdmin::deserializeDescriptionListRequest(void) { + LOGD("Deserialized DescriptionListRequest"); + return std::make_shared(m_frameHeader.sequenceNumber()); +} + RequestPtr ProtocolAdmin::deserializeEraseRequest(void) { PolicyBucketId startBucket; bool recursive; @@ -201,6 +208,8 @@ RequestPtr ProtocolAdmin::extractRequestFromBuffer(BinaryQueuePtr bufferQueue) { switch (opCode) { case OpAdminCheckRequest: return deserializeAdminCheckRequest(); + case OpDescriptionListRequest: + return deserializeDescriptionListRequest(); case OpEraseRequest: return deserializeEraseRequest(); case OpInsertOrUpdateBucket: @@ -248,6 +257,24 @@ ResponsePtr ProtocolAdmin::deserializeCodeResponse(void) { m_frameHeader.sequenceNumber()); } +ResponsePtr ProtocolAdmin::deserializeDescriptionListResponse(void) { + ProtocolFrameFieldsCount descriptionsCount; + + ProtocolDeserialization::deserialize(m_frameHeader, descriptionsCount); + std::vector descriptions(descriptionsCount, + PolicyDescription(PredefinedPolicyType::NONE)); + + for (ProtocolFrameFieldsCount fields = 0; fields < descriptionsCount; fields++) { + ProtocolDeserialization::deserialize(m_frameHeader, descriptions[fields].type); + ProtocolDeserialization::deserialize(m_frameHeader, descriptions[fields].name); + } + + LOGD("Deserialized DescriptionListResponse: number of descriptions [%" PRIu16 "]", + descriptionsCount); + + return std::make_shared(descriptions, m_frameHeader.sequenceNumber()); +} + ResponsePtr ProtocolAdmin::deserializeListResponse(void) { ProtocolFrameFieldsCount policiesCount; PolicyKeyFeature::ValueType client, user, privilege; @@ -294,6 +321,8 @@ ResponsePtr ProtocolAdmin::extractResponseFromBuffer(BinaryQueuePtr bufferQueue) return deserializeAdminCheckResponse(); case OpCodeResponse: return deserializeCodeResponse(); + case OpDescriptionListResponse: + return deserializeDescriptionListResponse(); case OpListResponse: return deserializeListResponse(); default: @@ -323,6 +352,15 @@ void ProtocolAdmin::execute(RequestContextPtr context, AdminCheckRequestPtr requ ProtocolFrameSerializer::finishSerialization(frame, *(context->responseQueue())); } +void ProtocolAdmin::execute(RequestContextPtr context, DescriptionListRequestPtr request) { + LOGD("Serializing DescriptionListRequest"); + ProtocolFrame frame = ProtocolFrameSerializer::startSerialization(request->sequenceNumber()); + + ProtocolSerialization::serialize(frame, OpDescriptionListRequest); + + ProtocolFrameSerializer::finishSerialization(frame, *(context->responseQueue())); +} + void ProtocolAdmin::execute(RequestContextPtr context, EraseRequestPtr request) { LOGD("Serializing EraseRequest: sequenceNumber [%" PRIu16 "], startBucket <%s>, " "recursive [%d], filter client <%s> filter user <%s> filter privilege <%s>", @@ -461,6 +499,25 @@ void ProtocolAdmin::execute(RequestContextPtr context, CodeResponsePtr response) ProtocolFrameSerializer::finishSerialization(frame, *(context->responseQueue())); } +void ProtocolAdmin::execute(RequestContextPtr context, DescriptionListResponsePtr response) { + ProtocolFrameFieldsCount descriptionsSize + = static_cast(response->descriptions().size()); + + LOGD("Serializing DescriptionListResponse: op [%" PRIu8 "], sequenceNumber [%" PRIu16 "], " + "number of descriptions [%" PRIu16 "]", OpDescriptionListResponse, + response->sequenceNumber(), descriptionsSize); + + ProtocolFrame frame = ProtocolFrameSerializer::startSerialization(response->sequenceNumber()); + + ProtocolSerialization::serialize(frame, OpDescriptionListResponse); + ProtocolSerialization::serialize(frame, descriptionsSize); + for (auto &desc : response->descriptions()) { + ProtocolSerialization::serialize(frame, desc.type); + ProtocolSerialization::serialize(frame, desc.name); + } + ProtocolFrameSerializer::finishSerialization(frame, *(context->responseQueue())); +} + void ProtocolAdmin::execute(RequestContextPtr context, ListResponsePtr response) { ProtocolFrameFieldsCount policiesSize = static_cast(response->policies().size()); diff --git a/src/common/protocol/ProtocolAdmin.h b/src/common/protocol/ProtocolAdmin.h index f1db4e4..254dd33 100644 --- a/src/common/protocol/ProtocolAdmin.h +++ b/src/common/protocol/ProtocolAdmin.h @@ -39,6 +39,7 @@ public: virtual ResponsePtr extractResponseFromBuffer(BinaryQueuePtr bufferQueue); virtual void execute(RequestContextPtr context, AdminCheckRequestPtr request); + virtual void execute(RequestContextPtr context, DescriptionListRequestPtr request); virtual void execute(RequestContextPtr context, EraseRequestPtr request); virtual void execute(RequestContextPtr context, InsertOrUpdateBucketRequestPtr request); virtual void execute(RequestContextPtr context, ListRequestPtr request); @@ -47,10 +48,12 @@ public: virtual void execute(RequestContextPtr context, AdminCheckResponsePtr response); virtual void execute(RequestContextPtr context, CodeResponsePtr response); + virtual void execute(RequestContextPtr context, DescriptionListResponsePtr response); virtual void execute(RequestContextPtr context, ListResponsePtr response); private: RequestPtr deserializeAdminCheckRequest(void); + RequestPtr deserializeDescriptionListRequest(void); RequestPtr deserializeEraseRequest(void); RequestPtr deserializeInsertOrUpdateBucketRequest(void); RequestPtr deserializeListRequest(void); @@ -59,6 +62,7 @@ private: ResponsePtr deserializeAdminCheckResponse(void); ResponsePtr deserializeCodeResponse(void); + ResponsePtr deserializeDescriptionListResponse(void); ResponsePtr deserializeListResponse(void); }; diff --git a/src/common/protocol/ProtocolOpCode.h b/src/common/protocol/ProtocolOpCode.h index 42289ac..6aefb10 100644 --- a/src/common/protocol/ProtocolOpCode.h +++ b/src/common/protocol/ProtocolOpCode.h @@ -49,8 +49,10 @@ enum ProtocolOpCode : uint8_t { OpListResponse, OpAdminCheckPolicyResponse, OpEraseRequest, + OpDescriptionListRequest, + OpDescriptionListResponse, - /** Opcodes 29 - 39 are reserved for future use */ + /** Opcodes 31 - 39 are reserved for future use */ /** Agent operations */ OpAgentRegisterRequest = 40, diff --git a/src/service/logic/Logic.cpp b/src/service/logic/Logic.cpp index 4a547a0..c6a045f 100644 --- a/src/service/logic/Logic.cpp +++ b/src/service/logic/Logic.cpp @@ -277,7 +277,6 @@ void Logic::execute(RequestContextPtr context, DescriptionListRequestPtr request auto descriptions = m_pluginManager->getPolicyDescriptions(); descriptions.insert(descriptions.begin(), predefinedPolicyDescr.begin(), predefinedPolicyDescr.end()); - context->returnResponse(context, std::make_shared(descriptions, request->sequenceNumber())); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 99097cc..f0c3736 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -29,6 +29,7 @@ SET(CYNARA_SOURCES_FOR_TESTS ${CYNARA_SRC}/common/protocol/ProtocolFrameHeader.cpp ${CYNARA_SRC}/common/protocol/ProtocolFrameSerializer.cpp ${CYNARA_SRC}/common/request/AdminCheckRequest.cpp + ${CYNARA_SRC}/common/request/DescriptionListRequest.cpp ${CYNARA_SRC}/common/request/EraseRequest.cpp ${CYNARA_SRC}/common/request/InsertOrUpdateBucketRequest.cpp ${CYNARA_SRC}/common/request/ListRequest.cpp @@ -36,6 +37,7 @@ SET(CYNARA_SOURCES_FOR_TESTS ${CYNARA_SRC}/common/request/RequestTaker.cpp ${CYNARA_SRC}/common/request/SetPoliciesRequest.cpp ${CYNARA_SRC}/common/response/AdminCheckResponse.cpp + ${CYNARA_SRC}/common/response/DescriptionListResponse.cpp ${CYNARA_SRC}/common/response/CheckResponse.cpp ${CYNARA_SRC}/common/response/CodeResponse.cpp ${CYNARA_SRC}/common/response/ListResponse.cpp @@ -43,6 +45,7 @@ SET(CYNARA_SOURCES_FOR_TESTS ${CYNARA_SRC}/common/types/PolicyBucket.cpp ${CYNARA_SRC}/common/types/PolicyKey.cpp ${CYNARA_SRC}/common/types/PolicyKeyHelpers.cpp + ${CYNARA_SRC}/common/types/PolicyDescription.cpp ${CYNARA_SRC}/common/types/PolicyResult.cpp ${CYNARA_SRC}/common/types/PolicyType.cpp ${CYNARA_SRC}/helpers/creds-commons/CredsCommonsInner.cpp -- 2.7.4 From c4f69ad41c30dee9e313e65a2dcb1f263deef5fe Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Sun, 28 Dec 2014 01:38:33 +0100 Subject: [PATCH 09/16] Add serialization tests for DescriptionList Add tests checking serialization/deserialization of DescriptionListRequest and DescriptionListResponse implementation in ProtocolAdmin. Change-Id: Ic3579436f361cbf9a9d60393de733c800c52181d --- test/CMakeLists.txt | 2 + .../protocols/admin/descriptionlistrequest.cpp | 59 ++++++ .../protocols/admin/descriptionlistresponse.cpp | 203 +++++++++++++++++++++ 3 files changed, 264 insertions(+) create mode 100644 test/common/protocols/admin/descriptionlistrequest.cpp create mode 100644 test/common/protocols/admin/descriptionlistresponse.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f0c3736..6f8ef37 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -63,6 +63,8 @@ SET(CYNARA_TESTS_SOURCES common/exceptions/bucketrecordcorrupted.cpp common/protocols/admin/admincheckrequest.cpp common/protocols/admin/admincheckresponse.cpp + common/protocols/admin/descriptionlistrequest.cpp + common/protocols/admin/descriptionlistresponse.cpp common/protocols/admin/eraserequest.cpp common/protocols/admin/listrequest.cpp common/protocols/admin/listresponse.cpp diff --git a/test/common/protocols/admin/descriptionlistrequest.cpp b/test/common/protocols/admin/descriptionlistrequest.cpp new file mode 100644 index 0000000..e34008f --- /dev/null +++ b/test/common/protocols/admin/descriptionlistrequest.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014 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. + */ +/** + * @file test/common/protocols/admin/descriptionlistrequest.cpp + * @author Lukasz Wojciechowski + * @version 1.0 + * @brief Tests for Cynara::DescriptionListRequest usage in Cynara::ProtocolAdmin + */ + +#include + +#include +#include + +#include +#include + +namespace { + +template<> +void compare(const Cynara::DescriptionListRequest &req1, const Cynara::DescriptionListRequest &req2) +{ + EXPECT_EQ(req1.sequenceNumber(), req2.sequenceNumber()); +} + +} /* namespace anonymous */ + +using namespace Cynara; +using namespace RequestTestHelper; +using namespace TestDataCollection; + +/* *** compare by objects test cases *** */ + +TEST(ProtocolAdmin, DescriptionListRequest01) { + auto request = std::make_shared(SN::min); + auto protocol = std::make_shared(); + testRequest(request, protocol); +} + +/* *** compare by serialized data test cases *** */ + +TEST(ProtocolAdmin, DescriptionListRequestBinary01) { + auto request = std::make_shared(SN::min); + auto protocol = std::make_shared(); + binaryTestRequest(request, protocol); +} diff --git a/test/common/protocols/admin/descriptionlistresponse.cpp b/test/common/protocols/admin/descriptionlistresponse.cpp new file mode 100644 index 0000000..43acbaa --- /dev/null +++ b/test/common/protocols/admin/descriptionlistresponse.cpp @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2014 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. + */ +/** + * @file test/common/protocols/admin/descriptionlistresponse.cpp + * @author Lukasz Wojciechowski + * @version 1.0 + * @brief Tests for Cynara::DescriptionListResponse usage in Cynara::ProtocolAdmin + */ + +#include + +#include + +#include +#include +#include + +#include +#include + +namespace { + +template<> +void compare(const Cynara::DescriptionListResponse &resp1, + const Cynara::DescriptionListResponse &resp2) { + ASSERT_EQ(resp1.descriptions().size(), resp2.descriptions().size()); + for (size_t i = 0U; i < resp1.descriptions().size(); ++i) { + SCOPED_TRACE(std::to_string(i)); + EXPECT_EQ(resp1.descriptions()[i].name, resp2.descriptions()[i].name); + EXPECT_EQ(resp1.descriptions()[i].type, resp2.descriptions()[i].type); + } +} + +} /* namespace anonymous */ + +using namespace Cynara; +using namespace ResponseTestHelper; +using namespace TestDataCollection; + +/* *** compare by objects test cases *** */ + +TEST(ProtocolAdmin, DescriptionListResponse01) { + std::vector descriptions = { + PolicyDescription(Types::allow, "allow"), + }; + + auto response = std::make_shared(descriptions, SN::min); + auto protocol = std::make_shared(); + testResponse(response, protocol); +} + +TEST(ProtocolAdmin, DescriptionListResponse02) { + std::vector descriptions = { + PolicyDescription(Types::bucket, "bucket"), + }; + + auto response = std::make_shared(descriptions, SN::min_1); + auto protocol = std::make_shared(); + testResponse(response, protocol); +} + +TEST(ProtocolAdmin, DescriptionListResponse03) { + std::vector descriptions = { + PolicyDescription(Types::deny, "deny"), + }; + + auto response = std::make_shared(descriptions, SN::max); + auto protocol = std::make_shared(); + testResponse(response, protocol); +} + +TEST(ProtocolAdmin, DescriptionListResponse04) { + std::vector descriptions = { + PolicyDescription(Types::none, "none"), + }; + + auto response = std::make_shared(descriptions, SN::max_1); + auto protocol = std::make_shared(); + testResponse(response, protocol); +} + +TEST(ProtocolAdmin, DescriptionListResponse05) { + std::vector descriptions = { + PolicyDescription(Types::plugin_type, "plugin"), + }; + + auto response = std::make_shared(descriptions, SN::mid); + auto protocol = std::make_shared(); + testResponse(response, protocol); +} + +TEST(ProtocolAdmin, DescriptionListResponseMultipleDescriptions) { + std::vector descriptions = { + PolicyDescription(Types::allow, "allow"), + PolicyDescription(Types::bucket, "bucket"), + PolicyDescription(Types::deny, "deny"), + PolicyDescription(Types::none, "none"), + PolicyDescription(Types::plugin_type, ""), + PolicyDescription(Types::plugin_type, "plugin"), + PolicyDescription(Types::plugin_type, "plugin"), + }; + + auto response = std::make_shared(descriptions, SN::max_2); + auto protocol = std::make_shared(); + testResponse(response, protocol); +} + +TEST(ProtocolAdmin, DescriptionListResponseEmptyDescriptions) { + std::vector descriptions; + + auto response = std::make_shared(descriptions, SN::min_2); + auto protocol = std::make_shared(); + testResponse(response, protocol); +} + +/* *** compare by serialized data test cases *** */ + +TEST(ProtocolAdmin, DescriptionListResponseBinary01) { + std::vector descriptions = { + PolicyDescription(Types::allow, "allow"), + }; + + auto response = std::make_shared(descriptions, SN::min); + auto protocol = std::make_shared(); + binaryTestResponse(response, protocol); +} + +TEST(ProtocolAdmin, DescriptionListResponseBinary02) { + std::vector descriptions = { + PolicyDescription(Types::bucket, "bucket"), + }; + + auto response = std::make_shared(descriptions, SN::min_1); + auto protocol = std::make_shared(); + binaryTestResponse(response, protocol); +} + +TEST(ProtocolAdmin, DescriptionListResponseBinary03) { + std::vector descriptions = { + PolicyDescription(Types::deny, "deny"), + }; + + auto response = std::make_shared(descriptions, SN::max); + auto protocol = std::make_shared(); + binaryTestResponse(response, protocol); +} + +TEST(ProtocolAdmin, DescriptionListResponseBinary04) { + std::vector descriptions = { + PolicyDescription(Types::none, "none"), + }; + + auto response = std::make_shared(descriptions, SN::max_1); + auto protocol = std::make_shared(); + binaryTestResponse(response, protocol); +} + +TEST(ProtocolAdmin, DescriptionListResponseBinary05) { + std::vector descriptions = { + PolicyDescription(Types::plugin_type, "plugin"), + }; + + auto response = std::make_shared(descriptions, SN::mid); + auto protocol = std::make_shared(); + binaryTestResponse(response, protocol); +} + +TEST(ProtocolAdmin, DescriptionListResponseBinaryMultipleDescriptions) { + std::vector descriptions = { + PolicyDescription(Types::allow, "allow"), + PolicyDescription(Types::bucket, "bucket"), + PolicyDescription(Types::deny, "deny"), + PolicyDescription(Types::none, "none"), + PolicyDescription(Types::plugin_type, ""), + PolicyDescription(Types::plugin_type, "plugin"), + PolicyDescription(Types::plugin_type, "plugin"), + }; + + auto response = std::make_shared(descriptions, SN::max_2); + auto protocol = std::make_shared(); + binaryTestResponse(response, protocol); +} + +TEST(ProtocolAdmin, DescriptionListResponseBinaryEmptyDescriptions) { + std::vector descriptions; + + auto response = std::make_shared(descriptions, SN::min_2); + auto protocol = std::make_shared(); + binaryTestResponse(response, protocol); +} -- 2.7.4 From e8b68f17f299c52e067acd21e7e6fd8b5c3d346d Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Tue, 9 Dec 2014 09:56:06 +0100 Subject: [PATCH 10/16] Fix unregistering agents on contextClosed event Also: * fix agent talkers removing * optimize check requests removing Change-Id: I0f0251783f00a90a5e3004638b08878255251eb8 --- src/service/agent/AgentManager.cpp | 20 +++++++++++++------- src/service/request/CheckRequestManager.cpp | 8 +++++--- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/service/agent/AgentManager.cpp b/src/service/agent/AgentManager.cpp index d551790..7c8d4be 100644 --- a/src/service/agent/AgentManager.cpp +++ b/src/service/agent/AgentManager.cpp @@ -101,19 +101,25 @@ AgentTalkerPtr AgentManager::getTalker(const LinkId &linkId, ProtocolFrameSequen } void AgentManager::removeTalker(const AgentTalkerPtr &agentTalker) { - m_talkers[agentTalker->linkId()].erase(agentTalker->checkId()); + auto it = m_talkers.find(agentTalker->linkId()); + if (it != m_talkers.end()) { + it->second.erase(agentTalker->checkId()); + if (it->second.empty()) { + m_talkers.erase(it); + } + } } void AgentManager::cleanupAgent(const LinkId &linkId, TalkerCleanupFunction cleanupFunction) { auto talkerMap = m_talkers.find(linkId); - if (talkerMap == m_talkers.end()) - return; - - if (cleanupFunction) { - for (auto p : talkerMap->second) { - cleanupFunction(p.second); + if (talkerMap != m_talkers.end()) { + if (cleanupFunction) { + for (auto p : talkerMap->second) { + cleanupFunction(p.second); + } } } + unregisterAgent(linkId); } diff --git a/src/service/request/CheckRequestManager.cpp b/src/service/request/CheckRequestManager.cpp index 8090f47..06ae4ea 100644 --- a/src/service/request/CheckRequestManager.cpp +++ b/src/service/request/CheckRequestManager.cpp @@ -68,10 +68,12 @@ CheckContextPtr CheckRequestManager::getContext(const AgentTalkerPtr &talker) { } void CheckRequestManager::removeRequest(const CheckContextPtr &checkContextPtr) { - m_checks[checkContextPtr->m_requestContext->responseQueue()].erase(checkContextPtr->m_checkId); auto it = m_checks.find(checkContextPtr->m_requestContext->responseQueue()); - if (it->second.empty()) { - m_checks.erase(it); + if (it != m_checks.end()) { + it->second.erase(checkContextPtr->m_checkId); + if (it->second.empty()) { + m_checks.erase(it); + } } } -- 2.7.4 From 88c6d0114460b70ab810850b7a2a884c297ca5bb Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Wed, 17 Dec 2014 17:45:08 +0100 Subject: [PATCH 11/16] Make logs initialized in the very begining of libs Change-Id: I44bffd736e29c59c9d0d929906e43816dcf927d2 --- src/admin/api/admin-api.cpp | 4 ++-- src/agent/api/agent-api.cpp | 4 ++-- src/client-async/api/client-async-api.cpp | 4 ++-- src/client/api/client-api.cpp | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/admin/api/admin-api.cpp b/src/admin/api/admin-api.cpp index 10077df..a41171b 100644 --- a/src/admin/api/admin-api.cpp +++ b/src/admin/api/admin-api.cpp @@ -62,6 +62,8 @@ int cynara_admin_initialize(struct cynara_admin **pp_cynara_admin) { if (!pp_cynara_admin) return CYNARA_API_INVALID_PARAM; + init_log(); + return Cynara::tryCatch([&]() { try { *pp_cynara_admin = new cynara_admin(new Cynara::Logic); @@ -70,8 +72,6 @@ int cynara_admin_initialize(struct cynara_admin **pp_cynara_admin) { return CYNARA_API_OPERATION_FAILED; } - init_log(); - LOGD("Cynara admin initialized"); return CYNARA_API_SUCCESS; diff --git a/src/agent/api/agent-api.cpp b/src/agent/api/agent-api.cpp index 4baec2d..fe5eb40 100644 --- a/src/agent/api/agent-api.cpp +++ b/src/agent/api/agent-api.cpp @@ -51,11 +51,11 @@ int cynara_agent_initialize(cynara_agent **pp_cynara_agent, const char *p_agent_ if (!pp_cynara_agent) return CYNARA_API_INVALID_PARAM; + init_log(); + return Cynara::tryCatch([&]() { *pp_cynara_agent = new cynara_agent(new Cynara::Logic(p_agent_type)); - init_log(); - LOGD("Cynara agent initialized"); return CYNARA_API_SUCCESS; diff --git a/src/client-async/api/client-async-api.cpp b/src/client-async/api/client-async-api.cpp index 13e5a16..e3e4ef1 100644 --- a/src/client-async/api/client-async-api.cpp +++ b/src/client-async/api/client-async-api.cpp @@ -48,11 +48,11 @@ int cynara_async_initialize(cynara_async **pp_cynara, if (!pp_cynara) return CYNARA_API_INVALID_PARAM; + init_log(); + return Cynara::tryCatch([&]() { *pp_cynara = new cynara_async(new Cynara::Logic(callback, user_status_data)); - init_log(); - LOGD("Cynara client async initialized"); return CYNARA_API_SUCCESS; diff --git a/src/client/api/client-api.cpp b/src/client/api/client-api.cpp index 935c6cd..0bd7c91 100644 --- a/src/client/api/client-api.cpp +++ b/src/client/api/client-api.cpp @@ -48,11 +48,11 @@ int cynara_initialize(cynara **pp_cynara, const cynara_configuration *p_conf UNU if (!pp_cynara) return CYNARA_API_INVALID_PARAM; + init_log(); + return Cynara::tryCatch([&]() { *pp_cynara = new cynara(new Cynara::Logic); - init_log(); - LOGD("Cynara client initialized"); return CYNARA_API_SUCCESS; -- 2.7.4 From 676ab079e03e84afb855ca4ebfbbb12a8dc2fb3f Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Wed, 17 Dec 2014 19:19:20 +0100 Subject: [PATCH 12/16] Add debug info in plugins loading mechanism Change-Id: Ifebe1dcb8b985764b3cbcdbf9f3bb3d0462ad234 --- src/common/plugin/PluginManager.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/common/plugin/PluginManager.cpp b/src/common/plugin/PluginManager.cpp index 300dc7f..853b719 100644 --- a/src/common/plugin/PluginManager.cpp +++ b/src/common/plugin/PluginManager.cpp @@ -103,6 +103,8 @@ void PluginManager::loadPlugins(void) { } void PluginManager::openPlugin(const std::string &path) { + LOGD("Loading plugin: <%s>", path.c_str()); + void *handle = dlopen(path.c_str(), RTLD_LAZY); if (!handle) { @@ -141,8 +143,10 @@ void PluginManager::openPlugin(const std::string &path) { } for (auto &desc : policies) { if (!m_plugins.insert(std::make_pair(desc, pluginPtr)).second) { - LOGW("policy type: [%" PRIu16 "] name: <%s> was already supported.", + LOGW("Policy: type [%" PRIu16 "] name <%s> was already supported.", desc.type, desc.name.c_str()); + } else { + LOGD("Supported policy: type [%" PRIu16 "] name <%s>", desc.type, desc.name.c_str()); } } -- 2.7.4 From f7f67570b1de2be45d952c790f60e2f30619a30b Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Wed, 17 Dec 2014 19:34:38 +0100 Subject: [PATCH 13/16] Fix searching plugin in CapacityCache::update() Also put procedure finding plugin into method as it repeats twice. Change-Id: Icd77e45f77637a7e52871aa8d2b2c9d8d4af925d --- src/client-common/cache/CapacityCache.cpp | 41 +++++++++++++++++-------------- src/client-common/cache/CapacityCache.h | 2 +- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/client-common/cache/CapacityCache.cpp b/src/client-common/cache/CapacityCache.cpp index 25ae6ad..0a9a207 100644 --- a/src/client-common/cache/CapacityCache.cpp +++ b/src/client-common/cache/CapacityCache.cpp @@ -47,18 +47,11 @@ int CapacityCache::get(const ClientSession &session, const PolicyKey &key) { auto &cachedValue = resultIt->second; auto &policyResult = std::get<0>(cachedValue); - ClientPluginInterfacePtr plugin; - auto pluginIt = m_plugins.find(policyResult.policyType()); - if (pluginIt != m_plugins.end()) { - plugin = pluginIt->second; - } else { - plugin = std::dynamic_pointer_cast( - m_pluginManager.getPlugin(policyResult.policyType())); - if (!plugin) { - LOGE("No plugin registered for given PolicyType : %" PRIu16, - policyResult.policyType()); - return CYNARA_API_ACCESS_DENIED; - } + ClientPluginInterfacePtr plugin = findPlugin(policyResult.policyType()); + if (!plugin) { + LOGE("No plugin registered for given policyType: [%" PRIu16 "]", + policyResult.policyType()); + return CYNARA_API_ACCESS_DENIED; } //Is it still usable? @@ -117,15 +110,11 @@ int CapacityCache::update(const ClientSession &session, const PolicyKey &key, const PolicyResult &result) { - auto pluginIt = m_plugins.find(result.policyType()); - - //No registered plugin for returned type of policy - if (pluginIt == m_plugins.end()) { - LOGE("No registered plugin for given PolicyType: %" PRIu16, - result.policyType()); + ClientPluginInterfacePtr plugin = findPlugin(result.policyType()); + if (!plugin) { + LOGE("No plugin registered for given policyType: [%" PRIu16 "]", result.policyType()); return CYNARA_API_ACCESS_DENIED; } - auto plugin = pluginIt->second; PolicyResult storedResult = result; @@ -160,4 +149,18 @@ int CapacityCache::update(const ClientSession &session, return plugin->toResult(session, storedResult); } +ClientPluginInterfacePtr CapacityCache::findPlugin(PolicyType policyType) { + ClientPluginInterfacePtr plugin; + + auto pluginIt = m_plugins.find(policyType); + if (pluginIt != m_plugins.end()) { + plugin = pluginIt->second; + } else { + plugin = std::dynamic_pointer_cast( + m_pluginManager.getPlugin(policyType)); + } + + return plugin; +} + } // namespace Cynara diff --git a/src/client-common/cache/CapacityCache.h b/src/client-common/cache/CapacityCache.h index 24e1092..59ff772 100644 --- a/src/client-common/cache/CapacityCache.h +++ b/src/client-common/cache/CapacityCache.h @@ -54,7 +54,7 @@ private: static std::string keyToString(const PolicyKey &key); void evict(void); - + ClientPluginInterfacePtr findPlugin(PolicyType policyType); std::size_t m_capacity; -- 2.7.4 From c795e004a472a814b1ffdb9686c8d6a9dda5202c Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Tue, 9 Dec 2014 12:23:37 +0100 Subject: [PATCH 14/16] Introduce Cyad A command-line tool for managing Cynara's database. Change-Id: I3731f0c3166469c2e4e43dff9e4593adfc66106e --- CMakeLists.txt | 1 + packaging/cyad.manifest | 5 +++++ packaging/cynara.spec | 12 ++++++++++++ src/CMakeLists.txt | 1 + src/cyad/CMakeLists.txt | 37 +++++++++++++++++++++++++++++++++++++ src/cyad/main.cpp | 25 +++++++++++++++++++++++++ 6 files changed, 81 insertions(+) create mode 100644 packaging/cyad.manifest create mode 100644 src/cyad/CMakeLists.txt create mode 100644 src/cyad/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c7a802c..048d098 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,6 +94,7 @@ SET(TARGET_LIB_CREDS_DBUS "cynara-creds-dbus") SET(TARGET_LIB_CREDS_SOCKET "cynara-creds-socket") SET(TARGET_LIB_SESSION "cynara-session") SET(TARGET_LIB_CYNARA_STORAGE "cynara-storage") +SET(TARGET_CYAD "cyad") ADD_SUBDIRECTORY(src) ADD_SUBDIRECTORY(pkgconfig) diff --git a/packaging/cyad.manifest b/packaging/cyad.manifest new file mode 100644 index 0000000..a76fdba --- /dev/null +++ b/packaging/cyad.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/cynara.spec b/packaging/cynara.spec index c057aa1..f62aed9 100644 --- a/packaging/cynara.spec +++ b/packaging/cynara.spec @@ -17,6 +17,7 @@ Source1008: libcynara-creds-dbus.manifest Source1009: libcynara-creds-socket.manifest Source1010: libcynara-session.manifest Source1011: cynara-db-migration.manifest +Source1012: cyad.manifest Requires: default-ac-domains Requires(pre): pwdutils Requires(pre): cynara-db-migration >= %{version}-%{release} @@ -149,6 +150,12 @@ Summary: Migration tools for Cynara's database %description -n cynara-db-migration Migration tools for Cynara's database +%package -n cyad +Summary: Cynara's command-line tool + +%description -n cyad +Command-line tool to manage Cynara's database + %prep %setup -q cp -a %{SOURCE1001} . @@ -162,6 +169,7 @@ cp -a %{SOURCE1008} . cp -a %{SOURCE1009} . cp -a %{SOURCE1010} . cp -a %{SOURCE1011} . +cp -a %{SOURCE1012} . cp -a test/db/db* . %build @@ -358,3 +366,7 @@ fi %files -n cynara-db-migration %manifest cynara-db-migration.manifest %attr(700,root,root) %{_sbindir}/cynara/cynara-db-migration.sh + +%files -n cyad +%manifest cyad.manifest +%attr(700,root,root) %{_sbindir}/cyad diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 60a8a40..4bcf18c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,6 +48,7 @@ ADD_SUBDIRECTORY(common) ADD_SUBDIRECTORY(client) ADD_SUBDIRECTORY(client-async) ADD_SUBDIRECTORY(client-common) +ADD_SUBDIRECTORY(cyad) ADD_SUBDIRECTORY(admin) ADD_SUBDIRECTORY(agent) ADD_SUBDIRECTORY(storage) diff --git a/src/cyad/CMakeLists.txt b/src/cyad/CMakeLists.txt new file mode 100644 index 0000000..1e379da --- /dev/null +++ b/src/cyad/CMakeLists.txt @@ -0,0 +1,37 @@ +# Copyright (c) 2014 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. +# +# @file CMakeLists.txt +# @author Aleksander Zdyb +# + +SET(CYAD_PATH ${CYNARA_PATH}/cyad) + +SET(CYAD_SOURCES + ${CYAD_PATH}/main.cpp + ) + +INCLUDE_DIRECTORIES( + ${CYNARA_PATH} + ${CYNARA_PATH}/include + ) + +ADD_EXECUTABLE(${TARGET_CYAD} ${CYAD_SOURCES}) + +TARGET_LINK_LIBRARIES(${TARGET_CYAD} + ${TARGET_LIB_CYNARA_ADMIN} + ${TARGET_LIB_CYNARA_STORAGE} + ) + +INSTALL(TARGETS ${TARGET_CYAD} DESTINATION ${SBIN_INSTALL_DIR}) diff --git a/src/cyad/main.cpp b/src/cyad/main.cpp new file mode 100644 index 0000000..ab4a0a8 --- /dev/null +++ b/src/cyad/main.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2014 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. + */ +/** + * @file src/cyad/main.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief A commandline tool for managing Cynara's database + */ + +int main(int, char **) { + return 0; +} -- 2.7.4 From 4f39cf7bf1c01a29aba8d77c25696bced57004ae Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Tue, 9 Dec 2014 12:37:44 +0100 Subject: [PATCH 15/16] Introduce AdminApiWrapper BaseAdminApiWrapper provides interface for wrapping functions of cynara-admin API. The wrapping is needed mainly for testing purposes. AdminApiWrapper is a target implementation, while FakeAdminApiWrapper is a mock for testing. Change-Id: I0b4afb89d8b4bec62693cf070f2a5a90f1148b79 --- src/cyad/AdminApiWrapper.cpp | 59 +++++++++++++++++++++++++++++++++++++++++ src/cyad/AdminApiWrapper.h | 52 ++++++++++++++++++++++++++++++++++++ src/cyad/BaseAdminApiWrapper.h | 48 +++++++++++++++++++++++++++++++++ src/cyad/CMakeLists.txt | 1 + test/cyad/FakeAdminApiWrapper.h | 47 ++++++++++++++++++++++++++++++++ 5 files changed, 207 insertions(+) create mode 100644 src/cyad/AdminApiWrapper.cpp create mode 100644 src/cyad/AdminApiWrapper.h create mode 100644 src/cyad/BaseAdminApiWrapper.h create mode 100644 test/cyad/FakeAdminApiWrapper.h diff --git a/src/cyad/AdminApiWrapper.cpp b/src/cyad/AdminApiWrapper.cpp new file mode 100644 index 0000000..6a31b4b --- /dev/null +++ b/src/cyad/AdminApiWrapper.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014 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. + */ +/** + * @file src/cyad/AdminApiWrapper.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief Wrapper around cynara-admin API + */ + +#include + +#include "AdminApiWrapper.h" + +namespace Cynara { + +AdminApiWrapper::AdminApiWrapper() {} + +AdminApiWrapper::~AdminApiWrapper() {} + +int AdminApiWrapper::cynara_admin_initialize(struct cynara_admin **pp_cynara_admin) { + return ::cynara_admin_initialize(pp_cynara_admin); +} + +int AdminApiWrapper::cynara_admin_finish(struct cynara_admin *p_cynara_admin) { + return ::cynara_admin_finish(p_cynara_admin); +} + +int AdminApiWrapper::cynara_admin_set_policies(struct cynara_admin *p_cynara_admin, + const struct cynara_admin_policy *const *policies) { + return ::cynara_admin_set_policies(p_cynara_admin, policies); +} + +int AdminApiWrapper::cynara_admin_set_bucket(struct cynara_admin *p_cynara_admin, + const char *bucket, int operation, const char *extra) { + return ::cynara_admin_set_bucket(p_cynara_admin, bucket, operation, extra); +} + +int AdminApiWrapper::cynara_admin_check(struct cynara_admin *p_cynara_admin, + const char *start_bucket, const int recursive, + const char *client, const char *user, const char *privilege, + int *result, char **result_extra) { + return ::cynara_admin_check(p_cynara_admin, start_bucket, recursive, client, user, privilege, + result, result_extra); +} + +} /* namespace Cynara */ diff --git a/src/cyad/AdminApiWrapper.h b/src/cyad/AdminApiWrapper.h new file mode 100644 index 0000000..d688271 --- /dev/null +++ b/src/cyad/AdminApiWrapper.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2014 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. + */ +/** + * @file src/cyad/AdminApiWrapper.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Wrapper around cynara-admin API + */ + +#ifndef SRC_CYAD_ADMINAPIWRAPPER_H_ +#define SRC_CYAD_ADMINAPIWRAPPER_H_ + +#include "BaseAdminApiWrapper.h" + +struct cynara_admin; +struct cynara_admin_policy; + +namespace Cynara { + +class AdminApiWrapper : public BaseAdminApiWrapper { +public: + AdminApiWrapper(); + virtual ~AdminApiWrapper(); + + virtual int cynara_admin_initialize(struct cynara_admin **pp_cynara_admin); + virtual int cynara_admin_finish(struct cynara_admin *p_cynara_admin); + virtual int cynara_admin_set_policies(struct cynara_admin *p_cynara_admin, + const struct cynara_admin_policy *const *policies); + virtual int cynara_admin_set_bucket(struct cynara_admin *p_cynara_admin, const char *bucket, + int operation, const char *extra); + virtual int cynara_admin_check(struct cynara_admin *p_cynara_admin, + const char *start_bucket, const int recursive, + const char *client, const char *user, const char *privilege, + int *result, char **result_extra); +}; + +} /* namespace Cynara */ + +#endif /* SRC_CYAD_ADMINAPIWRAPPER_H_ */ diff --git a/src/cyad/BaseAdminApiWrapper.h b/src/cyad/BaseAdminApiWrapper.h new file mode 100644 index 0000000..a24aec2 --- /dev/null +++ b/src/cyad/BaseAdminApiWrapper.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014 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. + */ +/** + * @file src/cyad/BaseAdminApiWrapper.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Wrapper around cynara-admin API (base) + */ + +#ifndef SRC_CYAD_BASEADMINAPIWRAPPER_H_ +#define SRC_CYAD_BASEADMINAPIWRAPPER_H_ + +struct cynara_admin; +struct cynara_admin_policy; + +namespace Cynara { + +class BaseAdminApiWrapper { +public: + virtual ~BaseAdminApiWrapper() {}; + virtual int cynara_admin_initialize(struct cynara_admin **pp_cynara_admin) = 0; + virtual int cynara_admin_finish(struct cynara_admin *p_cynara_admin) = 0; + virtual int cynara_admin_set_policies(struct cynara_admin *p_cynara_admin, + const struct cynara_admin_policy *const *policies) = 0; + virtual int cynara_admin_set_bucket(struct cynara_admin *p_cynara_admin, const char *bucket, + int operation, const char *extra) = 0; + virtual int cynara_admin_check(struct cynara_admin *p_cynara_admin, + const char *start_bucket, const int recursive, + const char *client, const char *user, const char *privilege, + int *result, char **result_extra) = 0; +}; + +} /* namespace Cynara */ + +#endif /* SRC_CYAD_BASEADMINAPIWRAPPER_H_ */ diff --git a/src/cyad/CMakeLists.txt b/src/cyad/CMakeLists.txt index 1e379da..1000a0a 100644 --- a/src/cyad/CMakeLists.txt +++ b/src/cyad/CMakeLists.txt @@ -19,6 +19,7 @@ SET(CYAD_PATH ${CYNARA_PATH}/cyad) SET(CYAD_SOURCES + ${CYAD_PATH}/AdminApiWrapper.cpp ${CYAD_PATH}/main.cpp ) diff --git a/test/cyad/FakeAdminApiWrapper.h b/test/cyad/FakeAdminApiWrapper.h new file mode 100644 index 0000000..8e9b86b --- /dev/null +++ b/test/cyad/FakeAdminApiWrapper.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014 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. + */ +/** + * @file test/cyad/FakeAdminApiWrapper.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Wrapper around cynara-admin API (mock) + */ + +#ifndef TEST_CYAD_FAKEADMINAPIWRAPPER_H_ +#define TEST_CYAD_FAKEADMINAPIWRAPPER_H_ + +#include +#include + +#include + +class FakeAdminApiWrapper : public Cynara::BaseAdminApiWrapper { +public: + using BaseAdminApiWrapper::BaseAdminApiWrapper; + + MOCK_METHOD1(cynara_admin_initialize, int(struct cynara_admin **pp_cynara_admin)); + MOCK_METHOD1(cynara_admin_finish, int(struct cynara_admin *p_cynara_admin)); + MOCK_METHOD2(cynara_admin_set_policies, int(struct cynara_admin *p_cynara_admin, + const struct cynara_admin_policy *const *policies)); + MOCK_METHOD4(cynara_admin_set_bucket, int(struct cynara_admin *p_cynara_admin, + const char *bucket, int operation, const char *extra)); + MOCK_METHOD8(cynara_admin_check, int(struct cynara_admin *p_cynara_admin, + const char *start_bucket, const int recursive, + const char *client, const char *user, const char *privilege, + int *result, char **result_extra)); +}; + +#endif /* TEST_CYAD_FAKEADMINAPIWRAPPER_H_ */ -- 2.7.4 From 6d58a7c2c18f159ab5b6606509f25df7c8e2b54c Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Tue, 9 Dec 2014 13:22:55 +0100 Subject: [PATCH 16/16] Introduce CynaraAdminPolicies This is a collection of cynara_admin_policy structs. It helps to manage memory and creates a convenient wrapper while still allowing to pass it to API calls. Change-Id: I61e39dbab88cbbbef07a0bd5ace4967d20336b17 --- src/cyad/CMakeLists.txt | 1 + src/cyad/CynaraAdminPolicies.cpp | 97 ++++++++++++++++++++++++++++++++++++++++ src/cyad/CynaraAdminPolicies.h | 60 +++++++++++++++++++++++++ test/CMakeLists.txt | 3 ++ test/cyad/helpers.cpp | 64 ++++++++++++++++++++++++++ test/cyad/helpers.h | 41 +++++++++++++++++ test/cyad/policy_collection.cpp | 68 ++++++++++++++++++++++++++++ 7 files changed, 334 insertions(+) create mode 100644 src/cyad/CynaraAdminPolicies.cpp create mode 100644 src/cyad/CynaraAdminPolicies.h create mode 100644 test/cyad/helpers.cpp create mode 100644 test/cyad/helpers.h create mode 100644 test/cyad/policy_collection.cpp diff --git a/src/cyad/CMakeLists.txt b/src/cyad/CMakeLists.txt index 1000a0a..d221c75 100644 --- a/src/cyad/CMakeLists.txt +++ b/src/cyad/CMakeLists.txt @@ -20,6 +20,7 @@ SET(CYAD_PATH ${CYNARA_PATH}/cyad) SET(CYAD_SOURCES ${CYAD_PATH}/AdminApiWrapper.cpp + ${CYAD_PATH}/CynaraAdminPolicies.cpp ${CYAD_PATH}/main.cpp ) diff --git a/src/cyad/CynaraAdminPolicies.cpp b/src/cyad/CynaraAdminPolicies.cpp new file mode 100644 index 0000000..4d83014 --- /dev/null +++ b/src/cyad/CynaraAdminPolicies.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2014 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. + */ +/** + * @file src/cyad/CynaraAdminPolicies.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief Collection of cynara_admin_policy structs + */ + +#include +#include +#include +#include +#include + +#include + +#include "CynaraAdminPolicies.h" + +namespace Cynara { + +CynaraAdminPolicies::CynaraAdminPolicies() : m_sealed(false) {} + +CynaraAdminPolicies::~CynaraAdminPolicies() { + auto freePolicy = [] (cynara_admin_policy *admin_policy) { + if (admin_policy == nullptr) + return; + + free(admin_policy->bucket); + free(admin_policy->client); + free(admin_policy->user); + free(admin_policy->privilege); + free(admin_policy->result_extra); + + delete admin_policy; + }; + + std::for_each(m_policies.begin(), m_policies.end(), freePolicy); +} + +void CynaraAdminPolicies::add(const PolicyBucketId &bucketId, const PolicyResult &policyResult, + const PolicyKey &policyKey) { + if (sealed()) { + throw std::logic_error("Collection is sealed"); + } + + // TODO: Optimize -- try not to malloc every item + cynara_admin_policy *policy = new cynara_admin_policy(); + + auto duplicateString = [] (const std::string &str) -> char * { + auto ret = strdup(str.c_str()); + if (ret == nullptr) + throw std::bad_alloc(); + return ret; + }; + + policy->bucket = duplicateString(bucketId); + policy->client = duplicateString(policyKey.client().toString()); + policy->user = duplicateString(policyKey.user().toString()); + policy->privilege = duplicateString(policyKey.privilege().toString()); + policy->result = policyResult.policyType(); + + if (policyResult.metadata().empty()) + policy->result_extra = nullptr; + else + policy->result_extra = duplicateString(policyResult.metadata()); + + m_policies.push_back(policy); +} + +void CynaraAdminPolicies::seal(void) { + m_policies.push_back(nullptr); + m_sealed = true; +} + +cynara_admin_policy* const *CynaraAdminPolicies::data(void) const { + if (sealed() == false) { + throw std::logic_error("Collection is not sealed"); + } + + return m_policies.data(); +} + +} /* namespace Cynara */ diff --git a/src/cyad/CynaraAdminPolicies.h b/src/cyad/CynaraAdminPolicies.h new file mode 100644 index 0000000..8541783 --- /dev/null +++ b/src/cyad/CynaraAdminPolicies.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014 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. + */ +/** + * @file src/cyad/CynaraAdminPolicies.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Collection of cynara_admin_policy structs + */ + +#ifndef SRC_CYAD_CYNARAADMINPOLICIES_H_ +#define SRC_CYAD_CYNARAADMINPOLICIES_H_ + +#include + +#include +#include +#include +#include + +struct cynara_admin_policy; + +namespace Cynara { + +class CynaraAdminPolicies { +public: + CynaraAdminPolicies(); + virtual ~CynaraAdminPolicies(); + + void add(const PolicyBucketId &bucketId, const PolicyResult &policyResult, + const PolicyKey &policyKey); + + void seal(void); + + cynara_admin_policy* const *data(void) const; + + bool sealed(void) const { + return m_sealed; + } + +private: + std::vector m_policies; + bool m_sealed; +}; + +} /* namespace Cynara */ + +#endif /* SRC_CYAD_CYNARAADMINPOLICIES_H_ */ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6f8ef37..a60837c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -48,6 +48,7 @@ SET(CYNARA_SOURCES_FOR_TESTS ${CYNARA_SRC}/common/types/PolicyDescription.cpp ${CYNARA_SRC}/common/types/PolicyResult.cpp ${CYNARA_SRC}/common/types/PolicyType.cpp + ${CYNARA_SRC}/cyad/CynaraAdminPolicies.cpp ${CYNARA_SRC}/helpers/creds-commons/CredsCommonsInner.cpp ${CYNARA_SRC}/helpers/creds-commons/creds-commons.cpp ${CYNARA_SRC}/storage/BucketDeserializer.cpp @@ -70,6 +71,8 @@ SET(CYNARA_TESTS_SOURCES common/protocols/admin/listresponse.cpp common/types/policybucket.cpp credsCommons/parser/Parser.cpp + cyad/helpers.cpp + cyad/policy_collection.cpp helpers.cpp storage/performance/bucket.cpp storage/storage/policies.cpp diff --git a/test/cyad/helpers.cpp b/test/cyad/helpers.cpp new file mode 100644 index 0000000..1f600cb --- /dev/null +++ b/test/cyad/helpers.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014 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. + */ +/** + * @file test/cyad/helpers.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief Helper functions, matchers and operators + */ + +#include +#include + +#include + +#include "helpers.h" + +bool operator==(const cynara_admin_policy &lhs, const cynara_admin_policy &rhs) { + auto strEq = [] (const char *lhs, const char *rhs) -> bool { + if (lhs != nullptr && rhs != nullptr) + return strcmp(lhs, rhs) == 0; + else + return lhs == rhs; + }; + + return lhs.result == rhs.result + && strEq(lhs.bucket, rhs.bucket) + && strEq(lhs.client, rhs.client) + && strEq(lhs.user, rhs.user) + && strEq(lhs.privilege, rhs.privilege) + && strEq(lhs.result_extra, rhs.result_extra); +} + +bool operator!=(const cynara_admin_policy &lhs, const cynara_admin_policy &rhs) { + return !(lhs == rhs); +} + +namespace Cynara { + +namespace Helpers { + +void freeAdminPolicyMembers(cynara_admin_policy *admin_policy) { + free(admin_policy->bucket); + free(admin_policy->client); + free(admin_policy->user); + free(admin_policy->privilege); + free(admin_policy->result_extra); +} + +} /* namespace Helpers */ + +} /* namespace Cynara */ diff --git a/test/cyad/helpers.h b/test/cyad/helpers.h new file mode 100644 index 0000000..b4fd02c --- /dev/null +++ b/test/cyad/helpers.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014 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. + */ +/** + * @file test/cyad/helpers.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Helper functions, matchers and operators + */ + +#ifndef TEST_CYAD_HELPERS_H_ +#define TEST_CYAD_HELPERS_H_ + +struct cynara_admin_policy; + +bool operator==(const cynara_admin_policy &lhs, const cynara_admin_policy &rhs); +bool operator!=(const cynara_admin_policy &lhs, const cynara_admin_policy &rhs); + +namespace Cynara { + +namespace Helpers { + +void freeAdminPolicyMembers(cynara_admin_policy *admin_policy); + +} /* namespace Helpers */ + +} /* namespace Cynara */ + +#endif /* TEST_CYAD_HELPERS_H_ */ diff --git a/test/cyad/policy_collection.cpp b/test/cyad/policy_collection.cpp new file mode 100644 index 0000000..425e025 --- /dev/null +++ b/test/cyad/policy_collection.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2014 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. + */ +/** + * @file test/cyad/policy_collection.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief Tests for CynaraAdminPolicies + */ + +#include +#include + +#include +#include + +#include +#include + +#include + +#include "helpers.h" + +TEST(CynaraAdminPolicies, notSealed) { + Cynara::CynaraAdminPolicies policies; + ASSERT_THROW(policies.data(), std::logic_error); +} + +TEST(CynaraAdminPolicies, sealEmpty) { + Cynara::CynaraAdminPolicies policies; + policies.seal(); + ASSERT_EQ(nullptr, policies.data()[0]); +} + +TEST(CynaraAdminPolicies, addToSealed) { + Cynara::CynaraAdminPolicies policies; + policies.seal(); + ASSERT_THROW(policies.add("", { CYNARA_ADMIN_ALLOW, "" }, { "", "", ""} ), std::logic_error); +} + +TEST(CynaraAdminPolicies, addOne) { + using ::testing::ElementsAreArray; + + Cynara::CynaraAdminPolicies policies; + policies.add("test-bucket", { CYNARA_ADMIN_ALLOW, "" }, { "client", "user", "privilege"} ); + policies.seal(); + ASSERT_NO_THROW(policies.data()); + + cynara_admin_policy policy = { strdup("test-bucket"), strdup("client"), strdup("user"), + strdup("privilege"), CYNARA_ADMIN_ALLOW, nullptr }; + + ASSERT_EQ(policy, *policies.data()[0]); + ASSERT_EQ(nullptr, policies.data()[1]); + + Cynara::Helpers::freeAdminPolicyMembers(&policy); +} -- 2.7.4