Remove PolicyBucket() constructor
[platform/core/security/cynara.git] / test / storage / storage / check.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /**
17  * @file        test/storage/storage/check.cpp
18  * @author      Aleksander Zdyb <a.zdyb@samsung.com>
19  * @version     1.0
20  * @brief       Tests of check in Storage
21  */
22
23 #include <gtest/gtest.h>
24 #include <gmock/gmock.h>
25
26 #include "types/PolicyType.h"
27 #include "types/PolicyKey.h"
28 #include "types/PolicyResult.h"
29 #include "types/PolicyCollection.h"
30 #include "types/pointers.h"
31 #include "exceptions/DefaultBucketDeletionException.h"
32 #include "storage/Storage.h"
33 #include "storage/StorageBackend.h"
34
35 #include "fakestoragebackend.h"
36 #include "../../helpers.h"
37
38 #include <memory>
39 #include <tuple>
40
41 using namespace Cynara;
42
43 TEST(storage, checkEmpty) {
44     using ::testing::ReturnPointee;
45
46     PolicyBucket emptyBucket("empty");
47
48     FakeStorageBackend backend;
49     Cynara::Storage storage(backend);
50     PolicyKey pk = Helpers::generatePolicyKey();
51
52     EXPECT_CALL(backend, searchBucket(defaultPolicyBucketId, pk))
53         .WillOnce(ReturnPointee(&emptyBucket));
54
55     // Default bucket empty -- return DENY
56     auto policyAnswer = storage.checkPolicy(pk);
57     ASSERT_EQ(PredefinedPolicyType::DENY, policyAnswer.policyType());
58 }
59
60 TEST(storage, checkSimple) {
61     using ::testing::ReturnPointee;
62
63     PolicyBucket bucket(defaultPolicyBucketId);
64     FakeStorageBackend backend;
65
66     Cynara::Storage storage(backend);
67     PolicyKey pk = Helpers::generatePolicyKey();
68
69     EXPECT_CALL(backend, searchBucket(defaultPolicyBucketId, pk))
70         .WillRepeatedly(ReturnPointee(&bucket));
71
72     // Default bucket empty -- return DENY
73     ASSERT_EQ(PredefinedPolicyType::DENY, storage.checkPolicy(pk).policyType());
74
75     // Add ALLOW to default bucket -- return ALLOW
76     bucket.insertPolicy(Policy::simpleWithKey(pk, PredefinedPolicyType::ALLOW));
77     ASSERT_EQ(PredefinedPolicyType::ALLOW, storage.checkPolicy(pk).policyType());
78
79     // Add DENY to default bucket -- return DENY
80     bucket.insertPolicy(Policy::simpleWithKey(pk, PredefinedPolicyType::DENY));
81     ASSERT_EQ(PredefinedPolicyType::DENY, storage.checkPolicy(pk).policyType());
82 }
83
84 // TODO: Refactorize to resemble checkNonrecursive()
85 TEST(storage, checkBucket) {
86     using ::testing::ReturnPointee;
87
88     const PolicyBucketId additionalBucketId = "additional-bucket";
89
90     FakeStorageBackend backend;
91     Cynara::Storage storage(backend);
92     PolicyKey pk = Helpers::generatePolicyKey();
93
94     PolicyBucket defaultBucket(defaultPolicyBucketId, PolicyCollection({
95         Policy::simpleWithKey(pk, PredefinedPolicyType::ALLOW),
96         Policy::bucketWithKey(pk, additionalBucketId)
97     }));
98
99     PolicyBucket additionalBucket("additional");
100
101     EXPECT_CALL(backend, searchBucket(defaultPolicyBucketId, pk))
102         .WillRepeatedly(ReturnPointee(&defaultBucket));
103
104     EXPECT_CALL(backend, searchBucket(additionalBucketId, pk))
105         .WillRepeatedly(ReturnPointee(&additionalBucket));
106
107
108     // Bucket empty -- should return DENY as default bucket value
109     ASSERT_EQ(PredefinedPolicyType::DENY, storage.checkPolicy(pk).policyType());
110
111     // Add ALLOW to bucket, so return ALLOW
112     additionalBucket.insertPolicy(Policy::simpleWithKey(pk, PredefinedPolicyType::ALLOW));
113     ASSERT_EQ(PredefinedPolicyType::ALLOW, storage.checkPolicy(pk).policyType());
114
115     // Add DENY to default bucket -- return DENY, even though ALLOW in other bucket
116     defaultBucket.insertPolicy(Policy::simpleWithKey(pk, PredefinedPolicyType::DENY));
117     ASSERT_EQ(PredefinedPolicyType::DENY, storage.checkPolicy(pk).policyType());
118 }
119
120 // Catch a bug, where consecutive buckets were filtered with wildcard policies' keys
121 // instead of original key being checked
122 TEST(storage, checkBucketWildcard) {
123     using ::testing::Return;
124     using ::testing::ReturnPointee;
125
126     const PolicyBucketId additionalBucketId = "additional-bucket";
127     const PolicyKey defaultBucketKey = PolicyKey("c", "*", "p");
128     const PolicyKey checkKey = PolicyKey("c", "u1", "p");
129
130     PolicyBucket defaultBucket(defaultPolicyBucketId, PolicyCollection({
131         Policy::bucketWithKey(defaultBucketKey, additionalBucketId)
132     }));
133
134     FakeStorageBackend backend;
135     Cynara::Storage storage(backend);
136
137     EXPECT_CALL(backend, searchBucket(defaultPolicyBucketId, checkKey))
138         .WillRepeatedly(ReturnPointee(&defaultBucket));
139
140     // Check, if next bucket is filtered with original key
141     EXPECT_CALL(backend, searchBucket(additionalBucketId, checkKey))
142         .WillRepeatedly(Return(PolicyBucket("id")));    // additional bucket would yield no records
143
144     // Should return additional bucket's default policy
145     ASSERT_EQ(PredefinedPolicyType::DENY, storage.checkPolicy(checkKey));
146 }
147
148 TEST(storage, checkBucketWildcardOtherDefault) {
149     using ::testing::ReturnPointee;
150
151     const PolicyBucketId additionalBucketId = "additional-bucket";
152     const PolicyKey defaultBucketKey = PolicyKey("c", "*", "p");
153     const PolicyKey checkKey = PolicyKey("c", "u1", "p");
154
155     PolicyBucket defaultBucket(defaultPolicyBucketId, PolicyCollection({
156         Policy::bucketWithKey(defaultBucketKey, additionalBucketId)
157     }));
158
159     PolicyBucket additionalBucket(additionalBucketId, PredefinedPolicyType::ALLOW);
160
161     FakeStorageBackend backend;
162     Cynara::Storage storage(backend);
163
164     EXPECT_CALL(backend, searchBucket(defaultPolicyBucketId, checkKey))
165         .WillRepeatedly(ReturnPointee(&defaultBucket));
166
167     // Check, if next bucket is filtered with original key
168     EXPECT_CALL(backend, searchBucket(additionalBucketId, checkKey))
169         .WillRepeatedly(ReturnPointee(&additionalBucket));
170
171     // Should return additional bucket's default policy
172     ASSERT_EQ(PredefinedPolicyType::ALLOW, storage.checkPolicy(checkKey));
173 }
174
175 TEST(storage, checkNonrecursive) {
176     using ::testing::ReturnPointee;
177
178     PolicyKey pk = Helpers::generatePolicyKey();
179     PolicyBucketId bucketId = "a-bucket";
180
181     PolicyBucket bucket(bucketId, PredefinedPolicyType::ALLOW,
182                                { Policy::bucketWithKey(pk, "must-not-be-touched") });
183     FakeStorageBackend backend;
184
185     Cynara::Storage storage(backend);
186
187     EXPECT_CALL(backend, searchBucket(bucketId, pk))
188         .WillOnce(ReturnPointee(&bucket));
189
190     ASSERT_EQ(PredefinedPolicyType::ALLOW, storage.checkPolicy(pk, bucketId, false));
191 }
192
193 /*
194  * bucket1 contains policy (with key pk) pointing to bucket2
195  * bucket2 is empty and it's default policy is NONE
196  * Because NONE policy in bucket2, check should yield default policy of bucket1 and not of bucket2
197  */
198 TEST(storage, noneBucket) {
199     using ::testing::ReturnPointee;
200     using PredefinedPolicyType::ALLOW;
201     using PredefinedPolicyType::NONE;
202
203     auto pk = Helpers::generatePolicyKey();
204
205     PolicyBucket bucket2("bucket-2", NONE);
206     PolicyBucket bucket1("bucket-1", ALLOW, { Policy::bucketWithKey(pk, bucket2.id()) });
207
208     FakeStorageBackend backend;
209     Cynara::Storage storage(backend);
210
211     EXPECT_CALL(backend, searchBucket(bucket1.id(), pk))
212         .WillOnce(ReturnPointee(&bucket1));
213     EXPECT_CALL(backend, searchBucket(bucket2.id(), pk))
214         .WillOnce(ReturnPointee(&bucket2));
215
216     ASSERT_EQ(ALLOW, storage.checkPolicy(pk, bucket1.id(), true));
217 }
218
219 /*
220  * Scenario similar to noneBucket, but bucket2 contains matching policy.
221  * In this case this policy should be returned.
222  */
223 TEST(storage, noneBucketNotEmpty) {
224     using ::testing::ReturnPointee;
225     using PredefinedPolicyType::ALLOW;
226     using PredefinedPolicyType::DENY;
227     using PredefinedPolicyType::NONE;
228
229     auto pk = Helpers::generatePolicyKey();
230
231     PolicyBucket bucket2("bucket-2", NONE, { Policy::simpleWithKey(pk, DENY) });
232     PolicyBucket bucket1("bucket-1", ALLOW, { Policy::bucketWithKey(pk, bucket2.id()) });
233
234     FakeStorageBackend backend;
235     Cynara::Storage storage(backend);
236
237     EXPECT_CALL(backend, searchBucket(bucket1.id(), pk))
238         .WillOnce(ReturnPointee(&bucket1));
239     EXPECT_CALL(backend, searchBucket(bucket2.id(), pk))
240         .WillOnce(ReturnPointee(&bucket2));
241
242     ASSERT_EQ(DENY, storage.checkPolicy(pk, bucket1.id(), true));
243 }
244
245 /*
246  * Single empty bucket with default policy of NONE
247  * -- searching for any key should yield NONE
248  */
249 TEST(storage, singleNoneBucket) {
250     using ::testing::ReturnPointee;
251     using PredefinedPolicyType::NONE;
252
253     auto pk = Helpers::generatePolicyKey();
254
255     PolicyBucket bucket("bucket", NONE, {});
256
257     FakeStorageBackend backend;
258     Cynara::Storage storage(backend);
259
260     EXPECT_CALL(backend, searchBucket(bucket.id(), pk))
261         .WillOnce(ReturnPointee(&bucket));
262
263     ASSERT_EQ(NONE, storage.checkPolicy(pk, bucket.id(), true));
264 }