PageRenderTime 51ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/src/admin/api/admin-api.cpp

https://gitlab.com/admin-github-cloud/cynara
C++ | 393 lines | 322 code | 49 blank | 22 comment | 66 complexity | f09a51470c7e24ccf78331d02a34327c MD5 | raw file
  1. /*
  2. * Copyright (c) 2014-2016 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/api/admin-api.cpp
  18. * @author Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
  19. * @author Oskar Świtalski <o.switalski@samsung.com>
  20. * @version 1.0
  21. * @brief Implementation of external libcynara-admin API
  22. */
  23. #include <functional>
  24. #include <limits>
  25. #include <map>
  26. #include <stdexcept>
  27. #include <string>
  28. #include <cstring>
  29. #include <vector>
  30. #include <common.h>
  31. #include <exceptions/FileLockAcquiringException.h>
  32. #include <exceptions/TryCatch.h>
  33. #include <log/log.h>
  34. #include <types/Policy.h>
  35. #include <types/PolicyBucket.h>
  36. #include <types/PolicyBucketId.h>
  37. #include <types/PolicyDescription.h>
  38. #include <types/PolicyKey.h>
  39. #include <types/PolicyResult.h>
  40. #include <types/PolicyType.h>
  41. #include <types/string_validation.h>
  42. #include <cynara-admin.h>
  43. #include <cynara-error.h>
  44. #include <cynara-limits.h>
  45. #include <api/ApiInterface.h>
  46. #include <logic/Logic.h>
  47. #include <logic/OnlineLogic.h>
  48. #include <utils/Lists.h>
  49. struct cynara_admin {
  50. Cynara::ApiInterface *impl;
  51. cynara_admin(Cynara::ApiInterface *_impl) : impl(_impl) {
  52. }
  53. ~cynara_admin() {
  54. delete impl;
  55. }
  56. };
  57. CYNARA_API
  58. int cynara_admin_initialize(struct cynara_admin **pp_cynara_admin) {
  59. if (!pp_cynara_admin)
  60. return CYNARA_API_INVALID_PARAM;
  61. init_log();
  62. return Cynara::tryCatch([&]() {
  63. try {
  64. Cynara::LogicUniquePtr ptr(new Cynara::Logic());
  65. *pp_cynara_admin = new cynara_admin(ptr.get());
  66. ptr.release();
  67. } catch (const Cynara::FileLockAcquiringException &ex) {
  68. LOGE("%s", ex.what());
  69. return CYNARA_API_OPERATION_FAILED;
  70. }
  71. LOGD("Cynara admin initialized");
  72. return CYNARA_API_SUCCESS;
  73. });
  74. }
  75. CYNARA_API
  76. int cynara_admin_finish(struct cynara_admin *p_cynara_admin) {
  77. delete p_cynara_admin;
  78. return CYNARA_API_SUCCESS;
  79. }
  80. bool int2PolicyType(int type, Cynara::PolicyType &policyType) {
  81. if (type < std::numeric_limits<Cynara::PolicyType>::min())
  82. return false;
  83. if (type > std::numeric_limits<Cynara::PolicyType>::max())
  84. return false;
  85. policyType = static_cast<Cynara::PolicyType>(type);
  86. return true;
  87. }
  88. CYNARA_API
  89. int cynara_admin_set_policies(struct cynara_admin *p_cynara_admin,
  90. const struct cynara_admin_policy *const *policies) {
  91. if (!p_cynara_admin || !p_cynara_admin->impl)
  92. return CYNARA_API_INVALID_PARAM;
  93. if (!policies)
  94. return CYNARA_API_INVALID_PARAM;
  95. return Cynara::tryCatch([&]() {
  96. std::map<Cynara::PolicyBucketId, std::vector<Cynara::Policy>> insertOrUpdate;
  97. std::map<Cynara::PolicyBucketId, std::vector<Cynara::PolicyKey>> remove;
  98. auto key = ([](const cynara_admin_policy *policy)->Cynara::PolicyKey {
  99. std::string wildcard(CYNARA_ADMIN_WILDCARD);
  100. auto feature = ([&wildcard] (const char *str)->Cynara::PolicyKeyFeature {
  101. if (wildcard.compare(str))
  102. return Cynara::PolicyKeyFeature::create(str);
  103. else
  104. return Cynara::PolicyKeyFeature::createWildcard();
  105. });
  106. return Cynara::PolicyKey(feature(policy->client), feature(policy->user),
  107. feature(policy->privilege));
  108. });
  109. for (auto i = policies; *i; i++) {
  110. if (i - policies >= CYNARA_MAX_VECTOR_SIZE)
  111. return CYNARA_API_INVALID_PARAM;
  112. const cynara_admin_policy *policy = *i;
  113. if (!isStringValid(policy->bucket) || !isStringValid(policy->client))
  114. return CYNARA_API_INVALID_PARAM;
  115. if (!isStringValid(policy->user) || !isStringValid(policy->privilege))
  116. return CYNARA_API_INVALID_PARAM;
  117. switch (policy->result) {
  118. case CYNARA_ADMIN_NONE:
  119. return CYNARA_API_INVALID_PARAM;
  120. case CYNARA_ADMIN_DELETE:
  121. remove[policy->bucket].push_back(key(policy));
  122. break;
  123. case CYNARA_ADMIN_BUCKET:
  124. if (!isStringValid(policy->result_extra))
  125. return CYNARA_API_INVALID_PARAM;
  126. default:
  127. {
  128. std::string extraStr = policy->result_extra ? policy->result_extra : "";
  129. Cynara::PolicyType policyType;
  130. if (!int2PolicyType(policy->result, policyType))
  131. return CYNARA_API_INVALID_PARAM;
  132. insertOrUpdate[policy->bucket].push_back(Cynara::Policy(key(policy),
  133. Cynara::PolicyResult(
  134. policyType,
  135. extraStr)));
  136. }
  137. }
  138. }
  139. return p_cynara_admin->impl->setPolicies(insertOrUpdate, remove);
  140. });
  141. }
  142. CYNARA_API
  143. int cynara_admin_set_bucket(struct cynara_admin *p_cynara_admin, const char *bucket,
  144. int operation, const char *extra) {
  145. if (!p_cynara_admin || !p_cynara_admin->impl)
  146. return CYNARA_API_INVALID_PARAM;
  147. if (!isStringValid(bucket) || !isExtraStringValid(extra))
  148. return CYNARA_API_INVALID_PARAM;
  149. return Cynara::tryCatch([&]() {
  150. switch (operation) {
  151. case CYNARA_ADMIN_DELETE:
  152. return p_cynara_admin->impl->removeBucket(bucket);
  153. case CYNARA_ADMIN_NONE:
  154. if (bucket != Cynara::defaultPolicyBucketId) {
  155. return p_cynara_admin->impl->insertOrUpdateBucket(bucket,
  156. Cynara::PolicyResult(Cynara::PredefinedPolicyType::NONE));
  157. }
  158. return CYNARA_API_OPERATION_NOT_ALLOWED;
  159. case CYNARA_ADMIN_BUCKET:
  160. return CYNARA_API_INVALID_PARAM;
  161. default:
  162. {
  163. std::string extraStr = extra ? extra : "";
  164. Cynara::PolicyType policyType;
  165. if (!int2PolicyType(operation, policyType))
  166. return CYNARA_API_INVALID_PARAM;
  167. return p_cynara_admin->impl->insertOrUpdateBucket(bucket,
  168. Cynara::PolicyResult(policyType, extraStr));
  169. }
  170. }
  171. });
  172. }
  173. CYNARA_API
  174. int cynara_admin_check(struct cynara_admin *p_cynara_admin,
  175. const char *start_bucket, const int recursive,
  176. const char *client, const char *user, const char *privilege,
  177. int *result, char **result_extra) {
  178. if (!p_cynara_admin || !p_cynara_admin->impl)
  179. return CYNARA_API_INVALID_PARAM;
  180. if (!result || !result_extra)
  181. return CYNARA_API_INVALID_PARAM;
  182. if (!isStringValid(start_bucket) || !isStringValid(client))
  183. return CYNARA_API_INVALID_PARAM;
  184. if (!isStringValid(user)|| !isStringValid(privilege))
  185. return CYNARA_API_INVALID_PARAM;
  186. return Cynara::tryCatch([&]() {
  187. Cynara::PolicyResult policyResult;
  188. Cynara::PolicyBucketId startBucket;
  189. std::string clientStr;
  190. std::string userStr;
  191. std::string privilegeStr;
  192. try {
  193. startBucket = start_bucket;
  194. clientStr = client;
  195. userStr = user;
  196. privilegeStr = privilege;
  197. } catch (const std::length_error &e) {
  198. LOGE("%s", e.what());
  199. return CYNARA_API_INVALID_PARAM;
  200. }
  201. int ret = p_cynara_admin->impl->adminCheck(startBucket, recursive != 0,
  202. Cynara::PolicyKey(clientStr, userStr,
  203. privilegeStr), policyResult);
  204. if (ret != CYNARA_API_SUCCESS)
  205. return ret;
  206. char *str = nullptr;
  207. if (!policyResult.metadata().empty()) {
  208. str = strdup(policyResult.metadata().c_str());
  209. if (!str)
  210. return CYNARA_API_OUT_OF_MEMORY;
  211. }
  212. *result = static_cast<int>(policyResult.policyType());
  213. *result_extra = str;
  214. return CYNARA_API_SUCCESS;
  215. });
  216. }
  217. static int copyPolicy(const char *bucket, const Cynara::Policy &from, cynara_admin_policy *&to) {
  218. to = reinterpret_cast<cynara_admin_policy*>(calloc(1, sizeof(cynara_admin_policy)));
  219. if (!to)
  220. return CYNARA_API_OUT_OF_MEMORY;
  221. to->bucket = strdup(bucket);
  222. if (!to->bucket)
  223. return CYNARA_API_OUT_OF_MEMORY;
  224. to->client = strdup(from.key().client().value().c_str());
  225. if (!to->client)
  226. return CYNARA_API_OUT_OF_MEMORY;
  227. to->user = strdup(from.key().user().value().c_str());
  228. if (!to->user)
  229. return CYNARA_API_OUT_OF_MEMORY;
  230. to->privilege = strdup(from.key().privilege().value().c_str());
  231. if (!to->privilege)
  232. return CYNARA_API_OUT_OF_MEMORY;
  233. to->result = static_cast<int>(from.result().policyType());
  234. if (!from.result().metadata().empty()) {
  235. to->result_extra = strdup(from.result().metadata().c_str());
  236. if (!to->result_extra)
  237. return CYNARA_API_OUT_OF_MEMORY;
  238. }
  239. return CYNARA_API_SUCCESS;
  240. }
  241. static void freeElem(struct cynara_admin_policy *policyPtr) {
  242. free(policyPtr->bucket);
  243. free(policyPtr->client);
  244. free(policyPtr->user);
  245. free(policyPtr->privilege);
  246. free(policyPtr->result_extra);
  247. free(policyPtr);
  248. }
  249. CYNARA_API
  250. int cynara_admin_list_policies(struct cynara_admin *p_cynara_admin, const char *bucket,
  251. const char *client, const char *user, const char *privilege,
  252. struct cynara_admin_policy ***policies) {
  253. if (!p_cynara_admin || !p_cynara_admin->impl)
  254. return CYNARA_API_INVALID_PARAM;
  255. if (!policies)
  256. return CYNARA_API_INVALID_PARAM;
  257. if (!isStringValid(bucket) || !isStringValid(client))
  258. return CYNARA_API_INVALID_PARAM;
  259. if (!isStringValid(user) || !isStringValid(privilege))
  260. return CYNARA_API_INVALID_PARAM;
  261. return Cynara::tryCatch([&]() {
  262. Cynara::PolicyKeyFeature::ValueType clientStr;
  263. Cynara::PolicyKeyFeature::ValueType userStr;
  264. Cynara::PolicyKeyFeature::ValueType privilegeStr;
  265. Cynara::PolicyBucketId bucketId;
  266. try {
  267. clientStr = client;
  268. userStr = user;
  269. privilegeStr = privilege;
  270. bucketId = bucket;
  271. } catch (const std::length_error &e) {
  272. LOGE("%s", e.what());
  273. return CYNARA_API_INVALID_PARAM;
  274. }
  275. std::vector<Cynara::Policy> policiesVector;
  276. int ret = p_cynara_admin->impl->listPolicies(bucketId, Cynara::PolicyKey(clientStr, userStr,
  277. privilegeStr), policiesVector);
  278. if (ret != CYNARA_API_SUCCESS)
  279. return ret;
  280. auto copyFun = std::bind(copyPolicy, bucket, std::placeholders::_1, std::placeholders::_2);
  281. return Cynara::createNullTerminatedArray<Cynara::Policy, cynara_admin_policy>
  282. (policiesVector, policies, copyFun);
  283. });
  284. }
  285. static int copyDescr(const Cynara::PolicyDescription &from, cynara_admin_policy_descr *&to) {
  286. to = reinterpret_cast<cynara_admin_policy_descr*>(calloc(1, sizeof(cynara_admin_policy_descr)));
  287. if (!to)
  288. return CYNARA_API_OUT_OF_MEMORY;
  289. to->result = static_cast<int>(from.type);
  290. to->name = strdup(from.name.c_str());
  291. if (!to->name)
  292. return CYNARA_API_OUT_OF_MEMORY;
  293. return CYNARA_API_SUCCESS;
  294. }
  295. static void freeElem(struct cynara_admin_policy_descr *descrPtr) {
  296. free(descrPtr->name);
  297. free(descrPtr);
  298. }
  299. CYNARA_API
  300. int cynara_admin_list_policies_descriptions(struct cynara_admin *p_cynara_admin,
  301. struct cynara_admin_policy_descr ***descriptions) {
  302. if (!p_cynara_admin || !p_cynara_admin->impl)
  303. return CYNARA_API_INVALID_PARAM;
  304. if (!descriptions)
  305. return CYNARA_API_INVALID_PARAM;
  306. return Cynara::tryCatch([&p_cynara_admin, &descriptions] () {
  307. std::vector<Cynara::PolicyDescription> descriptionsVector;
  308. int ret = p_cynara_admin->impl->listDescriptions(descriptionsVector);
  309. if (ret != CYNARA_API_SUCCESS)
  310. return ret;
  311. return Cynara::createNullTerminatedArray<Cynara::PolicyDescription,
  312. cynara_admin_policy_descr>
  313. (descriptionsVector, descriptions, copyDescr);
  314. });
  315. }
  316. CYNARA_API
  317. int cynara_admin_erase(struct cynara_admin *p_cynara_admin,
  318. const char *start_bucket, const int recursive,
  319. const char *client, const char *user, const char *privilege) {
  320. if (!p_cynara_admin || !p_cynara_admin->impl)
  321. return CYNARA_API_INVALID_PARAM;
  322. if (!isStringValid(start_bucket) || !isStringValid(client))
  323. return CYNARA_API_INVALID_PARAM;
  324. if (!isStringValid(user) || !isStringValid(privilege))
  325. return CYNARA_API_INVALID_PARAM;
  326. return Cynara::tryCatch([&]() {
  327. Cynara::PolicyKeyFeature::ValueType clientStr;
  328. Cynara::PolicyKeyFeature::ValueType userStr;
  329. Cynara::PolicyKeyFeature::ValueType privilegeStr;
  330. Cynara::PolicyBucketId startBucket;
  331. try {
  332. clientStr = client;
  333. userStr = user;
  334. privilegeStr = privilege;
  335. startBucket = start_bucket;
  336. } catch (const std::length_error &e) {
  337. LOGE("%s", e.what());
  338. return CYNARA_API_INVALID_PARAM;
  339. }
  340. return p_cynara_admin->impl->erasePolicies(startBucket, recursive != 0,
  341. Cynara::PolicyKey(clientStr, userStr,
  342. privilegeStr));
  343. });
  344. }