Catch and throw more detailed exception, when bucket not found
[platform/core/security/cynara.git] / src / service / storage / InMemoryStorageBackend.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        InMemoryStorageBackend.cpp
18  * @author      Aleksander Zdyb <a.zdyb@partner.samsung.com>
19  * @version     1.0
20  * @brief       Implementation of InMemoryStorageBackend
21  */
22
23 #include "InMemoryStorageBackend.h"
24
25 namespace Cynara {
26
27 InMemoryStorageBackend::InMemoryStorageBackend() {
28     // Make sure, there's always default bucket
29     this->buckets().insert({ defaultPolicyBucketId, PolicyBucket() });
30 }
31
32 InMemoryStorageBackend::~InMemoryStorageBackend() {}
33
34 PolicyBucket InMemoryStorageBackend::searchDefaultBucket(const PolicyKey &key) {
35     return searchBucket(defaultPolicyBucketId, key);
36 }
37
38 PolicyBucket InMemoryStorageBackend::searchBucket(const PolicyBucketId &bucketId,
39                                                   const PolicyKey &key) {
40     try {
41         const auto &bucket = this->buckets().at(bucketId);
42         return bucket.filtered(key);
43     } catch (const std::out_of_range &) {
44         throw BucketNotExistsException(bucketId);
45     }
46 }
47
48 void InMemoryStorageBackend::insertPolicy(const PolicyBucketId &bucketId, PolicyPtr policy) {
49     try {
50         auto &bucket = buckets().at(bucketId);
51         auto &policies = bucket.policyCollection();
52         policies.push_back(policy);
53     } catch (const std::out_of_range &) {
54         throw BucketNotExistsException(bucketId);
55     }
56 }
57
58 void InMemoryStorageBackend::createBucket(const PolicyBucketId &bucketId,
59                                           const PolicyResult &defaultPolicy) {
60     PolicyBucket newBucket;
61     newBucket.setDefaultPolicy(defaultPolicy);
62     buckets().insert({ bucketId, newBucket });
63 }
64
65 void InMemoryStorageBackend::updateBucket(const PolicyBucketId &bucketId,
66                                           const PolicyResult &defaultPolicy) {
67     try {
68         auto &bucket = buckets().at(bucketId);
69         bucket.setDefaultPolicy(defaultPolicy);
70     } catch (const std::out_of_range &) {
71         throw BucketNotExistsException(bucketId);
72     }
73 }
74
75 void InMemoryStorageBackend::deleteBucket(const PolicyBucketId &bucketId) {
76     auto bucketErased = buckets().erase(bucketId);
77     if (bucketErased == 0) {
78         throw BucketNotExistsException(bucketId);
79     }
80 }
81
82 bool InMemoryStorageBackend::hasBucket(const PolicyBucketId &bucketId) {
83     return buckets().find(bucketId) != buckets().end();
84 }
85
86 void InMemoryStorageBackend::deletePolicy(const PolicyBucketId &bucketId, const PolicyKey &key) {
87     try {
88         // TODO: Move the erase code to PolicyCollection maybe?
89         auto &bucket = buckets().at(bucketId);
90         auto &policies = bucket.policyCollection();
91         policies.erase(remove_if(policies.begin(), policies.end(),
92                 [key](PolicyPtr policy) -> bool {
93                     return policy->key() == key;
94             }), policies.end());
95     } catch(const std::out_of_range &) {
96         throw BucketNotExistsException(bucketId);
97     }
98 }
99
100 void InMemoryStorageBackend::deleteLinking(const PolicyBucketId &bucketId) {
101     auto bucketIdMatches = [&bucketId] (PolicyPtr policy) -> bool {
102         auto policyResult = policy->result();
103
104         // Check bucket id only if policy is a bucket policy
105         // TODO: Maybe move the test to PolicyResult
106         if (policyResult.policyType() == PredefinedPolicyType::BUCKET) {
107             return policyResult.metadata() == bucketId;
108         }
109         return false;
110     };
111
112     for(auto &bucketIter : buckets()) {
113         // TODO: Move the erase code to PolicyCollection maybe?
114         auto &bucket = bucketIter.second;
115         auto &policies = bucket.policyCollection();
116         policies.erase(remove_if(policies.begin(), policies.end(), bucketIdMatches),
117                 policies.end());
118     }
119 }
120
121 } /* namespace Cynara */