Introduce 'default' method type for credential helpers
[platform/core/security/cynara.git] / test / cyad / commands_dispatcher.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  * @file        test/cyad/commands_dispatcher.cpp
18  * @author      Aleksander Zdyb <a.zdyb@samsung.com>
19  * @version     1.0
20  * @brief       Tests for CommandsDispatcher
21  */
22
23 #include <cstring>
24 #include <ostream>
25 #include <tuple>
26 #include <vector>
27
28 #include <gmock/gmock.h>
29 #include <gtest/gtest.h>
30
31 #include <cynara-admin-types.h>
32 #include <cynara-error.h>
33 #include <cynara-policy-types.h>
34
35 #include <common/types/PolicyKey.h>
36 #include <common/types/PolicyResult.h>
37 #include <common/types/PolicyType.h>
38 #include <cyad/CynaraAdminPolicies.h>
39 #include <cyad/CommandlineParser/CyadCommand.h>
40 #include <cyad/CommandsDispatcher.h>
41
42 #include "CyadCommandlineDispatcherTest.h"
43 #include "helpers.h"
44
45 /**
46  * @brief   Dispatcher should not touch admin API on help or error
47  * @test    Scenario:
48  * - Prepare some parsing results not requiring API calls
49  * - Check if no API calls were made
50  */
51 TEST_F(CyadCommandlineDispatcherTest, noApi) {
52     using ::testing::_;
53     using ::testing::Return;
54
55     Cynara::CommandsDispatcher dispatcher(m_io, m_adminApi, m_errorApi);
56
57     Cynara::CyadCommand result;
58     Cynara::HelpCyadCommand helpResult;
59     Cynara::ErrorCyadCommand errorResult("Fake error");
60
61     dispatcher.execute(result);
62     dispatcher.execute(helpResult);
63     dispatcher.execute(errorResult);
64 }
65
66 TEST_F(CyadCommandlineDispatcherTest, deleteBucket) {
67     using ::testing::_;
68     using ::testing::Return;
69     using ::testing::StrEq;
70     using ::testing::IsNull;
71
72     Cynara::CommandsDispatcher dispatcher(m_io, m_adminApi, m_errorApi);
73     Cynara::DeleteBucketCyadCommand result("test-bucket");
74
75     EXPECT_CALL(m_adminApi,
76             cynara_admin_set_bucket(_, StrEq("test-bucket"), CYNARA_ADMIN_DELETE, IsNull()))
77         .WillOnce(Return(CYNARA_API_SUCCESS));
78
79     dispatcher.execute(result);
80 }
81
82 TEST_F(CyadCommandlineDispatcherTest, setBucket) {
83     using ::testing::_;
84     using ::testing::Return;
85     using ::testing::StrEq;
86     using ::testing::IsNull;
87     using ::testing::NotNull;
88     using Cynara::PolicyBucketId;
89     using Cynara::PolicyType;
90     using Cynara::PolicyResult;
91
92     addDescriptions({ { 42, "hitchhiker" } });
93
94     Cynara::CommandsDispatcher dispatcher(m_io, m_adminApi, m_errorApi);
95
96     typedef std::string RawPolicyType;
97     typedef std::string Metadata;
98     typedef std::tuple<PolicyBucketId, PolicyType, RawPolicyType, Metadata> BucketData;
99     typedef std::vector<BucketData> Buckets;
100     const Buckets buckets = {
101         BucketData("test-bucket-1", CYNARA_ADMIN_ALLOW, "ALLOW", ""),
102         BucketData("test-bucket-2", CYNARA_ADMIN_DENY, "DENY", ""),
103         BucketData("test-bucket-3", CYNARA_ADMIN_BUCKET, "BUCKET", "other-bucket"),
104         BucketData("test-bucket-2", CYNARA_ADMIN_NONE, "NONE", ""),
105         BucketData("test-bucket-4", 42, "hitchhiker", "douglas-noel-adams") };
106
107     for (const auto &bucket : buckets) {
108         const auto &bucketId = std::get<0>(bucket);
109         const auto &policyType = std::get<1>(bucket);
110         const auto &rawPolicyType = std::get<2>(bucket);
111         const auto &metadata = std::get<3>(bucket);
112
113         SCOPED_TRACE(bucketId);
114
115         Cynara::SetBucketCyadCommand result(bucketId, { rawPolicyType, metadata });
116
117         if (metadata.empty() == false) {
118             EXPECT_CALL(m_adminApi,
119                     cynara_admin_set_bucket(_, StrEq(bucketId.c_str()), policyType,
120                                             StrEq(metadata.c_str())))
121                 .WillOnce(Return(CYNARA_API_SUCCESS));
122         } else {
123             EXPECT_CALL(m_adminApi,
124                     cynara_admin_set_bucket(_, StrEq(bucketId.c_str()), policyType, IsNull()))
125                 .WillOnce(Return(CYNARA_API_SUCCESS));
126         }
127
128         dispatcher.execute(result);
129     }
130 }
131
132 TEST_F(CyadCommandlineDispatcherTest, setPolicy) {
133     using ::testing::_;
134     using ::testing::Return;
135
136     Cynara::CommandsDispatcher dispatcher(m_io, m_adminApi, m_errorApi);
137     Cynara::SetPolicyCyadCommand result("test-bucket", { "allow", "" },
138                                         { "client", "user", "privilege" });
139
140     Cynara::CynaraAdminPolicies expectedPolicies;
141     expectedPolicies.add("test-bucket", { CYNARA_ADMIN_ALLOW, "" },
142                          { "client", "user", "privilege"} );
143     expectedPolicies.seal();
144
145     EXPECT_CALL(m_adminApi, cynara_admin_set_policies(_, AdmPolicyListEq(expectedPolicies.data())))
146         .WillOnce(Return(CYNARA_API_SUCCESS));
147
148     dispatcher.execute(result);
149 }
150
151 TEST_F(CyadCommandlineDispatcherTest, setPolicyWithMetadata) {
152     using ::testing::_;
153     using ::testing::Return;
154
155     Cynara::CommandsDispatcher dispatcher(m_io, m_adminApi, m_errorApi);
156     Cynara::SetPolicyCyadCommand result("test-bucket", { "allow", "metadata" },
157                                         Cynara::PolicyKey("client", "user", "privilege"));
158
159     Cynara::CynaraAdminPolicies expectedPolicies;
160     expectedPolicies.add("test-bucket", { CYNARA_ADMIN_ALLOW, "metadata" },
161                          { "client", "user", "privilege"} );
162     expectedPolicies.seal();
163
164     EXPECT_CALL(m_adminApi, cynara_admin_set_policies(_, AdmPolicyListEq(expectedPolicies.data())))
165         .WillOnce(Return(CYNARA_API_SUCCESS));
166
167     dispatcher.execute(result);
168 }
169
170 TEST_F(CyadCommandlineDispatcherTest, setPoliciesBulk) {
171     using ::testing::_;
172     using ::testing::Return;
173
174     Cynara::CommandsDispatcher dispatcher(m_io, m_adminApi, m_errorApi);
175     Cynara::SetPolicyBulkCyadCommand result("-");
176
177     // fake stdin ;)
178     m_io.file() << "bucket;cli;usr;privilege;0;metadata" << std::endl;
179     m_io.file() << "bucket-2;cli;usr;privilege;0xFFFF;" << std::endl;
180     m_io.file() << "bucket-3;cli;usr;priv;bucket;bucket-2";
181
182     Cynara::CynaraAdminPolicies expectedPolicies;
183     expectedPolicies.add("bucket", { CYNARA_ADMIN_DENY, "metadata" }, {"cli", "usr", "privilege"} );
184     expectedPolicies.add("bucket-2", { CYNARA_ADMIN_ALLOW, "" }, {"cli", "usr", "privilege"} );
185     expectedPolicies.add("bucket-3", { CYNARA_ADMIN_BUCKET, "bucket-2" }, {"cli", "usr", "priv"} );
186     expectedPolicies.seal();
187
188     EXPECT_CALL(m_adminApi, cynara_admin_set_policies(_, AdmPolicyListEq(expectedPolicies.data())))
189         .WillOnce(Return(CYNARA_API_SUCCESS));
190
191     dispatcher.execute(result);
192 }
193
194 TEST_F(CyadCommandlineDispatcherTest, setPoliciesBulkInputError) {
195     using ::testing::_;
196     using ::testing::Return;
197
198     Cynara::CommandsDispatcher dispatcher(m_io, m_adminApi, m_errorApi);
199     Cynara::SetPolicyBulkCyadCommand result("-");
200
201     // fake stdin ;)
202     m_io.file() << "invalid input" << std::endl;
203
204     dispatcher.execute(result);
205
206     ASSERT_FALSE(m_io.cerrRaw().str().empty());
207 }
208
209 TEST_F(CyadCommandlineDispatcherTest, erase) {
210     using ::testing::_;
211     using ::testing::Return;
212     using ::testing::StrEq;
213
214     Cynara::CommandsDispatcher dispatcher(m_io, m_adminApi, m_errorApi);
215
216     Cynara::EraseCyadCommand command("", true, { "client", "user", "privilege" });
217
218     EXPECT_CALL(m_adminApi, cynara_admin_erase(_, StrEq(""), true, StrEq("client"), StrEq("user"),
219                                              StrEq("privilege")))
220         .WillOnce(Return(CYNARA_API_SUCCESS));
221
222     dispatcher.execute(command);
223 }
224
225 TEST_F(CyadCommandlineDispatcherTest, check) {
226     using ::testing::_;
227     using ::testing::DoAll;
228     using ::testing::NotNull;
229     using ::testing::Return;
230     using ::testing::SetArgPointee;
231     using ::testing::StrEq;
232
233     Cynara::CommandsDispatcher dispatcher(m_io, m_adminApi, m_errorApi);
234
235     Cynara::CheckCyadCommand command("", true, { "client", "user", "privilege" });
236     int result = 42;
237
238     EXPECT_CALL(m_adminApi, cynara_admin_check(_, StrEq(""), true, StrEq("client"), StrEq("user"),
239                                              StrEq("privilege"), NotNull(), NotNull()))
240         .WillOnce(DoAll(SetArgPointee<6>(result), SetArgPointee<7>(nullptr),
241                         Return(CYNARA_API_SUCCESS)));
242
243     dispatcher.execute(command);
244
245     ASSERT_EQ("42;\n", m_io.coutRaw().str());
246 }
247
248 TEST_F(CyadCommandlineDispatcherTest, checkWithMetadata) {
249     using ::testing::_;
250     using ::testing::DoAll;
251     using ::testing::NotNull;
252     using ::testing::Return;
253     using ::testing::SetArgPointee;
254     using ::testing::StrEq;
255
256     Cynara::CommandsDispatcher dispatcher(m_io, m_adminApi, m_errorApi);
257
258     Cynara::CheckCyadCommand command("", true, { "client", "user", "privilege" });
259     int result = 42;
260     char *resultExtra = strdup("adams");
261
262     EXPECT_CALL(m_adminApi, cynara_admin_check(_, StrEq(""), true, StrEq("client"), StrEq("user"),
263                                              StrEq("privilege"), NotNull(), NotNull()))
264         .WillOnce(DoAll(SetArgPointee<6>(result), SetArgPointee<7>(resultExtra),
265                         Return(CYNARA_API_SUCCESS)));
266
267     dispatcher.execute(command);
268
269     ASSERT_EQ("42;adams\n", m_io.coutRaw().str());
270 }
271
272 TEST_F(CyadCommandlineDispatcherTest, checkWithError) {
273     using ::testing::_;
274     using ::testing::HasSubstr;
275     using ::testing::Invoke;
276     using ::testing::NotNull;
277     using ::testing::Return;
278     using ::testing::StrEq;
279     using ::testing::Unused;
280
281     Cynara::CommandsDispatcher dispatcher(m_io, m_adminApi, m_errorApi);
282
283     Cynara::CheckCyadCommand command("", true, { "client", "user", "privilege" });
284
285     auto setErrorMessage = [] (Unused, char *buf, std::size_t buflen) {
286         strncpy(buf, "Test error message", buflen);
287     };
288
289     EXPECT_CALL(m_adminApi, cynara_admin_check(_, StrEq(""), true, StrEq("client"), StrEq("user"),
290                                              StrEq("privilege"), NotNull(), NotNull()))
291         .WillOnce(Return(CYNARA_API_UNKNOWN_ERROR));
292
293     // Should we expect some minimal buflen here?
294     EXPECT_CALL(m_errorApi, cynara_strerror(CYNARA_API_UNKNOWN_ERROR, NotNull(), _))
295         .WillOnce(DoAll(Invoke(setErrorMessage), Return(CYNARA_API_SUCCESS)));
296
297     dispatcher.execute(command);
298
299     ASSERT_THAT(m_io.cerrRaw().str(), HasSubstr("Test error message"));
300 }
301
302 TEST_F(CyadCommandlineDispatcherTest, listPoliciesNone) {
303     using ::testing::_;
304     using ::testing::DoAll;
305     using ::testing::NotNull;
306     using ::testing::Return;
307     using ::testing::SetArgPointee;
308     using ::testing::StrEq;
309
310     Cynara::CommandsDispatcher dispatcher(m_io, m_adminApi, m_errorApi);
311
312     Cynara::ListPoliciesCyadCommand command("", { "client", "user", "privilege" });
313
314     Cynara::CynaraAdminPolicies resultPolicies;
315     resultPolicies.seal();
316     auto policies = resultPolicies.duplicate();
317
318     EXPECT_CALL(m_adminApi, cynara_admin_list_policies(_, StrEq(""), StrEq("client"), StrEq("user"),
319                                                      StrEq("privilege"), NotNull()))
320         .WillOnce(DoAll(SetArgPointee<5>(policies), Return(CYNARA_API_SUCCESS)));
321
322     dispatcher.execute(command);
323
324     ASSERT_EQ("", m_io.coutRaw().str());
325 }
326
327 TEST_F(CyadCommandlineDispatcherTest, listPoliciesTwo) {
328     using ::testing::_;
329     using ::testing::DoAll;
330     using ::testing::NotNull;
331     using ::testing::Return;
332     using ::testing::SetArgPointee;
333     using ::testing::StrEq;
334
335     Cynara::CommandsDispatcher dispatcher(m_io, m_adminApi, m_errorApi);
336
337     Cynara::ListPoliciesCyadCommand command("", { "client", "user", "privilege" });
338
339     Cynara::CynaraAdminPolicies resultPolicies;
340     resultPolicies.add("bucket", { CYNARA_ADMIN_DENY, "metadata" }, {"cli", "usr", "privilege"} );
341     resultPolicies.add("bucket-2", { CYNARA_ADMIN_ALLOW, "" }, {"cli", "usr", "privilege"} );
342     resultPolicies.seal();
343     auto policies = resultPolicies.duplicate();
344
345     EXPECT_CALL(m_adminApi, cynara_admin_list_policies(_, StrEq(""), StrEq("client"), StrEq("user"),
346                                                      StrEq("privilege"), NotNull()))
347         .WillOnce(DoAll(SetArgPointee<5>(policies), Return(CYNARA_API_SUCCESS)));
348
349     dispatcher.execute(command);
350
351     ASSERT_EQ("bucket;cli;usr;privilege;0;metadata\nbucket-2;cli;usr;privilege;65535;\n",
352               m_io.coutRaw().str());
353 }
354
355 TEST_F(CyadCommandlineDispatcherTest, listPoliciesDesc) {
356     using ::testing::_;
357     using ::testing::DoAll;
358     using ::testing::NotNull;
359     using ::testing::Return;
360     using ::testing::SetArgPointee;
361     using ::testing::HasSubstr;
362
363     addDescriptions({ { 42, "adams" } });
364
365     Cynara::CommandsDispatcher dispatcher(m_io, m_adminApi, m_errorApi);
366
367     Cynara::ListPoliciesDescCyadCommand command;
368     dispatcher.execute(command);
369
370     EXPECT_THAT(m_io.coutRaw().str(), HasSubstr("42;adams\n"));
371 }