From bb718b1017aacdd44d9301831b1e60111cb9867b Mon Sep 17 00:00:00 2001 From: Zofia Abramowska Date: Mon, 22 Dec 2014 16:40:16 +0100 Subject: [PATCH 01/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 02/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 03/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 04/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 05/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 06/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 07/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 08/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 09/16] Fix searching plugin in CapacityCache::update() Also put procedure finding plugin into method as it repeats twice. Change-Id: Icd77e45f77637a7e52871aa8d2b2c9d8d4af925d --- src/client-common/cache/CapacityCache.cpp | 41 +++++++++++++++++-------------- src/client-common/cache/CapacityCache.h | 2 +- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/client-common/cache/CapacityCache.cpp b/src/client-common/cache/CapacityCache.cpp index 25ae6ad..0a9a207 100644 --- a/src/client-common/cache/CapacityCache.cpp +++ b/src/client-common/cache/CapacityCache.cpp @@ -47,18 +47,11 @@ int CapacityCache::get(const ClientSession &session, const PolicyKey &key) { auto &cachedValue = resultIt->second; auto &policyResult = std::get<0>(cachedValue); - ClientPluginInterfacePtr plugin; - auto pluginIt = m_plugins.find(policyResult.policyType()); - if (pluginIt != m_plugins.end()) { - plugin = pluginIt->second; - } else { - plugin = std::dynamic_pointer_cast( - m_pluginManager.getPlugin(policyResult.policyType())); - if (!plugin) { - LOGE("No plugin registered for given PolicyType : %" PRIu16, - policyResult.policyType()); - return CYNARA_API_ACCESS_DENIED; - } + ClientPluginInterfacePtr plugin = findPlugin(policyResult.policyType()); + if (!plugin) { + LOGE("No plugin registered for given policyType: [%" PRIu16 "]", + policyResult.policyType()); + return CYNARA_API_ACCESS_DENIED; } //Is it still usable? @@ -117,15 +110,11 @@ int CapacityCache::update(const ClientSession &session, const PolicyKey &key, const PolicyResult &result) { - auto pluginIt = m_plugins.find(result.policyType()); - - //No registered plugin for returned type of policy - if (pluginIt == m_plugins.end()) { - LOGE("No registered plugin for given PolicyType: %" PRIu16, - result.policyType()); + ClientPluginInterfacePtr plugin = findPlugin(result.policyType()); + if (!plugin) { + LOGE("No plugin registered for given policyType: [%" PRIu16 "]", result.policyType()); return CYNARA_API_ACCESS_DENIED; } - auto plugin = pluginIt->second; PolicyResult storedResult = result; @@ -160,4 +149,18 @@ int CapacityCache::update(const ClientSession &session, return plugin->toResult(session, storedResult); } +ClientPluginInterfacePtr CapacityCache::findPlugin(PolicyType policyType) { + ClientPluginInterfacePtr plugin; + + auto pluginIt = m_plugins.find(policyType); + if (pluginIt != m_plugins.end()) { + plugin = pluginIt->second; + } else { + plugin = std::dynamic_pointer_cast( + m_pluginManager.getPlugin(policyType)); + } + + return plugin; +} + } // namespace Cynara diff --git a/src/client-common/cache/CapacityCache.h b/src/client-common/cache/CapacityCache.h index 24e1092..59ff772 100644 --- a/src/client-common/cache/CapacityCache.h +++ b/src/client-common/cache/CapacityCache.h @@ -54,7 +54,7 @@ private: static std::string keyToString(const PolicyKey &key); void evict(void); - + ClientPluginInterfacePtr findPlugin(PolicyType policyType); std::size_t m_capacity; -- 2.7.4 From c795e004a472a814b1ffdb9686c8d6a9dda5202c Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Tue, 9 Dec 2014 12:23:37 +0100 Subject: [PATCH 10/16] Introduce Cyad A command-line tool for managing Cynara's database. Change-Id: I3731f0c3166469c2e4e43dff9e4593adfc66106e --- CMakeLists.txt | 1 + packaging/cyad.manifest | 5 +++++ packaging/cynara.spec | 12 ++++++++++++ src/CMakeLists.txt | 1 + src/cyad/CMakeLists.txt | 37 +++++++++++++++++++++++++++++++++++++ src/cyad/main.cpp | 25 +++++++++++++++++++++++++ 6 files changed, 81 insertions(+) create mode 100644 packaging/cyad.manifest create mode 100644 src/cyad/CMakeLists.txt create mode 100644 src/cyad/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c7a802c..048d098 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,6 +94,7 @@ SET(TARGET_LIB_CREDS_DBUS "cynara-creds-dbus") SET(TARGET_LIB_CREDS_SOCKET "cynara-creds-socket") SET(TARGET_LIB_SESSION "cynara-session") SET(TARGET_LIB_CYNARA_STORAGE "cynara-storage") +SET(TARGET_CYAD "cyad") ADD_SUBDIRECTORY(src) ADD_SUBDIRECTORY(pkgconfig) diff --git a/packaging/cyad.manifest b/packaging/cyad.manifest new file mode 100644 index 0000000..a76fdba --- /dev/null +++ b/packaging/cyad.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/cynara.spec b/packaging/cynara.spec index c057aa1..f62aed9 100644 --- a/packaging/cynara.spec +++ b/packaging/cynara.spec @@ -17,6 +17,7 @@ Source1008: libcynara-creds-dbus.manifest Source1009: libcynara-creds-socket.manifest Source1010: libcynara-session.manifest Source1011: cynara-db-migration.manifest +Source1012: cyad.manifest Requires: default-ac-domains Requires(pre): pwdutils Requires(pre): cynara-db-migration >= %{version}-%{release} @@ -149,6 +150,12 @@ Summary: Migration tools for Cynara's database %description -n cynara-db-migration Migration tools for Cynara's database +%package -n cyad +Summary: Cynara's command-line tool + +%description -n cyad +Command-line tool to manage Cynara's database + %prep %setup -q cp -a %{SOURCE1001} . @@ -162,6 +169,7 @@ cp -a %{SOURCE1008} . cp -a %{SOURCE1009} . cp -a %{SOURCE1010} . cp -a %{SOURCE1011} . +cp -a %{SOURCE1012} . cp -a test/db/db* . %build @@ -358,3 +366,7 @@ fi %files -n cynara-db-migration %manifest cynara-db-migration.manifest %attr(700,root,root) %{_sbindir}/cynara/cynara-db-migration.sh + +%files -n cyad +%manifest cyad.manifest +%attr(700,root,root) %{_sbindir}/cyad diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 60a8a40..4bcf18c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,6 +48,7 @@ ADD_SUBDIRECTORY(common) ADD_SUBDIRECTORY(client) ADD_SUBDIRECTORY(client-async) ADD_SUBDIRECTORY(client-common) +ADD_SUBDIRECTORY(cyad) ADD_SUBDIRECTORY(admin) ADD_SUBDIRECTORY(agent) ADD_SUBDIRECTORY(storage) diff --git a/src/cyad/CMakeLists.txt b/src/cyad/CMakeLists.txt new file mode 100644 index 0000000..1e379da --- /dev/null +++ b/src/cyad/CMakeLists.txt @@ -0,0 +1,37 @@ +# Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Aleksander Zdyb +# + +SET(CYAD_PATH ${CYNARA_PATH}/cyad) + +SET(CYAD_SOURCES + ${CYAD_PATH}/main.cpp + ) + +INCLUDE_DIRECTORIES( + ${CYNARA_PATH} + ${CYNARA_PATH}/include + ) + +ADD_EXECUTABLE(${TARGET_CYAD} ${CYAD_SOURCES}) + +TARGET_LINK_LIBRARIES(${TARGET_CYAD} + ${TARGET_LIB_CYNARA_ADMIN} + ${TARGET_LIB_CYNARA_STORAGE} + ) + +INSTALL(TARGETS ${TARGET_CYAD} DESTINATION ${SBIN_INSTALL_DIR}) diff --git a/src/cyad/main.cpp b/src/cyad/main.cpp new file mode 100644 index 0000000..ab4a0a8 --- /dev/null +++ b/src/cyad/main.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file src/cyad/main.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief A commandline tool for managing Cynara's database + */ + +int main(int, char **) { + return 0; +} -- 2.7.4 From 4f39cf7bf1c01a29aba8d77c25696bced57004ae Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Tue, 9 Dec 2014 12:37:44 +0100 Subject: [PATCH 11/16] Introduce AdminApiWrapper BaseAdminApiWrapper provides interface for wrapping functions of cynara-admin API. The wrapping is needed mainly for testing purposes. AdminApiWrapper is a target implementation, while FakeAdminApiWrapper is a mock for testing. Change-Id: I0b4afb89d8b4bec62693cf070f2a5a90f1148b79 --- src/cyad/AdminApiWrapper.cpp | 59 +++++++++++++++++++++++++++++++++++++++++ src/cyad/AdminApiWrapper.h | 52 ++++++++++++++++++++++++++++++++++++ src/cyad/BaseAdminApiWrapper.h | 48 +++++++++++++++++++++++++++++++++ src/cyad/CMakeLists.txt | 1 + test/cyad/FakeAdminApiWrapper.h | 47 ++++++++++++++++++++++++++++++++ 5 files changed, 207 insertions(+) create mode 100644 src/cyad/AdminApiWrapper.cpp create mode 100644 src/cyad/AdminApiWrapper.h create mode 100644 src/cyad/BaseAdminApiWrapper.h create mode 100644 test/cyad/FakeAdminApiWrapper.h diff --git a/src/cyad/AdminApiWrapper.cpp b/src/cyad/AdminApiWrapper.cpp new file mode 100644 index 0000000..6a31b4b --- /dev/null +++ b/src/cyad/AdminApiWrapper.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file src/cyad/AdminApiWrapper.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief Wrapper around cynara-admin API + */ + +#include + +#include "AdminApiWrapper.h" + +namespace Cynara { + +AdminApiWrapper::AdminApiWrapper() {} + +AdminApiWrapper::~AdminApiWrapper() {} + +int AdminApiWrapper::cynara_admin_initialize(struct cynara_admin **pp_cynara_admin) { + return ::cynara_admin_initialize(pp_cynara_admin); +} + +int AdminApiWrapper::cynara_admin_finish(struct cynara_admin *p_cynara_admin) { + return ::cynara_admin_finish(p_cynara_admin); +} + +int AdminApiWrapper::cynara_admin_set_policies(struct cynara_admin *p_cynara_admin, + const struct cynara_admin_policy *const *policies) { + return ::cynara_admin_set_policies(p_cynara_admin, policies); +} + +int AdminApiWrapper::cynara_admin_set_bucket(struct cynara_admin *p_cynara_admin, + const char *bucket, int operation, const char *extra) { + return ::cynara_admin_set_bucket(p_cynara_admin, bucket, operation, extra); +} + +int AdminApiWrapper::cynara_admin_check(struct cynara_admin *p_cynara_admin, + const char *start_bucket, const int recursive, + const char *client, const char *user, const char *privilege, + int *result, char **result_extra) { + return ::cynara_admin_check(p_cynara_admin, start_bucket, recursive, client, user, privilege, + result, result_extra); +} + +} /* namespace Cynara */ diff --git a/src/cyad/AdminApiWrapper.h b/src/cyad/AdminApiWrapper.h new file mode 100644 index 0000000..d688271 --- /dev/null +++ b/src/cyad/AdminApiWrapper.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file src/cyad/AdminApiWrapper.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Wrapper around cynara-admin API + */ + +#ifndef SRC_CYAD_ADMINAPIWRAPPER_H_ +#define SRC_CYAD_ADMINAPIWRAPPER_H_ + +#include "BaseAdminApiWrapper.h" + +struct cynara_admin; +struct cynara_admin_policy; + +namespace Cynara { + +class AdminApiWrapper : public BaseAdminApiWrapper { +public: + AdminApiWrapper(); + virtual ~AdminApiWrapper(); + + virtual int cynara_admin_initialize(struct cynara_admin **pp_cynara_admin); + virtual int cynara_admin_finish(struct cynara_admin *p_cynara_admin); + virtual int cynara_admin_set_policies(struct cynara_admin *p_cynara_admin, + const struct cynara_admin_policy *const *policies); + virtual int cynara_admin_set_bucket(struct cynara_admin *p_cynara_admin, const char *bucket, + int operation, const char *extra); + virtual int cynara_admin_check(struct cynara_admin *p_cynara_admin, + const char *start_bucket, const int recursive, + const char *client, const char *user, const char *privilege, + int *result, char **result_extra); +}; + +} /* namespace Cynara */ + +#endif /* SRC_CYAD_ADMINAPIWRAPPER_H_ */ diff --git a/src/cyad/BaseAdminApiWrapper.h b/src/cyad/BaseAdminApiWrapper.h new file mode 100644 index 0000000..a24aec2 --- /dev/null +++ b/src/cyad/BaseAdminApiWrapper.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file src/cyad/BaseAdminApiWrapper.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Wrapper around cynara-admin API (base) + */ + +#ifndef SRC_CYAD_BASEADMINAPIWRAPPER_H_ +#define SRC_CYAD_BASEADMINAPIWRAPPER_H_ + +struct cynara_admin; +struct cynara_admin_policy; + +namespace Cynara { + +class BaseAdminApiWrapper { +public: + virtual ~BaseAdminApiWrapper() {}; + virtual int cynara_admin_initialize(struct cynara_admin **pp_cynara_admin) = 0; + virtual int cynara_admin_finish(struct cynara_admin *p_cynara_admin) = 0; + virtual int cynara_admin_set_policies(struct cynara_admin *p_cynara_admin, + const struct cynara_admin_policy *const *policies) = 0; + virtual int cynara_admin_set_bucket(struct cynara_admin *p_cynara_admin, const char *bucket, + int operation, const char *extra) = 0; + virtual int cynara_admin_check(struct cynara_admin *p_cynara_admin, + const char *start_bucket, const int recursive, + const char *client, const char *user, const char *privilege, + int *result, char **result_extra) = 0; +}; + +} /* namespace Cynara */ + +#endif /* SRC_CYAD_BASEADMINAPIWRAPPER_H_ */ diff --git a/src/cyad/CMakeLists.txt b/src/cyad/CMakeLists.txt index 1e379da..1000a0a 100644 --- a/src/cyad/CMakeLists.txt +++ b/src/cyad/CMakeLists.txt @@ -19,6 +19,7 @@ SET(CYAD_PATH ${CYNARA_PATH}/cyad) SET(CYAD_SOURCES + ${CYAD_PATH}/AdminApiWrapper.cpp ${CYAD_PATH}/main.cpp ) diff --git a/test/cyad/FakeAdminApiWrapper.h b/test/cyad/FakeAdminApiWrapper.h new file mode 100644 index 0000000..8e9b86b --- /dev/null +++ b/test/cyad/FakeAdminApiWrapper.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file test/cyad/FakeAdminApiWrapper.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Wrapper around cynara-admin API (mock) + */ + +#ifndef TEST_CYAD_FAKEADMINAPIWRAPPER_H_ +#define TEST_CYAD_FAKEADMINAPIWRAPPER_H_ + +#include +#include + +#include + +class FakeAdminApiWrapper : public Cynara::BaseAdminApiWrapper { +public: + using BaseAdminApiWrapper::BaseAdminApiWrapper; + + MOCK_METHOD1(cynara_admin_initialize, int(struct cynara_admin **pp_cynara_admin)); + MOCK_METHOD1(cynara_admin_finish, int(struct cynara_admin *p_cynara_admin)); + MOCK_METHOD2(cynara_admin_set_policies, int(struct cynara_admin *p_cynara_admin, + const struct cynara_admin_policy *const *policies)); + MOCK_METHOD4(cynara_admin_set_bucket, int(struct cynara_admin *p_cynara_admin, + const char *bucket, int operation, const char *extra)); + MOCK_METHOD8(cynara_admin_check, int(struct cynara_admin *p_cynara_admin, + const char *start_bucket, const int recursive, + const char *client, const char *user, const char *privilege, + int *result, char **result_extra)); +}; + +#endif /* TEST_CYAD_FAKEADMINAPIWRAPPER_H_ */ -- 2.7.4 From 6d58a7c2c18f159ab5b6606509f25df7c8e2b54c Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Tue, 9 Dec 2014 13:22:55 +0100 Subject: [PATCH 12/16] Introduce CynaraAdminPolicies This is a collection of cynara_admin_policy structs. It helps to manage memory and creates a convenient wrapper while still allowing to pass it to API calls. Change-Id: I61e39dbab88cbbbef07a0bd5ace4967d20336b17 --- src/cyad/CMakeLists.txt | 1 + src/cyad/CynaraAdminPolicies.cpp | 97 ++++++++++++++++++++++++++++++++++++++++ src/cyad/CynaraAdminPolicies.h | 60 +++++++++++++++++++++++++ test/CMakeLists.txt | 3 ++ test/cyad/helpers.cpp | 64 ++++++++++++++++++++++++++ test/cyad/helpers.h | 41 +++++++++++++++++ test/cyad/policy_collection.cpp | 68 ++++++++++++++++++++++++++++ 7 files changed, 334 insertions(+) create mode 100644 src/cyad/CynaraAdminPolicies.cpp create mode 100644 src/cyad/CynaraAdminPolicies.h create mode 100644 test/cyad/helpers.cpp create mode 100644 test/cyad/helpers.h create mode 100644 test/cyad/policy_collection.cpp diff --git a/src/cyad/CMakeLists.txt b/src/cyad/CMakeLists.txt index 1000a0a..d221c75 100644 --- a/src/cyad/CMakeLists.txt +++ b/src/cyad/CMakeLists.txt @@ -20,6 +20,7 @@ SET(CYAD_PATH ${CYNARA_PATH}/cyad) SET(CYAD_SOURCES ${CYAD_PATH}/AdminApiWrapper.cpp + ${CYAD_PATH}/CynaraAdminPolicies.cpp ${CYAD_PATH}/main.cpp ) diff --git a/src/cyad/CynaraAdminPolicies.cpp b/src/cyad/CynaraAdminPolicies.cpp new file mode 100644 index 0000000..4d83014 --- /dev/null +++ b/src/cyad/CynaraAdminPolicies.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file src/cyad/CynaraAdminPolicies.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief Collection of cynara_admin_policy structs + */ + +#include +#include +#include +#include +#include + +#include + +#include "CynaraAdminPolicies.h" + +namespace Cynara { + +CynaraAdminPolicies::CynaraAdminPolicies() : m_sealed(false) {} + +CynaraAdminPolicies::~CynaraAdminPolicies() { + auto freePolicy = [] (cynara_admin_policy *admin_policy) { + if (admin_policy == nullptr) + return; + + free(admin_policy->bucket); + free(admin_policy->client); + free(admin_policy->user); + free(admin_policy->privilege); + free(admin_policy->result_extra); + + delete admin_policy; + }; + + std::for_each(m_policies.begin(), m_policies.end(), freePolicy); +} + +void CynaraAdminPolicies::add(const PolicyBucketId &bucketId, const PolicyResult &policyResult, + const PolicyKey &policyKey) { + if (sealed()) { + throw std::logic_error("Collection is sealed"); + } + + // TODO: Optimize -- try not to malloc every item + cynara_admin_policy *policy = new cynara_admin_policy(); + + auto duplicateString = [] (const std::string &str) -> char * { + auto ret = strdup(str.c_str()); + if (ret == nullptr) + throw std::bad_alloc(); + return ret; + }; + + policy->bucket = duplicateString(bucketId); + policy->client = duplicateString(policyKey.client().toString()); + policy->user = duplicateString(policyKey.user().toString()); + policy->privilege = duplicateString(policyKey.privilege().toString()); + policy->result = policyResult.policyType(); + + if (policyResult.metadata().empty()) + policy->result_extra = nullptr; + else + policy->result_extra = duplicateString(policyResult.metadata()); + + m_policies.push_back(policy); +} + +void CynaraAdminPolicies::seal(void) { + m_policies.push_back(nullptr); + m_sealed = true; +} + +cynara_admin_policy* const *CynaraAdminPolicies::data(void) const { + if (sealed() == false) { + throw std::logic_error("Collection is not sealed"); + } + + return m_policies.data(); +} + +} /* namespace Cynara */ diff --git a/src/cyad/CynaraAdminPolicies.h b/src/cyad/CynaraAdminPolicies.h new file mode 100644 index 0000000..8541783 --- /dev/null +++ b/src/cyad/CynaraAdminPolicies.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file src/cyad/CynaraAdminPolicies.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Collection of cynara_admin_policy structs + */ + +#ifndef SRC_CYAD_CYNARAADMINPOLICIES_H_ +#define SRC_CYAD_CYNARAADMINPOLICIES_H_ + +#include + +#include +#include +#include +#include + +struct cynara_admin_policy; + +namespace Cynara { + +class CynaraAdminPolicies { +public: + CynaraAdminPolicies(); + virtual ~CynaraAdminPolicies(); + + void add(const PolicyBucketId &bucketId, const PolicyResult &policyResult, + const PolicyKey &policyKey); + + void seal(void); + + cynara_admin_policy* const *data(void) const; + + bool sealed(void) const { + return m_sealed; + } + +private: + std::vector m_policies; + bool m_sealed; +}; + +} /* namespace Cynara */ + +#endif /* SRC_CYAD_CYNARAADMINPOLICIES_H_ */ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6f8ef37..a60837c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -48,6 +48,7 @@ SET(CYNARA_SOURCES_FOR_TESTS ${CYNARA_SRC}/common/types/PolicyDescription.cpp ${CYNARA_SRC}/common/types/PolicyResult.cpp ${CYNARA_SRC}/common/types/PolicyType.cpp + ${CYNARA_SRC}/cyad/CynaraAdminPolicies.cpp ${CYNARA_SRC}/helpers/creds-commons/CredsCommonsInner.cpp ${CYNARA_SRC}/helpers/creds-commons/creds-commons.cpp ${CYNARA_SRC}/storage/BucketDeserializer.cpp @@ -70,6 +71,8 @@ SET(CYNARA_TESTS_SOURCES common/protocols/admin/listresponse.cpp common/types/policybucket.cpp credsCommons/parser/Parser.cpp + cyad/helpers.cpp + cyad/policy_collection.cpp helpers.cpp storage/performance/bucket.cpp storage/storage/policies.cpp diff --git a/test/cyad/helpers.cpp b/test/cyad/helpers.cpp new file mode 100644 index 0000000..1f600cb --- /dev/null +++ b/test/cyad/helpers.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file test/cyad/helpers.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief Helper functions, matchers and operators + */ + +#include +#include + +#include + +#include "helpers.h" + +bool operator==(const cynara_admin_policy &lhs, const cynara_admin_policy &rhs) { + auto strEq = [] (const char *lhs, const char *rhs) -> bool { + if (lhs != nullptr && rhs != nullptr) + return strcmp(lhs, rhs) == 0; + else + return lhs == rhs; + }; + + return lhs.result == rhs.result + && strEq(lhs.bucket, rhs.bucket) + && strEq(lhs.client, rhs.client) + && strEq(lhs.user, rhs.user) + && strEq(lhs.privilege, rhs.privilege) + && strEq(lhs.result_extra, rhs.result_extra); +} + +bool operator!=(const cynara_admin_policy &lhs, const cynara_admin_policy &rhs) { + return !(lhs == rhs); +} + +namespace Cynara { + +namespace Helpers { + +void freeAdminPolicyMembers(cynara_admin_policy *admin_policy) { + free(admin_policy->bucket); + free(admin_policy->client); + free(admin_policy->user); + free(admin_policy->privilege); + free(admin_policy->result_extra); +} + +} /* namespace Helpers */ + +} /* namespace Cynara */ diff --git a/test/cyad/helpers.h b/test/cyad/helpers.h new file mode 100644 index 0000000..b4fd02c --- /dev/null +++ b/test/cyad/helpers.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file test/cyad/helpers.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Helper functions, matchers and operators + */ + +#ifndef TEST_CYAD_HELPERS_H_ +#define TEST_CYAD_HELPERS_H_ + +struct cynara_admin_policy; + +bool operator==(const cynara_admin_policy &lhs, const cynara_admin_policy &rhs); +bool operator!=(const cynara_admin_policy &lhs, const cynara_admin_policy &rhs); + +namespace Cynara { + +namespace Helpers { + +void freeAdminPolicyMembers(cynara_admin_policy *admin_policy); + +} /* namespace Helpers */ + +} /* namespace Cynara */ + +#endif /* TEST_CYAD_HELPERS_H_ */ diff --git a/test/cyad/policy_collection.cpp b/test/cyad/policy_collection.cpp new file mode 100644 index 0000000..425e025 --- /dev/null +++ b/test/cyad/policy_collection.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file test/cyad/policy_collection.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief Tests for CynaraAdminPolicies + */ + +#include +#include + +#include +#include + +#include +#include + +#include + +#include "helpers.h" + +TEST(CynaraAdminPolicies, notSealed) { + Cynara::CynaraAdminPolicies policies; + ASSERT_THROW(policies.data(), std::logic_error); +} + +TEST(CynaraAdminPolicies, sealEmpty) { + Cynara::CynaraAdminPolicies policies; + policies.seal(); + ASSERT_EQ(nullptr, policies.data()[0]); +} + +TEST(CynaraAdminPolicies, addToSealed) { + Cynara::CynaraAdminPolicies policies; + policies.seal(); + ASSERT_THROW(policies.add("", { CYNARA_ADMIN_ALLOW, "" }, { "", "", ""} ), std::logic_error); +} + +TEST(CynaraAdminPolicies, addOne) { + using ::testing::ElementsAreArray; + + Cynara::CynaraAdminPolicies policies; + policies.add("test-bucket", { CYNARA_ADMIN_ALLOW, "" }, { "client", "user", "privilege"} ); + policies.seal(); + ASSERT_NO_THROW(policies.data()); + + cynara_admin_policy policy = { strdup("test-bucket"), strdup("client"), strdup("user"), + strdup("privilege"), CYNARA_ADMIN_ALLOW, nullptr }; + + ASSERT_EQ(policy, *policies.data()[0]); + ASSERT_EQ(nullptr, policies.data()[1]); + + Cynara::Helpers::freeAdminPolicyMembers(&policy); +} -- 2.7.4 From 8069773e3b5568c07c4ea8b9e1412fc909e641fc Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Tue, 9 Dec 2014 13:42:33 +0100 Subject: [PATCH 13/16] Introduce DispatcherIO BaseDispatcherIO provides interface for wrapping and aggregating I/O streams. The wrapping is needed mainly for testing purposes, but in near future will be used for printing messages, errors, etc. DispatcherIO is a target implementation, while FakeDispatcherIO is a stub for testing. Change-Id: I1ce231c3bbaf5f7f483358478cdf1eb5ff618589 --- src/cyad/BaseDispatcherIO.h | 49 ++++++++++++++++++++++++++++ src/cyad/CMakeLists.txt | 1 + src/cyad/DispatcherIO.cpp | 40 +++++++++++++++++++++++ src/cyad/DispatcherIO.h | 54 +++++++++++++++++++++++++++++++ test/cyad/FakeDispatcherIO.h | 76 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 220 insertions(+) create mode 100644 src/cyad/BaseDispatcherIO.h create mode 100644 src/cyad/DispatcherIO.cpp create mode 100644 src/cyad/DispatcherIO.h create mode 100644 test/cyad/FakeDispatcherIO.h diff --git a/src/cyad/BaseDispatcherIO.h b/src/cyad/BaseDispatcherIO.h new file mode 100644 index 0000000..3cd8af5 --- /dev/null +++ b/src/cyad/BaseDispatcherIO.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file src/cyad/BaseDispatcherIO.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Aggregates I/O methods (base) + */ + +#ifndef SRC_CYAD_BASEDISPATCHERIO_H_ +#define SRC_CYAD_BASEDISPATCHERIO_H_ + +#include +#include +#include +#include + +namespace Cynara { + +class BaseDispatcherIO { +public: + typedef std::string Filename; + typedef std::shared_ptr InputStreamPtr; + + BaseDispatcherIO() = default; + virtual ~BaseDispatcherIO() {} + + virtual InputStreamPtr openFile(const Filename &filename) = 0; + virtual std::ostream &cout(void) = 0; + virtual std::istream &cin(void) = 0; + virtual std::ostream &cerr(void) = 0; +}; + +} /* namespace Cynara */ + +#endif /* SRC_CYAD_BASEDISPATCHERIO_H_ */ diff --git a/src/cyad/CMakeLists.txt b/src/cyad/CMakeLists.txt index d221c75..d5f220c 100644 --- a/src/cyad/CMakeLists.txt +++ b/src/cyad/CMakeLists.txt @@ -21,6 +21,7 @@ SET(CYAD_PATH ${CYNARA_PATH}/cyad) SET(CYAD_SOURCES ${CYAD_PATH}/AdminApiWrapper.cpp ${CYAD_PATH}/CynaraAdminPolicies.cpp + ${CYAD_PATH}/DispatcherIO.cpp ${CYAD_PATH}/main.cpp ) diff --git a/src/cyad/DispatcherIO.cpp b/src/cyad/DispatcherIO.cpp new file mode 100644 index 0000000..80837e8 --- /dev/null +++ b/src/cyad/DispatcherIO.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file src/cyad/DispatcherIO.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief Aggregates I/O methods + */ + +#include + +#include "DispatcherIO.h" + +namespace Cynara { + +BaseDispatcherIO::InputStreamPtr DispatcherIO::openFile(const BaseDispatcherIO::Filename &filename) +{ + BaseDispatcherIO::InputStreamPtr streamPtr; + if (filename == "-") { + streamPtr.reset(&std::cin, [] (BaseDispatcherIO::InputStreamPtr::element_type *) {}); + } else { + streamPtr.reset(new std::ifstream(filename)); + } + return streamPtr; +} + +} /* namespace Cynara */ diff --git a/src/cyad/DispatcherIO.h b/src/cyad/DispatcherIO.h new file mode 100644 index 0000000..b29dfe1 --- /dev/null +++ b/src/cyad/DispatcherIO.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file src/cyad/DispatcherIO.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Aggregates I/O methods + */ + +#ifndef SRC_CYAD_DISPATCHERIO_H_ +#define SRC_CYAD_DISPATCHERIO_H_ + +#include + +#include "BaseDispatcherIO.h" + +namespace Cynara { + +class DispatcherIO : public BaseDispatcherIO { +public: + + using BaseDispatcherIO::BaseDispatcherIO; + + BaseDispatcherIO::InputStreamPtr openFile(const BaseDispatcherIO::Filename &filename); + + std::ostream &cout(void) { + return std::cout; + } + + std::istream &cin(void) { + return std::cin; + } + + std::ostream &cerr(void) { + return std::cerr; + } +}; + +} /* namespace Cynara */ + +#endif /* SRC_CYAD_DISPATCHERIO_H_ */ diff --git a/test/cyad/FakeDispatcherIO.h b/test/cyad/FakeDispatcherIO.h new file mode 100644 index 0000000..eb6299b --- /dev/null +++ b/test/cyad/FakeDispatcherIO.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file test/cyad/FakeDispatcherIO.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Aggregates I/O methods (stub) + */ + +#ifndef TEST_CYAD_FAKEDISPATCHERIO_H_ +#define TEST_CYAD_FAKEDISPATCHERIO_H_ + +#include +#include + +#include + +class FakeDispatcherIO : public Cynara::BaseDispatcherIO { +public: + + FakeDispatcherIO() : m_inputFile(new std::stringstream()) {} + ~FakeDispatcherIO() = default; + + BaseDispatcherIO::InputStreamPtr openFile(const BaseDispatcherIO::Filename &) { + return m_inputFile; + } + + std::ostream &cout(void) { + return m_out; + } + + std::istream &cin(void) { + return m_cin; + } + + std::ostream &cerr(void) { + return m_err; + } + + std::ostream &file(void) { + return *m_inputFile; + } + + std::stringstream &cerrRaw(void) { + return m_err; + } + + std::stringstream &coutRaw(void) { + return m_out; + } + + std::stringstream &cinRaw(void) { + return m_cin; + } + +private: + std::stringstream m_out; + std::stringstream m_err; + std::stringstream m_cin; + std::shared_ptr m_inputFile; +}; + +#endif /* TEST_CYAD_FAKEDISPATCHERIO_H_ */ -- 2.7.4 From d48d7a933ae8f323ec9a2f3ffac1a410d9f20aa5 Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Sat, 6 Dec 2014 14:58:00 +0100 Subject: [PATCH 14/16] Make BucketDeserializer::parseKey() public This static function will be needed in Cyad. Change-Id: Iccc28a9ea6754e23ba7878a07546d426af9e0c9a --- src/storage/BucketDeserializer.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/storage/BucketDeserializer.h b/src/storage/BucketDeserializer.h index 465ecef..666e14e 100644 --- a/src/storage/BucketDeserializer.h +++ b/src/storage/BucketDeserializer.h @@ -38,8 +38,6 @@ public: } PolicyCollection loadPolicies(void); - -protected: static PolicyKey parseKey(const std::string &line, std::size_t &beginToken); private: -- 2.7.4 From 4bd8f4c6596f891d616b9820a995b4110ec77eae Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Tue, 9 Dec 2014 14:17:49 +0100 Subject: [PATCH 15/16] Introduce AdminPolicyParser::parse() This function parses input stream and returns a CynaraAdminPolicies collection. It uses parsing functions from cynara-storage library. Change-Id: I3615563a2a8184a5c39b88952af795abd8399748 --- src/cyad/AdminPolicyParser.cpp | 62 ++++++++++++++++++++++++++++++ src/cyad/AdminPolicyParser.h | 41 ++++++++++++++++++++ src/cyad/CMakeLists.txt | 1 + test/CMakeLists.txt | 2 + test/cyad/helpers.h | 14 +++++++ test/cyad/policy_parser.cpp | 85 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 205 insertions(+) create mode 100644 src/cyad/AdminPolicyParser.cpp create mode 100644 src/cyad/AdminPolicyParser.h create mode 100644 test/cyad/policy_parser.cpp diff --git a/src/cyad/AdminPolicyParser.cpp b/src/cyad/AdminPolicyParser.cpp new file mode 100644 index 0000000..517dc04 --- /dev/null +++ b/src/cyad/AdminPolicyParser.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file src/cyad/AdminPolicyParser.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief Parses policies from input stream + */ + +#include +#include +#include + +#include "AdminPolicyParser.h" + +namespace Cynara { + +namespace AdminPolicyParser { + +CynaraAdminPolicies parse(const std::shared_ptr &input) { + CynaraAdminPolicies policies; + + for (std::size_t lineNum = 1; !input->eof(); ++lineNum) { + std::string line; + std::getline(*input, line, StorageSerializer::recordSeparator()); + + if (line.empty()) + break; + + try { + std::size_t beginToken = 0; + auto bucketId = StorageDeserializer::parseBucketId(line, beginToken); + auto policyKey = BucketDeserializer::parseKey(line, beginToken); + auto policyType = StorageDeserializer::parsePolicyType(line, beginToken); + auto metadata = StorageDeserializer::parseMetadata(line, beginToken); + + policies.add(bucketId, PolicyResult(policyType, metadata), policyKey); + } catch (const BucketRecordCorruptedException &ex) { + throw ex.withLineNumber(lineNum); + } + } + + policies.seal(); + return policies; +} + +} /* namespace AdminPolicyParser */ + +} /* namespace Cynara */ diff --git a/src/cyad/AdminPolicyParser.h b/src/cyad/AdminPolicyParser.h new file mode 100644 index 0000000..f448408 --- /dev/null +++ b/src/cyad/AdminPolicyParser.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file src/cyad/AdminPolicyParser.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Parses policies from input stream + */ + +#ifndef SRC_CYAD_ADMINPOLICYPARSER_H_ +#define SRC_CYAD_ADMINPOLICYPARSER_H_ + +#include +#include + +#include + +namespace Cynara { + +namespace AdminPolicyParser { + +CynaraAdminPolicies parse(const std::shared_ptr &input); + +} /* namespace AdminPolicyParser */ + +} /* namespace Cynara */ + +#endif /* SRC_CYAD_ADMINPOLICYPARSER_H_ */ diff --git a/src/cyad/CMakeLists.txt b/src/cyad/CMakeLists.txt index d5f220c..788e8f2 100644 --- a/src/cyad/CMakeLists.txt +++ b/src/cyad/CMakeLists.txt @@ -20,6 +20,7 @@ SET(CYAD_PATH ${CYNARA_PATH}/cyad) SET(CYAD_SOURCES ${CYAD_PATH}/AdminApiWrapper.cpp + ${CYAD_PATH}/AdminPolicyParser.cpp ${CYAD_PATH}/CynaraAdminPolicies.cpp ${CYAD_PATH}/DispatcherIO.cpp ${CYAD_PATH}/main.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a60837c..6e6d12c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -48,6 +48,7 @@ SET(CYNARA_SOURCES_FOR_TESTS ${CYNARA_SRC}/common/types/PolicyDescription.cpp ${CYNARA_SRC}/common/types/PolicyResult.cpp ${CYNARA_SRC}/common/types/PolicyType.cpp + ${CYNARA_SRC}/cyad/AdminPolicyParser.cpp ${CYNARA_SRC}/cyad/CynaraAdminPolicies.cpp ${CYNARA_SRC}/helpers/creds-commons/CredsCommonsInner.cpp ${CYNARA_SRC}/helpers/creds-commons/creds-commons.cpp @@ -73,6 +74,7 @@ SET(CYNARA_TESTS_SOURCES credsCommons/parser/Parser.cpp cyad/helpers.cpp cyad/policy_collection.cpp + cyad/policy_parser.cpp helpers.cpp storage/performance/bucket.cpp storage/storage/policies.cpp diff --git a/test/cyad/helpers.h b/test/cyad/helpers.h index b4fd02c..eb29f9a 100644 --- a/test/cyad/helpers.h +++ b/test/cyad/helpers.h @@ -23,11 +23,25 @@ #ifndef TEST_CYAD_HELPERS_H_ #define TEST_CYAD_HELPERS_H_ +#include +#include + struct cynara_admin_policy; bool operator==(const cynara_admin_policy &lhs, const cynara_admin_policy &rhs); bool operator!=(const cynara_admin_policy &lhs, const cynara_admin_policy &rhs); + +MATCHER_P(AdmPolicyListEq, policies, "") { + unsigned i = 0; + while (policies[i] != nullptr && arg[i] != nullptr) { + if (*policies[i] != *arg[i]) + return false; + ++i; + } + return policies[i] == nullptr && arg[i] == nullptr; +} + namespace Cynara { namespace Helpers { diff --git a/test/cyad/policy_parser.cpp b/test/cyad/policy_parser.cpp new file mode 100644 index 0000000..ab95987 --- /dev/null +++ b/test/cyad/policy_parser.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file test/cyad/commandline.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief Tests for AdminPolicyParser + */ + +#include +#include + +#include +#include + +#include +#include +#include + +#include "helpers.h" + +TEST(AdminPolicyParser, parseInvalid) { + auto input = std::make_shared(); + + *input << "invalid input" << std::endl; + + ASSERT_THROW(Cynara::AdminPolicyParser::parse(input), Cynara::BucketRecordCorruptedException); +} + +TEST(AdminPolicyParser, parse0) { + auto input = std::make_shared(); + + Cynara::CynaraAdminPolicies expectedPolicies; + expectedPolicies.seal(); + + auto policies = Cynara::AdminPolicyParser::parse(input); + + ASSERT_TRUE(policies.sealed()); + ASSERT_THAT(policies.data(), AdmPolicyListEq(expectedPolicies.data())); +} + +TEST(AdminPolicyParser, parse1) { + auto input = std::make_shared(); + + *input << "b;c;u;p;0;m" << std::endl; + + Cynara::CynaraAdminPolicies expectedPolicies; + expectedPolicies.add("b", { 0, "m" }, { "c", "u", "p" }); + expectedPolicies.seal(); + + auto policies = Cynara::AdminPolicyParser::parse(input); + + ASSERT_TRUE(policies.sealed()); + ASSERT_THAT(policies.data(), AdmPolicyListEq(expectedPolicies.data())); +} + +TEST(AdminPolicyParser, parse2) { + auto input = std::make_shared(); + + *input << "b1;c1;u1;p1;0;m1" << std::endl; + *input << "b2;c2;u2;p2;0;m2" << std::endl; + + Cynara::CynaraAdminPolicies expectedPolicies; + expectedPolicies.add("b1", { 0, "m1" }, { "c1", "u1", "p1" }); + expectedPolicies.add("b2", { 0, "m2" }, { "c2", "u2", "p2" }); + expectedPolicies.seal(); + + auto policies = Cynara::AdminPolicyParser::parse(input); + + ASSERT_TRUE(policies.sealed()); + ASSERT_THAT(policies.data(), AdmPolicyListEq(expectedPolicies.data())); +} -- 2.7.4 From e3bd02b695ee50b6da7fc0a21c4fa4bca3aa5787 Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Sat, 20 Dec 2014 12:49:27 +0100 Subject: [PATCH 16/16] Introduce CommandsDispatcher Change-Id: I220422f667c32c673e0b55b04d9faac39d840037 --- .../AdminLibraryInitializationFailedException.h | 54 ++++++++++++++++ src/cyad/CMakeLists.txt | 2 + src/cyad/CommandlineParser/CyadCommand.cpp | 41 ++++++++++++ src/cyad/CommandlineParser/CyadCommand.h | 72 ++++++++++++++++++++++ src/cyad/CommandsDispatcher.cpp | 61 ++++++++++++++++++ src/cyad/CommandsDispatcher.h | 56 +++++++++++++++++ src/include/cynara-error.h | 32 +++++----- test/CMakeLists.txt | 3 + test/cyad/CyadCommandlineDispatcherTest.h | 36 +++++++++++ test/cyad/commands_dispatcher.cpp | 58 +++++++++++++++++ 10 files changed, 401 insertions(+), 14 deletions(-) create mode 100644 src/cyad/AdminLibraryInitializationFailedException.h create mode 100644 src/cyad/CommandlineParser/CyadCommand.cpp create mode 100644 src/cyad/CommandlineParser/CyadCommand.h create mode 100644 src/cyad/CommandsDispatcher.cpp create mode 100644 src/cyad/CommandsDispatcher.h create mode 100644 test/cyad/CyadCommandlineDispatcherTest.h create mode 100644 test/cyad/commands_dispatcher.cpp diff --git a/src/cyad/AdminLibraryInitializationFailedException.h b/src/cyad/AdminLibraryInitializationFailedException.h new file mode 100644 index 0000000..570660f --- /dev/null +++ b/src/cyad/AdminLibraryInitializationFailedException.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file src/cyad/AdminLibraryInitializationFailedException.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Exception thrown when cynara_admin_initialize() fails + */ + +#ifndef SRC_CYAD_ADMINLIBRARYINITIALIZATIONFAILEDEXCEPTION_H_ +#define SRC_CYAD_ADMINLIBRARYINITIALIZATIONFAILEDEXCEPTION_H_ + +#include + +#include + +namespace Cynara { + +class AdminLibraryInitializationFailedException: public Exception { +public: + AdminLibraryInitializationFailedException(int errorCode) : m_errorCode(errorCode) { + m_message = "Initialization of cynara-admin failed: [" + std::to_string(m_errorCode) + "]"; + } + virtual ~AdminLibraryInitializationFailedException() {}; + + virtual const std::string &message(void) const { + return m_message; + } + + int errorCode(void) const { + return m_errorCode; + } + +private: + int m_errorCode; + std::string m_message; +}; + +} /* namespace Cynara */ + +#endif /* SRC_CYAD_ADMINLIBRARYINITIALIZATIONFAILEDEXCEPTION_H_ */ diff --git a/src/cyad/CMakeLists.txt b/src/cyad/CMakeLists.txt index 788e8f2..1ce4d1e 100644 --- a/src/cyad/CMakeLists.txt +++ b/src/cyad/CMakeLists.txt @@ -22,6 +22,8 @@ SET(CYAD_SOURCES ${CYAD_PATH}/AdminApiWrapper.cpp ${CYAD_PATH}/AdminPolicyParser.cpp ${CYAD_PATH}/CynaraAdminPolicies.cpp + ${CYAD_PATH}/CommandlineParser/CyadCommand.cpp + ${CYAD_PATH}/CommandsDispatcher.cpp ${CYAD_PATH}/DispatcherIO.cpp ${CYAD_PATH}/main.cpp ) diff --git a/src/cyad/CommandlineParser/CyadCommand.cpp b/src/cyad/CommandlineParser/CyadCommand.cpp new file mode 100644 index 0000000..6723e7e --- /dev/null +++ b/src/cyad/CommandlineParser/CyadCommand.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file src/cyad/CommandlineParser/CyadCommand.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief A representation of Cyad command + */ + +#include + +#include "CyadCommand.h" + +namespace Cynara { + +int CyadCommand::run(CommandsDispatcher &dispatcher) { + return dispatcher.execute(*this); +} + +int ErrorCyadCommand::run(CommandsDispatcher &dispatcher) { + return dispatcher.execute(*this); +} + +int HelpCyadCommand::run(CommandsDispatcher &dispatcher) { + return dispatcher.execute(*this); +} + +} /* namespace Cynara */ diff --git a/src/cyad/CommandlineParser/CyadCommand.h b/src/cyad/CommandlineParser/CyadCommand.h new file mode 100644 index 0000000..2a233d7 --- /dev/null +++ b/src/cyad/CommandlineParser/CyadCommand.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file src/cyad/CommandlineParser/CyadCommand.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief A representation of Cyad command + */ + +#ifndef SRC_CYAD_COMMANDLINEPARSER_CYADCOMMAND_H_ +#define SRC_CYAD_COMMANDLINEPARSER_CYADCOMMAND_H_ + +#include + +namespace Cynara { + +class CommandsDispatcher; + +class CyadCommand { +public: + CyadCommand() = default; + virtual ~CyadCommand() {} + + virtual int run(CommandsDispatcher &dispatcher); + + virtual bool isError(void) const { + return false; + } +}; + +class ErrorCyadCommand : public CyadCommand { +public: + ErrorCyadCommand(const std::string &message) : m_message(message) {} + virtual ~ErrorCyadCommand() {} + + virtual int run(CommandsDispatcher &dispatcher); + + virtual bool isError(void) const { + return true; + } + + virtual const std::string &message(void) const { + return m_message; + } + +private: + std::string m_message; +}; + +class HelpCyadCommand : public CyadCommand { +public: + using CyadCommand::CyadCommand; + + virtual int run(CommandsDispatcher &dispatcher); +}; + +} /* namespace Cynara */ + +#endif /* SRC_CYAD_COMMANDLINEPARSER_CYADCOMMAND_H_ */ diff --git a/src/cyad/CommandsDispatcher.cpp b/src/cyad/CommandsDispatcher.cpp new file mode 100644 index 0000000..dee8ce3 --- /dev/null +++ b/src/cyad/CommandsDispatcher.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file src/cyad/CommandsDispatcher.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief CommandsDispatcher class (implementation) + */ + +#include + +#include + +#include "CommandsDispatcher.h" + +namespace Cynara { + +CommandsDispatcher::CommandsDispatcher(BaseDispatcherIO &io, BaseAdminApiWrapper &adminApiWrapper) + : m_io(io), m_adminApiWrapper(adminApiWrapper), m_cynaraAdmin(nullptr) +{ + auto ret = m_adminApiWrapper.cynara_admin_initialize(&m_cynaraAdmin); + if (ret != CYNARA_API_SUCCESS) + throw AdminLibraryInitializationFailedException(ret); +} + +CommandsDispatcher::~CommandsDispatcher() { + m_adminApiWrapper.cynara_admin_finish(m_cynaraAdmin); +} + +int CommandsDispatcher::execute(CyadCommand &) { + m_io.cout() << "Whatever you wanted, it's not implemented" << std::endl; + return CYNARA_API_UNKNOWN_ERROR; +} + +int CommandsDispatcher::execute(HelpCyadCommand &) { + m_io.cout() << helpMessage << std::endl; + return CYNARA_API_SUCCESS; +} + +int CommandsDispatcher::execute(ErrorCyadCommand &result) { + m_io.cout() << "There was an error in command-line options:" << std::endl; + m_io.cout() << result.message() << std::endl; + + m_io.cout() << std::endl << helpMessage << std::endl; + return CYNARA_API_INVALID_COMMANDLINE_PARAM; +} + +} /* namespace Cynara */ diff --git a/src/cyad/CommandsDispatcher.h b/src/cyad/CommandsDispatcher.h new file mode 100644 index 0000000..a776682 --- /dev/null +++ b/src/cyad/CommandsDispatcher.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/cyad/CommandsDispatcher.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief CommandsDispatcher class + */ + +#ifndef SRC_CYAD_COMMANDSDISPATCHER_H_ +#define SRC_CYAD_COMMANDSDISPATCHER_H_ + +#include +#include +#include + +struct cynara_admin; +struct cynara_admin_policy; + +namespace Cynara { + +class CommandsDispatcher { +public: + CommandsDispatcher(BaseDispatcherIO &io, BaseAdminApiWrapper &adminApiWrapper); + virtual ~CommandsDispatcher(); + + virtual int execute(CyadCommand &); + virtual int execute(HelpCyadCommand &); + virtual int execute(ErrorCyadCommand &); + +private: + // TODO: Get argv[0] instead of hardcoded name + const std::string helpMessage = "Usage: cyad [OPTIONS]\n\n" + "Help options:\n" + " -h, --help print help message"; + BaseDispatcherIO &m_io; + BaseAdminApiWrapper &m_adminApiWrapper; + struct cynara_admin *m_cynaraAdmin; +}; + +} /* namespace Cynara */ + +#endif /* SRC_CYAD_COMMANDSDISPATCHER_H_ */ diff --git a/src/include/cynara-error.h b/src/include/cynara-error.h index 8ac7de1..66d75f0 100644 --- a/src/include/cynara-error.h +++ b/src/include/cynara-error.h @@ -18,6 +18,7 @@ * @author Lukasz Wojciechowski * @author Zofia Abramowska * @author Radoslaw Bartosiak + * @author Aleksander Zdyb * @version 1.0 * @brief This file contains error codes returned by APIs of Cynara. */ @@ -33,46 +34,49 @@ */ /*! \brief indicating access that was checked is allowed */ -#define CYNARA_API_ACCESS_ALLOWED 2 +#define CYNARA_API_ACCESS_ALLOWED 2 /*! \brief indicating that access that was checked is denied */ -#define CYNARA_API_ACCESS_DENIED 1 +#define CYNARA_API_ACCESS_DENIED 1 /*! \brief indicating the result of the one specific API is successful */ -#define CYNARA_API_SUCCESS 0 +#define CYNARA_API_SUCCESS 0 /*! \brief indicating that value is not present in cache */ -#define CYNARA_API_CACHE_MISS -1 +#define CYNARA_API_CACHE_MISS -1 /*! \brief indicating that pending requests reached maximum */ -#define CYNARA_API_MAX_PENDING_REQUESTS -2 +#define CYNARA_API_MAX_PENDING_REQUESTS -2 /*! \brief indicating system is running out of memory state */ -#define CYNARA_API_OUT_OF_MEMORY -3 +#define CYNARA_API_OUT_OF_MEMORY -3 /*! \brief indicating the API's parameter is malformed */ -#define CYNARA_API_INVALID_PARAM -4 +#define CYNARA_API_INVALID_PARAM -4 /*! \brief indicating that service is not available */ -#define CYNARA_API_SERVICE_NOT_AVAILABLE -5 +#define CYNARA_API_SERVICE_NOT_AVAILABLE -5 /*! \brief indicating that provided method is not supported by library */ -#define CYNARA_API_METHOD_NOT_SUPPORTED -6 +#define CYNARA_API_METHOD_NOT_SUPPORTED -6 /*! \brief cynara service does not allow to perform requested operation */ -#define CYNARA_API_OPERATION_NOT_ALLOWED -7 +#define CYNARA_API_OPERATION_NOT_ALLOWED -7 /*! \brief cynara service failed to perform requested operation */ -#define CYNARA_API_OPERATION_FAILED -8 +#define CYNARA_API_OPERATION_FAILED -8 /*! \brief cynara service hasn't found requested bucket */ -#define CYNARA_API_BUCKET_NOT_FOUND -9 +#define CYNARA_API_BUCKET_NOT_FOUND -9 /*! \brief indicating an unknown error */ -#define CYNARA_API_UNKNOWN_ERROR -10 +#define CYNARA_API_UNKNOWN_ERROR -10 /*! \brief indicating configuration error */ -#define CYNARA_API_CONFIGURATION_ERROR -11 +#define CYNARA_API_CONFIGURATION_ERROR -11 + +/*! \brief indicating invalid parameter in command-line */ +#define CYNARA_API_INVALID_COMMANDLINE_PARAM -12 /** @}*/ #endif /* CYNARA_ERROR_H */ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6e6d12c..f99d555 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -49,6 +49,8 @@ SET(CYNARA_SOURCES_FOR_TESTS ${CYNARA_SRC}/common/types/PolicyResult.cpp ${CYNARA_SRC}/common/types/PolicyType.cpp ${CYNARA_SRC}/cyad/AdminPolicyParser.cpp + ${CYNARA_SRC}/cyad/CommandlineParser/CyadCommand.cpp + ${CYNARA_SRC}/cyad/CommandsDispatcher.cpp ${CYNARA_SRC}/cyad/CynaraAdminPolicies.cpp ${CYNARA_SRC}/helpers/creds-commons/CredsCommonsInner.cpp ${CYNARA_SRC}/helpers/creds-commons/creds-commons.cpp @@ -72,6 +74,7 @@ SET(CYNARA_TESTS_SOURCES common/protocols/admin/listresponse.cpp common/types/policybucket.cpp credsCommons/parser/Parser.cpp + cyad/commands_dispatcher.cpp cyad/helpers.cpp cyad/policy_collection.cpp cyad/policy_parser.cpp diff --git a/test/cyad/CyadCommandlineDispatcherTest.h b/test/cyad/CyadCommandlineDispatcherTest.h new file mode 100644 index 0000000..504af80 --- /dev/null +++ b/test/cyad/CyadCommandlineDispatcherTest.h @@ -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 test/cyad/CyadCommandlineDispatcherTest.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Test fixture for CyadCommandlineDispatcher + */ + +#ifndef TEST_CYAD_CYADCOMMANDLINEDISPATCHERTEST_H_ +#define TEST_CYAD_CYADCOMMANDLINEDISPATCHERTEST_H_ + +#include +#include + +#include "FakeDispatcherIO.h" + +class CyadCommandlineDispatcherTest : public ::testing::Test { +protected: + FakeDispatcherIO m_io; +}; + +#endif /* TEST_CYAD_CYADCOMMANDLINEDISPATCHERTEST_H_ */ diff --git a/test/cyad/commands_dispatcher.cpp b/test/cyad/commands_dispatcher.cpp new file mode 100644 index 0000000..9a948e6 --- /dev/null +++ b/test/cyad/commands_dispatcher.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file test/cyad/commands_dispatcher.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief Tests for CommandsDispatcher + */ + +#include +#include + +#include + +#include +#include + +#include "CyadCommandlineDispatcherTest.h" +#include "FakeAdminApiWrapper.h" + +/** + * @brief Dispatcher should not touch admin API on help or error + * @test Scenario: + * - Prepare some parsing results not requiring API calls + * - Check if no API calls were made + */ +TEST_F(CyadCommandlineDispatcherTest, noApi) { + using ::testing::_; + using ::testing::Return; + + FakeAdminApiWrapper adminApi; + + EXPECT_CALL(adminApi, cynara_admin_initialize(_)).WillOnce(Return(CYNARA_API_SUCCESS)); + EXPECT_CALL(adminApi, cynara_admin_finish(_)).WillOnce(Return(CYNARA_API_SUCCESS)); + + Cynara::CommandsDispatcher dispatcher(m_io, adminApi); + + Cynara::CyadCommand result; + Cynara::HelpCyadCommand helpResult; + Cynara::ErrorCyadCommand errorResult("Fake error"); + + dispatcher.execute(result); + dispatcher.execute(helpResult); + dispatcher.execute(errorResult); +} -- 2.7.4