From 7155f2d34363ac078c093fad920adc1bdeb28390 Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Fri, 1 Aug 2014 09:45:16 +0200 Subject: [PATCH 01/16] Disallow pointing to nonexistent buckets Storage::insertPolicies() now cares, if bucket pointed by inserted policies exists. Change-Id: I113de2ead6ae17d18eb9a5928ef0181bee2f67d3 --- src/service/storage/Storage.cpp | 19 ++++++++++++++++ test/storage/storage/policies.cpp | 46 ++++++++++++++++++++++++++++++++++----- 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/src/service/storage/Storage.cpp b/src/service/storage/Storage.cpp index f8e7b8a..7f92c34 100644 --- a/src/service/storage/Storage.cpp +++ b/src/service/storage/Storage.cpp @@ -24,6 +24,7 @@ #include #include +#include #include "exceptions/DefaultBucketDeletionException.h" #include #include @@ -79,6 +80,24 @@ PolicyResult Storage::minimalPolicy(const PolicyBucket &bucket, const PolicyKey } void Storage::insertPolicies(const std::map> &policiesByBucketId) { + + auto pointedBucketExists = [this] (const Policy &policy) -> void { + if (policy.result().policyType() == PredefinedPolicyType::BUCKET) { + const auto &bucketId = policy.result().metadata(); + if (m_backend.hasBucket(bucketId) == false) { + throw BucketNotExistsException(bucketId); + } + } + }; + + // TODO: Rewrite, when transactions are supported + // Check if all of buckets exist + for (const auto &group : policiesByBucketId) { + const auto &policies = group.second; + std::for_each(policies.cbegin(), policies.cend(), pointedBucketExists); + } + + // Then insert policies for (const auto &group : policiesByBucketId) { const PolicyBucketId &bucketId = group.first; const auto &policies = group.second; diff --git a/test/storage/storage/policies.cpp b/test/storage/storage/policies.cpp index fbe40fa..54e0455 100644 --- a/test/storage/storage/policies.cpp +++ b/test/storage/storage/policies.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -78,6 +79,10 @@ TEST(storage, deleteBucketWithLinkedPolicies) { TEST(storage, insertPolicies) { using ::testing::Pointee; using ::testing::Return; + using PredefinedPolicyType::ALLOW; + using PredefinedPolicyType::BUCKET; + using PredefinedPolicyType::DENY; + FakeStorageBackend backend; Storage storage(backend); @@ -86,22 +91,24 @@ TEST(storage, insertPolicies) { typedef std::pair> BucketPolicyPair; - auto createPolicy = [] (const std::string &keySuffix, const PolicyType &type) -> Policy { - return Policy(Helpers::generatePolicyKey(keySuffix), type); + auto createPolicy = [] (const std::string &keySuffix, const PolicyResult &result) -> Policy { + return Policy(Helpers::generatePolicyKey(keySuffix), result); }; std::map> policiesToInsert = { BucketPolicyPair(testBucket1, { - createPolicy("1", PredefinedPolicyType::ALLOW), - createPolicy("2", PredefinedPolicyType::DENY), - createPolicy("3", PredefinedPolicyType::DENY) + createPolicy("1", ALLOW), + createPolicy("2", DENY), + createPolicy("3", DENY) }), BucketPolicyPair(testBucket2, { - createPolicy("4", PredefinedPolicyType::ALLOW), + createPolicy("4", { BUCKET, testBucket1 }), createPolicy("5", PredefinedPolicyType::ALLOW) }) }; + EXPECT_CALL(backend, hasBucket(testBucket1)).WillOnce(Return(true)); + for (const auto &group : policiesToInsert) { const auto &bucketId = group.first; const auto &policies = group.second; @@ -113,3 +120,30 @@ TEST(storage, insertPolicies) { storage.insertPolicies(policiesToInsert); } + +TEST(storage, insertPointingToNonexistentBucket) { + using ::testing::Pointee; + using ::testing::Return; + FakeStorageBackend backend; + Storage storage(backend); + + PolicyBucketId testBucketId = "test-bucket-1"; + PolicyBucketId nonexistentBucketId = "nonexistent"; + + typedef std::pair> BucketPolicyPair; + + auto createPolicy = [] (const std::string &keySuffix, const PolicyResult &result) -> Policy { + return Policy(Helpers::generatePolicyKey(keySuffix), result); + }; + + std::map> policiesToInsert = { + BucketPolicyPair(testBucketId, { + createPolicy("1", { PredefinedPolicyType::DENY }), + createPolicy("2", { PredefinedPolicyType::BUCKET, nonexistentBucketId }), + }), + }; + + EXPECT_CALL(backend, hasBucket(nonexistentBucketId)).WillOnce(Return(false)); + + ASSERT_THROW(storage.insertPolicies(policiesToInsert), BucketNotExistsException); +} -- 2.7.4 From 69d41ab34958afe806bf8673f55af47f670b681f Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Fri, 1 Aug 2014 12:29:02 +0200 Subject: [PATCH 02/16] Release version 0.2.0 Change-Id: Ied0ad56182536bbd0012bc3bf68f7ec3ea1dcc6f --- packaging/cynara.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/cynara.spec b/packaging/cynara.spec index a872b29..a3d82f0 100644 --- a/packaging/cynara.spec +++ b/packaging/cynara.spec @@ -1,6 +1,6 @@ Name: cynara Summary: Cynara service with client libraries -Version: 0.1.0 +Version: 0.2.0 Release: 1 Group: Security/Access Control License: Apache-2.0 -- 2.7.4 From f32215d2aeff3b2c24d801690d2ae60e442bf75f Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Mon, 4 Aug 2014 13:39:33 +0200 Subject: [PATCH 03/16] Fix format string concatenating in log message Change-Id: I945ca6a4fcc80ff83415b285b761369356757e6a --- src/common/protocol/ProtocolAdmin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/protocol/ProtocolAdmin.cpp b/src/common/protocol/ProtocolAdmin.cpp index 1a6ff67..a42f8fc 100644 --- a/src/common/protocol/ProtocolAdmin.cpp +++ b/src/common/protocol/ProtocolAdmin.cpp @@ -213,7 +213,7 @@ void ProtocolAdmin::execute(RequestContextPtr context, RemoveBucketRequestPtr re } void ProtocolAdmin::execute(RequestContextPtr context, SetPoliciesRequestPtr request) { - LOGD("Serializing SetPoliciesRequestPtr: sequenceNumber [%u], insertOrUpdate count [%zu]", + LOGD("Serializing SetPoliciesRequestPtr: sequenceNumber [%u], insertOrUpdate count [%zu], " "remove count [%zu]", static_cast(request->sequenceNumber()), request->policiesToBeInsertedOrUpdated().size(), request->policiesToBeRemoved().size()); -- 2.7.4 From 24815d050799b0f46a9caeee8aedaefa033489a2 Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Mon, 4 Aug 2014 13:43:17 +0200 Subject: [PATCH 04/16] Add missing include in InMemoryStorageBackend.cpp file Change-Id: I82e40449ce7f797d656482af39749d6879298860 --- src/service/storage/InMemoryStorageBackend.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/service/storage/InMemoryStorageBackend.cpp b/src/service/storage/InMemoryStorageBackend.cpp index e46e485..dc802e2 100644 --- a/src/service/storage/InMemoryStorageBackend.cpp +++ b/src/service/storage/InMemoryStorageBackend.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include -- 2.7.4 From 629833fb521b7b61ab2c4cbb8a1b5930acfbd645 Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Mon, 4 Aug 2014 14:02:20 +0200 Subject: [PATCH 05/16] Change member initialization This change is needed by other compilers to build without error. Change-Id: I38826a3c72fed96f948ad1b1eaf9735bd3f5b99f --- src/service/storage/InMemoryStorageBackend.cpp | 2 ++ src/service/storage/InMemoryStorageBackend.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/service/storage/InMemoryStorageBackend.cpp b/src/service/storage/InMemoryStorageBackend.cpp index dc802e2..9fee197 100644 --- a/src/service/storage/InMemoryStorageBackend.cpp +++ b/src/service/storage/InMemoryStorageBackend.cpp @@ -49,6 +49,8 @@ namespace Cynara { +const std::string InMemoryStorageBackend::m_indexFileName = "buckets"; + void InMemoryStorageBackend::load(void) { std::string indexFilename = m_dbPath + m_indexFileName; diff --git a/src/service/storage/InMemoryStorageBackend.h b/src/service/storage/InMemoryStorageBackend.h index 68d042e..be187bb 100644 --- a/src/service/storage/InMemoryStorageBackend.h +++ b/src/service/storage/InMemoryStorageBackend.h @@ -70,7 +70,7 @@ protected: private: std::string m_dbPath; Buckets m_buckets; - const std::string m_indexFileName = "buckets"; + static const std::string m_indexFileName; protected: virtual Buckets &buckets(void) { -- 2.7.4 From dd800411de0c60833227b59084cf6d157b9b8f76 Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Mon, 4 Aug 2014 14:09:56 +0200 Subject: [PATCH 06/16] Add 'class' keyword in friend class declaration Change-Id: I1a63573faf35313b600439678198112cd9a6dcd9 --- src/common/types/PolicyKey.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/types/PolicyKey.h b/src/common/types/PolicyKey.h index ae9774e..f7d0fe0 100644 --- a/src/common/types/PolicyKey.h +++ b/src/common/types/PolicyKey.h @@ -33,7 +33,7 @@ namespace Cynara { class PolicyKey; class PolicyKeyFeature { -friend PolicyKey; +friend class PolicyKey; public: typedef std::string ValueType; -- 2.7.4 From 90f40c36c40d99533afc4326a9804c6a65f4e9e3 Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Mon, 4 Aug 2014 14:12:13 +0200 Subject: [PATCH 07/16] Change default virtual destructor from '= default' to '{}' '= default' seems to be problematic. Some compilers give error: "declared virtual cannot be defaulted in the class body". Change-Id: Iaca3a70f64e45309430bc010883a87fcdc536d1b --- src/admin/api/ApiInterface.h | 2 +- src/admin/logic/Logic.h | 2 +- src/client/api/ApiInterface.h | 2 +- src/client/cache/CacheInterface.h | 6 +++--- src/client/logic/Logic.h | 2 +- src/common/exceptions/BucketDeserializationException.h | 1 + src/common/exceptions/BucketNotExistsException.h | 2 +- src/common/exceptions/BucketRecordCorruptedException.h | 2 +- src/common/exceptions/BucketSerializationException.h | 1 + src/common/exceptions/CannotCreateFileException.h | 2 +- src/common/exceptions/DefaultBucketDeletionException.h | 2 +- src/common/exceptions/DescriptorNotExistsException.h | 2 +- src/common/exceptions/Exception.h | 2 +- src/common/exceptions/FileNotFoundException.h | 2 +- src/common/exceptions/InitException.h | 2 +- src/common/exceptions/InvalidProtocolException.h | 2 +- src/common/exceptions/NotImplementedException.h | 2 +- src/common/exceptions/NullPointerException.h | 2 +- src/common/exceptions/OutOfDataException.h | 2 +- src/common/exceptions/PluginNotFoundException.h | 2 +- src/common/exceptions/ServerConnectionErrorException.h | 2 +- src/common/exceptions/UnexpectedErrorException.h | 2 +- src/common/protocol/Protocol.h | 2 +- src/common/protocol/ProtocolFrame.h | 2 +- src/common/protocol/ProtocolFrameHeader.h | 2 +- src/common/protocol/ProtocolSerialization.h | 4 ++-- src/common/request/CheckRequest.h | 2 +- src/common/request/InsertOrUpdateBucketRequest.h | 2 +- src/common/request/RemoveBucketRequest.h | 2 +- src/common/request/Request.h | 2 +- src/common/request/RequestTaker.h | 2 +- src/common/request/SetPoliciesRequest.h | 2 +- src/common/request/SignalRequest.h | 2 +- src/common/response/CheckResponse.h | 2 +- src/common/response/CodeResponse.h | 2 +- src/common/response/Response.h | 2 +- src/common/response/ResponseTaker.h | 2 +- src/common/sockets/SocketClient.h | 2 +- src/service/storage/InMemoryStorageBackend.h | 2 +- src/service/storage/StorageSerializer.h | 2 +- test/storage/serializer/bucket_load.cpp | 2 +- test/storage/serializer/serialize.cpp | 2 +- 42 files changed, 45 insertions(+), 43 deletions(-) diff --git a/src/admin/api/ApiInterface.h b/src/admin/api/ApiInterface.h index 9c513f6..eb2b17b 100644 --- a/src/admin/api/ApiInterface.h +++ b/src/admin/api/ApiInterface.h @@ -39,7 +39,7 @@ namespace Cynara { class ApiInterface { public: ApiInterface() = default; - virtual ~ApiInterface() = default; + virtual ~ApiInterface() {}; virtual int setPolicies(const std::map> &insertOrUpdate, const std::map> &remove) noexcept = 0; diff --git a/src/admin/logic/Logic.h b/src/admin/logic/Logic.h index d61c7e8..2d349f3 100644 --- a/src/admin/logic/Logic.h +++ b/src/admin/logic/Logic.h @@ -40,7 +40,7 @@ private: public: Logic(); - virtual ~Logic() = default; + virtual ~Logic() {}; virtual int setPolicies(const std::map> &insertOrUpdate, const std::map> &remove) noexcept; diff --git a/src/client/api/ApiInterface.h b/src/client/api/ApiInterface.h index f268508..73bcec5 100644 --- a/src/client/api/ApiInterface.h +++ b/src/client/api/ApiInterface.h @@ -31,7 +31,7 @@ namespace Cynara { class ApiInterface { public: ApiInterface() = default; - virtual ~ApiInterface() = default; + virtual ~ApiInterface() {}; virtual int check(const std::string &client, const std::string &session, const std::string &user, const std::string &privilege) = 0; diff --git a/src/client/cache/CacheInterface.h b/src/client/cache/CacheInterface.h index f325a42..0279fdb 100644 --- a/src/client/cache/CacheInterface.h +++ b/src/client/cache/CacheInterface.h @@ -47,7 +47,7 @@ typedef std::shared_ptr ResultGetterInterfacePtr; class ResultGetterInterface { public: virtual int requestResult(const PolicyKey &key, PolicyResult &result) noexcept = 0; - virtual ~ResultGetterInterface() = default; + virtual ~ResultGetterInterface() {}; }; class InterpreterInterface { @@ -56,7 +56,7 @@ public: virtual bool isUsable(const PolicyResult &result) noexcept = 0; virtual int toResult(const PolicyResult &result) noexcept = 0; - virtual ~InterpreterInterface() = default; + virtual ~InterpreterInterface() {}; }; class PluginCache { @@ -72,7 +72,7 @@ public: m_plugins.clear(); } - virtual ~PluginCache() = default; + virtual ~PluginCache() {}; protected: std::map m_plugins; diff --git a/src/client/logic/Logic.h b/src/client/logic/Logic.h index e9f2c23..ec298da 100644 --- a/src/client/logic/Logic.h +++ b/src/client/logic/Logic.h @@ -41,7 +41,7 @@ private: public: Logic(); - virtual ~Logic() = default; + virtual ~Logic() {}; virtual int check(const std::string &client, const std::string &session, const std::string &user, const std::string &privilege) noexcept; diff --git a/src/common/exceptions/BucketDeserializationException.h b/src/common/exceptions/BucketDeserializationException.h index 2a00555..01d9a80 100644 --- a/src/common/exceptions/BucketDeserializationException.h +++ b/src/common/exceptions/BucketDeserializationException.h @@ -30,6 +30,7 @@ namespace Cynara { class BucketDeserializationException : public DatabaseException { public: BucketDeserializationException(const PolicyBucketId &bucketId) : m_bucketId(bucketId) {} + ~BucketDeserializationException() noexcept {}; const std::string message(void) const { if (m_message.empty()) { diff --git a/src/common/exceptions/BucketNotExistsException.h b/src/common/exceptions/BucketNotExistsException.h index 54c942e..18eb190 100644 --- a/src/common/exceptions/BucketNotExistsException.h +++ b/src/common/exceptions/BucketNotExistsException.h @@ -34,7 +34,7 @@ class BucketNotExistsException : public Exception { public: BucketNotExistsException() = delete; BucketNotExistsException(const PolicyBucketId &bucketId) : m_bucketId(bucketId) {} - virtual ~BucketNotExistsException() = default; + virtual ~BucketNotExistsException() noexcept {}; virtual const std::string message(void) const { return "BucketNotExistsException"; diff --git a/src/common/exceptions/BucketRecordCorruptedException.h b/src/common/exceptions/BucketRecordCorruptedException.h index 227c1d9..8152a77 100644 --- a/src/common/exceptions/BucketRecordCorruptedException.h +++ b/src/common/exceptions/BucketRecordCorruptedException.h @@ -31,7 +31,7 @@ namespace Cynara { class BucketRecordCorruptedException : public Exception { public: BucketRecordCorruptedException(void) = delete; - virtual ~BucketRecordCorruptedException(void) = default; + virtual ~BucketRecordCorruptedException() noexcept {}; BucketRecordCorruptedException(const std::string &line) : m_lineNumber(0), m_line(line) {} diff --git a/src/common/exceptions/BucketSerializationException.h b/src/common/exceptions/BucketSerializationException.h index 8882ff4..83f3397 100644 --- a/src/common/exceptions/BucketSerializationException.h +++ b/src/common/exceptions/BucketSerializationException.h @@ -30,6 +30,7 @@ namespace Cynara { class BucketSerializationException : public DatabaseException { public: BucketSerializationException(const PolicyBucketId &bucketId) : m_bucketId(bucketId) {} + ~BucketSerializationException() noexcept {}; const std::string message(void) const { if (m_message.empty()) { diff --git a/src/common/exceptions/CannotCreateFileException.h b/src/common/exceptions/CannotCreateFileException.h index bb3f937..cfdfb49 100644 --- a/src/common/exceptions/CannotCreateFileException.h +++ b/src/common/exceptions/CannotCreateFileException.h @@ -32,7 +32,7 @@ namespace Cynara { class CannotCreateFileException : public DatabaseException { public: CannotCreateFileException(const std::string &filename) : m_filename(filename) {}; - virtual ~CannotCreateFileException() = default; + virtual ~CannotCreateFileException() noexcept {}; const std::string message(void) const { if (m_message.empty()) { diff --git a/src/common/exceptions/DefaultBucketDeletionException.h b/src/common/exceptions/DefaultBucketDeletionException.h index 6a92ec5..92e1a73 100644 --- a/src/common/exceptions/DefaultBucketDeletionException.h +++ b/src/common/exceptions/DefaultBucketDeletionException.h @@ -32,7 +32,7 @@ namespace Cynara { class DefaultBucketDeletionException : public Exception { public: DefaultBucketDeletionException() = default; - virtual ~DefaultBucketDeletionException() = default; + virtual ~DefaultBucketDeletionException() noexcept {}; virtual const std::string message(void) const { return "DefaultBucketDeletionException"; diff --git a/src/common/exceptions/DescriptorNotExistsException.h b/src/common/exceptions/DescriptorNotExistsException.h index 5dd9553..095ffba 100644 --- a/src/common/exceptions/DescriptorNotExistsException.h +++ b/src/common/exceptions/DescriptorNotExistsException.h @@ -43,7 +43,7 @@ public: m_whatMsg = stream.str(); } - virtual ~DescriptorNotExistsException() = default; + virtual ~DescriptorNotExistsException() noexcept {}; virtual const std::string message(void) const { return m_whatMsg; diff --git a/src/common/exceptions/Exception.h b/src/common/exceptions/Exception.h index b709060..74ded47 100644 --- a/src/common/exceptions/Exception.h +++ b/src/common/exceptions/Exception.h @@ -33,7 +33,7 @@ public: m_backtrace = Backtrace::getBacktrace(); } - virtual ~Exception() = default; + virtual ~Exception() noexcept {}; virtual const char *what(void) const noexcept { if(m_whatMessage.empty()) { diff --git a/src/common/exceptions/FileNotFoundException.h b/src/common/exceptions/FileNotFoundException.h index e353c19..bce1fcb 100644 --- a/src/common/exceptions/FileNotFoundException.h +++ b/src/common/exceptions/FileNotFoundException.h @@ -32,7 +32,7 @@ namespace Cynara { class FileNotFoundException : public DatabaseException { public: FileNotFoundException(const std::string &filename) : m_filename(filename) {}; - virtual ~FileNotFoundException() = default; + virtual ~FileNotFoundException() noexcept {}; const std::string message(void) const { if (m_message.empty()) { diff --git a/src/common/exceptions/InitException.h b/src/common/exceptions/InitException.h index d06e1d7..c51cb5b 100644 --- a/src/common/exceptions/InitException.h +++ b/src/common/exceptions/InitException.h @@ -32,7 +32,7 @@ namespace Cynara { class InitException : public Exception { public: InitException() = default; - virtual ~InitException() = default; + virtual ~InitException() noexcept {}; virtual const std::string message(void) const { return "InitException"; diff --git a/src/common/exceptions/InvalidProtocolException.h b/src/common/exceptions/InvalidProtocolException.h index a2d65d1..33053e9 100644 --- a/src/common/exceptions/InvalidProtocolException.h +++ b/src/common/exceptions/InvalidProtocolException.h @@ -59,7 +59,7 @@ public: } - virtual ~InvalidProtocolException() = default; + virtual ~InvalidProtocolException() noexcept {}; virtual const std::string message(void) const { return m_whatMessage; diff --git a/src/common/exceptions/NotImplementedException.h b/src/common/exceptions/NotImplementedException.h index ceabb9a..3d1882a 100644 --- a/src/common/exceptions/NotImplementedException.h +++ b/src/common/exceptions/NotImplementedException.h @@ -32,7 +32,7 @@ namespace Cynara { class NotImplementedException : public Exception { public: NotImplementedException() = default; - virtual ~NotImplementedException() = default; + virtual ~NotImplementedException() noexcept {}; virtual const std::string message(void) const { return "NotImplementedException"; diff --git a/src/common/exceptions/NullPointerException.h b/src/common/exceptions/NullPointerException.h index ffd0bef..02db1c5 100644 --- a/src/common/exceptions/NullPointerException.h +++ b/src/common/exceptions/NullPointerException.h @@ -42,7 +42,7 @@ public: + std::string(">"); } - virtual ~NullPointerException() = default; + virtual ~NullPointerException() noexcept {}; virtual const std::string message(void) const { return m_whatMsg; diff --git a/src/common/exceptions/OutOfDataException.h b/src/common/exceptions/OutOfDataException.h index 827eb7a..c0b63bd 100644 --- a/src/common/exceptions/OutOfDataException.h +++ b/src/common/exceptions/OutOfDataException.h @@ -44,7 +44,7 @@ public: m_whatMsg = stream.str(); } - virtual ~OutOfDataException() = default; + virtual ~OutOfDataException() noexcept {}; virtual const std::string message(void) const { return m_whatMsg; diff --git a/src/common/exceptions/PluginNotFoundException.h b/src/common/exceptions/PluginNotFoundException.h index 345fd1d..4e422d3 100644 --- a/src/common/exceptions/PluginNotFoundException.h +++ b/src/common/exceptions/PluginNotFoundException.h @@ -45,7 +45,7 @@ public: m_whatMessage = stream.str(); } - virtual ~PluginNotFoundException() = default; + virtual ~PluginNotFoundException() noexcept {}; virtual const std::string message(void) const { return m_whatMessage; diff --git a/src/common/exceptions/ServerConnectionErrorException.h b/src/common/exceptions/ServerConnectionErrorException.h index a5a7b08..88a5e47 100644 --- a/src/common/exceptions/ServerConnectionErrorException.h +++ b/src/common/exceptions/ServerConnectionErrorException.h @@ -32,7 +32,7 @@ namespace Cynara { class ServerConnectionErrorException : public Exception { public: ServerConnectionErrorException() = default; - virtual ~ServerConnectionErrorException() = default; + virtual ~ServerConnectionErrorException() noexcept {}; virtual const std::string message(void) const { return "ServerConnectionError"; } diff --git a/src/common/exceptions/UnexpectedErrorException.h b/src/common/exceptions/UnexpectedErrorException.h index a7d100b..f3fca09 100644 --- a/src/common/exceptions/UnexpectedErrorException.h +++ b/src/common/exceptions/UnexpectedErrorException.h @@ -49,7 +49,7 @@ public: m_whatMessage = stream.str(); } - virtual ~UnexpectedErrorException() = default; + virtual ~UnexpectedErrorException() noexcept {}; virtual const std::string message(void) const { return m_whatMessage; diff --git a/src/common/protocol/Protocol.h b/src/common/protocol/Protocol.h index daf001c..5069cff 100644 --- a/src/common/protocol/Protocol.h +++ b/src/common/protocol/Protocol.h @@ -40,7 +40,7 @@ typedef std::shared_ptr ProtocolPtr; class Protocol : public RequestTaker, public ResponseTaker { public: Protocol() = default; - virtual ~Protocol() = default; + virtual ~Protocol() {}; virtual ProtocolPtr clone(void) = 0; diff --git a/src/common/protocol/ProtocolFrame.h b/src/common/protocol/ProtocolFrame.h index 709196e..f3c64b8 100644 --- a/src/common/protocol/ProtocolFrame.h +++ b/src/common/protocol/ProtocolFrame.h @@ -40,7 +40,7 @@ class ProtocolFrame: public IStream { public: ProtocolFrame(ProtocolFrameHeaderPtr frameHeader, BinaryQueuePtr headerContent); - virtual ~ProtocolFrame() = default; + virtual ~ProtocolFrame() {}; ProtocolFrameHeaderPtr frameHeader(void) { return m_frameHeader; diff --git a/src/common/protocol/ProtocolFrameHeader.h b/src/common/protocol/ProtocolFrameHeader.h index 0db0d6b..6560255 100644 --- a/src/common/protocol/ProtocolFrameHeader.h +++ b/src/common/protocol/ProtocolFrameHeader.h @@ -46,7 +46,7 @@ private: public: ProtocolFrameHeader(BinaryQueuePtr headerContent = nullptr); - virtual ~ProtocolFrameHeader() = default; + virtual ~ProtocolFrameHeader() {}; virtual void read(size_t num, void *bytes); virtual void write(size_t num, const void *bytes); diff --git a/src/common/protocol/ProtocolSerialization.h b/src/common/protocol/ProtocolSerialization.h index 532f78b..f3acff7 100644 --- a/src/common/protocol/ProtocolSerialization.h +++ b/src/common/protocol/ProtocolSerialization.h @@ -38,7 +38,7 @@ class IStream { public: virtual void read(size_t num, void *bytes) = 0; virtual void write(size_t num, const void *bytes) = 0; - virtual ~IStream() = default; + virtual ~IStream() {}; }; // Serializable interface @@ -47,7 +47,7 @@ public: /* ISerializable(){}; * ISerializable(IStream&){}; */ virtual void serialize(IStream &) const = 0; - virtual ~ISerializable() = default; + virtual ~ISerializable() {}; }; struct ProtocolSerialization { diff --git a/src/common/request/CheckRequest.h b/src/common/request/CheckRequest.h index 03135c7..7262347 100644 --- a/src/common/request/CheckRequest.h +++ b/src/common/request/CheckRequest.h @@ -40,7 +40,7 @@ public: Request(sequenceNumber), m_key(key) { } - virtual ~CheckRequest() = default; + virtual ~CheckRequest() {}; const PolicyKey &key(void) const { return m_key; diff --git a/src/common/request/InsertOrUpdateBucketRequest.h b/src/common/request/InsertOrUpdateBucketRequest.h index b166d71..2cf03ce 100644 --- a/src/common/request/InsertOrUpdateBucketRequest.h +++ b/src/common/request/InsertOrUpdateBucketRequest.h @@ -43,7 +43,7 @@ public: Request(sequenceNumber), m_bucketId(bucketId), m_result(result) { } - virtual ~InsertOrUpdateBucketRequest() = default; + virtual ~InsertOrUpdateBucketRequest() {}; const PolicyBucketId &bucketId(void) const { return m_bucketId; diff --git a/src/common/request/RemoveBucketRequest.h b/src/common/request/RemoveBucketRequest.h index ff49a43..49ef2a0 100644 --- a/src/common/request/RemoveBucketRequest.h +++ b/src/common/request/RemoveBucketRequest.h @@ -40,7 +40,7 @@ public: : Request(sequenceNumber), m_bucketId(bucketId) { } - virtual ~RemoveBucketRequest() = default; + virtual ~RemoveBucketRequest() {}; const PolicyBucketId &bucketId(void) const { return m_bucketId; diff --git a/src/common/request/Request.h b/src/common/request/Request.h index ac92398..9b9a2d2 100644 --- a/src/common/request/Request.h +++ b/src/common/request/Request.h @@ -33,7 +33,7 @@ class Request { public: Request(ProtocolFrameSequenceNumber sequenceNumber) : m_sequenceNumber(sequenceNumber) { } - virtual ~Request() = default; + virtual ~Request() {}; virtual void execute(RequestPtr self, RequestTakerPtr taker, RequestContextPtr context) const = 0; diff --git a/src/common/request/RequestTaker.h b/src/common/request/RequestTaker.h index 0c3ff7d..9d0a10f 100644 --- a/src/common/request/RequestTaker.h +++ b/src/common/request/RequestTaker.h @@ -30,7 +30,7 @@ namespace Cynara { class RequestTaker { public: RequestTaker() = default; - virtual ~RequestTaker() = default; + virtual ~RequestTaker() {}; virtual void execute(RequestContextPtr context, CheckRequestPtr request); virtual void execute(RequestContextPtr context, InsertOrUpdateBucketRequestPtr request); diff --git a/src/common/request/SetPoliciesRequest.h b/src/common/request/SetPoliciesRequest.h index d876ad1..afb8f14 100644 --- a/src/common/request/SetPoliciesRequest.h +++ b/src/common/request/SetPoliciesRequest.h @@ -49,7 +49,7 @@ public: m_removePolicies(removePolicies) { } - virtual ~SetPoliciesRequest() = default; + virtual ~SetPoliciesRequest() {}; const std::map> &policiesToBeInsertedOrUpdated(void) const { return m_insertOrUpdatePolicies; diff --git a/src/common/request/SignalRequest.h b/src/common/request/SignalRequest.h index f9d1422..068834d 100644 --- a/src/common/request/SignalRequest.h +++ b/src/common/request/SignalRequest.h @@ -38,7 +38,7 @@ public: SignalRequest(struct signalfd_siginfo sigInfo) : Request(0), m_sigInfo(sigInfo) { } - virtual ~SignalRequest() = default; + virtual ~SignalRequest() {}; virtual void execute(RequestPtr self, RequestTakerPtr taker, RequestContextPtr context) const; diff --git a/src/common/response/CheckResponse.h b/src/common/response/CheckResponse.h index 1f49648..1ca69f3 100644 --- a/src/common/response/CheckResponse.h +++ b/src/common/response/CheckResponse.h @@ -39,7 +39,7 @@ public: Response(sequenceNumber), m_resultRef(result) { } - virtual ~CheckResponse() = default; + virtual ~CheckResponse() {}; virtual void execute(ResponsePtr self, ResponseTakerPtr taker, RequestContextPtr context) const; diff --git a/src/common/response/CodeResponse.h b/src/common/response/CodeResponse.h index ec04e03..96d04c6 100644 --- a/src/common/response/CodeResponse.h +++ b/src/common/response/CodeResponse.h @@ -43,7 +43,7 @@ public: Response(sequenceNumber), m_code(code) { } - virtual ~CodeResponse() = default; + virtual ~CodeResponse() {}; virtual void execute(ResponsePtr self, ResponseTakerPtr taker, RequestContextPtr context) const; diff --git a/src/common/response/Response.h b/src/common/response/Response.h index e85de48..0731975 100644 --- a/src/common/response/Response.h +++ b/src/common/response/Response.h @@ -33,7 +33,7 @@ class Response { public: Response(ProtocolFrameSequenceNumber sequenceNumber) : m_sequenceNumber(sequenceNumber) { }; - virtual ~Response() = default; + virtual ~Response() {}; virtual void execute(ResponsePtr self, ResponseTakerPtr taker, RequestContextPtr context) const = 0; diff --git a/src/common/response/ResponseTaker.h b/src/common/response/ResponseTaker.h index 545f60f..8aede4d 100644 --- a/src/common/response/ResponseTaker.h +++ b/src/common/response/ResponseTaker.h @@ -31,7 +31,7 @@ namespace Cynara { class ResponseTaker { public: ResponseTaker() = default; - virtual ~ResponseTaker() = default; + virtual ~ResponseTaker() {}; virtual void execute(RequestContextPtr context, CheckResponsePtr response); virtual void execute(RequestContextPtr context, CodeResponsePtr response); diff --git a/src/common/sockets/SocketClient.h b/src/common/sockets/SocketClient.h index fae5ba3..7553a5a 100644 --- a/src/common/sockets/SocketClient.h +++ b/src/common/sockets/SocketClient.h @@ -46,7 +46,7 @@ private: public: SocketClient(const std::string &socketPath, ProtocolPtr protocol); - virtual ~SocketClient() = default; + virtual ~SocketClient() {}; //returns pointer to response // or nullptr when connection to cynara service is lost diff --git a/src/service/storage/InMemoryStorageBackend.h b/src/service/storage/InMemoryStorageBackend.h index be187bb..d811edd 100644 --- a/src/service/storage/InMemoryStorageBackend.h +++ b/src/service/storage/InMemoryStorageBackend.h @@ -44,7 +44,7 @@ class InMemoryStorageBackend : public StorageBackend { public: InMemoryStorageBackend(const std::string &path) : m_dbPath(path) { } - virtual ~InMemoryStorageBackend() = default; + virtual ~InMemoryStorageBackend() {}; virtual void load(void); virtual void save(void); diff --git a/src/service/storage/StorageSerializer.h b/src/service/storage/StorageSerializer.h index a995265..55ec2cd 100644 --- a/src/service/storage/StorageSerializer.h +++ b/src/service/storage/StorageSerializer.h @@ -45,7 +45,7 @@ public: BucketStreamOpener; StorageSerializer(std::shared_ptr os); - virtual ~StorageSerializer() = default; + virtual ~StorageSerializer() {}; virtual void dump(const Buckets &buckets, BucketStreamOpener streamOpener); diff --git a/test/storage/serializer/bucket_load.cpp b/test/storage/serializer/bucket_load.cpp index 3c2096e..8e5b2df 100644 --- a/test/storage/serializer/bucket_load.cpp +++ b/test/storage/serializer/bucket_load.cpp @@ -43,7 +43,7 @@ MATCHER_P(PolicyAtPtrEq, policy, "") { class BucketDeserializerFixture : public ::testing::Test { public: - virtual ~BucketDeserializerFixture() = default; + virtual ~BucketDeserializerFixture() {}; PolicyPtr createPolicy(const PolicyKey &pk, const PolicyResult &pr) { return std::make_shared(pk, pr); diff --git a/test/storage/serializer/serialize.cpp b/test/storage/serializer/serialize.cpp index 07804f4..ad55495 100644 --- a/test/storage/serializer/serialize.cpp +++ b/test/storage/serializer/serialize.cpp @@ -56,7 +56,7 @@ public: class StorageSerializerFixture : public ::testing::Test { public: - virtual ~StorageSerializerFixture() = default; + virtual ~StorageSerializerFixture() {}; Cynara::Buckets buckets; FakeStreamForBucketId fakeStreamOpener; -- 2.7.4 From 88cebd4b4739baf26d06114b40efb28cbd43a9a4 Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Wed, 6 Aug 2014 15:12:15 +0200 Subject: [PATCH 08/16] Move user and group creating section from %post to %pre scriptlet This change is needed for creating cynara local state directory with proper user and group. Change-Id: I50d353f7fee1e352c7377a8902a237519c0a6491 --- packaging/cynara.spec | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packaging/cynara.spec b/packaging/cynara.spec index a3d82f0..937fbea 100644 --- a/packaging/cynara.spec +++ b/packaging/cynara.spec @@ -104,13 +104,7 @@ mkdir -p %{buildroot}/%{state_path} ln -s ../cynara.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/cynara.socket ln -s ../cynara-admin.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/cynara-admin.socket -%post -### Add file capabilities if needed -### setcap/getcap binary are useful. To use them you must install libcap and libcap-tools packages -### In such case uncomment Requires with those packages - -systemctl daemon-reload - +%pre id -g %{group_name} > /dev/null 2>&1 if [ $? -eq 1 ]; then groupadd %{group_name} -r > /dev/null 2>&1 @@ -121,6 +115,13 @@ if [ $? -eq 1 ]; then useradd -m %{user_name} -r > /dev/null 2>&1 fi +%post +### Add file capabilities if needed +### setcap/getcap binary are useful. To use them you must install libcap and libcap-tools packages +### In such case uncomment Requires with those packages + +systemctl daemon-reload + if [ $1 = 1 ]; then systemctl enable %{name}.service fi -- 2.7.4 From 895c4129ad96d10029491fc514caad6475f38d7d Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Wed, 6 Aug 2014 21:18:47 +0200 Subject: [PATCH 09/16] Release version 0.2.1 Change-Id: Ibae38957b9c8e359b351ce888358e7554af1b8ee --- packaging/cynara.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/cynara.spec b/packaging/cynara.spec index 937fbea..8d9c94f 100644 --- a/packaging/cynara.spec +++ b/packaging/cynara.spec @@ -1,6 +1,6 @@ Name: cynara Summary: Cynara service with client libraries -Version: 0.2.0 +Version: 0.2.1 Release: 1 Group: Security/Access Control License: Apache-2.0 -- 2.7.4 From afb766d37eaed3409323efe82e957f99455bfb02 Mon Sep 17 00:00:00 2001 From: Zofia Abramowska Date: Fri, 1 Aug 2014 15:20:52 +0200 Subject: [PATCH 10/16] Merge cynara and cynara-tests spec files Change-Id: I254584d5ef8a5e546be8bec4eb9e9629199306bc --- CMakeLists.txt | 2 ++ .../cynara-tests.manifest | 0 packaging/cynara.spec | 18 ++++++++++- packaging_tests/cynara-tests.spec | 31 ------------------- test/CMakeLists.txt | 36 +++------------------- 5 files changed, 24 insertions(+), 63 deletions(-) rename {packaging_tests => packaging}/cynara-tests.manifest (100%) delete mode 100644 packaging_tests/cynara-tests.spec diff --git a/CMakeLists.txt b/CMakeLists.txt index 85bcfdb..354d39b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,7 +57,9 @@ SET(TARGET_CYNARA "cynara") SET(TARGET_LIB_CYNARA "cynara-client") SET(TARGET_LIB_CYNARA_ADMIN "cynara-admin") SET(TARGET_CYNARA_COMMON "cynara-commons") +SET(TARGET_CYNARA_TESTS "cynara-tests") ADD_SUBDIRECTORY(src) +ADD_SUBDIRECTORY(test) ADD_SUBDIRECTORY(build) ADD_SUBDIRECTORY(systemd) diff --git a/packaging_tests/cynara-tests.manifest b/packaging/cynara-tests.manifest similarity index 100% rename from packaging_tests/cynara-tests.manifest rename to packaging/cynara-tests.manifest diff --git a/packaging/cynara.spec b/packaging/cynara.spec index 8d9c94f..8bb7e14 100644 --- a/packaging/cynara.spec +++ b/packaging/cynara.spec @@ -8,6 +8,7 @@ Source0: %{name}-%{version}.tar.gz Source1001: cynara.manifest Source1002: libcynara-client.manifest Source1003: libcynara-admin.manifest +Source1004: cynara-tests.manifest Requires: default-ac-domains BuildRequires: cmake BuildRequires: zip @@ -29,7 +30,8 @@ BuildRequires: pkgconfig(libunwind) %endif %description -service and client libraries (libcynara-client, libcynara-admin) +service, client libraries (libcynara-client, libcynara-admin) +and tests (cynara-tests) ####################################################### %package -n libcynara-client @@ -66,6 +68,15 @@ Requires: libcynara-admin = %{version}-%{release} admin client library (devel) for setting, listing and removing policies ####################################################### +%package -n cynara-tests +Summary: Cynara - cynara test binaries +BuildRequires: pkgconfig(gmock) + +%description -n cynara-tests +Cynara tests + +####################################################### + %package -n cynara-devel Summary: Cynara service (devel) Requires: cynara = %{version}-%{release} @@ -78,6 +89,7 @@ service (devel version) cp -a %{SOURCE1001} . cp -a %{SOURCE1002} . cp -a %{SOURCE1003} . +cp -a %{SOURCE1004} . %build %if 0%{?sec_build_binary_debug_enable} @@ -199,3 +211,7 @@ fi %{_includedir}/cynara/cynara-admin.h %{_libdir}/libcynara-admin.so %{_libdir}/pkgconfig/cynara-admin.pc + +%files -n cynara-tests +%manifest cynara-tests.manifest +%attr(755,root,root) /usr/bin/cynara-tests diff --git a/packaging_tests/cynara-tests.spec b/packaging_tests/cynara-tests.spec deleted file mode 100644 index 8b1de31..0000000 --- a/packaging_tests/cynara-tests.spec +++ /dev/null @@ -1,31 +0,0 @@ -Name: cynara-tests -Summary: Cynara tests -Version: 0.0.1 -Release: 1 -Group: Development/Testing -License: Apache-2.0 -Source0: %{name}-%{version}.tar.gz -Source1001: cynara-tests.manifest -BuildRequires: cmake -BuildRequires: pkgconfig(gmock) - -%description -Cynara tests - -%global build_type %{?build_type:%build_type}%{!?build_type:RELEASE} - -%prep -%setup -q -cp -a %{SOURCE1001} . - -%build -%cmake test -DCMAKE_BUILD_TYPE=%{?build_type} \ - -DCMAKE_VERBOSE_MAKEFILE=ON -make %{?jobs:-j%jobs} - -%install -%make_install - -%files -%manifest cynara-tests.manifest -%attr(755,root,root) /usr/bin/cynara-tests diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b391a4c..820279f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -16,47 +16,21 @@ # @author Aleksander Zdyb # @brief Cmake for tests # - -############################# Check minimum CMake version ##################### - -CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3) -PROJECT("cynara-tests") - -############################# cmake packages ################################## - -INCLUDE(FindPkgConfig) - -############################# compiler flags ################################## - -SET(CMAKE_C_FLAGS_DEBUG "-g -O0 -ggdb") -SET(CMAKE_CXX_FLAGS_DEBUG "-g -std=c++0x -O0 -ggdb -Wp,-U_FORTIFY_SOURCE") -SET(CMAKE_C_FLAGS_RELEASE "-g -O2") -SET(CMAKE_CXX_FLAGS_RELEASE "-g -std=c++0x -O2") - -# Set compiler warning flags -ADD_DEFINITIONS("-Werror") # Make all warnings into errors. -ADD_DEFINITIONS("-Wall") # Generate all warnings -ADD_DEFINITIONS("-Wextra") # Generate even more extra warnings -ADD_DEFINITIONS("-DCYNARA_NO_LOGS") # Disable building logs - -MESSAGE(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") - -SET(TARGET_CYNARA_TESTS "cynara-tests") - PKG_CHECK_MODULES(PKGS REQUIRED gmock_main) -SET(CYNARA_SRC ${PROJECT_SOURCE_DIR}/../src) +ADD_DEFINITIONS("-DCYNARA_NO_LOGS") +SET(CYNARA_SRC ${PROJECT_SOURCE_DIR}/src) SET(CYNARA_SOURCES_FOR_TESTS - ${CYNARA_SRC}/service/storage/Storage.cpp ${CYNARA_SRC}/common/types/PolicyBucket.cpp + ${CYNARA_SRC}/common/types/PolicyKey.cpp ${CYNARA_SRC}/common/types/PolicyKeyHelpers.cpp + ${CYNARA_SRC}/common/types/PolicyType.cpp + ${CYNARA_SRC}/service/storage/Storage.cpp ${CYNARA_SRC}/service/storage/InMemoryStorageBackend.cpp ${CYNARA_SRC}/service/storage/BucketDeserializer.cpp ${CYNARA_SRC}/service/storage/StorageDeserializer.cpp ${CYNARA_SRC}/service/storage/StorageSerializer.cpp - ${CYNARA_SRC}/common/types/PolicyKey.cpp - ${CYNARA_SRC}/common/types/PolicyType.cpp ) SET(CYNARA_TESTS_SOURCES -- 2.7.4 From f801eff5a438cb0267aeea84b330037c47144ccc Mon Sep 17 00:00:00 2001 From: Zofia Abramowska Date: Fri, 8 Aug 2014 14:16:54 +0200 Subject: [PATCH 11/16] Release version 0.2.2 Change-Id: I33c53395cb9af581dd1c1ed3ac37c36b4f874435 --- packaging/cynara.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/cynara.spec b/packaging/cynara.spec index 8bb7e14..5524b9d 100644 --- a/packaging/cynara.spec +++ b/packaging/cynara.spec @@ -1,6 +1,6 @@ Name: cynara Summary: Cynara service with client libraries -Version: 0.2.1 +Version: 0.2.2 Release: 1 Group: Security/Access Control License: Apache-2.0 -- 2.7.4 From c1e566ededb9aa086d2c6ab011519fb1df88ee0a Mon Sep 17 00:00:00 2001 From: Zofia Abramowska Date: Fri, 8 Aug 2014 14:22:29 +0200 Subject: [PATCH 12/16] Change Cache to be based on std::unordered_map Change-Id: Iaadc74c426d9d6e7851a55b69556463b53aa31e6 --- src/client/cache/CapacityCache.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/cache/CapacityCache.h b/src/client/cache/CapacityCache.h index 39ca928..12101db 100644 --- a/src/client/cache/CapacityCache.h +++ b/src/client/cache/CapacityCache.h @@ -24,7 +24,7 @@ #define SRC_CLIENT_CACHE_CAPACITYCACHE_H_ #include -#include +#include #include @@ -44,7 +44,7 @@ public: private: typedef std::list KeyUsageList; - typedef std::map> KeyValueMap; -- 2.7.4 From ab73c19c44d7f4e6f4a25ba1243ce08af11c84c0 Mon Sep 17 00:00:00 2001 From: Marcin Niesluchowski Date: Thu, 31 Jul 2014 17:55:36 +0200 Subject: [PATCH 13/16] Add asynchronous client api Change-Id: I76f4374a96a09f53dd4154a8049c42683fb39bf7 --- CMakeLists.txt | 1 + build/CMakeLists.txt | 1 + build/cynara-client-async/CMakeLists.txt | 25 ++ .../cynara-client-async/cynara-client-async.pc.in | 11 + packaging/cynara.spec | 45 +++- packaging/libcynara-client-async.manifest | 5 + src/CMakeLists.txt | 1 + src/client-async/CMakeLists.txt | 48 ++++ src/client-async/api/ApiInterface.h | 47 ++++ src/client-async/api/client-async-api.cpp | 118 +++++++++ src/client-async/logic/Logic.cpp | 52 ++++ src/client-async/logic/Logic.h | 47 ++++ src/include/CMakeLists.txt | 5 + src/include/cynara-client-async.h | 294 +++++++++++++++++++++ 14 files changed, 697 insertions(+), 3 deletions(-) create mode 100644 build/cynara-client-async/CMakeLists.txt create mode 100644 build/cynara-client-async/cynara-client-async.pc.in create mode 100644 packaging/libcynara-client-async.manifest create mode 100644 src/client-async/CMakeLists.txt create mode 100644 src/client-async/api/ApiInterface.h create mode 100644 src/client-async/api/client-async-api.cpp create mode 100644 src/client-async/logic/Logic.cpp create mode 100644 src/client-async/logic/Logic.h create mode 100644 src/include/cynara-client-async.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 354d39b..eadba21 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,7 @@ ENDIF (CMAKE_BUILD_TYPE MATCHES "DEBUG") SET(TARGET_CYNARA "cynara") SET(TARGET_LIB_CYNARA "cynara-client") +SET(TARGET_LIB_CYNARA_ASYNC "cynara-client-async") SET(TARGET_LIB_CYNARA_ADMIN "cynara-admin") SET(TARGET_CYNARA_COMMON "cynara-commons") SET(TARGET_CYNARA_TESTS "cynara-tests") diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 269b258..ff93082 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -17,4 +17,5 @@ # ADD_SUBDIRECTORY(cynara-client) +ADD_SUBDIRECTORY(cynara-client-async) ADD_SUBDIRECTORY(cynara-admin) diff --git a/build/cynara-client-async/CMakeLists.txt b/build/cynara-client-async/CMakeLists.txt new file mode 100644 index 0000000..c24b331 --- /dev/null +++ b/build/cynara-client-async/CMakeLists.txt @@ -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 CMakeLists.txt +# @author Marcin Niesluchowski +# + +CONFIGURE_FILE(cynara-client-async.pc.in cynara-client-async.pc @ONLY) + +INSTALL(FILES + ${CMAKE_BINARY_DIR}/build/cynara-client-async/cynara-client-async.pc + DESTINATION + ${LIB_INSTALL_DIR}/pkgconfig + ) diff --git a/build/cynara-client-async/cynara-client-async.pc.in b/build/cynara-client-async/cynara-client-async.pc.in new file mode 100644 index 0000000..c3f1be5 --- /dev/null +++ b/build/cynara-client-async/cynara-client-async.pc.in @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +libdir=@LIB_INSTALL_DIR@ +includedir=${prefix}/include + +Name: cynara-client-async +Description: cynara-client-async package +Version: 0.0.1 +Requires: +Libs: -L${libdir} -lcynara-client-async +Cflags: -I${includedir}/cynara diff --git a/packaging/cynara.spec b/packaging/cynara.spec index 5524b9d..a75ed92 100644 --- a/packaging/cynara.spec +++ b/packaging/cynara.spec @@ -7,8 +7,9 @@ License: Apache-2.0 Source0: %{name}-%{version}.tar.gz Source1001: cynara.manifest Source1002: libcynara-client.manifest -Source1003: libcynara-admin.manifest -Source1004: cynara-tests.manifest +Source1003: libcynara-client-async.manifest +Source1004: libcynara-admin.manifest +Source1005: cynara-tests.manifest Requires: default-ac-domains BuildRequires: cmake BuildRequires: zip @@ -30,7 +31,7 @@ BuildRequires: pkgconfig(libunwind) %endif %description -service, client libraries (libcynara-client, libcynara-admin) +service and client libraries (libcynara-client, libcynara-client-async, libcynara-admin) and tests (cynara-tests) ####################################################### @@ -51,6 +52,23 @@ Requires: libcynara-client = %{version}-%{release} client library (devel) for checking policies ####################################################### +%package -n libcynara-client-async +Summary: Cynara - asynchronous client library +Requires: cynara = %{version}-%{release} +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description -n libcynara-client-async +asynchronous client library for checking policies + +%package -n libcynara-client-async-devel +Summary: Cynara - asynchronous client library (devel) +Requires: libcynara-client-async = %{version}-%{release} + +%description -n libcynara-client-async-devel +asynchronous client library (devel) for checking policies + +####################################################### %package -n libcynara-admin Summary: Cynara - admin client library Requires: cynara = %{version}-%{release} @@ -90,6 +108,7 @@ cp -a %{SOURCE1001} . cp -a %{SOURCE1002} . cp -a %{SOURCE1003} . cp -a %{SOURCE1004} . +cp -a %{SOURCE1005} . %build %if 0%{?sec_build_binary_debug_enable} @@ -163,6 +182,10 @@ fi %postun -n libcynara-client -p /sbin/ldconfig +%post -n libcynara-client-async -p /sbin/ldconfig + +%postun -n libcynara-client-async -p /sbin/ldconfig + %post -n libcynara-admin -p /sbin/ldconfig %postun -n libcynara-admin -p /sbin/ldconfig @@ -171,6 +194,10 @@ fi %postun -n libcynara-client-devel -p /sbin/ldconfig +%post -n libcynara-client-async-devel -p /sbin/ldconfig + +%postun -n libcynara-client-async-devel -p /sbin/ldconfig + %post -n libcynara-admin-devel -p /sbin/ldconfig %postun -n libcynara-admin-devel -p /sbin/ldconfig @@ -200,6 +227,18 @@ fi %{_libdir}/pkgconfig/cynara-client.pc %{_libdir}/libcynara-client.so +%files -n libcynara-client-async +%manifest libcynara-client-async.manifest +%license LICENSE +%defattr(-,root,root,-) +%{_libdir}/libcynara-client-async.so.* + +%files -n libcynara-client-async-devel +%defattr(-,root,root,-) +%{_includedir}/cynara/cynara-client-async.h +%{_libdir}/pkgconfig/cynara-client-async.pc +%{_libdir}/libcynara-client-async.so + %files -n libcynara-admin %manifest libcynara-admin.manifest %license LICENSE diff --git a/packaging/libcynara-client-async.manifest b/packaging/libcynara-client-async.manifest new file mode 100644 index 0000000..a76fdba --- /dev/null +++ b/packaging/libcynara-client-async.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 852e0a5..385e440 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -47,5 +47,6 @@ INCLUDE_DIRECTORIES( ADD_SUBDIRECTORY(include) ADD_SUBDIRECTORY(common) ADD_SUBDIRECTORY(client) +ADD_SUBDIRECTORY(client-async) ADD_SUBDIRECTORY(admin) ADD_SUBDIRECTORY(service) diff --git a/src/client-async/CMakeLists.txt b/src/client-async/CMakeLists.txt new file mode 100644 index 0000000..98f5ad6 --- /dev/null +++ b/src/client-async/CMakeLists.txt @@ -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 CMakeLists.txt +# @author Marcin Niesluchowski +# + +SET(LIB_CYNARA_ASYNC_VERSION_MAJOR 0) +SET(LIB_CYNARA_ASYNC_VERSION ${LIB_CYNARA_ASYNC_VERSION_MAJOR}.0.2) + +SET(CYNARA_LIB_CYNARA_ASYNC_PATH ${CYNARA_PATH}/client-async) + +SET(LIB_CYNARA_ASYNC_SOURCES + ${CYNARA_LIB_CYNARA_ASYNC_PATH}/api/client-async-api.cpp + ${CYNARA_LIB_CYNARA_ASYNC_PATH}/logic/Logic.cpp + ) + +INCLUDE_DIRECTORIES( + ${CYNARA_LIB_CYNARA_ASYNC_PATH} + ) + +ADD_LIBRARY(${TARGET_LIB_CYNARA_ASYNC} SHARED ${LIB_CYNARA_ASYNC_SOURCES}) + +SET_TARGET_PROPERTIES( + ${TARGET_LIB_CYNARA_ASYNC} + PROPERTIES + COMPILE_FLAGS "-D_GNU_SOURCE -fPIC -fvisibility=hidden" + SOVERSION ${LIB_CYNARA_ASYNC_VERSION_MAJOR} + VERSION ${LIB_CYNARA_ASYNC_VERSION} + ) + +TARGET_LINK_LIBRARIES(${TARGET_LIB_CYNARA_ASYNC} + ${CYNARA_DEP_LIBRARIES} + ${TARGET_CYNARA_COMMON} + ) + +INSTALL(TARGETS ${TARGET_LIB_CYNARA_ASYNC} DESTINATION ${LIB_INSTALL_DIR}) diff --git a/src/client-async/api/ApiInterface.h b/src/client-async/api/ApiInterface.h new file mode 100644 index 0000000..216713a --- /dev/null +++ b/src/client-async/api/ApiInterface.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 ApiInterface.h + * @author Marcin Niesluchowski + * @version 1.0 + * @brief This file contains libcynara-client-async API interface definition. + */ + +#ifndef SRC_CLIENT_ASYNC_API_APIINTERFACE_H_ +#define SRC_CLIENT_ASYNC_API_APIINTERFACE_H_ + +#include + +#include + +namespace Cynara { + +class ApiInterface { +public: + ApiInterface() = default; + virtual ~ApiInterface() {}; + + virtual int connect(int &sockFd) = 0; + virtual int check(const std::string &client, const std::string &session, + const std::string &user, const std::string &privilege, + cynara_check_id &checkId) = 0; + virtual int receive(cynara_check_id &checkId) = 0; + virtual int cancel(const cynara_check_id checkId) = 0; +}; + +} // namespace Cynara + +#endif /* SRC_CLIENT_ASYNC_API_APIINTERFACE_H_ */ diff --git a/src/client-async/api/client-async-api.cpp b/src/client-async/api/client-async-api.cpp new file mode 100644 index 0000000..34111f6 --- /dev/null +++ b/src/client-async/api/client-async-api.cpp @@ -0,0 +1,118 @@ +/* + * 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 client-async-api.cpp + * @author Marcin Niesluchowski + * @version 1.0 + * @brief Implementation of external libcynara-client-async API + */ + +#include + +#include +#include + +#include +#include +#include + +struct cynara_async { + Cynara::ApiInterface *impl; + + cynara_async(Cynara::ApiInterface *_impl) : impl(_impl) { + } + + ~cynara_async() { + delete impl; + } +}; + +CYNARA_API +int cynara_async_initialize(cynara_async **pp_cynara, + const cynara_async_configuration *p_conf UNUSED) +{ + if (!pp_cynara) + return CYNARA_ASYNC_API_INVALID_PARAM; + + try { + *pp_cynara = new cynara_async(new Cynara::Logic); + } catch (const std::bad_alloc &ex) { + return CYNARA_ASYNC_API_OUT_OF_MEMORY; + } + + init_log(); + + LOGD("Cynara client async initialized"); + + return CYNARA_ASYNC_API_SUCCESS; +} + +CYNARA_API +int cynara_async_finish(cynara_async *p_cynara) +{ + delete p_cynara; + + return CYNARA_ASYNC_API_SUCCESS; +} + +CYNARA_API +int cynara_async_connect(cynara_async *p_cynara, int *p_sock_fd) +{ + if (!p_cynara || !p_cynara->impl) + return CYNARA_ASYNC_API_INVALID_PARAM; + if (!p_sock_fd) + return CYNARA_ASYNC_API_INVALID_PARAM; + + return p_cynara->impl->connect(*p_sock_fd); +} + +CYNARA_API +int cynara_async_check(cynara_async *p_cynara, + const char *client, const char *client_session, + const char *user, const char *privilege, + cynara_check_id *p_check_id) +{ + if (!p_cynara || !p_cynara->impl) + return CYNARA_ASYNC_API_INVALID_PARAM; + if (!client || !client_session || !user || !privilege) + return CYNARA_ASYNC_API_INVALID_PARAM; + if (!p_check_id) + return CYNARA_ASYNC_API_INVALID_PARAM; + + return p_cynara->impl->check(client, client_session, + user, privilege, + *p_check_id); +} + +CYNARA_API +int cynara_async_receive(cynara_async *p_cynara, cynara_check_id *p_check_id) +{ + if (!p_cynara || !p_cynara->impl) + return CYNARA_ASYNC_API_INVALID_PARAM; + if (!p_check_id) + return CYNARA_ASYNC_API_INVALID_PARAM; + + return p_cynara->impl->receive(*p_check_id); +} + +CYNARA_API +int cynara_async_cancel(cynara_async *p_cynara, const cynara_check_id check_id) +{ + if (!p_cynara || !p_cynara->impl) + return CYNARA_ASYNC_API_INVALID_PARAM; + + return p_cynara->impl->cancel(check_id); +} diff --git a/src/client-async/logic/Logic.cpp b/src/client-async/logic/Logic.cpp new file mode 100644 index 0000000..c6e7860 --- /dev/null +++ b/src/client-async/logic/Logic.cpp @@ -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 Logic.cpp + * @author Marcin Niesluchowski + * @version 1.0 + * @brief This file contains implementation of Logic class - main + * libcynara-client-async class + */ + +#include + +#include "Logic.h" + +namespace Cynara { + +int Logic::connect(int &sockFd UNUSED) noexcept +{ + return CYNARA_ASYNC_API_SUCCESS; +} + +int Logic::check(const std::string &client UNUSED, const std::string &session UNUSED, + const std::string &user UNUSED, const std::string &privilege UNUSED, + cynara_check_id &checkId UNUSED) noexcept +{ + return CYNARA_ASYNC_API_SUCCESS; +} + +int Logic::receive(cynara_check_id &checkId UNUSED) noexcept +{ + return CYNARA_ASYNC_API_SUCCESS; +} + +int Logic::cancel(const cynara_check_id checkId UNUSED) noexcept +{ + return CYNARA_ASYNC_API_SUCCESS; +} + +} // namespace Cynara diff --git a/src/client-async/logic/Logic.h b/src/client-async/logic/Logic.h new file mode 100644 index 0000000..e63ce68 --- /dev/null +++ b/src/client-async/logic/Logic.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 Logic.h + * @author Marcin Niesluchowski + * @version 1.0 + * @brief This file contains declaration of Logic class - main + * libcynara-client-async class + */ + +#ifndef SRC_CLIENT_ASYNC_LOGIC_LOGIC_H_ +#define SRC_CLIENT_ASYNC_LOGIC_LOGIC_H_ + +#include +#include + +namespace Cynara { + +class Logic : public ApiInterface { +public: + Logic() = default; + virtual ~Logic() {}; + + virtual int connect(int &sockFd) noexcept; + virtual int check(const std::string &client, const std::string &session, + const std::string &user, const std::string &privilege, + cynara_check_id &checkId) noexcept; + virtual int receive(cynara_check_id &checkId) noexcept; + virtual int cancel(const cynara_check_id checkId) noexcept; +}; + +} // namespace Cynara + +#endif /* SRC_CLIENT_ASYNC_LOGIC_LOGIC_H_ */ diff --git a/src/include/CMakeLists.txt b/src/include/CMakeLists.txt index 5d8ed5a..edf2938 100644 --- a/src/include/CMakeLists.txt +++ b/src/include/CMakeLists.txt @@ -22,6 +22,11 @@ INSTALL(FILES ) INSTALL(FILES + ${CYNARA_PATH}/include/cynara-client-async.h + DESTINATION ${INCLUDE_INSTALL_DIR}/cynara + ) + +INSTALL(FILES ${CYNARA_PATH}/include/cynara-admin.h DESTINATION ${INCLUDE_INSTALL_DIR}/cynara ) diff --git a/src/include/cynara-client-async.h b/src/include/cynara-client-async.h new file mode 100644 index 0000000..c04d0b5 --- /dev/null +++ b/src/include/cynara-client-async.h @@ -0,0 +1,294 @@ +/* + * 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 cynara-client-async.h + * @author Marcin Niesluchowski + * @version 1.0 + * @brief This file contains asynchronous client APIs of Cynara available + * with libcynara-client-asynchronous. + */ + + +#ifndef CYNARA_CLIENT_ASYNC_H +#define CYNARA_CLIENT_ASYNC_H + +#include + +/** + * \name Return Codes + * exported by the foundation API. + * result codes begin with the start error code and extend into negative direction. + * @{ +*/ + +/*! \brief indicating the result of the one specific API is successful or access is allowed */ +#define CYNARA_ASYNC_API_SUCCESS 0 + +/*! \brief indicating that access that was checked is denied */ +#define CYNARA_ASYNC_API_ACCESS_DENIED -1 + +/*! \brief indicating that answer was not yet received */ +#define CYNARA_ASYNC_API_ANSWER_NOT_READY -2 + +/*! \brief indicating that client is already connected */ +#define CYNARA_ASYNC_API_ALREADY_CONNECTED -3 + +/*! \brief indicating system is running out of memory state */ +#define CYNARA_ASYNC_API_OUT_OF_MEMORY -4 + +/*! \brief indicating the API's parameter is malformed */ +#define CYNARA_ASYNC_API_INVALID_PARAM -5 + +/*! \brief service not available */ +#define CYNARA_ASYNC_API_SERVICE_NOT_AVAILABLE -6 + +/** @}*/ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct cynara_async cynara_async; +typedef struct cynara_async_configuration cynara_async_configuration; +typedef uint16_t cynara_check_id; + +/** + * \par Description: + * Initialize cynara-async-client library with given configuration. + * Create structure used in following API calls. + * + * \par Purpose: + * This API must be used prior to calling cynara_async_connect function. + * + * \par Typical use case: + * Once before a service can call cynara_async_connect. + * + * \par Method of function operation: + * This API initializes inner library structures and in case of success creates + * and returns cynara_async structure. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread-safety: + * This function is NOT thread-safe. If functions from described API are called by multithreaded + * application from different threads, they must be put into protected critical section. + * + * \par Important notes: + * Structure cynara_async created by cynara_async_initialize call should be released + * with cynara_async_finish. + * + * \param[out] pp_cynara Placeholder for created cynara_async structure. + * \param[in] p_conf Configuration for cynara-async-client library. NULL for default parameters. + * + * \return CYNARA_ASYNC_API_SUCCESS on success, or error code on error. + */ + +int cynara_async_initialize(cynara_async **pp_cynara, + const cynara_async_configuration *p_conf); + +/** + * \par Description: + * Release cynara-async-client library and destroy structure created with cynara_async_initialize. + * + * \par Purpose: + * This API should be used to clean up after usage of cynara-async-client library. + * + * \par Typical use case: + * Once after all checks have been answered. + * + * \par Method of function operation: + * This API releases inner library structure and destroys cynara_async structure. All pending + * requests are cancelled. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread-safety: + * This function is NOT thread-safe. If functions from described API are called by multithreaded + * application from different threads, they must be put into protected critical section. + * + * \par Important notes: + * No other call to cynara-async-client library should be made after call to cynara_async_finish. + * + * \param[in] p_cynara cynara_async structure. + * + * \return CYNARA_ASYNC_API_SUCCESS on success, or error code on error. + */ +int cynara_async_finish(cynara_async *p_cynara); + +/** + * \par Description: + * Connect with cynara server. + * + * \par Purpose: + * This API must be used prior to calling cynara_async_check and cynara_async_receive. + * + * \par Typical use case: + * After initiating cynara_async structure and after connection with cynara server has been lost. + * + * \par Method of function operation: + * This API connects to cynara server and provides socket descriptor of this connection. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread-safety: + * This function is NOT thread-safe. If functions from described API are called by multithreaded + * application from different threads, they must be put into protected critical section. + * + * \par Important notes: + * Call to cynara_async_check needs cynara_async structure to be created first by + * cynara_async_initialize. + * + * \param[in] p_cynara cynara_async structure. + * \param[out] p_sock_fd Placeholder for connection socket descriptor. + * + * \return CYNARA_ASYNC_API_SUCCESS on success, CYNARA_ASYNC_API_ALREADY_CONNECTED when client is + * already connected or error code on error. + */ +int cynara_async_connect(cynara_async *p_cynara, int *p_sock_fd); + +/** + * \par Description: + * Check client, user access for given privilege. + * + * \par Purpose: + * This API should be used to check if a user running application identified as client + * has access to a privilege. + * + * \par Typical use case: + * A service wants to ask Cynara daemon, if a client demanding access to some privilege + * has proper rights. Despite the fact that the final response has been received, if there are + * still some pending checks, cynara_async_receive MUST be called after this call until not ready + * answer is returned. If service does not get answer after this sequence, it may get it + * asynchronously by calling cynara_async_receive. + * + * \par Method of function operation: + * Client (a process / application) demanding access to a privilege is running as some user. + * For such triple an access to a privilege is checked by calling cynara. + * Depending on defined policy, an external application may be launched to ask user a question, + * e.g. if [s]he wants to allow client to use a privilege. Additional parameter client_session + * may be used to distinguish between client session (e.g. for allowing access only for this + * particular application launch). If final answer is not returned, id of current check should + * be received. + * + * \par Sync (or) Async: + * This is an asynchronous API. + * + * \par Thread-safety: + * This function is NOT thread-safe. If functions from described API are called by multithreaded + * application from different threads, they must be put into protected critical section. + * + * \par Important notes: + * An external application may be launched to allow user interaction in granting or denying access. + * Call cynara_async_cancel to cancel pending request. Call to cynara_async_check needs + * cynara_async structure to be created first and connected with cynara daemon. To do that call + * cynara_async_initialize and cynara_async_connect. + * + * \param[in] p_cynara cynara_async structure. + * \param[in] client Application or process identifier. + * \param[in] client_session Session of client (connection, launch). + * \param[in] user User running client. + * \param[in] privilege Privilege that is a subject of a check. + * \param[out] p_check_id Placeholder for check id. + * + * \return CYNARA_ASYNC_API_SUCCESS on success (access granted), CYNARA_API_ACCESS_DENIED + * on access denial, CYNARA_ASYNC_API_ANSWER_NOT_READY on asynchronous request sent + * or other error code on error. + */ +int cynara_async_check(cynara_async *p_cynara, + const char *client, const char *client_session, + const char *user, const char *privilege, + cynara_check_id *p_check_id); + +/** + * \par Description: + * Receive answer of cynara_async_check call from cynara daemon. + * + * \par Purpose: + * This API should be used to receive answer on single check not answered by cynara_async_check. + * + * \par Typical use case: + * After calling cynara_async_check, if there are still pending checks, this function MUST be + * called until not ready answer is returned. After that, answer can be received by this call + * if a read event occurs on socket received by cynara_async_connect. It MUST be called then + * the same way as after cynara_async_check. + * + * \par Method of function operation: + * Receives answer sent by cynara daemon in response to cynara_async_check call. + * + * \par Sync (or) Async: + * This is an asynchronous API. + * + * \par Thread-safety: + * This function is NOT thread-safe. If functions from described API are called by multithreaded + * application from different threads, they must be put into protected critical section. + * + * \par Important notes: + * An external application may be launched to allow user interaction in granting or denying access. + * Call cynara_async_cancel to cancel pending request. Call to cynara_async_receive needs + * cynara_async structure to be created first and connected with cynara daemon. To do that call + * cynara_async_initialize and cynara_async_connect. As multiple answers can be available at once, + * cynara_async_receive MUST be called until not ready answer is returned. + * + * \param[in] p_cynara cynara_async structure. + * \param[out] p_check_id Placeholder for check id. + * + * \return CYNARA_ASYNC_API_SUCCESS on success (access granted), CYNARA_API_ACCESS_DENIED + * on access denial, CYNARA_ASYNC_API_ANSWER_NOT_READY on answer not yet fully received + * or other error code on error. + */ +int cynara_async_receive(cynara_async *p_cynara, cynara_check_id *p_check_id); + +/** + * \par Description: + * Cancel check request created by cynara_async_check. + * + * \par Purpose: + * This API should be used to cancel check request created by cynara_async_check. + * + * \par Typical use case: + * A service did not get final answer in cynara_async_check call and answer did not come yet + * due to check hanging on user decision to allow or deny privilege. + * + * \par Method of function operation: + * Cancels check request created by cynara_async_check call. + * + * \par Sync (or) Async: + * This is an asynchronous API. + * + * \par Thread-safety: + * This function is NOT thread-safe. If functions from described API are called by multithreaded + * application from different threads, they must be put into protected critical section. + * + * \par Important notes: + * Call to cynara_async_cancel needs cynara_async structure to be created first and connected + * with cynara daemon. To do that call cynara_async_initialize and cynara_async_connect. + * + * \param[in] p_cynara cynara_async structure. + * \param[in] check_id Check id to be cancelled + * + * \return CYNARA_ASYNC_API_SUCCESS on success or other error code on error. + */ +int cynara_async_cancel(cynara_async *p_cynara, cynara_check_id check_id); + + +#ifdef __cplusplus +} +#endif + +#endif /* CYNARA_CLIENT_ASYNC_H */ -- 2.7.4 From 1b06a8e259d044ae3f6fe0782e754f125eab4e03 Mon Sep 17 00:00:00 2001 From: Jacek Bukarewicz Date: Tue, 12 Aug 2014 11:10:10 +0200 Subject: [PATCH 14/16] Use instead of in async client header cannot be used since cynara-client-async.h is a C header which can be included by C projects like dbus. Change-Id: Ife9f75ff594457d67831b487d85f8034bd556b05 Signed-off-by: Jacek Bukarewicz --- src/include/cynara-client-async.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/cynara-client-async.h b/src/include/cynara-client-async.h index c04d0b5..b7aa35b 100644 --- a/src/include/cynara-client-async.h +++ b/src/include/cynara-client-async.h @@ -25,7 +25,7 @@ #ifndef CYNARA_CLIENT_ASYNC_H #define CYNARA_CLIENT_ASYNC_H -#include +#include /** * \name Return Codes -- 2.7.4 From fbd9ddae22fc3f2c99733016a80d304d24ec47a5 Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Thu, 14 Aug 2014 07:13:23 +0200 Subject: [PATCH 15/16] Add custom TestEventListener This is needed to show custom properties of test cases (like for example time elapsed in benchmarks). Change-Id: Id54c709125c07ceb4d3b387f76047706361d05b3 --- test/CMakeLists.txt | 4 +- test/TestEventListenerProxy.cpp | 86 +++++++++++++++++++++++++++++++++++++++++ test/TestEventListenerProxy.h | 63 ++++++++++++++++++++++++++++++ test/tests.cpp | 59 ++++++++++++++++++++++++++++ 4 files changed, 211 insertions(+), 1 deletion(-) create mode 100644 test/TestEventListenerProxy.cpp create mode 100644 test/TestEventListenerProxy.h create mode 100644 test/tests.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 820279f..0f64ab4 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -16,7 +16,7 @@ # @author Aleksander Zdyb # @brief Cmake for tests # -PKG_CHECK_MODULES(PKGS REQUIRED gmock_main) +PKG_CHECK_MODULES(PKGS REQUIRED gmock) ADD_DEFINITIONS("-DCYNARA_NO_LOGS") SET(CYNARA_SRC ${PROJECT_SOURCE_DIR}/src) @@ -49,6 +49,8 @@ SET(CYNARA_TESTS_SOURCES storage/serializer/serialize.cpp common/types/policybucket.cpp helpers.cpp + TestEventListenerProxy.cpp + tests.cpp ) INCLUDE_DIRECTORIES( diff --git a/test/TestEventListenerProxy.cpp b/test/TestEventListenerProxy.cpp new file mode 100644 index 0000000..f00a00a --- /dev/null +++ b/test/TestEventListenerProxy.cpp @@ -0,0 +1,86 @@ +/* + * 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 TestEventListenerProxy.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief Proxy for ::testing::TestEventListener + */ + +#include "TestEventListenerProxy.h" + +namespace Cynara { + +TestEventListenerProxy::TestEventListenerProxy(TestEventListener *originalListener) + : m_originalListener(originalListener) {}; + +TestEventListenerProxy::~TestEventListenerProxy() { + delete m_originalListener; +}; + +void TestEventListenerProxy::OnTestProgramStart(const UnitTest &unit_test) { + m_originalListener->OnTestProgramStart(unit_test); +} + +void TestEventListenerProxy::OnTestIterationStart(const UnitTest &unit_test, int iteration) { + m_originalListener->OnTestIterationStart(unit_test, iteration); +} + +void TestEventListenerProxy::OnEnvironmentsSetUpStart(const UnitTest &unit_test) { + m_originalListener->OnEnvironmentsSetUpStart(unit_test); +} + +void TestEventListenerProxy::OnEnvironmentsSetUpEnd(const UnitTest &unit_test) { + m_originalListener->OnEnvironmentsSetUpEnd(unit_test); +} + +void TestEventListenerProxy::OnTestCaseStart(const TestCase &test_case) { + m_originalListener->OnTestCaseStart(test_case); +} + +void TestEventListenerProxy::OnTestStart(const TestInfo &test_info) { + m_originalListener->OnTestStart(test_info); +} + +void TestEventListenerProxy::OnTestPartResult(const TestPartResult &result) { + m_originalListener->OnTestPartResult(result); +} + +void TestEventListenerProxy::OnTestEnd(const TestInfo &test_info) { + m_originalListener->OnTestEnd(test_info); +} + +void TestEventListenerProxy::OnTestCaseEnd(const TestCase &test_case) { + m_originalListener->OnTestCaseEnd(test_case); +} + +void TestEventListenerProxy::OnEnvironmentsTearDownStart(const UnitTest &unit_test) { + m_originalListener->OnEnvironmentsTearDownStart(unit_test); +} + +void TestEventListenerProxy::OnEnvironmentsTearDownEnd(const UnitTest &unit_test) { + m_originalListener->OnEnvironmentsTearDownEnd(unit_test); +} + +void TestEventListenerProxy::OnTestIterationEnd(const UnitTest &unit_test, int iteration) { + m_originalListener->OnTestIterationEnd(unit_test, iteration); +} + +void TestEventListenerProxy::OnTestProgramEnd(const UnitTest &unit_test) { + m_originalListener->OnTestProgramEnd(unit_test); +} + +} /* namespace Cynara */ diff --git a/test/TestEventListenerProxy.h b/test/TestEventListenerProxy.h new file mode 100644 index 0000000..79097ce --- /dev/null +++ b/test/TestEventListenerProxy.h @@ -0,0 +1,63 @@ +/* + * 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 TestEventListenerProxy.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Proxy for ::testing::TestEventListener + */ + +#ifndef TEST_TESTEVENTLISTENERPROXY_H_ +#define TEST_TESTEVENTLISTENERPROXY_H_ + +#include + +namespace Cynara { + +using namespace testing; + +class TestEventListenerProxy : public TestEventListener +{ +public: + explicit TestEventListenerProxy(TestEventListener *originalListener); + virtual ~TestEventListenerProxy(); + + virtual void OnTestProgramStart(const UnitTest &unit_test); + virtual void OnTestIterationStart(const UnitTest &unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest &unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest &unit_test); + virtual void OnTestCaseStart(const TestCase &test_case); + virtual void OnTestStart(const TestInfo &test_info); + virtual void OnTestPartResult(const TestPartResult &result); + virtual void OnTestEnd(const TestInfo &test_info); + virtual void OnTestCaseEnd(const TestCase &test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest &unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest &unit_test); + virtual void OnTestIterationEnd(const UnitTest &unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest &unit_test); + +protected: + TestEventListener *originalListener() { + return m_originalListener; + } + +private: + TestEventListener *m_originalListener; +}; + +} /* namespace Cynara */ + +#endif /* TEST_TESTEVENTLISTENERPROXY_H_ */ diff --git a/test/tests.cpp b/test/tests.cpp new file mode 100644 index 0000000..1525fa9 --- /dev/null +++ b/test/tests.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 tests.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief Unit-tests setup + */ + +#include +#include + +#include "TestEventListenerProxy.h" + +class PropertyAwarePrettyUnitTestResultPrinter : public Cynara::TestEventListenerProxy { + using Cynara::TestEventListenerProxy::TestEventListenerProxy; + + void OnTestEnd(const ::testing::TestInfo &testInfo) { + auto result = testInfo.result(); + for (int i = 0; i < result->test_property_count(); ++i) { + const auto &property = result->GetTestProperty(i); + std::cout << " - " + << property.key() << " = " << property.value() + << std::endl; + } + originalListener()->OnTestEnd(testInfo); + } +}; + +int main(int argc, char** argv) { + // Disables elapsed time by default. + ::testing::GTEST_FLAG(print_time) = false; + + // This allows the user to override the flag on the command line. + ::testing::InitGoogleTest(&argc, argv); + + // Gets hold of the event listener list. + auto& listeners = ::testing::UnitTest::GetInstance()->listeners(); + + // Remove original listener (PrettyUnitTestResultPrinter) + // and wrap it with our proxy (PropertyAwarePrettyUnitTestResultPrinter) + auto originalListener = listeners.Release(listeners.default_result_printer()); + listeners.Append(new PropertyAwarePrettyUnitTestResultPrinter(originalListener)); + + return RUN_ALL_TESTS(); +} -- 2.7.4 From dcb87304c3e74559386d39a303da5bde34fb8754 Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Mon, 18 Aug 2014 11:40:46 +0200 Subject: [PATCH 16/16] Add performance tests for PolicyBucket Change-Id: I3b7f88a7964552664f0a1d1b1a56916ac0726249 --- test/Benchmark.h | 50 +++++++++++++++++ test/CMakeLists.txt | 1 + test/storage/performance/bucket.cpp | 106 ++++++++++++++++++++++++++++++++++++ 3 files changed, 157 insertions(+) create mode 100644 test/Benchmark.h create mode 100644 test/storage/performance/bucket.cpp diff --git a/test/Benchmark.h b/test/Benchmark.h new file mode 100644 index 0000000..9902236 --- /dev/null +++ b/test/Benchmark.h @@ -0,0 +1,50 @@ +/* + * 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 Benchmark.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief A generic benchmark + */ + +#ifndef TEST_BENCHMARK_H_ +#define TEST_BENCHMARK_H_ + +#include + +namespace Cynara { + +namespace Benchmark { + +typedef std::function Function; + +template +Precision measure(Function fn) { + using std::chrono::high_resolution_clock; + + high_resolution_clock::time_point t0 = high_resolution_clock::now(); + fn(); + high_resolution_clock::time_point t1 = high_resolution_clock::now(); + + return std::chrono::duration_cast(t1 - t0); +} + +} // namespace Benchmark + +} // namespace Cynara + + +#endif /* TEST_BENCHMARK_H_ */ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0f64ab4..c3e3eea 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -36,6 +36,7 @@ SET(CYNARA_SOURCES_FOR_TESTS SET(CYNARA_TESTS_SOURCES common/exceptions/bucketrecordcorrupted.cpp types/policykey.cpp + storage/performance/bucket.cpp storage/storage/policies.cpp storage/storage/check.cpp storage/storage/buckets.cpp diff --git a/test/storage/performance/bucket.cpp b/test/storage/performance/bucket.cpp new file mode 100644 index 0000000..264482f --- /dev/null +++ b/test/storage/performance/bucket.cpp @@ -0,0 +1,106 @@ +/* + * 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 bucket.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief Performance tests for Cynara::PolicyBucket + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include "../../Benchmark.h" + +using namespace Cynara; + +class Benchmark { +public: + +}; + +class PolicyKeyGenerator { +public: + typedef std::vector Features; + typedef std::reference_wrapper FeaturesRef; + + PolicyKeyGenerator(size_t featuresCount, size_t featureLength) { + const std::vector toGenerate = { m_clients, m_users, m_privileges }; + for (auto featuresRef : toGenerate) { + auto &features = featuresRef.get(); + features.resize(featuresCount); + std::generate(std::begin(features), std::end(features), + std::bind(&PolicyKeyGenerator::randomKeyFeature, this, featureLength)); + } + } + + PolicyKey randomKey(void) const { + return { m_clients.at(rand() % m_clients.size()), + m_users.at(rand() % m_users.size()), + m_privileges.at(rand() % m_privileges.size()) + }; + } + + char randomChar(void) const { + return (std::rand() % ('z' - 'a')) + 'a'; + } + + std::string randomKeyFeature(size_t length) const { + std::string str(length, 0); + std::generate_n( str.begin(), length, std::bind(&PolicyKeyGenerator::randomChar, this)); + return str; + } + +private: + Features m_clients; + Features m_users; + Features m_privileges; +}; + +TEST(Performance, bucket_filtered_100000) { + using std::chrono::microseconds; + + PolicyBucket bucket; + + PolicyKeyGenerator generator(100, 10); + + const std::size_t policyNumber = 100000; + for (std::size_t i = 0; i < policyNumber; ++i) { + bucket.insertPolicy(std::make_shared(generator.randomKey(), + PredefinedPolicyType::ALLOW)); + } + + const unsigned int measureRepeats = 1000; + auto result = Benchmark::measure([&bucket, &generator, measureRepeats] () { + for (auto i = 0u; i < measureRepeats; ++i) { + bucket.filtered(generator.randomKey()); + } + }); + + auto key = std::string("performance_" + std::to_string(policyNumber)); + auto value = std::to_string(result.count() / measureRepeats) + " [us]"; + RecordProperty(key, value); +} -- 2.7.4