From b2abe6e5fd4ac22dc1e75b2efcb9f4177aa57a8d Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Mon, 27 Oct 2014 14:49:11 +0100 Subject: [PATCH 01/16] Lock database in Cynara::init() Change-Id: Ib90550c8dd26af899d9749901b3ab3e043fe3e2a --- src/service/main/Cynara.cpp | 5 ++++- src/service/main/Cynara.h | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/service/main/Cynara.cpp b/src/service/main/Cynara.cpp index 96443ce..a6b96c6 100644 --- a/src/service/main/Cynara.cpp +++ b/src/service/main/Cynara.cpp @@ -16,6 +16,7 @@ /** * @file src/service/main/Cynara.cpp * @author Lukasz Wojciechowski + * @author Aleksander Zdyb * @version 1.0 * @brief This file implements main class of cynara service */ @@ -40,7 +41,8 @@ namespace Cynara { Cynara::Cynara() - : m_logic(nullptr), m_socketManager(nullptr), m_storage(nullptr), m_storageBackend(nullptr) { + : m_logic(nullptr), m_socketManager(nullptr), m_storage(nullptr), m_storageBackend(nullptr), + m_lockFile(PathConfig::StoragePath::lockFile), m_databaseLock(m_lockFile) { } Cynara::~Cynara() { @@ -62,6 +64,7 @@ void Cynara::init(void) { m_socketManager->bindLogic(m_logic); + m_databaseLock.lock(); // Wait until database lock can be acquired m_storage->load(); } diff --git a/src/service/main/Cynara.h b/src/service/main/Cynara.h index 89bdd76..b138040 100644 --- a/src/service/main/Cynara.h +++ b/src/service/main/Cynara.h @@ -16,6 +16,7 @@ /** * @file src/service/main/Cynara.h * @author Lukasz Wojciechowski + * @author Aleksander Zdyb * @version 1.0 * @brief This file defines main class of cynara service */ @@ -23,6 +24,8 @@ #ifndef SRC_SERVICE_MAIN_CYNARA_H_ #define SRC_SERVICE_MAIN_CYNARA_H_ +#include + #include
namespace Cynara { @@ -43,6 +46,8 @@ private: SocketManagerPtr m_socketManager; StoragePtr m_storage; StorageBackendPtr m_storageBackend; + Lockable m_lockFile; + FileLock m_databaseLock; }; } // namespace Cynara -- 2.7.4 From 899a094acbd9523c65432a9cb9c55bd596ddc2bc Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Tue, 23 Dec 2014 14:11:15 +0100 Subject: [PATCH 02/16] Inherit from Exception in FileLockAcquiringException Change-Id: I40eb3f6b906f34261f8c6b6596e0afb503e41e7a --- src/common/exceptions/FileLockAcquiringException.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/exceptions/FileLockAcquiringException.h b/src/common/exceptions/FileLockAcquiringException.h index 44bc54a..4640719 100644 --- a/src/common/exceptions/FileLockAcquiringException.h +++ b/src/common/exceptions/FileLockAcquiringException.h @@ -30,12 +30,13 @@ namespace Cynara { -class FileLockAcquiringException { +class FileLockAcquiringException : public Exception { public: FileLockAcquiringException(const int errNumber) : m_errno(errNumber) { m_message = "File lock acquiring error [" + std::to_string(errorNumber()) + "]" + " <" + errorString() + ">"; }; + virtual ~FileLockAcquiringException() {}; const std::string &message(void) const { -- 2.7.4 From f308922e9e1ef90823bef58b504d70a5e4d7bf3a Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Wed, 17 Dec 2014 10:24:11 +0100 Subject: [PATCH 03/16] Rename admin's Logic to OnlineLogic This is a preparation to implement OfflineLogic. Change-Id: Ica6e7dfe12ac9bc921f77e2c5d08bc539373ed07 --- src/admin/CMakeLists.txt | 2 +- src/admin/api/admin-api.cpp | 4 ++-- src/admin/logic/{Logic.cpp => OnlineLogic.cpp} | 31 +++++++++++++------------- src/admin/logic/{Logic.h => OnlineLogic.h} | 18 +++++++-------- 4 files changed, 27 insertions(+), 28 deletions(-) rename src/admin/logic/{Logic.cpp => OnlineLogic.cpp} (86%) rename src/admin/logic/{Logic.h => OnlineLogic.h} (84%) diff --git a/src/admin/CMakeLists.txt b/src/admin/CMakeLists.txt index f58c751..321ca92 100644 --- a/src/admin/CMakeLists.txt +++ b/src/admin/CMakeLists.txt @@ -23,7 +23,7 @@ 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/OnlineLogic.cpp ) INCLUDE_DIRECTORIES( diff --git a/src/admin/api/admin-api.cpp b/src/admin/api/admin-api.cpp index 401df51..1dfeb90 100644 --- a/src/admin/api/admin-api.cpp +++ b/src/admin/api/admin-api.cpp @@ -43,7 +43,7 @@ #include #include -#include +#include struct cynara_admin { Cynara::ApiInterface *impl; @@ -61,7 +61,7 @@ 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::Logic); + *pp_cynara_admin = new cynara_admin(new Cynara::OnlineLogic); init_log(); diff --git a/src/admin/logic/Logic.cpp b/src/admin/logic/OnlineLogic.cpp similarity index 86% rename from src/admin/logic/Logic.cpp rename to src/admin/logic/OnlineLogic.cpp index b0ea895..9aa1831 100644 --- a/src/admin/logic/Logic.cpp +++ b/src/admin/logic/OnlineLogic.cpp @@ -14,10 +14,11 @@ * limitations under the License */ /** - * @file src/admin/logic/Logic.cpp + * @file src/admin/logic/OnlineLogic.cpp * @author Lukasz Wojciechowski + * @author Aleksander Zdyb * @version 1.0 - * @brief This file contains implementation of Logic class - main libcynara-admin class + * @brief This file contains implementation of online version of Logic class */ #include @@ -45,11 +46,11 @@ #include #include -#include "Logic.h" +#include "OnlineLogic.h" namespace Cynara { -Logic::Logic() { +OnlineLogic::OnlineLogic() { m_socketClient = std::make_shared(PathConfig::SocketPath::admin, std::make_shared()); } @@ -59,12 +60,12 @@ ProtocolFrameSequenceNumber generateSequenceNumber(void) { return ++sequenceNumber; } -bool Logic::ensureConnection(void) { +bool OnlineLogic::ensureConnection(void) { return m_socketClient->isConnected() || m_socketClient->connect(); } template -int Logic::askCynaraAndInterpreteCodeResponse(Args... args) { +int OnlineLogic::askCynaraAndInterpreteCodeResponse(Args... args) { if (!ensureConnection()) { LOGE("Cannot connect to cynara. Service not available."); return CYNARA_API_SERVICE_NOT_AVAILABLE; @@ -109,22 +110,22 @@ int Logic::askCynaraAndInterpreteCodeResponse(Args... args) { } } -int Logic::setPolicies(const ApiInterface::PoliciesByBucket &insertOrUpdate, - const ApiInterface::KeysByBucket &remove) { +int OnlineLogic::setPolicies(const ApiInterface::PoliciesByBucket &insertOrUpdate, + const ApiInterface::KeysByBucket &remove) { return askCynaraAndInterpreteCodeResponse(insertOrUpdate, remove); } -int Logic::insertOrUpdateBucket(const PolicyBucketId &bucket, - const PolicyResult &policyResult) { +int OnlineLogic::insertOrUpdateBucket(const PolicyBucketId &bucket, + const PolicyResult &policyResult) { return askCynaraAndInterpreteCodeResponse(bucket, policyResult); } -int Logic::removeBucket(const PolicyBucketId &bucket) { +int OnlineLogic::removeBucket(const PolicyBucketId &bucket) { return askCynaraAndInterpreteCodeResponse(bucket); } -int Logic::adminCheck(const PolicyBucketId &startBucket, bool recursive, const PolicyKey &key, - PolicyResult &result) { +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; @@ -163,7 +164,7 @@ int Logic::adminCheck(const PolicyBucketId &startBucket, bool recursive, const P return CYNARA_API_SUCCESS; } -int Logic::listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter, +int OnlineLogic::listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter, std::vector &policies) { if (!ensureConnection()) { LOGE("Cannot connect to cynara. Service not available."); @@ -199,7 +200,7 @@ int Logic::listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter, return CYNARA_API_SUCCESS; } -int Logic::erasePolicies(const PolicyBucketId &startBucket, bool recursive, +int OnlineLogic::erasePolicies(const PolicyBucketId &startBucket, bool recursive, const PolicyKey &filter) { return askCynaraAndInterpreteCodeResponse(startBucket, recursive, filter); } diff --git a/src/admin/logic/Logic.h b/src/admin/logic/OnlineLogic.h similarity index 84% rename from src/admin/logic/Logic.h rename to src/admin/logic/OnlineLogic.h index 584d35d..19e3304 100644 --- a/src/admin/logic/Logic.h +++ b/src/admin/logic/OnlineLogic.h @@ -14,16 +14,14 @@ * limitations under the License */ /** - * @file src/admin/logic/Logic.h + * @file src/admin/logic/OnlineLogic.h * @author Lukasz Wojciechowski * @version 1.0 - * @brief This file contains definition of Logic class - main libcynara-admin class + * @brief This file contains definition of online version of Logic class */ -#ifndef SRC_ADMIN_LOGIC_LOGIC_H_ -#define SRC_ADMIN_LOGIC_LOGIC_H_ - -#include +#ifndef SRC_ADMIN_LOGIC_ONLINELOGIC_H_ +#define SRC_ADMIN_LOGIC_ONLINELOGIC_H_ #include @@ -31,7 +29,7 @@ namespace Cynara { -class Logic : public ApiInterface { +class OnlineLogic : public ApiInterface { private: SocketClientPtr m_socketClient; @@ -40,8 +38,8 @@ private: int askCynaraAndInterpreteCodeResponse(Args... args); public: - Logic(); - virtual ~Logic() {}; + OnlineLogic(); + virtual ~OnlineLogic() {}; virtual int setPolicies(const ApiInterface::PoliciesByBucket &insertOrUpdate, const ApiInterface::KeysByBucket &remove); @@ -59,4 +57,4 @@ public: } // namespace Cynara -#endif /* SRC_ADMIN_LOGIC_LOGIC_H_ */ +#endif /* SRC_ADMIN_LOGIC_ONLINELOGIC_H_ */ -- 2.7.4 From 14d1fb229ad782830543cb3ac04b58a46c67f504 Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Tue, 23 Dec 2014 14:21:47 +0100 Subject: [PATCH 04/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 05/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 06/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 07/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 08/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 09/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 10/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 11/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 12/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 13/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 14/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 15/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 16/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