4ff300c39841e02f5f54b81c389a756beeb0bbe0
[platform/core/test/security-tests.git] / src / cynara-tests / common / cynara_test_admin.cpp
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 #include <cynara_test_admin.h>
18 #include <cynara_test_cynara_mask.h>
19 #include <memory.h>
20 #include <plugins.h>
21 #include <tests_common.h>
22
23
24 #include <algorithm>
25 #include <cstring>
26 #include <cstdlib>
27 #include <memory>
28 #include <ostream>
29 #include <string>
30 #include <sstream>
31
32 namespace CynaraTestAdmin {
33
34 namespace
35 {
36
37 std::ostream& operator<<(std::ostream& os, const cynara_admin_policy &policy)
38 {
39     os << "{";
40     os << " " << formatCstr(policy.bucket) << ",";
41     os << " " << formatCstr(policy.client) << ",";
42     os << " " << formatCstr(policy.user) << ",";
43     os << " " << formatCstr(policy.privilege) << ",";
44     os << " " << policy.result << ",";
45     os << " " << formatCstr(policy.result_extra);
46     os << " }" << std::endl;
47     return os;
48 }
49
50 std::ostream& operator<<(std::ostream& os, const cynara_admin_policy *const *policies)
51 {
52     os << "{" << std::endl;
53     for (size_t i = 0; policies[i] != nullptr; ++i)
54         os << *policies[i];
55     os << "}";
56     return os;
57 }
58
59 int string_compare(const char *s1, const char *s2)
60 {
61     if (!s2)
62     {
63         if (!s1)
64             return 0;
65         return 1;
66     }
67     if (!s1)
68         return -1;
69     return strcmp(s1, s2);
70 }
71
72 bool policy_less(const cynara_admin_policy &p1, const cynara_admin_policy &p2)
73 {
74     auto sc = string_compare(p1.bucket, p2.bucket);
75     if (sc != 0)
76         return (sc < 0);
77     sc = string_compare(p1.client, p2.client);
78     if (sc != 0)
79         return (sc < 0);
80     sc = string_compare(p1.user, p2.user);
81     if (sc != 0)
82         return (sc < 0);
83     sc = string_compare(p1.privilege, p2.privilege);
84     if (sc != 0)
85         return (sc < 0);
86     sc = string_compare(p1.result_extra, p2.result_extra);
87     if (sc != 0)
88         return (sc < 0);
89     return p1.result < p2.result;
90 }
91
92 bool policy_equal(const cynara_admin_policy &p1, const cynara_admin_policy &p2)
93 {
94     return (p1.result == p2.result
95             && string_compare(p1.bucket, p2.bucket) == 0
96             && string_compare(p1.client, p2.client) == 0
97             && string_compare(p1.user, p2.user) == 0
98             && string_compare(p1.privilege, p2.privilege) == 0
99             && string_compare(p1.result_extra, p2.result_extra) == 0);
100 }
101
102 std::ostream& operator<<(std::ostream& os, const CynaraTestPlugins::Descriptions &descriptions)
103 {
104     os << "{" << std::endl;
105     for (const auto &desc : descriptions)
106         os << "{ [" << desc.type << "], <" << desc.name << "> }" << std::endl;
107     os << "}";
108     return os;
109 }
110
111 } // namespace anonymous
112
113 CynaraPoliciesContainer::CynaraPoliciesContainer()
114 {
115 }
116
117 CynaraPoliciesContainer::CynaraPoliciesContainer(struct cynara_admin_policy **policies)
118 {
119     if (!policies)
120         return;
121
122     for (int i = 0; policies[i]; ++i) {
123         auto policyPtr = policies[i];
124         m_policies.push_back(*policyPtr);
125         free(policyPtr);
126     }
127     free(policies);
128 }
129
130 CynaraPoliciesContainer::~CynaraPoliciesContainer()
131 {
132     for (struct cynara_admin_policy &policy : m_policies) {
133         free(policy.bucket);
134         free(policy.client);
135         free(policy.user);
136         free(policy.privilege);
137         free(policy.result_extra);
138     }
139 }
140
141 void CynaraPoliciesContainer::add(const char *bucket,
142                                   const char *client,
143                                   const char *user,
144                                   const char *privilege,
145                                   const int result,
146                                   const char *resultExtra)
147 {
148     m_policies.push_back({ nullptr, nullptr, nullptr, nullptr, 0, nullptr });
149     struct cynara_admin_policy &policy = m_policies.back();
150     if (bucket)
151         policy.bucket = strdup(bucket);
152     if (client)
153         policy.client = strdup(client);
154     if (user)
155         policy.user = strdup(user);
156     if (privilege)
157         policy.privilege = strdup(privilege);
158     policy.result = result;
159     if (resultExtra)
160         policy.result_extra = strdup(resultExtra);
161 }
162
163 void CynaraPoliciesContainer::add(const char *bucket,
164                                   const CheckKey &checkKey,
165                                   const int result,
166                                   const char *resultExtra)
167 {
168     add(bucket, checkKey.m_client, checkKey.m_user, checkKey.m_privilege, result, resultExtra);
169 }
170
171 void CynaraPoliciesContainer::sort()
172 {
173     std::sort(m_policies.begin(), m_policies.end(), policy_less);
174 }
175
176 std::ostream& operator<<(std::ostream& os, const CynaraPoliciesContainer &policies)
177 {
178     os << "{" << std::endl;
179     for (const auto & policy : policies.m_policies)
180         os << policy;
181     os << "}";
182     return os;
183 }
184
185 Admin::Admin(bool isOnline)
186     : m_admin(nullptr), m_online(isOnline)
187 {
188     std::unique_ptr<CynaraMask>(m_online ? nullptr : new CynaraMask());
189
190
191     int ret = cynara_admin_initialize(&m_admin);
192     RUNNER_ASSERT_MSG(ret == CYNARA_API_SUCCESS,
193                          "cynara_admin_initialize failed. ret: " << ret);
194     RUNNER_ASSERT_MSG(m_admin != nullptr, "cynara_admin struct was not initialized");
195 }
196
197 Admin::~Admin() noexcept(false)
198 {
199     std::unique_ptr<CynaraMask>(m_online ? nullptr : new CynaraMask());
200     cynara_admin_finish(m_admin);
201 }
202
203 void Admin::setPolicies(const CynaraPoliciesContainer &policiesContainer,
204                         int expectedResult)
205 {
206     std::unique_ptr<CynaraMask>(m_online ? nullptr : new CynaraMask());
207
208     const cynara_admin_policy *policies[policiesContainer.m_policies.size()+1];
209
210     for (size_t i = 0; i < policiesContainer.m_policies.size(); ++i) {
211         policies[i] = &policiesContainer.m_policies[i];
212     }
213     policies[policiesContainer.m_policies.size()] = nullptr;
214
215     int ret = cynara_admin_set_policies(m_admin, policies);
216     RUNNER_ASSERT_MSG(ret == expectedResult,
217                          "cynara_admin_set_policies returned wrong value: "
218                              << ret << " != " << expectedResult << ". "
219                              << "policies:\n" << policies);
220 }
221
222 void Admin::setBucket(const char *bucket, int operation, const char *extra,
223                       int expectedResult)
224 {
225     std::unique_ptr<CynaraMask>(m_online ? nullptr : new CynaraMask());
226
227     int ret = cynara_admin_set_bucket(m_admin, bucket, operation, extra);
228     RUNNER_ASSERT_MSG(ret == expectedResult,
229                          "cynara_admin_set_bucket returned wrong value: "
230                              << ret << " != " << expectedResult << "."
231                              << " bucket: " << formatCstr(bucket) << ","
232                              << " operation: " << operation << ","
233                              << " extra: " << formatCstr(extra));
234 }
235
236 void Admin::adminCheck(const char *startBucket, int recursive,
237                        const char *client, const char *user, const char *privilege,
238                        int expectedCheckResult, const char *expectedCheckResultExtra,
239                        int expectedResult)
240 {
241     std::unique_ptr<CynaraMask>(m_online ? nullptr : new CynaraMask());
242
243     int checkResult;
244     char *checkResultExtra = nullptr;
245
246     int ret = cynara_admin_check(m_admin,
247                                  startBucket, recursive,
248                                  client, user, privilege,
249                                  &checkResult, &checkResultExtra);
250     CStringPtr extra(checkResultExtra);
251
252     auto dump = [&]() -> std::string
253     {
254         std::stringstream s;
255         s  << " functionReturn: " << ret << ","
256            << " functionExpectedReturn: " << expectedResult << ",";
257
258         s  << " startBucket: " << formatCstr(startBucket) << ","
259            << " recursive: " << recursive << ","
260            << " client: " << formatCstr(client) << ","
261            << " user: " << formatCstr(user) << ","
262            << " privilege: " << formatCstr(privilege) << ",";
263
264         s  << " checkResult: " << checkResult << ","
265            << " expectedCheckResult: " << expectedCheckResult << ","
266            << " checkResultExtra: " << formatCstr(checkResultExtra) << ","
267            << " expectedCheckResultExtra: " << formatCstr(expectedCheckResultExtra);
268         return s.str();
269     };
270
271     RUNNER_ASSERT_MSG(ret == expectedResult,
272                          "cynara_admin_check returned wrong value: "
273                              << ret << " != " << expectedResult << "."
274                              << dump());
275
276     RUNNER_ASSERT_MSG(checkResult == expectedCheckResult,
277                          "cynara_admin_check returned wrong check result: "
278                              << checkResult << " != " << expectedCheckResult << "."
279                              << dump());
280
281     RUNNER_ASSERT_MSG(formatCstr(checkResultExtra) == formatCstr(expectedCheckResultExtra),
282                          "cynara_admin_check returned wrong check result extra: "
283                              << formatCstr(checkResultExtra) << " != "
284                              << formatCstr(expectedCheckResultExtra) << "."
285                              << dump());
286 }
287
288 void Admin::listPolicies(const char *startBucket,
289                          const char *client, const char *user, const char *privilege,
290                          CynaraPoliciesContainer &expectedPolicyList,
291                          int expectedResult) {
292
293     std::unique_ptr<CynaraMask>(m_online ? nullptr : new CynaraMask());
294
295     struct cynara_admin_policy **policies = nullptr;
296
297     int ret = cynara_admin_list_policies(m_admin,
298                                          startBucket,
299                                          client, user, privilege,
300                                          &policies);
301
302     CynaraPoliciesContainer receivedPolicyList(policies);
303     receivedPolicyList.sort();
304     expectedPolicyList.sort();
305
306     auto dump = [&]() -> std::string
307     {
308         std::stringstream s;
309         s  << " functionReturn: " << ret << ","
310            << " functionExpectedReturn: " << expectedResult << ",";
311
312         s  << " startBucket: " << formatCstr(startBucket) << ","
313            << " client: " << formatCstr(client) << ","
314            << " user: " << formatCstr(user) << ","
315            << " privilege: " << formatCstr(privilege) << ",";
316
317         s  << " receivedPolicyList: " << receivedPolicyList << ","
318            << " expectedPolicyList: " << expectedPolicyList;
319         return s.str();
320     };
321
322     RUNNER_ASSERT_MSG(ret == expectedResult,
323                          "cynara_admin_list_policies returned wrong value: "
324                              << ret << " != " << expectedResult << "."
325                              << dump());
326
327     RUNNER_ASSERT_MSG(receivedPolicyList.m_policies.size() == expectedPolicyList.m_policies.size(),
328                      "size of list returned by cynara_admin_list_policies: "
329                          << receivedPolicyList.m_policies.size()
330                          << " doesn't match expected list size: "
331                          << expectedPolicyList.m_policies.size() << "."
332                          << dump());
333
334     RUNNER_ASSERT_MSG(std::equal(receivedPolicyList.m_policies.begin(),
335                                  receivedPolicyList.m_policies.end(),
336                                  expectedPolicyList.m_policies.begin(),
337                                  policy_equal),
338                      "list returned by cynara_admin_list_policies doesn't match expected: "
339                          << dump());
340 }
341
342 void Admin::erasePolicies(const char *startBucket, int recursive,
343                           const char *client, const char *user, const char *privilege,
344                           int expectedResult)
345 {
346     std::unique_ptr<CynaraMask>(m_online ? nullptr : new CynaraMask());
347
348     int ret = cynara_admin_erase(m_admin,
349                                  startBucket, recursive,
350                                  client, user, privilege);
351
352     auto dump = [&]() -> std::string
353     {
354         std::stringstream s;
355         s  << " functionReturn: " << ret << ","
356            << " functionExpectedReturn: " << expectedResult << ",";
357
358         s  << " startBucket: " << formatCstr(startBucket) << ","
359            << " recursive: " << recursive << ","
360            << " client: " << formatCstr(client) << ","
361            << " user: " << formatCstr(user) << ","
362            << " privilege: " << formatCstr(privilege);
363
364         return s.str();
365     };
366
367     RUNNER_ASSERT_MSG(ret == expectedResult,
368                          "cynara_admin_erase returned wrong value: "
369                              << ret << " != " << expectedResult << "."
370                              << dump());
371 }
372
373 CynaraTestPlugins::Descriptions parseAndRelease(cynara_admin_policy_descr **descriptions)
374 {
375     CynaraTestPlugins::Descriptions ret;
376
377     if (descriptions) {
378         for (size_t i = 0; descriptions[i] != nullptr; ++i) {
379             auto descPtr = descriptions[i];
380             ret.push_back({ static_cast<Cynara::PolicyType>(descPtr->result),
381                             std::string(descPtr->name) });
382             free(descPtr->name);
383             free(descPtr);
384         }
385         free(descriptions);
386     }
387     return ret;
388 }
389
390 void Admin::listPoliciesDescriptions(CynaraTestPlugins::Descriptions &expectedDescriptions,
391                                      int expectedResult)
392 {
393     std::unique_ptr<CynaraMask>(m_online ? nullptr : new CynaraMask());
394
395     struct cynara_admin_policy_descr **descriptions = nullptr;
396
397     int ret = cynara_admin_list_policies_descriptions(m_admin, &descriptions);
398
399     CynaraTestPlugins::Descriptions receivedDescriptions = parseAndRelease(descriptions);
400
401     auto description_less = [](const Cynara::PolicyDescription &d1,
402                                const Cynara::PolicyDescription &d2) -> bool {
403         return d1.type != d2.type ? d1.type < d2.type : d1.name < d2.name;
404     };
405
406     auto description_equal = [](const Cynara::PolicyDescription &d1,
407                                 const Cynara::PolicyDescription &d2) -> bool {
408         return d1.type == d2.type && d1.name == d2.name;
409     };
410
411     std::sort(receivedDescriptions.begin(), receivedDescriptions.end(), description_less);
412     std::sort(expectedDescriptions.begin(), expectedDescriptions.end(), description_less);
413
414     auto dump = [&]() -> std::string
415     {
416         std::stringstream s;
417         s  << " functionReturn: " << ret << ","
418            << " functionExpectedReturn: " << expectedResult << ",";
419
420         s  << " receivedPolicyDescriptionList: " << receivedDescriptions << ","
421            << " expectedPolicyDescriptionList: " << expectedDescriptions << ".";
422         return s.str();
423     };
424
425     RUNNER_ASSERT_MSG(ret == expectedResult,
426                          "cynara_admin_list_policies_descriptions returned wrong value: "
427                              << ret << " != " << expectedResult << "."
428                              << dump());
429
430     RUNNER_ASSERT_MSG(receivedDescriptions.size() == expectedDescriptions.size(),
431                      "size of list returned by cynara_admin_list_policies_descriptions: "
432                          << receivedDescriptions.size()
433                          << " doesn't match expected list size: "
434                          << expectedDescriptions.size() << "."
435                          << dump());
436
437     RUNNER_ASSERT_MSG(std::equal(receivedDescriptions.begin(),
438                                  receivedDescriptions.end(),
439                                  expectedDescriptions.begin(),
440                                  description_equal),
441                      "list returned by cynara_admin_list_policies_descriptions "
442                          "doesn't match expected. " << dump());
443 }
444
445 void Admin::getPolicyTypeForDescription(const std::string &description,
446                                         int &policyType, int expectedResult)
447 {
448     auto descr_deleter = [](cynara_admin_policy_descr** descr) {
449             if (descr != nullptr)
450                 for (int i = 0; descr[i] != nullptr; i++) {
451                     free(descr[i]->name);
452                     free(descr[i]);
453                 }
454             free(descr);
455          };
456     struct cynara_admin_policy_descr **descriptions = nullptr;
457     int ret = cynara_admin_list_policies_descriptions(m_admin, &descriptions);
458     std::unique_ptr<cynara_admin_policy_descr*, decltype(descr_deleter)>
459         descrPtr(descriptions, descr_deleter);
460     RUNNER_ASSERT_MSG(ret == expectedResult,
461         "cynara_admin_list_policies_descriptions returned wrong value: " <<
462         ret << " != " << expectedResult);
463     ret = 0;
464     for (int i = 0; descriptions[i] != nullptr; i++) {
465         if (descriptions[i]->name == description) {
466             policyType = descriptions[i]->result;
467             ret = 1;
468         }
469     }
470     if (!ret)
471         RUNNER_FAIL_MSG("Policy type for description " << description << " not found: ");
472 }
473
474 } // namespace CynaraTestAdmin