PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/cyad/CommandsDispatcher.cpp

https://gitlab.com/github-cloud-corporation/cynara
C++ | 302 lines | 220 code | 56 blank | 26 comment | 39 complexity | f7b6472e1714e068c0ead606cdb2d663 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/cyad/CommandsDispatcher.cpp
  18. * @author Aleksander Zdyb <a.zdyb@samsung.com>
  19. * @author Oskar Świtalski <o.switalski@samsung.com>
  20. * @version 1.0
  21. * @brief CommandsDispatcher class (implementation)
  22. */
  23. #include <cynara-admin-types.h>
  24. #include <cynara-error.h>
  25. #include <cynara-policy-types.h>
  26. #include <exceptions/BucketRecordCorruptedException.h>
  27. #include <cyad/AdminLibraryInitializationFailedException.h>
  28. #include <cyad/AdminPolicyParser.h>
  29. #include <cyad/CommandlineParser/CmdlineOpts.h>
  30. #include <cyad/CommandlineParser/PolicyParsingException.h>
  31. #include <cyad/CynaraAdminPolicies.h>
  32. #include "CommandsDispatcher.h"
  33. namespace Cynara {
  34. CommandsDispatcher::CommandsDispatcher(BaseDispatcherIO &io, BaseAdminApiWrapper &adminApiWrapper,
  35. BaseErrorApiWrapper &errorApiWrapper)
  36. : m_io(io), m_adminApiWrapper(adminApiWrapper), m_errorApiWrapper(errorApiWrapper),
  37. m_cynaraAdmin(nullptr)
  38. {
  39. auto ret = m_adminApiWrapper.cynara_admin_initialize(&m_cynaraAdmin);
  40. if (ret != CYNARA_API_SUCCESS) {
  41. printAdminApiError(ret);
  42. throw AdminLibraryInitializationFailedException(ret);
  43. }
  44. try {
  45. initPolicyTranslator();
  46. } catch (int ret) {
  47. printAdminApiError(ret);
  48. // It's not really initialization error, but still nothing depends on user input
  49. throw AdminLibraryInitializationFailedException(ret);
  50. }
  51. }
  52. CommandsDispatcher::~CommandsDispatcher() {
  53. auto ret = m_adminApiWrapper.cynara_admin_finish(m_cynaraAdmin);
  54. if (ret != CYNARA_API_SUCCESS)
  55. printAdminApiError(ret);
  56. }
  57. int CommandsDispatcher::execute(CyadCommand &) {
  58. m_io.cerr() << "Whatever you wanted, it's not implemented" << std::endl;
  59. return CYNARA_API_UNKNOWN_ERROR;
  60. }
  61. int CommandsDispatcher::execute(HelpCyadCommand &) {
  62. m_io.cout() << CmdlineOpts::makeHelp() << std::endl;
  63. return CYNARA_API_SUCCESS;
  64. }
  65. int CommandsDispatcher::execute(ErrorCyadCommand &result) {
  66. m_io.cerr() << "There was an error in command-line options:" << std::endl;
  67. m_io.cerr() << result.message() << ", use '-h' or '--help' to print help message" << std::endl;
  68. return CYNARA_API_INVALID_COMMANDLINE_PARAM;
  69. }
  70. int CommandsDispatcher::execute(DeleteBucketCyadCommand &result) {
  71. auto ret = m_adminApiWrapper.cynara_admin_set_bucket(m_cynaraAdmin, result.bucketId().c_str(),
  72. CYNARA_ADMIN_DELETE, nullptr);
  73. if (ret != CYNARA_API_SUCCESS)
  74. printAdminApiError(ret);
  75. return ret;
  76. }
  77. int CommandsDispatcher::execute(SetBucketCyadCommand &result) {
  78. const auto &policyResult = result.policyResult();
  79. const char *metadata = policyResult.metadata().empty() ? nullptr
  80. : policyResult.metadata().c_str();
  81. try {
  82. int policyType = m_policyTranslator.translate(result.policyResult().policyType());
  83. auto ret = m_adminApiWrapper.cynara_admin_set_bucket(m_cynaraAdmin,
  84. result.bucketId().c_str(),
  85. policyType, metadata);
  86. if (ret != CYNARA_API_SUCCESS)
  87. printAdminApiError(ret);
  88. return ret;
  89. } catch (const PolicyParsingException &) {
  90. m_io.cerr() << "Invalid policy" << std::endl;
  91. return CYNARA_API_INVALID_COMMANDLINE_PARAM;
  92. }
  93. }
  94. int CommandsDispatcher::execute(SetPolicyCyadCommand &result) {
  95. CynaraAdminPolicies policies;
  96. try {
  97. int policyType = m_policyTranslator.translate(result.policyResult().policyType());
  98. policies.add(result.bucketId(), PolicyResult(policyType, result.policyResult().metadata()),
  99. result.policyKey());
  100. policies.seal();
  101. } catch (const PolicyParsingException &) {
  102. m_io.cerr() << "Invalid policy" << std::endl;
  103. return CYNARA_API_INVALID_COMMANDLINE_PARAM;
  104. }
  105. auto ret = m_adminApiWrapper.cynara_admin_set_policies(m_cynaraAdmin, policies.data());
  106. if (ret != CYNARA_API_SUCCESS)
  107. printAdminApiError(ret);
  108. return ret;
  109. }
  110. int CommandsDispatcher::execute(SetPolicyBulkCyadCommand &result) {
  111. auto input = m_io.openFile(result.filename());
  112. try {
  113. using Cynara::AdminPolicyParser::parse;
  114. auto policies = parse(*input, std::bind(&PolicyTypeTranslator::translate,
  115. &m_policyTranslator, std::placeholders::_1));
  116. auto ret = m_adminApiWrapper.cynara_admin_set_policies(m_cynaraAdmin, policies.data());
  117. if (ret != CYNARA_API_SUCCESS)
  118. printAdminApiError(ret);
  119. return ret;
  120. } catch (const BucketRecordCorruptedException &ex) {
  121. m_io.cerr() << ex.message();
  122. return CYNARA_API_INVALID_COMMANDLINE_PARAM;
  123. } catch (const PolicyParsingException &) {
  124. m_io.cerr() << "Invalid policy" << std::endl;
  125. return CYNARA_API_INVALID_COMMANDLINE_PARAM;
  126. }
  127. }
  128. int CommandsDispatcher::execute(EraseCyadCommand &result) {
  129. const auto &key = result.policyKey();
  130. auto client = key.client().toString().c_str();
  131. auto user = key.user().toString().c_str();
  132. auto privilege = key.privilege().toString().c_str();
  133. auto ret = m_adminApiWrapper.cynara_admin_erase(m_cynaraAdmin, result.bucketId().c_str(),
  134. result.recursive(), client, user, privilege);
  135. if (ret != CYNARA_API_SUCCESS)
  136. printAdminApiError(ret);
  137. return ret;
  138. }
  139. int CommandsDispatcher::execute(CheckCyadCommand &command) {
  140. const auto &key = command.policyKey();
  141. auto client = key.client().toString().c_str();
  142. auto user = key.user().toString().c_str();
  143. auto privilege = key.privilege().toString().c_str();
  144. // Initialization is needed to make compiler happy (-Werror=maybe-uninitialized, FTW)
  145. int result = CYNARA_API_ACCESS_DENIED;
  146. char *resultExtra = nullptr;
  147. auto ret = m_adminApiWrapper.cynara_admin_check(m_cynaraAdmin, command.bucketId().c_str(),
  148. command.recursive(), client, user, privilege,
  149. &result, &resultExtra);
  150. if (ret == CYNARA_API_SUCCESS) {
  151. m_io.cout() << (command.humanize() ? m_policyTranslator.humanize(result) :
  152. std::to_string(result)) << ";";
  153. if (resultExtra != nullptr) {
  154. m_io.cout() << resultExtra;
  155. free(resultExtra);
  156. }
  157. m_io.cout() << std::endl;
  158. } else {
  159. printAdminApiError(ret);
  160. }
  161. return ret;
  162. }
  163. int CommandsDispatcher::execute(ListPoliciesCyadCommand &command) {
  164. const auto &key = command.policyKey();
  165. auto client = key.client().toString().c_str();
  166. auto user = key.user().toString().c_str();
  167. auto privilege = key.privilege().toString().c_str();
  168. // Initialization is needed to make compiler happy (-Werror=maybe-uninitialized, FTW)
  169. cynara_admin_policy **policies = nullptr;
  170. auto ret = m_adminApiWrapper.cynara_admin_list_policies(m_cynaraAdmin,
  171. command.bucketId().c_str(),
  172. client, user, privilege,
  173. &policies);
  174. auto policyTypeString = [this, &command] (int result) {
  175. return (command.humanize() ? m_policyTranslator.humanize(result) : std::to_string(result));
  176. };
  177. auto printPolicy = [this, &policyTypeString] (cynara_admin_policy *p) {
  178. m_io.cout() << p->bucket << ";"
  179. << p->client << ";"
  180. << p->user << ";"
  181. << p->privilege << ";"
  182. << policyTypeString(p->result) << ";";
  183. if (p->result_extra != nullptr) {
  184. m_io.cout() << p->result_extra;
  185. }
  186. m_io.cout() << std::endl;
  187. };
  188. auto freePolicy = [] (cynara_admin_policy *p) {
  189. free(p->bucket);
  190. free(p->client);
  191. free(p->user);
  192. free(p->privilege);
  193. free(p->result_extra);
  194. free(p);
  195. };
  196. if (ret == CYNARA_API_SUCCESS) {
  197. for (int i = 0; policies[i]; ++i) {
  198. auto p = policies[i];
  199. printPolicy(p);
  200. freePolicy(p);
  201. }
  202. free(policies);
  203. } else {
  204. printAdminApiError(ret);
  205. }
  206. return ret;
  207. }
  208. int CommandsDispatcher::execute(ListPoliciesDescCyadCommand &) {
  209. for (const auto desc : m_policyTranslator.descriptions()) {
  210. m_io.cout() << desc.first << ";" << desc.second << std::endl;
  211. }
  212. return CYNARA_API_SUCCESS;
  213. }
  214. void CommandsDispatcher::printAdminApiError(int errnum) {
  215. const std::size_t buffSize = 256;
  216. char buf[buffSize];
  217. auto ret = m_errorApiWrapper.cynara_strerror(errnum, buf, buffSize);
  218. m_io.cerr() << "Cynara: [" << errnum << "] ";
  219. if (ret == CYNARA_API_SUCCESS)
  220. m_io.cerr() << buf << std::endl;
  221. else if (ret == CYNARA_API_INVALID_PARAM)
  222. m_io.cerr() << "Unknown error (sic!)" << std::endl;
  223. else if (ret == CYNARA_API_BUFFER_TOO_SHORT)
  224. m_io.cerr() << "Error message too long" << std::endl;
  225. else
  226. m_io.cerr() << "Unknown error (sic! sic!)" << std::endl;
  227. }
  228. void CommandsDispatcher::initPolicyTranslator(void) {
  229. // Initialization is needed to make compiler happy (-Werror=maybe-uninitialized, FTW)
  230. cynara_admin_policy_descr **descs = nullptr;
  231. auto ret = m_adminApiWrapper.cynara_admin_list_policies_descriptions(m_cynaraAdmin, &descs);
  232. auto freePolicyDesc = [] (cynara_admin_policy_descr *pd) {
  233. free(pd->name);
  234. free(pd);
  235. };
  236. if (ret == CYNARA_API_SUCCESS) {
  237. m_policyTranslator.setDescriptions(descs);
  238. for (int i = 0; descs[i] != nullptr; ++i) {
  239. freePolicyDesc(descs[i]);
  240. }
  241. free(descs);
  242. } else {
  243. throw ret;
  244. }
  245. }
  246. } /* namespace Cynara */