PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/src/storage/Storage.cpp

https://gitlab.com/admin-github-cloud/cynara
C++ | 175 lines | 120 code | 29 blank | 26 comment | 29 complexity | 0a9834e0b3217e1393b1c0e27ebd2ece MD5 | raw file
  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 src/storage/Storage.cpp
  18. * @author Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
  19. * @author Aleksander Zdyb <a.zdyb@samsung.com>
  20. * @version 1.0
  21. * @brief This file implements policy rules storage procedures
  22. */
  23. #include <memory>
  24. #include <vector>
  25. #include <exceptions/BucketNotExistsException.h>
  26. #include <exceptions/DefaultBucketDeletionException.h>
  27. #include <exceptions/DefaultBucketSetNoneException.h>
  28. #include <types/pointers.h>
  29. #include <types/Policy.h>
  30. #include <types/PolicyBucket.h>
  31. #include <types/PolicyBucketId.h>
  32. #include <types/PolicyCollection.h>
  33. #include <types/PolicyResult.h>
  34. #include <types/PolicyType.h>
  35. #include "Storage.h"
  36. namespace Cynara {
  37. PolicyResult Storage::checkPolicy(const PolicyKey &key,
  38. const PolicyBucketId &startBucketId /*= defaultPolicyBucketId*/,
  39. bool recursive /*= true*/) {
  40. auto policies = m_backend.searchBucket(startBucketId, key);
  41. return minimalPolicy(policies, key, recursive);
  42. };
  43. PolicyResult Storage::minimalPolicy(const PolicyBucket &bucket, const PolicyKey &key,
  44. bool recursive) {
  45. bool hasMinimal = false;
  46. PolicyResult minimal = bucket.defaultPolicy();
  47. auto proposeMinimal = [&minimal, &hasMinimal](const PolicyResult &candidate) {
  48. if (hasMinimal == false) {
  49. minimal = candidate;
  50. } else if (candidate < minimal) {
  51. minimal = candidate;
  52. }
  53. hasMinimal = true;
  54. };
  55. for (const auto policy : bucket) {
  56. const auto &policyResult = policy->result();
  57. switch (policyResult.policyType()) {
  58. case PredefinedPolicyType::DENY:
  59. return policyResult; // Do not expect lower value than DENY
  60. case PredefinedPolicyType::BUCKET: {
  61. if (recursive == true) {
  62. auto bucketResults = m_backend.searchBucket(policyResult.metadata(), key);
  63. auto minimumOfBucket = minimalPolicy(bucketResults, key, true);
  64. if (minimumOfBucket != PredefinedPolicyType::NONE) {
  65. proposeMinimal(minimumOfBucket);
  66. }
  67. }
  68. continue;
  69. }
  70. case PredefinedPolicyType::ALLOW:
  71. default:
  72. break;
  73. }
  74. proposeMinimal(policyResult);
  75. }
  76. return minimal;
  77. }
  78. void Storage::insertPolicies(const std::map<PolicyBucketId, std::vector<Policy>> &policiesByBucketId) {
  79. auto pointedBucketExists = [this] (const Policy &policy) -> void {
  80. if (policy.result().policyType() == PredefinedPolicyType::BUCKET) {
  81. const auto &bucketId = policy.result().metadata();
  82. if (m_backend.hasBucket(bucketId) == false) {
  83. throw BucketNotExistsException(bucketId);
  84. }
  85. }
  86. };
  87. // TODO: Rewrite, when transactions are supported
  88. // Check if all of buckets exist
  89. for (const auto &group : policiesByBucketId) {
  90. const auto &bucketId = group.first;
  91. const auto &policies = group.second;
  92. if (m_backend.hasBucket(bucketId) == false) {
  93. throw BucketNotExistsException(bucketId);
  94. }
  95. std::for_each(policies.cbegin(), policies.cend(), pointedBucketExists);
  96. }
  97. // Then insert policies
  98. for (const auto &group : policiesByBucketId) {
  99. const PolicyBucketId &bucketId = group.first;
  100. const auto &policies = group.second;
  101. for (const auto &policy : policies) {
  102. m_backend.insertPolicy(bucketId, std::make_shared<Policy>(policy));
  103. }
  104. }
  105. }
  106. void Storage::addOrUpdateBucket(const PolicyBucketId &bucketId,
  107. const PolicyResult &defaultBucketPolicy) {
  108. if (bucketId == defaultPolicyBucketId && defaultBucketPolicy == PredefinedPolicyType::NONE)
  109. throw DefaultBucketSetNoneException();
  110. if (m_backend.hasBucket(bucketId)) {
  111. m_backend.updateBucket(bucketId, defaultBucketPolicy);
  112. } else {
  113. m_backend.createBucket(bucketId, defaultBucketPolicy);
  114. }
  115. }
  116. void Storage::deleteBucket(const PolicyBucketId &bucketId) {
  117. // TODO: Check if bucket exists
  118. if (bucketId == defaultPolicyBucketId) {
  119. throw DefaultBucketDeletionException();
  120. }
  121. m_backend.deleteLinking(bucketId);
  122. m_backend.deleteBucket(bucketId);
  123. }
  124. void Storage::deletePolicies(const std::map<PolicyBucketId, std::vector<PolicyKey>> &keysByBucketId) {
  125. for (const auto &bucket : keysByBucketId) {
  126. const PolicyBucketId &bucketId = bucket.first;
  127. for (const auto &policyKey : bucket.second) {
  128. m_backend.deletePolicy(bucketId, policyKey);
  129. }
  130. }
  131. }
  132. PolicyBucket::Policies Storage::listPolicies(const PolicyBucketId &bucketId,
  133. const PolicyKey &filter) const {
  134. return m_backend.listPolicies(bucketId, filter);
  135. }
  136. void Storage::erasePolicies(const PolicyBucketId &bucketId, bool recursive,
  137. const PolicyKey &filter) {
  138. return m_backend.erasePolicies(bucketId, recursive, filter);
  139. }
  140. void Storage::load(void) {
  141. m_backend.load();
  142. }
  143. void Storage::save(void) {
  144. m_backend.save();
  145. }
  146. } // namespace Cynara