From 88947829a167aa393f228433d903cd10586bd0cc Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Wed, 20 Aug 2014 08:30:23 +0200 Subject: [PATCH] Support NONE policy in storage Change-Id: I80d28fee394c5e461bccf102b0d6f7b4ab243174 --- .../exceptions/DefaultBucketSetNoneException.h | 44 +++++++++++++ src/common/types/PolicyResult.h | 8 +++ src/common/types/PolicyType.cpp | 4 ++ src/common/types/PolicyType.h | 2 + src/service/storage/Storage.cpp | 14 ++++- test/storage/storage/check.cpp | 73 ++++++++++++++++++++++ test/storage/storage/fakestoragebackend.h | 2 + 7 files changed, 144 insertions(+), 3 deletions(-) create mode 100644 src/common/exceptions/DefaultBucketSetNoneException.h diff --git a/src/common/exceptions/DefaultBucketSetNoneException.h b/src/common/exceptions/DefaultBucketSetNoneException.h new file mode 100644 index 0000000..d9664b3 --- /dev/null +++ b/src/common/exceptions/DefaultBucketSetNoneException.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file DefaultBucketSetNoneException.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Implementation of DefaultBucketSetNoneException + */ + +#ifndef SRC_COMMON_EXCEPTIONS_DEFAULTBUCKETSETNONEEXCEPTION_H_ +#define SRC_COMMON_EXCEPTIONS_DEFAULTBUCKETSETNONEEXCEPTION_H_ + +#include + +#include "Exception.h" + +namespace Cynara { + +class DefaultBucketSetNoneException : public Exception { +public: + DefaultBucketSetNoneException() = default; + virtual ~DefaultBucketSetNoneException() noexcept {}; + + virtual const std::string message(void) const { + return "DefaultBucketSetNoneException"; + } +}; + +} /* namespace Cynara */ + +#endif // SRC_COMMON_EXCEPTIONS_DEFAULTBUCKETSETNONEEXCEPTION_H_ diff --git a/src/common/types/PolicyResult.h b/src/common/types/PolicyResult.h index a9369d8..0e0c716 100644 --- a/src/common/types/PolicyResult.h +++ b/src/common/types/PolicyResult.h @@ -60,9 +60,17 @@ public: return std::tie(m_type, m_metadata) == std::tie(other.m_type, other.m_metadata); } + bool operator !=(const PolicyResult &other) const { + return !(*this == other); + } + bool operator ==(const PolicyType &policyType) const { return (m_type == policyType) && m_metadata.empty(); } + + bool operator !=(const PolicyType &policyType) const { + return !(*this == policyType); + } }; } // namespace Cynara diff --git a/src/common/types/PolicyType.cpp b/src/common/types/PolicyType.cpp index bf022f5..9491f6c 100644 --- a/src/common/types/PolicyType.cpp +++ b/src/common/types/PolicyType.cpp @@ -29,4 +29,8 @@ bool operator ==(const PolicyType &policyType, const PolicyResult &policyResult) return policyResult == policyType; } +bool operator !=(const PolicyType &policyType, const PolicyResult &policyResult) { + return !(policyResult == policyType); +} + } // namespace Cynara diff --git a/src/common/types/PolicyType.h b/src/common/types/PolicyType.h index 9131b1b..e7ad60d 100644 --- a/src/common/types/PolicyType.h +++ b/src/common/types/PolicyType.h @@ -33,12 +33,14 @@ typedef std::uint16_t PolicyType; namespace PredefinedPolicyType { const PolicyType DENY = 0; + const PolicyType NONE = 1; const PolicyType BUCKET = 0xFFFE; const PolicyType ALLOW = 0xFFFF; }; class PolicyResult; bool operator ==(const PolicyType &policyType, const PolicyResult &policyResult); +bool operator !=(const PolicyType &policyType, const PolicyResult &policyResult); } // namespace Cynara diff --git a/src/service/storage/Storage.cpp b/src/service/storage/Storage.cpp index 8e81edc..108ebe8 100644 --- a/src/service/storage/Storage.cpp +++ b/src/service/storage/Storage.cpp @@ -25,7 +25,8 @@ #include #include -#include "exceptions/DefaultBucketDeletionException.h" +#include +#include #include #include #include @@ -69,7 +70,9 @@ PolicyResult Storage::minimalPolicy(const PolicyBucket &bucket, const PolicyKey if (recursive == true) { auto bucketResults = m_backend.searchBucket(policyResult.metadata(), key); auto minimumOfBucket = minimalPolicy(bucketResults, key, true); - proposeMinimal(minimumOfBucket); + if (minimumOfBucket != PredefinedPolicyType::NONE) { + proposeMinimal(minimumOfBucket); + } } continue; } @@ -112,7 +115,12 @@ void Storage::insertPolicies(const std::map> } } -void Storage::addOrUpdateBucket(const PolicyBucketId &bucketId, const PolicyResult &defaultBucketPolicy) { +void Storage::addOrUpdateBucket(const PolicyBucketId &bucketId, + const PolicyResult &defaultBucketPolicy) { + + if (bucketId == defaultPolicyBucketId && defaultBucketPolicy == PredefinedPolicyType::NONE) + throw DefaultBucketSetNoneException(); + if (m_backend.hasBucket(bucketId)) { m_backend.updateBucket(bucketId, defaultBucketPolicy); } else { diff --git a/test/storage/storage/check.cpp b/test/storage/storage/check.cpp index f56e7fe..e1f6505 100644 --- a/test/storage/storage/check.cpp +++ b/test/storage/storage/check.cpp @@ -189,3 +189,76 @@ TEST(storage, checkNonrecursive) { ASSERT_EQ(PredefinedPolicyType::ALLOW, storage.checkPolicy(pk, bucketId, false)); } + +/* + * bucket1 contains policy (with key pk) pointing to bucket2 + * bucket2 is empty and it's default policy is NONE + * Because NONE policy in bucket2, check should yield default policy of bucket1 and not of bucket2 + */ +TEST(storage, noneBucket) { + using ::testing::ReturnPointee; + using PredefinedPolicyType::ALLOW; + using PredefinedPolicyType::NONE; + + auto pk = Helpers::generatePolicyKey(); + + PolicyBucket bucket2("bucket-2", NONE); + PolicyBucket bucket1("bucket-1", ALLOW, { Policy::bucketWithKey(pk, bucket2.id()) }); + + FakeStorageBackend backend; + Cynara::Storage storage(backend); + + EXPECT_CALL(backend, searchBucket(bucket1.id(), pk)) + .WillOnce(ReturnPointee(&bucket1)); + EXPECT_CALL(backend, searchBucket(bucket2.id(), pk)) + .WillOnce(ReturnPointee(&bucket2)); + + ASSERT_EQ(ALLOW, storage.checkPolicy(pk, bucket1.id(), true)); +} + +/* + * Scenario similar to noneBucket, but bucket2 contains matching policy. + * In this case this policy should be returned. + */ +TEST(storage, noneBucketNotEmpty) { + using ::testing::ReturnPointee; + using PredefinedPolicyType::ALLOW; + using PredefinedPolicyType::DENY; + using PredefinedPolicyType::NONE; + + auto pk = Helpers::generatePolicyKey(); + + PolicyBucket bucket2("bucket-2", NONE, { Policy::simpleWithKey(pk, DENY) }); + PolicyBucket bucket1("bucket-1", ALLOW, { Policy::bucketWithKey(pk, bucket2.id()) }); + + FakeStorageBackend backend; + Cynara::Storage storage(backend); + + EXPECT_CALL(backend, searchBucket(bucket1.id(), pk)) + .WillOnce(ReturnPointee(&bucket1)); + EXPECT_CALL(backend, searchBucket(bucket2.id(), pk)) + .WillOnce(ReturnPointee(&bucket2)); + + ASSERT_EQ(DENY, storage.checkPolicy(pk, bucket1.id(), true)); +} + +/* + * Single empty bucket with default policy of NONE + * -- searching for any key should yield NONE + */ +TEST(storage, singleNoneBucket) { + using ::testing::ReturnPointee; + using PredefinedPolicyType::NONE; + + auto pk = Helpers::generatePolicyKey(); + + PolicyBucket bucket("bucket", NONE, {}); + + FakeStorageBackend backend; + Cynara::Storage storage(backend); + + EXPECT_CALL(backend, searchBucket(bucket.id(), pk)) + .WillOnce(ReturnPointee(&bucket)); + + ASSERT_EQ(NONE, storage.checkPolicy(pk, bucket.id(), true)); +} diff --git a/test/storage/storage/fakestoragebackend.h b/test/storage/storage/fakestoragebackend.h index b1e8b69..fa8898b 100644 --- a/test/storage/storage/fakestoragebackend.h +++ b/test/storage/storage/fakestoragebackend.h @@ -23,6 +23,8 @@ #ifndef FAKESTORAGEBACKEND_H_ #define FAKESTORAGEBACKEND_H_ +#include + using namespace Cynara; class FakeStorageBackend : public StorageBackend { -- 2.7.4