1b1a29a053ad83fef775215c831a38079f0ab69a
[platform/core/security/cynara.git] / src / service / storage / Storage.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        Storage.cpp
18  * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
19  * @author      Aleksander Zdyb <a.zdyb@partner.samsung.com>
20  * @version     1.0
21  * @brief       This file implements policy rules storage procedures
22  */
23
24 #include "Storage.h"
25 #include "StorageBackend.h"
26 #include "types/pointers.h"
27 #include "types/PolicyType.h"
28 #include "exceptions/NotImplementedException.h"
29 #include "exceptions/DefaultBucketDeletionException.h"
30
31 #include <iostream>
32 #include <memory>
33
34
35 namespace Cynara {
36
37 PolicyResult Storage::checkPolicy(const PolicyKey &key) {
38     auto policies = m_backend.searchDefaultBucket(key);
39     return minimalPolicy(policies, key);
40 };
41
42 PolicyResult Storage::minimalPolicy(const PolicyBucket &bucket, const PolicyKey &key) {
43     bool hasMinimal = false;
44     PolicyResult minimal = bucket.defaultPolicy();
45
46     const auto &policies = bucket.policyCollection();
47
48     auto proposeMinimal = [&minimal, &hasMinimal](const PolicyResult &candidate) {
49         if (hasMinimal == false) {
50             minimal = candidate;
51         } else if (candidate < minimal) {
52             minimal = candidate;
53         }
54         hasMinimal = true;
55     };
56
57     for (const auto &policyRecord : policies) {
58         const auto &policyResult = policyRecord->result();
59
60         switch (policyResult.policyType()) {
61         case PredefinedPolicyType::DENY:
62             return policyResult; // Do not expect lower value than DENY
63             break;
64         case PredefinedPolicyType::BUCKET: {
65                 auto bucketResults = m_backend.searchBucket(policyResult.metadata(), key);
66                 auto minimumOfBucket = minimalPolicy(bucketResults, key);
67                 proposeMinimal(minimumOfBucket);
68                 continue;
69             }
70             break;
71         case PredefinedPolicyType::ALLOW:
72         default:
73             break;
74         }
75
76         proposeMinimal(policyResult);
77     }
78
79     return minimal;
80 }
81
82 //todo to be removed, after tests get updated
83 void Storage::insertPolicies(const std::vector<PolicyPolicyBucket> &policies) {
84     for (const auto &policyTuple : policies) {
85         PolicyBucketId bucketId;
86         PolicyPtr policyPtr;
87         std::tie(policyPtr, bucketId) = policyTuple;
88         auto existingPolicies = m_backend.searchBucket(bucketId, policyPtr->key());
89         for (auto existingPolicy : existingPolicies.policyCollection()) {
90             m_backend.deletePolicy(bucketId, existingPolicy->key());
91         }
92         m_backend.insertPolicy(bucketId, policyPtr);
93     }
94 }
95
96 void Storage::insertPolicies(const std::map<PolicyBucketId, std::vector<Policy>> &policies) {
97     for (const auto &bucket : policies) {
98         const PolicyBucketId &bucketId = bucket.first;
99         for (const auto &policy : bucket.second) {
100                 PolicyPtr policyPtr = std::make_shared<Policy>(policy);
101                 auto existingPolicies = m_backend.searchBucket(bucketId, policyPtr->key());
102                 for (auto existingPolicy : existingPolicies.policyCollection()) {
103                         m_backend.deletePolicy(bucketId, existingPolicy->key());
104                 }
105                 m_backend.insertPolicy(bucketId, policyPtr);
106         }
107     }
108 }
109
110 void Storage::addOrUpdateBucket(const PolicyBucketId &bucketId, const PolicyResult &defaultBucketPolicy) {
111     if (m_backend.hasBucket(bucketId)) {
112         m_backend.updateBucket(bucketId, defaultBucketPolicy);
113     } else {
114         m_backend.createBucket(bucketId, defaultBucketPolicy);
115     }
116 }
117
118 void Storage::deleteBucket(const PolicyBucketId &bucketId) {
119     // TODO: Check if bucket exists
120
121     if (bucketId == defaultPolicyBucketId) {
122         throw DefaultBucketDeletionException();
123     }
124
125     m_backend.deleteLinking(bucketId);
126     m_backend.deleteBucket(bucketId);
127 }
128
129 //todo to be removed, after tests get updated
130 void Storage::deletePolicies(const std::vector<PolicyKeyBucket> &policies) {
131     for (const auto &policy : policies) {
132         m_backend.deletePolicy(std::get<1>(policy), std::get<0>(policy));
133     }
134 }
135
136 void Storage::deletePolicies(const std::map<PolicyBucketId, std::vector<PolicyKey>> &policies) {
137     for (const auto &bucket : policies) {
138         const PolicyBucketId &bucketId = bucket.first;
139         for (const auto &policyKey : bucket.second) {
140             m_backend.deletePolicy(bucketId, policyKey);
141         }
142     }
143 }
144
145 } // namespace Cynara