5c142992b7b5cf2158e44c8ce30be93e49eae676
[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.wojciechowski@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/BucketAlreadyExistsException.h"
30 #include "exceptions/DefaultBucketDeletionException.h"
31
32 #include <iostream>
33 #include <memory>
34
35
36 namespace Cynara {
37
38 PolicyResult Storage::checkPolicy(const PolicyKey &key) {
39     auto policies = m_backend.searchDefaultBucket(key);
40     return minimalPolicy(policies);
41 };
42
43 PolicyResult Storage::minimalPolicy(const PolicyBucket &bucket) {
44     bool hasMinimal = false;
45     PolicyResult minimal = bucket.defaultPolicy();
46
47     const auto &policies = bucket.policyCollection();
48
49     auto proposeMinimal = [&minimal, &hasMinimal](const PolicyResult &candidate) {
50         if(hasMinimal == false) {
51             minimal = candidate;
52         } else if(candidate < minimal) {
53             minimal = candidate;
54         }
55         hasMinimal = true;
56     };
57
58     for(const auto &policyRecord : policies) {
59         const auto &policyResult = policyRecord->result();
60
61         switch(policyResult.policyType()) {
62         case PolicyType::DENY:
63             return policyResult; // Do not expect lower value than DENY
64             break;
65         case PolicyType::BUCKET: {
66                 auto bucketResults = m_backend.searchBucket(policyResult.metadata(),
67                         policyRecord->key());
68                 auto minimumOfBucket = minimalPolicy(bucketResults);
69                 proposeMinimal(minimumOfBucket);
70                 continue;
71             }
72             break;
73         case PolicyType::ALLOW:
74         default:
75             break;
76         }
77
78         proposeMinimal(policyResult);
79     }
80
81     return minimal;
82 }
83
84 void Storage::insertPolicies(const std::vector<PolicyPolicyBucket> &policies) {
85     for(const auto &policyTuple : policies) {
86         PolicyBucketId bucketId;
87         PolicyPtr policyPtr;
88         std::tie(policyPtr, bucketId) = policyTuple;
89         auto existingPolicies = m_backend.searchBucket(bucketId, policyPtr->key());
90         for(auto existingPolicy : existingPolicies.policyCollection()) {
91             m_backend.deletePolicy(bucketId, existingPolicy->key());
92         }
93         m_backend.insertPolicy(bucketId, policyPtr);
94     }
95 }
96
97 void Storage::createBucket(const PolicyBucketId &newBucketId, const PolicyResult &defaultBucketPolicy) {
98     // TODO: Check if bucket already exists
99
100     if (newBucketId == defaultPolicyBucketId) {
101         throw BucketAlreadyExistsException(newBucketId);
102     }
103
104     m_backend.createBucket(newBucketId, defaultBucketPolicy);
105 }
106
107 void Storage::deleteBucket(const PolicyBucketId &bucketId) {
108     // TODO: Check if bucket exists
109
110     if (bucketId == defaultPolicyBucketId) {
111         throw DefaultBucketDeletionException();
112     }
113
114     m_backend.deleteLinking(bucketId);
115     m_backend.deleteBucket(bucketId);
116 }
117
118 void Storage::deletePolicies(const std::vector<PolicyKeyBucket> &policies) {
119     for(const auto &policy : policies) {
120         m_backend.deletePolicy(std::get<1>(policy), std::get<0>(policy));
121     }
122 }
123
124 } // namespace Cynara