--- /dev/null
+/*
+ * 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 <a.zdyb@partner.samsung.com>
+ * @version 1.0
+ * @brief Implementation of DefaultBucketSetNoneException
+ */
+
+#ifndef SRC_COMMON_EXCEPTIONS_DEFAULTBUCKETSETNONEEXCEPTION_H_
+#define SRC_COMMON_EXCEPTIONS_DEFAULTBUCKETSETNONEEXCEPTION_H_
+
+#include <exception>
+
+#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_
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
return policyResult == policyType;
}
+bool operator !=(const PolicyType &policyType, const PolicyResult &policyResult) {
+ return !(policyResult == policyType);
+}
+
} // namespace Cynara
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
#include <vector>
#include <exceptions/BucketNotExistsException.h>
-#include "exceptions/DefaultBucketDeletionException.h"
+#include <exceptions/DefaultBucketDeletionException.h>
+#include <exceptions/DefaultBucketSetNoneException.h>
#include <types/pointers.h>
#include <types/Policy.h>
#include <types/PolicyBucket.h>
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;
}
}
}
-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 {
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));
+}
#ifndef FAKESTORAGEBACKEND_H_
#define FAKESTORAGEBACKEND_H_
+#include <storage/StorageBackend.h>
+
using namespace Cynara;
class FakeStorageBackend : public StorageBackend {