From 69133dcfc371766e241f25c9a6b4d8fcf75939b4 Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Mon, 14 Jul 2014 11:26:57 +0200 Subject: [PATCH 01/16] Add InMemoryStorageBackend::hasBucket() The function will be used by Cynara::Storage to check if new bucket should be created or an old one updated. Change-Id: I0c60724a112880010dcde7793346c1bc2fd687dc --- src/service/storage/InMemoryStorageBackend.cpp | 4 ++++ src/service/storage/InMemoryStorageBackend.h | 1 + src/service/storage/StorageBackend.h | 1 + test/storage/inmemorystoragebackend/buckets.cpp | 23 +++++++++++++++++++---- test/storage/storage/fakestoragebackend.h | 1 + 5 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/service/storage/InMemoryStorageBackend.cpp b/src/service/storage/InMemoryStorageBackend.cpp index 212c13a..51583c7 100644 --- a/src/service/storage/InMemoryStorageBackend.cpp +++ b/src/service/storage/InMemoryStorageBackend.cpp @@ -65,6 +65,10 @@ void InMemoryStorageBackend::deleteBucket(const PolicyBucketId &bucketId) { } } +bool InMemoryStorageBackend::hasBucket(const PolicyBucketId &bucketId) { + return buckets().find(bucketId) != buckets().end(); +} + void InMemoryStorageBackend::deletePolicy(const PolicyBucketId &bucketId, const PolicyKey &key) { try { // TODO: Move the erase code to PolicyCollection maybe? diff --git a/src/service/storage/InMemoryStorageBackend.h b/src/service/storage/InMemoryStorageBackend.h index 6ed0518..f4db588 100644 --- a/src/service/storage/InMemoryStorageBackend.h +++ b/src/service/storage/InMemoryStorageBackend.h @@ -47,6 +47,7 @@ public: virtual void insertPolicy(const PolicyBucketId &bucketId, PolicyPtr policy); virtual void createBucket(const PolicyBucketId &bucketId, const PolicyResult &defaultPolicy); virtual void deleteBucket(const PolicyBucketId &bucketId); + virtual bool hasBucket(const PolicyBucketId &bucketId); virtual void deletePolicy(const PolicyBucketId &bucketId, const PolicyKey &key); virtual void deleteLinking(const PolicyBucketId &bucketId); diff --git a/src/service/storage/StorageBackend.h b/src/service/storage/StorageBackend.h index 06a3a74..005a00d 100644 --- a/src/service/storage/StorageBackend.h +++ b/src/service/storage/StorageBackend.h @@ -45,6 +45,7 @@ public: virtual void createBucket(const PolicyBucketId &bucketId, const PolicyResult &defaultPolicy) = 0; virtual void deleteBucket(const PolicyBucketId &bucketId) = 0; + virtual bool hasBucket(const PolicyBucketId &bucketId) = 0; virtual void deletePolicy(const PolicyBucketId &bucketId, const PolicyKey &key) = 0; virtual void deleteLinking(const PolicyBucketId &bucket) = 0; diff --git a/test/storage/inmemorystoragebackend/buckets.cpp b/test/storage/inmemorystoragebackend/buckets.cpp index bf2c87c..37cf0ae 100644 --- a/test/storage/inmemorystoragebackend/buckets.cpp +++ b/test/storage/inmemorystoragebackend/buckets.cpp @@ -30,13 +30,13 @@ using namespace Cynara; -TEST_F(InMemeoryStorageBackendFixture, addBucket) { +TEST_F(InMemeoryStorageBackendFixture, createBucket) { using ::testing::ReturnRef; using ::testing::IsEmpty; FakeInMemoryStorageBackend backend; EXPECT_CALL(backend, buckets()) - .WillOnce(ReturnRef(m_buckets)); + .WillRepeatedly(ReturnRef(m_buckets)); PolicyResult defaultPolicy(PredefinedPolicyType::ALLOW); PolicyBucketId bucketId = "new-bucket"; @@ -55,7 +55,7 @@ TEST_F(InMemeoryStorageBackendFixture, deleteBucket) { FakeInMemoryStorageBackend backend; EXPECT_CALL(backend, buckets()) - .WillOnce(ReturnRef(m_buckets)); + .WillRepeatedly(ReturnRef(m_buckets)); PolicyBucketId bucketId = "delete-bucket"; m_buckets.insert({ bucketId, PolicyBucket() }); @@ -65,12 +65,27 @@ TEST_F(InMemeoryStorageBackendFixture, deleteBucket) { ASSERT_THAT(m_buckets, IsEmpty()); } +TEST_F(InMemeoryStorageBackendFixture, hasBucket) { + using ::testing::ReturnRef; + using ::testing::IsEmpty; + + FakeInMemoryStorageBackend backend; + EXPECT_CALL(backend, buckets()) + .WillRepeatedly(ReturnRef(m_buckets)); + + PolicyBucketId bucketId = "bucket"; + m_buckets.insert({ bucketId, PolicyBucket() }); + + ASSERT_TRUE(backend.hasBucket(bucketId)); + ASSERT_FALSE(backend.hasBucket("non-existent")); +} + TEST_F(InMemeoryStorageBackendFixture, deleteNonexistentBucket) { using ::testing::ReturnRef; FakeInMemoryStorageBackend backend; EXPECT_CALL(backend, buckets()) - .WillOnce(ReturnRef(m_buckets)); + .WillRepeatedly(ReturnRef(m_buckets)); EXPECT_THROW(backend.deleteBucket("non-existent"), BucketNotExistsException); } diff --git a/test/storage/storage/fakestoragebackend.h b/test/storage/storage/fakestoragebackend.h index d06c67d..b2f7a45 100644 --- a/test/storage/storage/fakestoragebackend.h +++ b/test/storage/storage/fakestoragebackend.h @@ -31,6 +31,7 @@ public: MOCK_METHOD2(searchBucket, PolicyBucket(const PolicyBucketId &bucket, const PolicyKey &key)); MOCK_METHOD2(createBucket, void(const PolicyBucketId &bucketId, const PolicyResult &defaultPolicy)); MOCK_METHOD1(deleteBucket, void(const PolicyBucketId &bucketId)); + MOCK_METHOD1(hasBucket, bool(const PolicyBucketId &bucketId)); MOCK_METHOD2(deletePolicy, void(const PolicyBucketId &bucketId, const PolicyKey &key)); MOCK_METHOD1(deleteLinking, void(const PolicyBucketId &bucket)); MOCK_METHOD2(insertPolicy, void(const PolicyBucketId &bucketId, PolicyPtr policy)); -- 2.7.4 From 75d8248c9e98ffd10b4948145602d8f82873c94b Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Mon, 14 Jul 2014 11:22:32 +0200 Subject: [PATCH 02/16] Add InMemoryStorageBackend::updateBucket() The function will be used by Cynara::Storage to update bucket's default policy without altering its policies. Change-Id: I777c930eedc9c63d8ce1f4a29b144eeee205f145 --- src/common/types/PolicyBucket.h | 1 + src/service/storage/InMemoryStorageBackend.cpp | 10 ++++++++++ src/service/storage/InMemoryStorageBackend.h | 1 + src/service/storage/StorageBackend.h | 1 + test/storage/inmemorystoragebackend/buckets.cpp | 26 +++++++++++++++++++++++++ test/storage/storage/fakestoragebackend.h | 5 ++++- 6 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/common/types/PolicyBucket.h b/src/common/types/PolicyBucket.h index 2e76713..120cf36 100644 --- a/src/common/types/PolicyBucket.h +++ b/src/common/types/PolicyBucket.h @@ -76,6 +76,7 @@ public: return m_policyCollection; } + // TODO: Consider StorageBackend to be only one to alter this property void setDefaultPolicy(const PolicyResult &defaultPolicy) { m_defaultPolicy = defaultPolicy; } diff --git a/src/service/storage/InMemoryStorageBackend.cpp b/src/service/storage/InMemoryStorageBackend.cpp index 51583c7..ab80521 100644 --- a/src/service/storage/InMemoryStorageBackend.cpp +++ b/src/service/storage/InMemoryStorageBackend.cpp @@ -58,6 +58,16 @@ void InMemoryStorageBackend::createBucket(const PolicyBucketId &bucketId, buckets().insert({ bucketId, newBucket }); } +void InMemoryStorageBackend::updateBucket(const PolicyBucketId &bucketId, + const PolicyResult &defaultPolicy) { + try { + auto &bucket = buckets().at(bucketId); + bucket.setDefaultPolicy(defaultPolicy); + } catch (const std::out_of_range &) { + throw BucketNotExistsException(bucketId); + } +} + void InMemoryStorageBackend::deleteBucket(const PolicyBucketId &bucketId) { auto bucketErased = buckets().erase(bucketId); if (bucketErased == 0) { diff --git a/src/service/storage/InMemoryStorageBackend.h b/src/service/storage/InMemoryStorageBackend.h index f4db588..409a84c 100644 --- a/src/service/storage/InMemoryStorageBackend.h +++ b/src/service/storage/InMemoryStorageBackend.h @@ -46,6 +46,7 @@ public: virtual PolicyBucket searchBucket(const PolicyBucketId &bucketId, const PolicyKey &key); virtual void insertPolicy(const PolicyBucketId &bucketId, PolicyPtr policy); virtual void createBucket(const PolicyBucketId &bucketId, const PolicyResult &defaultPolicy); + virtual void updateBucket(const PolicyBucketId &bucketId, const PolicyResult &defaultPolicy); virtual void deleteBucket(const PolicyBucketId &bucketId); virtual bool hasBucket(const PolicyBucketId &bucketId); virtual void deletePolicy(const PolicyBucketId &bucketId, const PolicyKey &key); diff --git a/src/service/storage/StorageBackend.h b/src/service/storage/StorageBackend.h index 005a00d..6689bae 100644 --- a/src/service/storage/StorageBackend.h +++ b/src/service/storage/StorageBackend.h @@ -44,6 +44,7 @@ public: virtual void insertPolicy(const PolicyBucketId &bucket, PolicyPtr policy) = 0; virtual void createBucket(const PolicyBucketId &bucketId, const PolicyResult &defaultPolicy) = 0; + virtual void updateBucket(const PolicyBucketId &bucketId, const PolicyResult &defaultPolicy) = 0; virtual void deleteBucket(const PolicyBucketId &bucketId) = 0; virtual bool hasBucket(const PolicyBucketId &bucketId) = 0; diff --git a/test/storage/inmemorystoragebackend/buckets.cpp b/test/storage/inmemorystoragebackend/buckets.cpp index 37cf0ae..bc9fcf6 100644 --- a/test/storage/inmemorystoragebackend/buckets.cpp +++ b/test/storage/inmemorystoragebackend/buckets.cpp @@ -48,6 +48,32 @@ TEST_F(InMemeoryStorageBackendFixture, createBucket) { ASSERT_THAT(m_buckets.at(bucketId).policyCollection(), IsEmpty()); } +TEST_F(InMemeoryStorageBackendFixture, updateBucket) { + using ::testing::ReturnRef; + + FakeInMemoryStorageBackend backend; + EXPECT_CALL(backend, buckets()) + .WillRepeatedly(ReturnRef(m_buckets)); + + PolicyBucketId bucketId = "bucket"; + auto &bucket = this->createBucket(bucketId); + bucket.setDefaultPolicy(PredefinedPolicyType::ALLOW); + + backend.updateBucket(bucketId, PredefinedPolicyType::DENY); + + ASSERT_EQ(PredefinedPolicyType::DENY, bucket.defaultPolicy()); +} + +TEST_F(InMemeoryStorageBackendFixture, updateNonexistentBucket) { + using ::testing::ReturnRef; + + FakeInMemoryStorageBackend backend; + EXPECT_CALL(backend, buckets()) + .WillRepeatedly(ReturnRef(m_buckets)); + + EXPECT_THROW(backend.updateBucket("non-existent", PredefinedPolicyType::ALLOW), + BucketNotExistsException); +} TEST_F(InMemeoryStorageBackendFixture, deleteBucket) { using ::testing::ReturnRef; diff --git a/test/storage/storage/fakestoragebackend.h b/test/storage/storage/fakestoragebackend.h index b2f7a45..bfa212d 100644 --- a/test/storage/storage/fakestoragebackend.h +++ b/test/storage/storage/fakestoragebackend.h @@ -29,7 +29,10 @@ class FakeStorageBackend : public StorageBackend { public: MOCK_METHOD1(searchDefaultBucket, PolicyBucket(const PolicyKey &key)); MOCK_METHOD2(searchBucket, PolicyBucket(const PolicyBucketId &bucket, const PolicyKey &key)); - MOCK_METHOD2(createBucket, void(const PolicyBucketId &bucketId, const PolicyResult &defaultPolicy)); + MOCK_METHOD2(createBucket, void(const PolicyBucketId &bucketId, + const PolicyResult &defaultPolicy)); + MOCK_METHOD2(updateBucket, void(const PolicyBucketId &bucketId, + const PolicyResult &defaultPolicy)); MOCK_METHOD1(deleteBucket, void(const PolicyBucketId &bucketId)); MOCK_METHOD1(hasBucket, bool(const PolicyBucketId &bucketId)); MOCK_METHOD2(deletePolicy, void(const PolicyBucketId &bucketId, const PolicyKey &key)); -- 2.7.4 From 74e95bd76deed9310c3ea966d9e2b9f89c9a2f40 Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Fri, 11 Jul 2014 10:58:35 +0200 Subject: [PATCH 03/16] Implement Storage::addOrUpdateBucket() createBucket() has been is renamed to addOrUpdateBucket() in Cynara::Storage. The function will now create new bucket or, if it existed, only update its default policy. Test asserting addition of default bucket has been removed, because the common function Storage::addOrUpdateBucket() will just update default policy in such case. Change-Id: I2099f9306873d192cbbbcd34ac9769ca663bdbe3 --- src/service/storage/Storage.cpp | 12 +++++------- src/service/storage/Storage.h | 2 +- test/storage/storage/buckets.cpp | 20 +++++++++++++------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/service/storage/Storage.cpp b/src/service/storage/Storage.cpp index a35da0c..9e9f00d 100644 --- a/src/service/storage/Storage.cpp +++ b/src/service/storage/Storage.cpp @@ -93,14 +93,12 @@ void Storage::insertPolicies(const std::vector &policies) { } } -void Storage::createBucket(const PolicyBucketId &newBucketId, const PolicyResult &defaultBucketPolicy) { - // TODO: Check if bucket already exists - - if (newBucketId == defaultPolicyBucketId) { - throw BucketAlreadyExistsException(newBucketId); +void Storage::addOrUpdateBucket(const PolicyBucketId &bucketId, const PolicyResult &defaultBucketPolicy) { + if (m_backend.hasBucket(bucketId)) { + m_backend.updateBucket(bucketId, defaultBucketPolicy); + } else { + m_backend.createBucket(bucketId, defaultBucketPolicy); } - - m_backend.createBucket(newBucketId, defaultBucketPolicy); } void Storage::deleteBucket(const PolicyBucketId &bucketId) { diff --git a/src/service/storage/Storage.h b/src/service/storage/Storage.h index e16d60c..177765c 100644 --- a/src/service/storage/Storage.h +++ b/src/service/storage/Storage.h @@ -50,7 +50,7 @@ public: PolicyResult checkPolicy(const PolicyKey &key); void insertPolicies(const std::vector &policies); - void createBucket(const PolicyBucketId &newBucketId, const PolicyResult &defaultBucketPolicy); + void addOrUpdateBucket(const PolicyBucketId &bucketId, const PolicyResult &defaultBucketPolicy); void deletePolicies(const std::vector &policies); void deleteBucket(const PolicyBucketId &bucketId); diff --git a/test/storage/storage/buckets.cpp b/test/storage/storage/buckets.cpp index 44e4cfd..c7d19ec 100644 --- a/test/storage/storage/buckets.cpp +++ b/test/storage/storage/buckets.cpp @@ -44,27 +44,33 @@ using namespace Cynara; TEST(storage, addBucket) { + using ::testing::Return; + FakeStorageBackend backend; Cynara::Storage storage(backend); PolicyBucketId bucketId = "test-bucket"; PolicyResult defaultPolicy(PredefinedPolicyType::DENY); + EXPECT_CALL(backend, hasBucket(bucketId)).WillOnce(Return(false)); EXPECT_CALL(backend, createBucket(bucketId, defaultPolicy)); - storage.createBucket(bucketId, defaultPolicy); + storage.addOrUpdateBucket(bucketId, defaultPolicy); } -// Cannot add bucket with default bucket's name -TEST(storage, addDefaultBucket) { +TEST(storage, updateBucket) { + using ::testing::Return; + FakeStorageBackend backend; Cynara::Storage storage(backend); + + PolicyBucketId bucketId = "test-bucket"; PolicyResult defaultPolicy(PredefinedPolicyType::DENY); - ASSERT_THROW( - storage.createBucket(defaultPolicyBucketId, defaultPolicy), - BucketAlreadyExistsException - ); + EXPECT_CALL(backend, hasBucket(bucketId)).WillOnce(Return(true)); + EXPECT_CALL(backend, updateBucket(bucketId, defaultPolicy)); + + storage.addOrUpdateBucket(bucketId, defaultPolicy); } // Cannot delete default bucket -- 2.7.4 From 36cfb0bc41cb796c8da6834a99892914982ea46c Mon Sep 17 00:00:00 2001 From: Rafal Krypa Date: Wed, 9 Jul 2014 16:24:10 +0200 Subject: [PATCH 04/16] Use proper printf length modifier for sizeof() Printing sizeof value needs %zu, not %u. Change-Id: I0d1cf2b9bfb8956e4377eccf70f24f6bfbe5bc4d --- src/common/sockets/Socket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/sockets/Socket.cpp b/src/common/sockets/Socket.cpp index 81be8d4..5149d17 100644 --- a/src/common/sockets/Socket.cpp +++ b/src/common/sockets/Socket.cpp @@ -132,7 +132,7 @@ bool Socket::connect(void) { if (m_socketPath.length() >= sizeof(clientAddr.sun_path)) { close(); - LOGE("Error: socket path <%s> is too long [%zu]. Max len is [%u]", m_socketPath.c_str(), + LOGE("Error: socket path <%s> is too long [%zu]. Max len is [%zu]", m_socketPath.c_str(), m_socketPath.length(), sizeof(clientAddr.sun_path)); throw InitException(); } -- 2.7.4 From 44553d4ca12dcca8330d950bfef85e2ca34db8fb Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Thu, 17 Jul 2014 11:29:46 +0200 Subject: [PATCH 05/16] Correct misspell in coment Change-Id: Icbe463a8242a79baafb19174d11c8169c710e659 --- src/common/types/PolicyBucketId.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/types/PolicyBucketId.h b/src/common/types/PolicyBucketId.h index ac557f3..3ec3aec 100644 --- a/src/common/types/PolicyBucketId.h +++ b/src/common/types/PolicyBucketId.h @@ -14,7 +14,7 @@ * limitations under the License. */ /* - * @file PolicBucketId.h + * @file PolicyBucketId.h * @author Aleksander Zdyb * @version 1.0 * @brief Definition of Cynara::PolicyBucketId type -- 2.7.4 From 7f9ca9097697d1c4d3f2454068eea5a0dec895b9 Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Thu, 17 Jul 2014 13:28:08 +0200 Subject: [PATCH 06/16] Add ApiInterface for libcynara-admin Implement ApiInterface in Logic class with stub functions. Interpret CAPI parameters and use ApiInterface in admin-api.cpp. Change-Id: I2fb617e23fe00a7183281e666388c4153c3d00f0 --- src/admin/api/ApiInterface.h | 13 ++++++++ src/admin/api/admin-api.cpp | 77 ++++++++++++++++++++++++++++++++++++++++---- src/admin/logic/Logic.cpp | 23 +++++++++++++ src/admin/logic/Logic.h | 7 ++++ 4 files changed, 113 insertions(+), 7 deletions(-) diff --git a/src/admin/api/ApiInterface.h b/src/admin/api/ApiInterface.h index 5a9acbc..9c513f6 100644 --- a/src/admin/api/ApiInterface.h +++ b/src/admin/api/ApiInterface.h @@ -23,7 +23,14 @@ #ifndef SRC_ADMIN_API_APIINTERFACE_H_ #define SRC_ADMIN_API_APIINTERFACE_H_ +#include #include +#include + +#include +#include +#include +#include #include @@ -33,6 +40,12 @@ class ApiInterface { public: ApiInterface() = default; virtual ~ApiInterface() = default; + + virtual int setPolicies(const std::map> &insertOrUpdate, + const std::map> &remove) noexcept = 0; + virtual int insertOrUpdateBucket(const PolicyBucketId &bucket, const PolicyResult &policyResult) + noexcept = 0; + virtual int removeBucket(const PolicyBucketId &bucket) noexcept = 0; }; } // namespace Cynara diff --git a/src/admin/api/admin-api.cpp b/src/admin/api/admin-api.cpp index 0809232..5c2e2e6 100644 --- a/src/admin/api/admin-api.cpp +++ b/src/admin/api/admin-api.cpp @@ -20,9 +20,18 @@ * @brief Implementation of external libcynara-admin API */ +#include #include +#include +#include #include +#include +#include +#include +#include +#include + #include #include @@ -67,25 +76,79 @@ int cynara_admin_set_policies(struct cynara_admin *p_cynara_admin, if (!policies) return CYNARA_ADMIN_API_INVALID_PARAM; - //todo This is a stub. Parameters should be passed to p_cynara_admin->impl - return CYNARA_ADMIN_API_SUCCESS; + std::map> insertOrUpdate; + std::map> remove; + + auto key = ([](const cynara_admin_policy *i)->Cynara::PolicyKey { + std::string wildcard(CYNARA_ADMIN_WILDCARD); + + auto feature = ([&wildcard] (const char *str)->Cynara::PolicyKeyFeature { + if (wildcard.compare(str)) + return Cynara::PolicyKeyFeature::create(str); + else + return Cynara::PolicyKeyFeature::createWildcard(); + }); + + return Cynara::PolicyKey(feature(i->client), feature(i->user), feature(i->privilege)); + }); + + try { + for (auto i = policies[0]; i; i++) { + if(!i->bucket || !i->client || !i->user || !i->privilege) + return CYNARA_ADMIN_API_INVALID_PARAM; + + switch (i->result) { + case CYNARA_ADMIN_DELETE: + remove[i->bucket].push_back(key(i)); + break; + case CYNARA_ADMIN_DENY: + insertOrUpdate[i->bucket].push_back(Cynara::Policy(key(i), + Cynara::PredefinedPolicyType::DENY)); + break; + case CYNARA_ADMIN_ALLOW: + insertOrUpdate[i->bucket].push_back(Cynara::Policy(key(i), + Cynara::PredefinedPolicyType::ALLOW)); + break; + case CYNARA_ADMIN_BUCKET: + insertOrUpdate[i->bucket].push_back(Cynara::Policy(key(i), + Cynara::PolicyResult( + Cynara::PredefinedPolicyType::BUCKET, + i->result_extra ? i->result_extra : ""))); + break; + default: + return CYNARA_ADMIN_API_INVALID_PARAM; + } + } + } catch (std::bad_alloc ex) { + return CYNARA_ADMIN_API_OUT_OF_MEMORY; + } + + return p_cynara_admin->impl->setPolicies(insertOrUpdate, remove); } CYNARA_API int cynara_admin_set_bucket(struct cynara_admin *p_cynara_admin, const char *bucket, - int operation, const char *extra UNUSED) { + int operation, const char *extra) { if (!p_cynara_admin || !p_cynara_admin->impl) return CYNARA_ADMIN_API_INVALID_PARAM; if (!bucket) return CYNARA_ADMIN_API_INVALID_PARAM; + + std::string extraStr; + try { + extraStr = extra ? extra : ""; + } catch (std::bad_alloc ex) { + return CYNARA_ADMIN_API_OUT_OF_MEMORY; + } switch (operation) { case CYNARA_ADMIN_DELETE: - //todo This is a stub. Parameters should be passed to p_cynara_admin->impl - return CYNARA_ADMIN_API_SUCCESS; + return p_cynara_admin->impl->removeBucket(bucket); case CYNARA_ADMIN_DENY: + return p_cynara_admin->impl->insertOrUpdateBucket(bucket, + Cynara::PolicyResult(Cynara::PredefinedPolicyType::DENY, extraStr)); case CYNARA_ADMIN_ALLOW: - //todo This is a stub. Parameters should be passed to p_cynara_admin->impl - return CYNARA_ADMIN_API_SUCCESS; + return p_cynara_admin->impl->insertOrUpdateBucket(bucket, + Cynara::PolicyResult(Cynara::PredefinedPolicyType::ALLOW, extraStr)); case CYNARA_ADMIN_BUCKET: default: return CYNARA_ADMIN_API_INVALID_PARAM; diff --git a/src/admin/logic/Logic.cpp b/src/admin/logic/Logic.cpp index 25b7e5e..d01353f 100644 --- a/src/admin/logic/Logic.cpp +++ b/src/admin/logic/Logic.cpp @@ -22,6 +22,7 @@ #include +#include #include #include #include @@ -37,4 +38,26 @@ Logic::Logic() { std::make_shared()); } +ProtocolFrameSequenceNumber generateSequenceNumber(void) { + static ProtocolFrameSequenceNumber sequenceNumber = 0; + return ++sequenceNumber; +} + +int Logic::setPolicies(const std::map> &insertOrUpdate UNUSED, + const std::map> &remove UNUSED) noexcept { +//todo this is only a stub + return CYNARA_ADMIN_API_SUCCESS; +} + +int Logic::insertOrUpdateBucket(const PolicyBucketId &bucket UNUSED, + const PolicyResult &policyResult UNUSED) noexcept { +//todo this is only a stub + return CYNARA_ADMIN_API_SUCCESS; +} + +int Logic::removeBucket(const PolicyBucketId &bucket UNUSED) noexcept { +//todo this is only a stub + return CYNARA_ADMIN_API_SUCCESS; +} + } // namespace Cynara diff --git a/src/admin/logic/Logic.h b/src/admin/logic/Logic.h index ac3dba2..2cc22fc 100644 --- a/src/admin/logic/Logic.h +++ b/src/admin/logic/Logic.h @@ -38,6 +38,13 @@ private: public: Logic(); virtual ~Logic() = default; + + virtual int setPolicies(const std::map> &insertOrUpdate, + const std::map> &remove) noexcept; + virtual int insertOrUpdateBucket(const PolicyBucketId &bucket, const PolicyResult &policyResult) + noexcept; + virtual int removeBucket(const PolicyBucketId &bucket) noexcept; + }; } // namespace Cynara -- 2.7.4 From 348244358590c15841c408fc70a55a13fceff2d3 Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Thu, 17 Jul 2014 08:55:45 +0200 Subject: [PATCH 07/16] Add deserialization IO exception BucketDeserializationException is thrown, when bucket file stream could not be opened. Change-Id: I0930793564beb73cfea937d43155e6953d42a6a1 --- .../exceptions/BucketDeserializationException.h | 52 ++++++++++++++++++++++ src/common/exceptions/DatabaseException.h | 35 +++++++++++++++ src/service/storage/StorageDeserializer.cpp | 9 ++-- test/storage/serializer/deserialize.cpp | 44 +++++++++++++----- 4 files changed, 126 insertions(+), 14 deletions(-) create mode 100644 src/common/exceptions/BucketDeserializationException.h create mode 100644 src/common/exceptions/DatabaseException.h diff --git a/src/common/exceptions/BucketDeserializationException.h b/src/common/exceptions/BucketDeserializationException.h new file mode 100644 index 0000000..2a00555 --- /dev/null +++ b/src/common/exceptions/BucketDeserializationException.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 BucketDeserializationException.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Implementation of BucketDeserializationException + */ +#ifndef SRC_COMMON_EXCEPTIONS_BUCKETDESERIALIZATIONEXCEPTION_H_ +#define SRC_COMMON_EXCEPTIONS_BUCKETDESERIALIZATIONEXCEPTION_H_ + +#include +#include + +namespace Cynara { + +class BucketDeserializationException : public DatabaseException { +public: + BucketDeserializationException(const PolicyBucketId &bucketId) : m_bucketId(bucketId) {} + + const std::string message(void) const { + if (m_message.empty()) { + m_message = "Could not deserialize bucket " + m_bucketId; + } + return m_message; + } + + const PolicyBucketId &bucketId(void) const { + return m_bucketId; + } + +private: + mutable std::string m_message; + PolicyBucketId m_bucketId; +}; + +} /* namespace Cynara */ + +#endif /* SRC_COMMON_EXCEPTIONS_BUCKETDESERIALIZATIONEXCEPTION_H_ */ diff --git a/src/common/exceptions/DatabaseException.h b/src/common/exceptions/DatabaseException.h new file mode 100644 index 0000000..b194fd3 --- /dev/null +++ b/src/common/exceptions/DatabaseException.h @@ -0,0 +1,35 @@ +/* + * 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 DatabaseException.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Common class for database exceptions + */ +#ifndef SRC_COMMON_EXCEPTIONS_DATABASEEXCEPTION_H_ +#define SRC_COMMON_EXCEPTIONS_DATABASEEXCEPTION_H_ + +#include + +namespace Cynara { + +class DatabaseException : public Exception { + +}; + +} /* namespace Cynara */ + +#endif /* SRC_COMMON_EXCEPTIONS_DATABASEEXCEPTION_H_ */ diff --git a/src/service/storage/StorageDeserializer.cpp b/src/service/storage/StorageDeserializer.cpp index 5f1b97b..0510670 100644 --- a/src/service/storage/StorageDeserializer.cpp +++ b/src/service/storage/StorageDeserializer.cpp @@ -20,14 +20,15 @@ * @brief Implementation for Cynara::StorageDeserializer */ -#include +#include +#include +#include #include #include #include -#include -#include +#include namespace Cynara { @@ -63,7 +64,7 @@ void StorageDeserializer::loadBuckets(InMemoryStorageBackend::Buckets &buckets) if (bucketDeserializer != nullptr) { bucket.setPolicyCollection(bucketDeserializer->loadPolicies()); } else { - // TODO: Throw? + throw BucketDeserializationException(bucketId); } } } diff --git a/test/storage/serializer/deserialize.cpp b/test/storage/serializer/deserialize.cpp index bcd5052..1fd6ad3 100644 --- a/test/storage/serializer/deserialize.cpp +++ b/test/storage/serializer/deserialize.cpp @@ -20,18 +20,17 @@ * @brief Tests for Cynara::StorageDeserializer */ +#include +#include +#include #include #include +#include #include #include -#include -#include -#include - - // TODO: Move to .h, because it's used also in bucket_load.cpp MATCHER_P(PolicyPtrEq, policy, "") { return std::tie(policy->key(), policy->result()) @@ -113,13 +112,16 @@ TEST_F(StorageDeserializerFixture, init_more) { TEST_F(StorageDeserializerFixture, init_overwrite) { using ::testing::UnorderedElementsAre; - std::istringstream ss(";0"); + std::istringstream ss(";0x0"); StorageDeserializer deserializer(ss, nullStreamOpener); InMemoryStorageBackend::Buckets buckets; + // Default bucket has ALLOW policy as default buckets.insert({ "", PolicyBucket("fakeId", PredefinedPolicyType::ALLOW) }); + deserializer.initBuckets(buckets); + // Check, if default bucket has now DENY as default policy, which would be read from stream ASSERT_THAT(buckets, UnorderedElementsAre( COMPARE_BUCKETS("", PolicyBucket("", PredefinedPolicyType::DENY)) )); @@ -146,7 +148,7 @@ TEST_F(StorageDeserializerFixture, load_buckets_plus_policies) { deserializer.loadBuckets(buckets); - // Check if our bucket is still there + // Check if pre-inserted bucket is still there ASSERT_THAT(buckets, UnorderedElementsAre( COMPARE_BUCKETS("", PolicyBucket("", PredefinedPolicyType::DENY)) )); @@ -179,13 +181,35 @@ TEST_F(StorageDeserializerFixture, load_buckets) { // Check, if streamOpener was called for each bucket EXPECT_CALL(streamOpener, streamForBucketId("")) - .WillOnce(Return(nullptr)); + .WillOnce(Return(emptyBucketStream())); EXPECT_CALL(streamOpener, streamForBucketId("bucket1")) - .WillOnce(Return(nullptr)); + .WillOnce(Return(emptyBucketStream())); EXPECT_CALL(streamOpener, streamForBucketId("bucket2")) - .WillOnce(Return(nullptr)); + .WillOnce(Return(emptyBucketStream())); deserializer.loadBuckets(buckets); } + +TEST_F(StorageDeserializerFixture, load_buckets_io_error) { + using ::testing::_; + using ::testing::Return; + using ::testing::UnorderedElementsAre; + + // Pre-insert some buckets + InMemoryStorageBackend::Buckets buckets; + buckets.insert({ "", PolicyBucket("", PredefinedPolicyType::DENY) }); + + std::istringstream bucketsStream; // Won't be used; buckets are pre-inserted above + FakeStreamForBucketId streamOpener; + auto streamOpenerFunc = std::bind(&FakeStreamForBucketId::streamForBucketId, &streamOpener, + std::placeholders::_1); + StorageDeserializer deserializer(bucketsStream, streamOpenerFunc); + + // Check, if streamOpener was called for each bucket + EXPECT_CALL(streamOpener, streamForBucketId("")) + .WillOnce(Return(nullptr)); + + ASSERT_THROW(deserializer.loadBuckets(buckets), BucketDeserializationException); +} -- 2.7.4 From 76799f1ae53ed60940b6376597686f9dd60153b4 Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Thu, 17 Jul 2014 15:36:05 +0200 Subject: [PATCH 08/16] Add 3 new Request classes for administrating Cynara Three added classes are: InsertOrUpdateBucketRequest - for inserting new bucket or modyfying default policy of existing one; RemoveBucketRequest - for removing bucket; SetPoliciesRequest - for modification of policies (adding, updating, removing). RequestTaker class has been extended with new execute() methods for processing newly added Request objects. Proper shared pointers definitions were added in request/pointers.h for supporting new Request types. Change-Id: I0a94eb9ce8326da4ccb9bd078d3a90b6bef25bfa --- src/common/CMakeLists.txt | 3 + src/common/request/InsertOrUpdateBucketRequest.cpp | 34 +++++++++++ src/common/request/InsertOrUpdateBucketRequest.h | 61 ++++++++++++++++++++ src/common/request/RemoveBucketRequest.cpp | 34 +++++++++++ src/common/request/RemoveBucketRequest.h | 54 +++++++++++++++++ src/common/request/RequestTaker.cpp | 14 +++++ src/common/request/RequestTaker.h | 3 + src/common/request/SetPoliciesRequest.cpp | 34 +++++++++++ src/common/request/SetPoliciesRequest.h | 67 ++++++++++++++++++++++ src/common/request/pointers.h | 9 +++ 10 files changed, 313 insertions(+) create mode 100644 src/common/request/InsertOrUpdateBucketRequest.cpp create mode 100644 src/common/request/InsertOrUpdateBucketRequest.h create mode 100644 src/common/request/RemoveBucketRequest.cpp create mode 100644 src/common/request/RemoveBucketRequest.h create mode 100644 src/common/request/SetPoliciesRequest.cpp create mode 100644 src/common/request/SetPoliciesRequest.h diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 9e7cece..39b9e47 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -32,7 +32,10 @@ SET(COMMON_SOURCES ${COMMON_PATH}/protocol/ProtocolSerialization.cpp ${COMMON_PATH}/protocol/ProtocolSignal.cpp ${COMMON_PATH}/request/CheckRequest.cpp + ${COMMON_PATH}/request/InsertOrUpdateBucketRequest.cpp + ${COMMON_PATH}/request/RemoveBucketRequest.cpp ${COMMON_PATH}/request/RequestTaker.cpp + ${COMMON_PATH}/request/SetPoliciesRequest.cpp ${COMMON_PATH}/request/SignalRequest.cpp ${COMMON_PATH}/response/CheckResponse.cpp ${COMMON_PATH}/response/ResponseTaker.cpp diff --git a/src/common/request/InsertOrUpdateBucketRequest.cpp b/src/common/request/InsertOrUpdateBucketRequest.cpp new file mode 100644 index 0000000..47900bc --- /dev/null +++ b/src/common/request/InsertOrUpdateBucketRequest.cpp @@ -0,0 +1,34 @@ +/* + * 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 InsertOrUpdateBucketRequest.cpp + * @author Lukasz Wojciechowski + * @version 1.0 + * @brief This file implements request class for inserting or updating policy bucket + */ + +#include + +#include "InsertOrUpdateBucketRequest.h" + +namespace Cynara { + +void InsertOrUpdateBucketRequest::execute(RequestPtr self, RequestTakerPtr taker, + RequestContextPtr context) const { + taker->execute(context, std::dynamic_pointer_cast(self)); +} + +} // namespace Cynara diff --git a/src/common/request/InsertOrUpdateBucketRequest.h b/src/common/request/InsertOrUpdateBucketRequest.h new file mode 100644 index 0000000..b166d71 --- /dev/null +++ b/src/common/request/InsertOrUpdateBucketRequest.h @@ -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 InsertOrUpdateBucketRequest.h + * @author Lukasz Wojciechowski + * @version 1.0 + * @brief This file defines request class for inserting or updating policy bucket + */ + +#ifndef SRC_COMMON_REQUEST_INSERTORUPDATEBUCKETREQUEST_H_ +#define SRC_COMMON_REQUEST_INSERTORUPDATEBUCKETREQUEST_H_ + +#include +#include + +#include +#include +#include + +namespace Cynara { + +class InsertOrUpdateBucketRequest : public Request { +private: + PolicyBucketId m_bucketId; + PolicyResult m_result; + +public: + InsertOrUpdateBucketRequest(const PolicyBucketId &bucketId, const PolicyResult &result, + ProtocolFrameSequenceNumber sequenceNumber) : + Request(sequenceNumber), m_bucketId(bucketId), m_result(result) { + } + + virtual ~InsertOrUpdateBucketRequest() = default; + + const PolicyBucketId &bucketId(void) const { + return m_bucketId; + } + + const PolicyResult &result(void) const { + return m_result; + } + + virtual void execute(RequestPtr self, RequestTakerPtr taker, RequestContextPtr context) const; +}; + +} // namespace Cynara + +#endif /* SRC_COMMON_REQUEST_INSERTORUPDATEBUCKETREQUEST_H_ */ diff --git a/src/common/request/RemoveBucketRequest.cpp b/src/common/request/RemoveBucketRequest.cpp new file mode 100644 index 0000000..69a2652 --- /dev/null +++ b/src/common/request/RemoveBucketRequest.cpp @@ -0,0 +1,34 @@ +/* + * 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 RemoveBucketRequest.cpp + * @author Lukasz Wojciechowski + * @version 1.0 + * @brief This file implements request class for bucket removal + */ + +#include + +#include "RemoveBucketRequest.h" + +namespace Cynara { + +void RemoveBucketRequest::execute(RequestPtr self, RequestTakerPtr taker, + RequestContextPtr context) const { + taker->execute(context, std::dynamic_pointer_cast(self)); +} + +} // namespace Cynara diff --git a/src/common/request/RemoveBucketRequest.h b/src/common/request/RemoveBucketRequest.h new file mode 100644 index 0000000..ff49a43 --- /dev/null +++ b/src/common/request/RemoveBucketRequest.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 RemoveBucketRequest.h + * @author Lukasz Wojciechowski + * @version 1.0 + * @brief This file defines request class for bucket removal + */ + +#ifndef SRC_COMMON_REQUEST_REMOVEBUCKETREQUEST_H_ +#define SRC_COMMON_REQUEST_REMOVEBUCKETREQUEST_H_ + +#include + +#include +#include +#include + +namespace Cynara { + +class RemoveBucketRequest : public Request { +private: + PolicyBucketId m_bucketId; + +public: + RemoveBucketRequest(const PolicyBucketId &bucketId, ProtocolFrameSequenceNumber sequenceNumber) + : Request(sequenceNumber), m_bucketId(bucketId) { + } + + virtual ~RemoveBucketRequest() = default; + + const PolicyBucketId &bucketId(void) const { + return m_bucketId; + } + + virtual void execute(RequestPtr self, RequestTakerPtr taker, RequestContextPtr context) const; +}; + +} // namespace Cynara + +#endif /* SRC_COMMON_REQUEST_REMOVEBUCKETREQUEST_H_ */ diff --git a/src/common/request/RequestTaker.cpp b/src/common/request/RequestTaker.cpp index 4ed8e7f..843c80e 100644 --- a/src/common/request/RequestTaker.cpp +++ b/src/common/request/RequestTaker.cpp @@ -33,6 +33,20 @@ void RequestTaker::execute(RequestContextPtr context UNUSED, CheckRequestPtr req throw NotImplementedException(); } +void RequestTaker::execute(RequestContextPtr context UNUSED, + InsertOrUpdateBucketRequestPtr request UNUSED) { + throw NotImplementedException(); +} + +void RequestTaker::execute(RequestContextPtr context UNUSED, + RemoveBucketRequestPtr request UNUSED) { + throw NotImplementedException(); +} + +void RequestTaker::execute(RequestContextPtr context UNUSED, SetPoliciesRequestPtr request UNUSED) { + throw NotImplementedException(); +} + void RequestTaker::execute(RequestContextPtr context UNUSED, SignalRequestPtr request UNUSED) { throw NotImplementedException(); } diff --git a/src/common/request/RequestTaker.h b/src/common/request/RequestTaker.h index 1739ba6..0c3ff7d 100644 --- a/src/common/request/RequestTaker.h +++ b/src/common/request/RequestTaker.h @@ -33,6 +33,9 @@ public: virtual ~RequestTaker() = default; virtual void execute(RequestContextPtr context, CheckRequestPtr request); + virtual void execute(RequestContextPtr context, InsertOrUpdateBucketRequestPtr request); + virtual void execute(RequestContextPtr context, RemoveBucketRequestPtr request); + virtual void execute(RequestContextPtr context, SetPoliciesRequestPtr request); virtual void execute(RequestContextPtr context, SignalRequestPtr request); }; diff --git a/src/common/request/SetPoliciesRequest.cpp b/src/common/request/SetPoliciesRequest.cpp new file mode 100644 index 0000000..e2bfb6f --- /dev/null +++ b/src/common/request/SetPoliciesRequest.cpp @@ -0,0 +1,34 @@ +/* + * 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 SetPoliciesRequest.cpp + * @author Lukasz Wojciechowski + * @version 1.0 + * @brief This file implements request class for modifying policies + */ + +#include + +#include "SetPoliciesRequest.h" + +namespace Cynara { + +void SetPoliciesRequest::execute(RequestPtr self, RequestTakerPtr taker, + RequestContextPtr context) const { + taker->execute(context, std::dynamic_pointer_cast(self)); +} + +} // namespace Cynara diff --git a/src/common/request/SetPoliciesRequest.h b/src/common/request/SetPoliciesRequest.h new file mode 100644 index 0000000..d876ad1 --- /dev/null +++ b/src/common/request/SetPoliciesRequest.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file SetPoliciesRequest.h + * @author Lukasz Wojciechowski + * @version 1.0 + * @brief This file defines request class for modifying policies + */ + +#ifndef SRC_COMMON_REQUEST_SETPOLICIESREQUEST_H_ +#define SRC_COMMON_REQUEST_SETPOLICIESREQUEST_H_ + +#include +#include + +#include +#include +#include + +#include +#include +#include + +namespace Cynara { + +class SetPoliciesRequest : public Request { +private: + std::map> m_insertOrUpdatePolicies; + std::map> m_removePolicies; + +public: + SetPoliciesRequest(const std::map> &insertOrUpdatePolicies, + const std::map> &removePolicies, + ProtocolFrameSequenceNumber sequenceNumber) : + Request(sequenceNumber), m_insertOrUpdatePolicies(insertOrUpdatePolicies), + m_removePolicies(removePolicies) { + } + + virtual ~SetPoliciesRequest() = default; + + const std::map> &policiesToBeInsertedOrUpdated(void) const { + return m_insertOrUpdatePolicies; + } + + const std::map> &policiesToBeRemoved(void) const { + return m_removePolicies; + } + + virtual void execute(RequestPtr self, RequestTakerPtr taker, RequestContextPtr context) const; +}; + +} // namespace Cynara + +#endif /* SRC_COMMON_REQUEST_SETPOLICIESREQUEST_H_ */ diff --git a/src/common/request/pointers.h b/src/common/request/pointers.h index b3c22e7..e04603e 100644 --- a/src/common/request/pointers.h +++ b/src/common/request/pointers.h @@ -30,6 +30,12 @@ namespace Cynara { class CheckRequest; typedef std::shared_ptr CheckRequestPtr; +class InsertOrUpdateBucketRequest; +typedef std::shared_ptr InsertOrUpdateBucketRequestPtr; + +class RemoveBucketRequest; +typedef std::shared_ptr RemoveBucketRequestPtr; + class Request; typedef std::shared_ptr RequestPtr; @@ -39,6 +45,9 @@ typedef std::shared_ptr RequestContextPtr; class RequestTaker; typedef std::shared_ptr RequestTakerPtr; +class SetPoliciesRequest; +typedef std::shared_ptr SetPoliciesRequestPtr; + class SignalRequest; typedef std::shared_ptr SignalRequestPtr; -- 2.7.4 From 346b7de870bbba9a244ade9304d519580ba1fbb0 Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Thu, 17 Jul 2014 17:52:13 +0200 Subject: [PATCH 09/16] Change collection types passed to Storage for changing policies Old methods shall be removed in another commit, after unit test are updated. Change-Id: Id8a7a48859b743f897a651ebff2156846d8f0e58 --- src/service/storage/Storage.cpp | 33 +++++++++++++++++++++++++++++---- src/service/storage/Storage.h | 17 ++++++++++++----- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/service/storage/Storage.cpp b/src/service/storage/Storage.cpp index 9e9f00d..3792721 100644 --- a/src/service/storage/Storage.cpp +++ b/src/service/storage/Storage.cpp @@ -47,7 +47,7 @@ PolicyResult Storage::minimalPolicy(const PolicyBucket &bucket, const PolicyKey const auto &policies = bucket.policyCollection(); auto proposeMinimal = [&minimal, &hasMinimal](const PolicyResult &candidate) { - if(hasMinimal == false) { + if (hasMinimal == false) { minimal = candidate; } else if (candidate < minimal) { minimal = candidate; @@ -80,19 +80,34 @@ PolicyResult Storage::minimalPolicy(const PolicyBucket &bucket, const PolicyKey return minimal; } +//todo to be removed, after tests get updated void Storage::insertPolicies(const std::vector &policies) { - for(const auto &policyTuple : policies) { + for (const auto &policyTuple : policies) { PolicyBucketId bucketId; PolicyPtr policyPtr; std::tie(policyPtr, bucketId) = policyTuple; auto existingPolicies = m_backend.searchBucket(bucketId, policyPtr->key()); - for(auto existingPolicy : existingPolicies.policyCollection()) { + for (auto existingPolicy : existingPolicies.policyCollection()) { m_backend.deletePolicy(bucketId, existingPolicy->key()); } m_backend.insertPolicy(bucketId, policyPtr); } } +void Storage::insertPolicies(const std::map> &policies) { + for (const auto &bucket : policies) { + const PolicyBucketId &bucketId = bucket.first; + for (const auto &policy : bucket.second) { + PolicyPtr policyPtr = std::make_shared(policy); + auto existingPolicies = m_backend.searchBucket(bucketId, policyPtr->key()); + for (auto existingPolicy : existingPolicies.policyCollection()) { + m_backend.deletePolicy(bucketId, existingPolicy->key()); + } + m_backend.insertPolicy(bucketId, policyPtr); + } + } +} + void Storage::addOrUpdateBucket(const PolicyBucketId &bucketId, const PolicyResult &defaultBucketPolicy) { if (m_backend.hasBucket(bucketId)) { m_backend.updateBucket(bucketId, defaultBucketPolicy); @@ -112,10 +127,20 @@ void Storage::deleteBucket(const PolicyBucketId &bucketId) { m_backend.deleteBucket(bucketId); } +//todo to be removed, after tests get updated void Storage::deletePolicies(const std::vector &policies) { - for(const auto &policy : policies) { + for (const auto &policy : policies) { m_backend.deletePolicy(std::get<1>(policy), std::get<0>(policy)); } } +void Storage::deletePolicies(const std::map> &policies) { + for (const auto &bucket : policies) { + const PolicyBucketId &bucketId = bucket.first; + for (const auto &policyKey : bucket.second) { + m_backend.deletePolicy(bucketId, policyKey); + } + } +} + } // namespace Cynara diff --git a/src/service/storage/Storage.h b/src/service/storage/Storage.h index 177765c..f7e9c78 100644 --- a/src/service/storage/Storage.h +++ b/src/service/storage/Storage.h @@ -24,15 +24,16 @@ #ifndef CYNARA_SERVICE_STORAGE_STORAGE_H #define CYNARA_SERVICE_STORAGE_STORAGE_H +#include +#include +#include +#include + #include "types/pointers.h" #include "types/PolicyBucketId.h" #include "types/PolicyResult.h" #include "types/PolicyKey.h" -#include -#include -#include - namespace Cynara { class StorageBackend; @@ -42,6 +43,7 @@ class Storage { public: // TODO: These tuples are ugly -- refactorize +//todo to be removed, after tests get updated typedef std::tuple PolicyPolicyBucket; typedef std::tuple PolicyKeyBucket; @@ -49,9 +51,14 @@ public: PolicyResult checkPolicy(const PolicyKey &key); +//todo below to functions should be removed, after tests get updated void insertPolicies(const std::vector &policies); - void addOrUpdateBucket(const PolicyBucketId &bucketId, const PolicyResult &defaultBucketPolicy); void deletePolicies(const std::vector &policies); + + void insertPolicies(const std::map> &policies); + void deletePolicies(const std::map> &policies); + + void addOrUpdateBucket(const PolicyBucketId &bucketId, const PolicyResult &defaultBucketPolicy); void deleteBucket(const PolicyBucketId &bucketId); protected: -- 2.7.4 From 9be977b85a40a1e30f1f472f0c2769e8f516bbf5 Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Thu, 17 Jul 2014 18:44:28 +0200 Subject: [PATCH 10/16] Catch and throw more detailed exception, when bucket not found There was an uncaught out_of_range exception, that can be thrown by unordered_map::at() method. It will be better to use a more detailed exception here. It will also fit into design of other methods from InMemoryStorageBackend. Change-Id: Ib70f10c79358b08f3b2a792143a1498050cc677a --- src/service/storage/InMemoryStorageBackend.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/service/storage/InMemoryStorageBackend.cpp b/src/service/storage/InMemoryStorageBackend.cpp index ab80521..b213111 100644 --- a/src/service/storage/InMemoryStorageBackend.cpp +++ b/src/service/storage/InMemoryStorageBackend.cpp @@ -37,8 +37,12 @@ PolicyBucket InMemoryStorageBackend::searchDefaultBucket(const PolicyKey &key) { PolicyBucket InMemoryStorageBackend::searchBucket(const PolicyBucketId &bucketId, const PolicyKey &key) { - const auto &bucket = this->buckets().at(bucketId); - return bucket.filtered(key); + try { + const auto &bucket = this->buckets().at(bucketId); + return bucket.filtered(key); + } catch (const std::out_of_range &) { + throw BucketNotExistsException(bucketId); + } } void InMemoryStorageBackend::insertPolicy(const PolicyBucketId &bucketId, PolicyPtr policy) { -- 2.7.4 From e327d78ccf7a1b22311feca64459ec797e1584fd Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Thu, 17 Jul 2014 19:56:55 +0200 Subject: [PATCH 11/16] Fix missing includes Change-Id: Id10efb9dc37c1b0567ce2e7e3f4e641b2a6ac4c3 --- src/common/protocol/ProtocolClient.cpp | 3 +++ src/common/request/RequestContext.h | 1 + src/common/response/ResponseTaker.h | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/common/protocol/ProtocolClient.cpp b/src/common/protocol/ProtocolClient.cpp index d87d7e7..d706338 100644 --- a/src/common/protocol/ProtocolClient.cpp +++ b/src/common/protocol/ProtocolClient.cpp @@ -32,7 +32,10 @@ #include #include #include +#include #include +#include +#include #include "ProtocolClient.h" diff --git a/src/common/request/RequestContext.h b/src/common/request/RequestContext.h index b5e518d..146ff68 100644 --- a/src/common/request/RequestContext.h +++ b/src/common/request/RequestContext.h @@ -28,6 +28,7 @@ #include #include #include +#include #include namespace Cynara { diff --git a/src/common/response/ResponseTaker.h b/src/common/response/ResponseTaker.h index 6100356..a54974c 100644 --- a/src/common/response/ResponseTaker.h +++ b/src/common/response/ResponseTaker.h @@ -24,7 +24,7 @@ #define SRC_COMMON_RESPONSE_RESPONSETAKER_H_ #include -#include +#include namespace Cynara { -- 2.7.4 From 524d4bb8aad042f011ce8f781a1a4e333bbee8dd Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Thu, 17 Jul 2014 20:07:16 +0200 Subject: [PATCH 12/16] Add CodeResponse class - a simple response with just a status This class shall be used as an answer for administrative requests: * InsertOrUpdateBucketRequest; * RemoveBucketRequest; * SetPoliciesRequest. Change-Id: I764ff5947a728504227114a1c5297df184a0c4bc --- src/common/CMakeLists.txt | 1 + src/common/response/CodeResponse.cpp | 34 ++++++++++++++++++++++ src/common/response/CodeResponse.h | 54 +++++++++++++++++++++++++++++++++++ src/common/response/ResponseTaker.cpp | 4 +++ src/common/response/ResponseTaker.h | 1 + src/common/response/pointers.h | 3 ++ 6 files changed, 97 insertions(+) create mode 100644 src/common/response/CodeResponse.cpp create mode 100644 src/common/response/CodeResponse.h diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 39b9e47..d2d5e03 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -38,6 +38,7 @@ SET(COMMON_SOURCES ${COMMON_PATH}/request/SetPoliciesRequest.cpp ${COMMON_PATH}/request/SignalRequest.cpp ${COMMON_PATH}/response/CheckResponse.cpp + ${COMMON_PATH}/response/CodeResponse.cpp ${COMMON_PATH}/response/ResponseTaker.cpp ${COMMON_PATH}/sockets/Socket.cpp ${COMMON_PATH}/sockets/SocketClient.cpp diff --git a/src/common/response/CodeResponse.cpp b/src/common/response/CodeResponse.cpp new file mode 100644 index 0000000..5b6f749 --- /dev/null +++ b/src/common/response/CodeResponse.cpp @@ -0,0 +1,34 @@ +/* + * 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 CodeResponse.cpp + * @author Lukasz Wojciechowski + * @version 1.0 + * @brief This file implements class for responding to a request with a code + */ + +#include + +#include "CodeResponse.h" + +namespace Cynara { + +void CodeResponse::execute(ResponsePtr self, ResponseTakerPtr taker, + RequestContextPtr context) const { + taker->execute(context, std::dynamic_pointer_cast(self)); +} + +} // namespace Cynara diff --git a/src/common/response/CodeResponse.h b/src/common/response/CodeResponse.h new file mode 100644 index 0000000..ec04e03 --- /dev/null +++ b/src/common/response/CodeResponse.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 CodeResponse.h + * @author Lukasz Wojciechowski + * @version 1.0 + * @brief This file defines class for responding to a request with a code + */ + +#ifndef SRC_COMMON_RESPONSE_CODERESPONSE_H_ +#define SRC_COMMON_RESPONSE_CODERESPONSE_H_ + +#include +#include +#include + +namespace Cynara { + +class CodeResponse : public Response { +public: + enum Code { + OK, + NO_BUCKET, + NOT_ALLOWED + }; + + const Code m_code; + + CodeResponse(Code code, ProtocolFrameSequenceNumber sequenceNumber) : + Response(sequenceNumber), m_code(code) { + } + + virtual ~CodeResponse() = default; + + virtual void execute(ResponsePtr self, ResponseTakerPtr taker, + RequestContextPtr context) const; +}; + +} // namespace Cynara + +#endif /* SRC_COMMON_RESPONSE_CODERESPONSE_H_ */ diff --git a/src/common/response/ResponseTaker.cpp b/src/common/response/ResponseTaker.cpp index 4ad200f..759c023 100644 --- a/src/common/response/ResponseTaker.cpp +++ b/src/common/response/ResponseTaker.cpp @@ -32,4 +32,8 @@ void ResponseTaker::execute(RequestContextPtr context UNUSED, CheckResponsePtr r throw NotImplementedException(); } +void ResponseTaker::execute(RequestContextPtr context UNUSED, CodeResponsePtr response UNUSED) { + throw NotImplementedException(); +} + } // namespace Cynara diff --git a/src/common/response/ResponseTaker.h b/src/common/response/ResponseTaker.h index a54974c..545f60f 100644 --- a/src/common/response/ResponseTaker.h +++ b/src/common/response/ResponseTaker.h @@ -34,6 +34,7 @@ public: virtual ~ResponseTaker() = default; virtual void execute(RequestContextPtr context, CheckResponsePtr response); + virtual void execute(RequestContextPtr context, CodeResponsePtr response); }; } // namespace Cynara diff --git a/src/common/response/pointers.h b/src/common/response/pointers.h index 3d39d2c..16d0a95 100644 --- a/src/common/response/pointers.h +++ b/src/common/response/pointers.h @@ -30,6 +30,9 @@ namespace Cynara { class CheckResponse; typedef std::shared_ptr CheckResponsePtr; +class CodeResponse; +typedef std::shared_ptr CodeResponsePtr; + class Response; typedef std::shared_ptr ResponsePtr; -- 2.7.4 From 08789710b45fe0bdd7e6b26d56b7fa5dd6bf429f Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Thu, 17 Jul 2014 20:09:37 +0200 Subject: [PATCH 13/16] Implement administrating request in Cynara service Logic class Change-Id: Ia4b1fe57ae2dc5a74565bf6f020cd14e72da19e8 --- src/service/logic/Logic.cpp | 43 ++++++++++++++++++++++++++++++++++++++++++- src/service/logic/Logic.h | 3 +++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/service/logic/Logic.cpp b/src/service/logic/Logic.cpp index a7c66d5..cd6e410 100644 --- a/src/service/logic/Logic.cpp +++ b/src/service/logic/Logic.cpp @@ -23,13 +23,19 @@ #include #include #include +#include +#include #include #include
#include +#include +#include #include +#include #include #include +#include #include #include @@ -57,7 +63,8 @@ void Logic::execute(RequestContextPtr context UNUSED, SignalRequestPtr request) void Logic::execute(RequestContextPtr context, CheckRequestPtr request) { PolicyResult result(PredefinedPolicyType::DENY); if (check(context, request->key(), result)) { - context->returnResponse(context, std::make_shared(result, request->sequenceNumber())); + context->returnResponse(context, std::make_shared(result, + request->sequenceNumber())); } } @@ -82,4 +89,38 @@ bool Logic::check(RequestContextPtr context UNUSED, const PolicyKey &key, throw PluginNotFoundException(result); } +void Logic::execute(RequestContextPtr context, InsertOrUpdateBucketRequestPtr request) { + m_storage->addOrUpdateBucket(request->bucketId(), request->result()); +//todo add saving to database + context->returnResponse(context, std::make_shared(CodeResponse::Code::OK, + request->sequenceNumber())); +} + +void Logic::execute(RequestContextPtr context, RemoveBucketRequestPtr request) { + auto code = CodeResponse::Code::OK; + try { + m_storage->deleteBucket(request->bucketId()); +//todo add saving to database + } catch (const BucketNotExistsException &ex) { + code = CodeResponse::Code::NO_BUCKET; + } catch (const DefaultBucketDeletionException &ex) { + code = CodeResponse::Code::NOT_ALLOWED; + } + context->returnResponse(context, std::make_shared(code, + request->sequenceNumber())); +} + +void Logic::execute(RequestContextPtr context, SetPoliciesRequestPtr request) { + auto code = CodeResponse::Code::OK; + try { + m_storage->insertPolicies(request->policiesToBeInsertedOrUpdated()); + m_storage->deletePolicies(request->policiesToBeRemoved()); +//todo add saving to database + } catch (const BucketNotExistsException &ex) { + code = CodeResponse::Code::NO_BUCKET; + } + context->returnResponse(context, std::make_shared(code, + request->sequenceNumber())); +} + } // namespace Cynara diff --git a/src/service/logic/Logic.h b/src/service/logic/Logic.h index a9d6cb9..e21419a 100644 --- a/src/service/logic/Logic.h +++ b/src/service/logic/Logic.h @@ -51,6 +51,9 @@ public: } virtual void execute(RequestContextPtr context, CheckRequestPtr request); + virtual void execute(RequestContextPtr context, InsertOrUpdateBucketRequestPtr request); + virtual void execute(RequestContextPtr context, RemoveBucketRequestPtr request); + virtual void execute(RequestContextPtr context, SetPoliciesRequestPtr request); virtual void execute(RequestContextPtr context, SignalRequestPtr request); private: -- 2.7.4 From 1695cef737ae00b1154d31ef64ad9903b38f7ce4 Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Thu, 17 Jul 2014 21:37:29 +0200 Subject: [PATCH 14/16] Add new libcynara-admin return codes and missing comments Change-Id: I7dd2bd16d82d9d4d6e19f4c980287034d6c94bea --- src/include/cynara-admin.h | 58 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/src/include/cynara-admin.h b/src/include/cynara-admin.h index 79f2b19..d998eb6 100644 --- a/src/include/cynara-admin.h +++ b/src/include/cynara-admin.h @@ -34,36 +34,80 @@ /*! \brief indicating the result of the one specific API is successful or access is allowed */ #define CYNARA_ADMIN_API_SUCCESS 0 -/*! \brief indicating system is running out of memory state */ +/*! \brief indicating client process is running out of memory */ #define CYNARA_ADMIN_API_OUT_OF_MEMORY -1 /*! \brief indicating the API's parameter is malformed */ #define CYNARA_ADMIN_API_INVALID_PARAM -2 -/*! \brief service not available */ +/*! \brief service not available (cannot connect to cynara service) */ #define CYNARA_ADMIN_API_SERVICE_NOT_AVAILABLE -3 + +/*! \brief unexpected error in client library */ +#define CYNARA_ADMIN_API_UNEXPECTED_CLIENT_ERROR -4 + +/*! \brief cynara service does not allow to perform requested operation */ +#define CYNARA_ADMIN_API_OPERATION_NOT_ALLOWED -5 + +/*! \brief cynara service hasn't found requested bucket */ +#define CYNARA_ADMIN_API_BUCKET_NOT_FOUND -6 /** @}*/ #ifdef __cplusplus extern "C" { #endif -//todo comment +/** + * \name cynara_admin + * forward declaration of structure allowing initialization of library + * and usage of all libcynara-admin API functions + */ struct cynara_admin; -//todo comment +/** + * \name Wildcard + * definition of WILDCARD, that can replace client, user or privilege name. + * WILDCARD matches any string during check procedure from libcynara-client. + */ #define CYNARA_ADMIN_WILDCARD "*" -//todo comment +/** + * \name Name of Default Bucket + * definition of name for default bucket - the one that check starts in. + * default bucket cannot be removed, although its default policy + * (which originaly is set to DENY) can be changed. + */ #define CYNARA_ADMIN_DEFAULT_BUCKET "" -//todo comments +/** + * \name Operation Codes + * operation codes that define action type to be taken in below defined functions + * they are used mosty to define policy result + * @{ + */ + +/*! \brief a policy or bucket should be removed */ #define CYNARA_ADMIN_DELETE -1 + +/*! \brief set policy result or bucket's default policy to DENY */ #define CYNARA_ADMIN_DENY 0 + +/*! \brief set policy result or bucket's default policy to ALLOW */ #define CYNARA_ADMIN_ALLOW 1 + +/*! \brief set policy to point into another bucket */ #define CYNARA_ADMIN_BUCKET 2 +/** @}*/ -//todo comments +/** + * \name cynara_admin_policy + * defines single policy + * bucket - is the name of bucket, in which policy is placed + * client, user, privilege - defines policy key + * result - defines result of policy + * result_extra - not always used, may contain some additional result data + * like e.g. name of bucket in case result == CYNARA_ADMIN_BUCKET + */ struct cynara_admin_policy { char *bucket; -- 2.7.4 From da85f8f39a1ed20861e0d579d47c40292a578456 Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Thu, 17 Jul 2014 21:38:55 +0200 Subject: [PATCH 15/16] Implement sending administration requests to Cynara service Implemented requests are: * InsertOrUpdateBucketRequest; * RemoveBucketRequest; * SetPoliciesRequest. All three requests have same response type (CodeResponse) so they are handled in common function. Change-Id: I84f7ad9375279d90db977d8a5d96ae38e29c3e5b --- src/admin/logic/Logic.cpp | 75 ++++++++++++++++++++++++++++++++++++++++------- src/admin/logic/Logic.h | 3 ++ 2 files changed, 67 insertions(+), 11 deletions(-) diff --git a/src/admin/logic/Logic.cpp b/src/admin/logic/Logic.cpp index d01353f..641929d 100644 --- a/src/admin/logic/Logic.cpp +++ b/src/admin/logic/Logic.cpp @@ -23,9 +23,18 @@ #include #include +#include +#include #include #include +#include +#include +#include +#include +#include +#include #include +#include #include "Logic.h" @@ -43,21 +52,65 @@ ProtocolFrameSequenceNumber generateSequenceNumber(void) { return ++sequenceNumber; } -int Logic::setPolicies(const std::map> &insertOrUpdate UNUSED, - const std::map> &remove UNUSED) noexcept { -//todo this is only a stub - return CYNARA_ADMIN_API_SUCCESS; +template +int Logic::askCynaraAndInterpreteCodeResponse(Args... args) { + ProtocolFrameSequenceNumber sequenceNumber = generateSequenceNumber(); + + //Ask cynara service + CodeResponsePtr codeResponse; + try { + RequestPtr request = std::make_shared(args..., sequenceNumber); + ResponsePtr response = m_socketClient->askCynaraServer(request); + if (!response) { + LOGW("Disconnected by cynara server."); + return CYNARA_ADMIN_API_SERVICE_NOT_AVAILABLE; + } + codeResponse = std::dynamic_pointer_cast(response); + if (!codeResponse) { + LOGC("Critical error. Casting Response to CodeResponse failed."); + return CYNARA_ADMIN_API_UNEXPECTED_CLIENT_ERROR; + } + + LOGD("codeResponse: code = %d", static_cast(codeResponse->m_code)); + switch (codeResponse->m_code) { + case CodeResponse::Code::OK: + LOGI("Policies set successfully."); + return CYNARA_ADMIN_API_SUCCESS; + case CodeResponse::Code::NOT_ALLOWED: + LOGE("Cynara service answered: Operation not allowed."); + return CYNARA_ADMIN_API_OPERATION_NOT_ALLOWED; + case CodeResponse::Code::NO_BUCKET: + LOGE("Trying to use unexisting bucket."); + return CYNARA_ADMIN_API_BUCKET_NOT_FOUND; + default: + LOGE("Unexpected response code from server: %d", + static_cast(codeResponse->m_code)); + return CYNARA_ADMIN_API_UNEXPECTED_CLIENT_ERROR; + } + } catch (const ServerConnectionErrorException &ex) { + LOGE("Cynara service not available."); + return CYNARA_ADMIN_API_SERVICE_NOT_AVAILABLE; + } catch (const std::bad_alloc &ex) { + LOGE("Cynara admin client out of memory."); + return CYNARA_ADMIN_API_OUT_OF_MEMORY; + } catch (const std::exception &ex) { + LOGE("Unexpected client error: %s", ex.what()); + return CYNARA_ADMIN_API_UNEXPECTED_CLIENT_ERROR; + } +} + +int Logic::setPolicies(const std::map> &insertOrUpdate, + const std::map> &remove) noexcept { + return askCynaraAndInterpreteCodeResponse(insertOrUpdate, remove); } -int Logic::insertOrUpdateBucket(const PolicyBucketId &bucket UNUSED, - const PolicyResult &policyResult UNUSED) noexcept { -//todo this is only a stub - return CYNARA_ADMIN_API_SUCCESS; +int Logic::insertOrUpdateBucket(const PolicyBucketId &bucket, + const PolicyResult &policyResult) noexcept { + return askCynaraAndInterpreteCodeResponse(bucket, policyResult); } -int Logic::removeBucket(const PolicyBucketId &bucket UNUSED) noexcept { -//todo this is only a stub - return CYNARA_ADMIN_API_SUCCESS; +int Logic::removeBucket(const PolicyBucketId &bucket) noexcept { + return askCynaraAndInterpreteCodeResponse(bucket); } } // namespace Cynara diff --git a/src/admin/logic/Logic.h b/src/admin/logic/Logic.h index 2cc22fc..d61c7e8 100644 --- a/src/admin/logic/Logic.h +++ b/src/admin/logic/Logic.h @@ -35,6 +35,9 @@ class Logic : public ApiInterface { private: SocketClientPtr m_socketClient; + template + int askCynaraAndInterpreteCodeResponse(Args... args); + public: Logic(); virtual ~Logic() = default; -- 2.7.4 From 6ed07339fd87b9bec3750169ceeef82371b469ea Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Fri, 18 Jul 2014 09:50:25 +0200 Subject: [PATCH 16/16] Remove unused class BucketAlreadyExistsException Change-Id: I382d02081925d3eda9424e869e26ff0b921cba48 --- .../exceptions/BucketAlreadyExistsException.h | 54 ---------------------- src/service/storage/Storage.cpp | 1 - .../inmemorystoragebackend.cpp | 1 - test/storage/storage/buckets.cpp | 1 - test/storage/storage/check.cpp | 1 - test/storage/storage/policies.cpp | 1 - 6 files changed, 59 deletions(-) delete mode 100644 src/common/exceptions/BucketAlreadyExistsException.h diff --git a/src/common/exceptions/BucketAlreadyExistsException.h b/src/common/exceptions/BucketAlreadyExistsException.h deleted file mode 100644 index 9fa7d6f..0000000 --- a/src/common/exceptions/BucketAlreadyExistsException.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * @file BucketAlreadyExistsException.h - * @author Aleksander Zdyb - * @version 1.0 - * @brief Implementation of BucketAlreadyExistsException - */ - -#ifndef SRC_COMMON_EXCEPTIONS_BUCKETALREADYEXISTSEXCEPTION_H_ -#define SRC_COMMON_EXCEPTIONS_BUCKETALREADYEXISTSEXCEPTION_H_ - -#include "Exception.h" -#include "types/PolicyBucketId.h" - -#include - -namespace Cynara { - -class BucketAlreadyExistsException : public Exception { -public: - BucketAlreadyExistsException() = delete; - BucketAlreadyExistsException(const PolicyBucketId &bucketId) : m_bucketId(bucketId) {} - virtual ~BucketAlreadyExistsException() = default; - - virtual const std::string message(void) const { - return "BucketAlreadyExistsException"; - } - -private: - PolicyBucketId m_bucketId; - -public: - const PolicyBucketId &bucketId() const { - return m_bucketId; - } -}; - -} /* namespace Cynara */ - -#endif // SRC_COMMON_EXCEPTIONS_BUCKETALREADYEXISTSEXCEPTION_H_ diff --git a/src/service/storage/Storage.cpp b/src/service/storage/Storage.cpp index 3792721..1b1a29a 100644 --- a/src/service/storage/Storage.cpp +++ b/src/service/storage/Storage.cpp @@ -26,7 +26,6 @@ #include "types/pointers.h" #include "types/PolicyType.h" #include "exceptions/NotImplementedException.h" -#include "exceptions/BucketAlreadyExistsException.h" #include "exceptions/DefaultBucketDeletionException.h" #include diff --git a/test/storage/inmemorystoragebackend/inmemorystoragebackend.cpp b/test/storage/inmemorystoragebackend/inmemorystoragebackend.cpp index bd682b3..34a3c42 100644 --- a/test/storage/inmemorystoragebackend/inmemorystoragebackend.cpp +++ b/test/storage/inmemorystoragebackend/inmemorystoragebackend.cpp @@ -28,7 +28,6 @@ #include "types/PolicyResult.h" #include "types/PolicyCollection.h" #include "exceptions/DefaultBucketDeletionException.h" -#include "exceptions/BucketAlreadyExistsException.h" #include "exceptions/BucketNotExistsException.h" #include "storage/StorageBackend.h" #include "storage/InMemoryStorageBackend.h" diff --git a/test/storage/storage/buckets.cpp b/test/storage/storage/buckets.cpp index c7d19ec..bbde254 100644 --- a/test/storage/storage/buckets.cpp +++ b/test/storage/storage/buckets.cpp @@ -30,7 +30,6 @@ #include "types/PolicyCollection.h" #include "types/pointers.h" #include "exceptions/DefaultBucketDeletionException.h" -#include "exceptions/BucketAlreadyExistsException.h" #include "storage/Storage.h" #include "storage/StorageBackend.h" diff --git a/test/storage/storage/check.cpp b/test/storage/storage/check.cpp index c91cd1f..492e7fb 100644 --- a/test/storage/storage/check.cpp +++ b/test/storage/storage/check.cpp @@ -29,7 +29,6 @@ #include "types/PolicyCollection.h" #include "types/pointers.h" #include "exceptions/DefaultBucketDeletionException.h" -#include "exceptions/BucketAlreadyExistsException.h" #include "storage/Storage.h" #include "storage/StorageBackend.h" diff --git a/test/storage/storage/policies.cpp b/test/storage/storage/policies.cpp index d43d918..8fcf900 100644 --- a/test/storage/storage/policies.cpp +++ b/test/storage/storage/policies.cpp @@ -29,7 +29,6 @@ #include "types/PolicyCollection.h" #include "types/pointers.h" #include "exceptions/DefaultBucketDeletionException.h" -#include "exceptions/BucketAlreadyExistsException.h" #include "storage/Storage.h" #include "storage/StorageBackend.h" -- 2.7.4