2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @author Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
19 * @author Aleksander Zdyb <a.zdyb@partner.samsung.com>
21 * @brief This file implements policy rules storage procedures
27 #include <exceptions/BucketNotExistsException.h>
28 #include "exceptions/DefaultBucketDeletionException.h"
29 #include <types/pointers.h>
30 #include <types/Policy.h>
31 #include <types/PolicyBucket.h>
32 #include <types/PolicyBucketId.h>
33 #include <types/PolicyCollection.h>
34 #include <types/PolicyResult.h>
35 #include <types/PolicyType.h>
41 PolicyResult Storage::checkPolicy(const PolicyKey &key,
42 const PolicyBucketId &startBucketId /*= defaultPolicyBucketId*/,
43 bool recursive /*= true*/) {
44 auto policies = m_backend.searchBucket(startBucketId, key);
45 return minimalPolicy(policies, key, recursive);
48 PolicyResult Storage::minimalPolicy(const PolicyBucket &bucket, const PolicyKey &key,
50 bool hasMinimal = false;
51 PolicyResult minimal = bucket.defaultPolicy();
53 auto proposeMinimal = [&minimal, &hasMinimal](const PolicyResult &candidate) {
54 if (hasMinimal == false) {
56 } else if (candidate < minimal) {
62 for (const auto policy : bucket) {
63 const auto &policyResult = policy->result();
65 switch (policyResult.policyType()) {
66 case PredefinedPolicyType::DENY:
67 return policyResult; // Do not expect lower value than DENY
68 case PredefinedPolicyType::BUCKET: {
69 if (recursive == true) {
70 auto bucketResults = m_backend.searchBucket(policyResult.metadata(), key);
71 auto minimumOfBucket = minimalPolicy(bucketResults, key, true);
72 proposeMinimal(minimumOfBucket);
76 case PredefinedPolicyType::ALLOW:
81 proposeMinimal(policyResult);
87 void Storage::insertPolicies(const std::map<PolicyBucketId, std::vector<Policy>> &policiesByBucketId) {
89 auto pointedBucketExists = [this] (const Policy &policy) -> void {
90 if (policy.result().policyType() == PredefinedPolicyType::BUCKET) {
91 const auto &bucketId = policy.result().metadata();
92 if (m_backend.hasBucket(bucketId) == false) {
93 throw BucketNotExistsException(bucketId);
98 // TODO: Rewrite, when transactions are supported
99 // Check if all of buckets exist
100 for (const auto &group : policiesByBucketId) {
101 const auto &policies = group.second;
102 std::for_each(policies.cbegin(), policies.cend(), pointedBucketExists);
105 // Then insert policies
106 for (const auto &group : policiesByBucketId) {
107 const PolicyBucketId &bucketId = group.first;
108 const auto &policies = group.second;
109 for (const auto &policy : policies) {
110 m_backend.insertPolicy(bucketId, std::make_shared<Policy>(policy));
115 void Storage::addOrUpdateBucket(const PolicyBucketId &bucketId, const PolicyResult &defaultBucketPolicy) {
116 if (m_backend.hasBucket(bucketId)) {
117 m_backend.updateBucket(bucketId, defaultBucketPolicy);
119 m_backend.createBucket(bucketId, defaultBucketPolicy);
123 void Storage::deleteBucket(const PolicyBucketId &bucketId) {
124 // TODO: Check if bucket exists
126 if (bucketId == defaultPolicyBucketId) {
127 throw DefaultBucketDeletionException();
130 m_backend.deleteLinking(bucketId);
131 m_backend.deleteBucket(bucketId);
134 void Storage::deletePolicies(const std::map<PolicyBucketId, std::vector<PolicyKey>> &keysByBucketId) {
135 for (const auto &bucket : keysByBucketId) {
136 const PolicyBucketId &bucketId = bucket.first;
137 for (const auto &policyKey : bucket.second) {
138 m_backend.deletePolicy(bucketId, policyKey);
143 void Storage::load(void) {
147 void Storage::save(void) {
151 } // namespace Cynara