PageRenderTime 37ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/src/admin/logic/OnlineLogic.cpp

https://gitlab.com/admin-github-cloud/cynara
C++ | 237 lines | 177 code | 36 blank | 24 comment | 25 complexity | 414e30022d493f7d7f2e6757a7a6560b MD5 | raw file
  1. /*
  2. * Copyright (c) 2014-2015 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/admin/logic/OnlineLogic.cpp
  18. * @author Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
  19. * @author Aleksander Zdyb <a.zdyb@samsung.com>
  20. * @author Zofia Abramowska <z.abramowska@samsung.com>
  21. * @author Pawel Wieczorek <p.wieczorek2@samsung.com>
  22. * @version 1.0
  23. * @brief This file contains implementation of online version of Logic class
  24. */
  25. #include <cinttypes>
  26. #include <memory>
  27. #include <utility>
  28. #include <cynara-error.h>
  29. #include <common.h>
  30. #include <config/PathConfig.h>
  31. #include <exceptions/Exception.h>
  32. #include <exceptions/UnexpectedErrorException.h>
  33. #include <log/log.h>
  34. #include <protocol/Protocol.h>
  35. #include <protocol/ProtocolAdmin.h>
  36. #include <request/AdminCheckRequest.h>
  37. #include <request/DescriptionListRequest.h>
  38. #include <request/EraseRequest.h>
  39. #include <request/InsertOrUpdateBucketRequest.h>
  40. #include <request/ListRequest.h>
  41. #include <request/pointers.h>
  42. #include <request/RemoveBucketRequest.h>
  43. #include <request/SetPoliciesRequest.h>
  44. #include <response/AdminCheckResponse.h>
  45. #include <response/CodeResponse.h>
  46. #include <response/DescriptionListResponse.h>
  47. #include <response/ListResponse.h>
  48. #include <response/pointers.h>
  49. #include <sockets/SocketClient.h>
  50. #include <types/ProtocolFields.h>
  51. #include "OnlineLogic.h"
  52. namespace Cynara {
  53. OnlineLogic::OnlineLogic() : m_socketClient(PathConfig::SocketPath::admin,
  54. std::make_shared<ProtocolAdmin>()) {
  55. }
  56. ProtocolFrameSequenceNumber generateSequenceNumber(void) {
  57. static ProtocolFrameSequenceNumber sequenceNumber = 0;
  58. return ++sequenceNumber;
  59. }
  60. bool OnlineLogic::ensureConnection(void) {
  61. return m_socketClient.isConnected() || m_socketClient.connect();
  62. }
  63. template<typename Req, typename Res, typename... ReqArgs>
  64. int OnlineLogic::getResponse(std::shared_ptr<Res> &retResponse, ReqArgs&&... args) {
  65. if (!ensureConnection()) {
  66. LOGE("Cannot connect to cynara. Service not available.");
  67. return CYNARA_API_SERVICE_NOT_AVAILABLE;
  68. }
  69. ProtocolFrameSequenceNumber sequenceNumber = generateSequenceNumber();
  70. Req request(std::forward<ReqArgs>(args)..., sequenceNumber);
  71. ResponsePtr response;
  72. while (!(response = m_socketClient.askCynaraServer(request))) {
  73. if (!m_socketClient.connect())
  74. return CYNARA_API_SERVICE_NOT_AVAILABLE;
  75. }
  76. retResponse = std::dynamic_pointer_cast<Res>(response);
  77. if (!retResponse) {
  78. LOGC("Critical error. Casting Response failed.");
  79. return CYNARA_API_UNKNOWN_ERROR;
  80. }
  81. return CYNARA_API_SUCCESS;
  82. }
  83. static int interpretCodeResponse(const CodeResponse::Code &code) {
  84. LOGD("codeResponse: code [%" PRIu16 "]", code);
  85. switch (code) {
  86. case CodeResponse::Code::OK:
  87. LOGI("Cynara command finished successfully.");
  88. return CYNARA_API_SUCCESS;
  89. case CodeResponse::Code::NOT_ALLOWED:
  90. LOGE("Cynara service answered: Operation not allowed.");
  91. return CYNARA_API_OPERATION_NOT_ALLOWED;
  92. case CodeResponse::Code::NO_BUCKET:
  93. LOGE("Trying to use unexisting bucket.");
  94. return CYNARA_API_BUCKET_NOT_FOUND;
  95. case CodeResponse::Code::NO_POLICY_TYPE:
  96. LOGE("Trying to use unknown policy type.");
  97. return CYNARA_API_INVALID_PARAM;
  98. case CodeResponse::Code::FAILED:
  99. LOGC("Cynara service answered: Operation failed.");
  100. return CYNARA_API_OPERATION_FAILED;
  101. case CodeResponse::Code::DB_CORRUPTED:
  102. LOGC("Cynara service answered: Database is corrupted.");
  103. return CYNARA_API_DATABASE_CORRUPTED;
  104. default:
  105. LOGE("Unexpected response code from server: [%d]",
  106. static_cast<int>(code));
  107. return CYNARA_API_UNKNOWN_ERROR;
  108. }
  109. }
  110. int OnlineLogic::setPolicies(const ApiInterface::PoliciesByBucket &insertOrUpdate,
  111. const ApiInterface::KeysByBucket &remove) {
  112. CodeResponsePtr codeResponse;
  113. int ret = getResponse<SetPoliciesRequest>(codeResponse, insertOrUpdate, remove);
  114. if (ret != CYNARA_API_SUCCESS) {
  115. return ret;
  116. }
  117. return interpretCodeResponse(codeResponse->m_code);
  118. }
  119. int OnlineLogic::insertOrUpdateBucket(const PolicyBucketId &bucket,
  120. const PolicyResult &policyResult) {
  121. CodeResponsePtr codeResponse;
  122. int ret = getResponse<InsertOrUpdateBucketRequest>(codeResponse, bucket, policyResult);
  123. if (ret != CYNARA_API_SUCCESS) {
  124. return ret;
  125. }
  126. return interpretCodeResponse(codeResponse->m_code);
  127. }
  128. int OnlineLogic::removeBucket(const PolicyBucketId &bucket) {
  129. CodeResponsePtr codeResponse;
  130. int ret = getResponse<RemoveBucketRequest>(codeResponse, bucket);
  131. if (ret != CYNARA_API_SUCCESS) {
  132. return ret;
  133. }
  134. return interpretCodeResponse(codeResponse->m_code);
  135. }
  136. int OnlineLogic::adminCheck(const PolicyBucketId &startBucket, bool recursive, const PolicyKey &key,
  137. PolicyResult &result) {
  138. AdminCheckResponsePtr adminCheckResponse;
  139. int ret = getResponse<AdminCheckRequest>(adminCheckResponse, key, startBucket, recursive);
  140. if (ret != CYNARA_API_SUCCESS) {
  141. return ret;
  142. }
  143. if (adminCheckResponse->isDbCorrupted()) {
  144. LOGC("Cynara service answered: Database is corrupted.");
  145. return CYNARA_API_DATABASE_CORRUPTED;
  146. }
  147. LOGD("AdminCheckResponse: policyType [%" PRIu16 "], metadata <%s>, bucketValid [%d]",
  148. adminCheckResponse->result().policyType(), adminCheckResponse->result().metadata().c_str(),
  149. static_cast<int>(adminCheckResponse->isBucketValid()));
  150. if (!adminCheckResponse->isBucketValid()) {
  151. LOGE("Bucket <%s> provided as startBucket in adminCheck does not exist in cynara database",
  152. startBucket.c_str());
  153. return CYNARA_API_BUCKET_NOT_FOUND;
  154. }
  155. result = adminCheckResponse->result();
  156. return CYNARA_API_SUCCESS;
  157. }
  158. int OnlineLogic::listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter,
  159. std::vector<Policy> &policies) {
  160. ListResponsePtr listResponse;
  161. int ret = getResponse<ListRequest>(listResponse, bucket, filter);
  162. if (ret != CYNARA_API_SUCCESS) {
  163. return ret;
  164. }
  165. if (listResponse->isDbCorrupted()) {
  166. LOGC("Cynara service answered: Database is corrupted.");
  167. return CYNARA_API_DATABASE_CORRUPTED;
  168. }
  169. LOGD("listResponse: number of policies [%zu], bucketValid [%d]",
  170. listResponse->policies().size(), listResponse->isBucketValid());
  171. if (!listResponse->isBucketValid()) {
  172. return CYNARA_API_BUCKET_NOT_FOUND;
  173. }
  174. policies = listResponse->policies();
  175. return CYNARA_API_SUCCESS;
  176. }
  177. int OnlineLogic::erasePolicies(const PolicyBucketId &startBucket, bool recursive,
  178. const PolicyKey &filter) {
  179. CodeResponsePtr codeResponse;
  180. int ret = getResponse<EraseRequest>(codeResponse, startBucket, recursive, filter);
  181. if (ret != CYNARA_API_SUCCESS) {
  182. return ret;
  183. }
  184. return interpretCodeResponse(codeResponse->m_code);
  185. }
  186. int OnlineLogic::listDescriptions(std::vector<PolicyDescription> &descriptions) {
  187. DescriptionListResponsePtr descrResponse;
  188. int ret = getResponse<DescriptionListRequest>(descrResponse);
  189. if (ret != CYNARA_API_SUCCESS) {
  190. return ret;
  191. }
  192. if (descrResponse->isDbCorrupted()) {
  193. LOGC("Cynara service answered: Database is corrupted.");
  194. return CYNARA_API_DATABASE_CORRUPTED;
  195. }
  196. LOGD("descriptionListResponse: number of plugin descriptions [%zu]",
  197. descrResponse->descriptions().size());
  198. descriptions = descrResponse->descriptions();
  199. return CYNARA_API_SUCCESS;
  200. }
  201. } // namespace Cynara