blob: 9d0d1560444ded9f3db6ae290677e4e18057ad6c [file] [log] [blame]
Borawski.Lukaszaecb47a2018-01-25 12:14:14 +01001#include "privileges.hpp"
2#include <fstream>
3#include <string>
4#include "nlohmann/json.hpp"
5#include "gmock/gmock.h"
6
7using namespace redfish;
8
9class PrivilegeTest : public testing::Test {
10 protected:
11 nlohmann::json privilegeRegistryMockJson;
12
13 std::vector<std::string> expectedBasePrivileges{
14 "Login", "ConfigureManager", "ConfigureUsers", "ConfigureComponents",
15 "ConfigureSelf"};
16
17 std::vector<std::string> expectedOEMPrivileges{"OEMRoot", "OEMDummy"};
18
19 PrivilegeTest() {
20 crow::logger::setLogLevel(crow::LogLevel::CRITICAL);
21
22 std::ofstream privilegeRegistryMockOfstream("privilege_registry_mock.json");
23 privilegeRegistryMockJson = nlohmann::json::parse(
24 "{\
25 \"@Redfish.Copyright\": \"Dummy copyright\",\
26 \"@odata.type\": \"#PrivilegeRegistry.v1_0_0.PrivilegeRegistry\",\
27 \"Id\": \"Dummy id\",\
28 \"Name\": \"Dummy name\",\
29 \"PrivilegesUsed\": [\
30 \"Login\",\
31 \"ConfigureManager\",\
32 \"ConfigureUsers\",\
33 \"ConfigureComponents\",\
34 \"ConfigureSelf\"],\
35 \"OEMPrivilegesUsed\": [\
36 \"OEMRoot\",\
37 \"OEMDummy\"],\
38 \"Mappings\": [\
39 {\
40 \"Entity\": \"TestEntity\",\
41 \"OperationMap\": {\
42 \"GET\": [\
43 {\
44 \"Privilege\": [\
45 \"Login\"\
46 ]\
47 }\
48 ],\
49 \"PATCH\": [\
50 {\
51 \"Privilege\": [\
52 \"ConfigureManager\"\
53 ]\
54 },\
55 {\
56 \"Privilege\": [\
57 \"ConfigureUser\",\
58 \"ConfigureDummy\",\
59 \"OEMRoot\"\
60 ]\
61 }\
62 ],\
63 \"POST\": [\
64 {\
65 \"Privilege\": [\
66 \"ConfigureManager\",\
67 \"OEMDummy\"\
68 ]\
69 }\
70 ],\
71 \"DELETE\": [\
72 {\
73 \"Privilege\": [\
74 \"ConfigureManager\"\
75 ]\
76 }\
77 ]\
78 }\
79 },\
80 {\
81 \"Entity\": \"EntityWithNonStringPrivilege\",\
82 \"OperationMap\": {\
83 \"GET\": [\
84 {\
85 \"Privilege\": [\"Login\"]\
86 }\
87 ],\
88 \"POST\": [\
89 {\
90 \"Privilege\": [1]\
91 }\
92 ]\
93 }\
94 }\
95 ]\
96 }");
97 privilegeRegistryMockOfstream << std::setw(4) << privilegeRegistryMockJson
98 << std::endl;
99 privilegeRegistryMockOfstream.close();
100 }
101
102 virtual ~PrivilegeTest() { std::remove("privilege_registry_mock.json"); }
103
104 void removeFieldFromRegistry(const std::string& field) {
105 std::ifstream in("privilege_registry_mock.json");
106 nlohmann::json tempJson = nlohmann::json::parse(in);
107 in.close();
108
109 tempJson.erase(field);
110
111 std::ofstream out("privilege_registry_mock.json");
112 out << std::setw(4) << tempJson << std::endl;
113 out.close();
114 }
115
116 void removeFieldFromMappings(const std::string& field) {
117 std::ifstream in("privilege_registry_mock.json");
118 nlohmann::json tempJson = nlohmann::json::parse(in);
119 in.close();
120
121 tempJson.at("Mappings")[0].erase(field);
122
123 std::ofstream out("privilege_registry_mock.json");
124 out << std::setw(4) << tempJson << std::endl;
125 out.close();
126 }
127
128 void clearArryInJson(const std::string& key) {
129 std::ifstream in("privilege_registry_mock.json");
130 nlohmann::json tempJson = nlohmann::json::parse(in);
131 in.close();
132
133 tempJson[key].clear();
134
135 std::ofstream out("privilege_registry_mock.json");
136 out << std::setw(4) << tempJson << std::endl;
137 out.close();
138 }
139
140 template <typename T>
141 void fillPrivilegeArray(const std::string& key,
142 const std::vector<T>& values) {
143 std::ifstream in("privilege_registry_mock.json");
144 nlohmann::json tempJson = nlohmann::json::parse(in);
145 in.close();
146
147 tempJson[key].clear();
148 for (const auto& value : values) {
149 tempJson[key].push_back(value);
150 }
151
152 std::ofstream out("privilege_registry_mock.json");
153 out << std::setw(4) << tempJson << std::endl;
154 out.close();
155 }
156
157 template <typename T>
158 void addRequiredPrivilege(const T& value) {
159 std::ifstream in("privilege_registry_mock.json");
160 nlohmann::json tempJson = nlohmann::json::parse(in);
161 in.close();
162
163 tempJson["Mappings"][0]["OperationMap"]["GET"][0]["Privilege"].push_back(
164 value);
165
166 std::ofstream out("privilege_registry_mock.json");
167 out << std::setw(4) << tempJson << std::endl;
168 out.close();
169 }
170
171 bool isPrivilegeRegistryParsed(const EntityPrivileges& entityPrivileges) {
172 auto userPrivileges = Privileges();
173 userPrivileges.setSinglePrivilege("Login");
174 // given the privileges_registry_mock.json, GET should be allowed with Login
175 // if the file got parsed successfully
176 return entityPrivileges.isMethodAllowedWithPrivileges(crow::HTTPMethod::GET,
177 userPrivileges);
178 }
179};
180
181TEST_F(PrivilegeTest, PrivilegeRegistryJsonSuccessfullParse) {
182 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
183 auto entityPrivileges =
184 privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
185 EXPECT_TRUE(isPrivilegeRegistryParsed(entityPrivileges));
186}
187
188TEST_F(PrivilegeTest, PrivilegeRegistryJsonNotFound) {
189 std::remove("privilege_registry_mock.json");
190 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
191 auto entityPrivileges =
192 privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
193 EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
194}
195
196TEST_F(PrivilegeTest, PrivilegeRegistryMissingCopyright) {
197 removeFieldFromRegistry("@Redfish.Copyright");
198 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
199 auto entityPrivileges =
200 privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
201 EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
202}
203
204TEST_F(PrivilegeTest, PrivilegeRegistryMissingOdataType) {
205 removeFieldFromRegistry("@odata.type");
206 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
207 auto entityPrivileges =
208 privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
209 EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
210}
211
212TEST_F(PrivilegeTest, PrivilegeRegistryMissingId) {
213 removeFieldFromRegistry("Id");
214 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
215 auto entityPrivileges =
216 privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
217 EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
218}
219
220TEST_F(PrivilegeTest, PrivilegeRegistryMissingName) {
221 removeFieldFromRegistry("Name");
222 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
223 auto entityPrivileges =
224 privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
225 EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
226}
227
228TEST_F(PrivilegeTest, PrivilegeRegistryMissingMappings) {
229 removeFieldFromRegistry("Mappings");
230 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
231 auto entityPrivileges =
232 privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
233 EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
234}
235
236TEST_F(PrivilegeTest, PrivilegeRegistryMissingPrivilegesUsed) {
237 removeFieldFromRegistry("PrivilegesUsed");
238 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
239 auto entityPrivileges =
240 privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
241 EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
242}
243
244TEST_F(PrivilegeTest, PrivilegeRegistryMissingOEMPrivilegesUsed) {
245 removeFieldFromRegistry("OEMPrivilegesUsed");
246 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
247 auto entityPrivileges =
248 privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
249 EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
250}
251
252TEST_F(PrivilegeTest, PrivilegeRegistryMissingOperationMap) {
253 removeFieldFromMappings("OperationMap");
254 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
255
256 auto entityPrivileges =
257 privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
258 EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
259}
260
261TEST_F(PrivilegeTest, PrivilegeRegistryPrivilegesUsedMayNotBeEmpty) {
262 clearArryInJson("PrivilegesUsed");
263 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
264 auto entityPrivileges =
265 privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
266 EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
267}
268
269TEST_F(PrivilegeTest, PrivilegeRegistryOEMPrivilegesUsedMayByEmpty) {
270 clearArryInJson("OEMPrivilegesUsed");
271 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
272 auto entityPrivileges =
273 privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
274 EXPECT_TRUE(isPrivilegeRegistryParsed(entityPrivileges));
275}
276
277TEST_F(PrivilegeTest, PrivilegeValuesMayOnlyBeStrings) {
278 std::vector<int> privilegesUsed = {1, 3, 4};
279 fillPrivilegeArray("PrivilegesUsed", privilegesUsed);
280
281 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
282 auto entityPrivileges =
283 privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
284 EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
285}
286
287TEST_F(PrivilegeTest, OnlyMaxNoOfBasePrivilegesGetsLoaded) {
288 const std::string excessivePrivilege("ExcessivePrivilege");
289 std::vector<std::string> privilegesUsed;
290
291 for (int i = 0; i < MAX_PRIVILEGE_COUNT; i++) {
292 privilegesUsed.push_back(std::to_string(i));
293 }
294 privilegesUsed.push_back(excessivePrivilege);
295
296 fillPrivilegeArray("PrivilegesUsed", privilegesUsed);
297 addRequiredPrivilege(excessivePrivilege);
298
299 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
300
301 Privileges privileges;
302 privileges.setSinglePrivilege(excessivePrivilege);
303
304 EXPECT_EQ(privileges.getBasePrivilegeBitset(), 0);
305}
306
307TEST_F(PrivilegeTest, OnlyMaxNoOfOEMPrivilegesGetsLoaded) {
308 const std::string excessivePrivilege("ExcessivePrivilege");
309 std::vector<std::string> privilegesUsed;
310
311 for (int i = 0; i < MAX_PRIVILEGE_COUNT; i++) {
312 privilegesUsed.push_back(std::to_string(i));
313 }
314 privilegesUsed.push_back(excessivePrivilege);
315
316 fillPrivilegeArray("OEMPrivilegesUsed", privilegesUsed);
317 addRequiredPrivilege(excessivePrivilege);
318
319 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
320
321 Privileges privileges;
322 privileges.setSinglePrivilege(excessivePrivilege);
323
324 EXPECT_EQ(privileges.getOEMPrivilegeBitset(), 0);
325}
326
327TEST_F(PrivilegeTest, LoadEntityPrivilegesForExistingEntity) {
328 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
329 auto entityPrivileges =
330 privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
331 EXPECT_TRUE(isPrivilegeRegistryParsed(entityPrivileges));
332}
333
334TEST_F(PrivilegeTest, LoadEntityPrivilegesForNonExistingEntity) {
335 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
336 auto entityPrivileges =
337 privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.NotExists");
338 EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
339}
340
341TEST_F(PrivilegeTest, LoadEntityPrivilegesForEntityWithNonStringPrivilege) {
342 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
343 auto entityPrivileges = privilegeProvider.getPrivilegesRequiredByEntity(
344 "", "foo.bar.EntityWithNonStringPrivilege");
345 EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
346}
347
348TEST_F(PrivilegeTest, DefaultEntityPrivilegesDenyAccess) {
349 auto entityPrivileges = EntityPrivileges();
350
351 auto res =
352 entityPrivileges.isMethodAllowedForUser(crow::HTTPMethod::GET, "user");
353 EXPECT_FALSE(res);
354}
355
356TEST_F(PrivilegeTest, PrivilegeCheckForSingleCaseSuccess) {
357 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
358
359 auto entityPrivileges = EntityPrivileges();
360 auto userPrivileges = Privileges();
361 auto requiredPrivileges = Privileges();
362
363 userPrivileges.setSinglePrivilege("Login");
364 requiredPrivileges.setSinglePrivilege("Login");
365 entityPrivileges.addPrivilegesRequiredByMethod(crow::HTTPMethod::GET,
366 requiredPrivileges);
367 EXPECT_TRUE(entityPrivileges.isMethodAllowedWithPrivileges(
368 crow::HTTPMethod::GET, userPrivileges));
369}
370
371TEST_F(PrivilegeTest, PrivilegeCheckForSingleCaseFailure) {
372 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
373
374 auto entityPrivileges = EntityPrivileges();
375 auto userPrivileges = Privileges();
376 auto requiredPrivileges = Privileges();
377
378 userPrivileges.setSinglePrivilege("Login");
379 requiredPrivileges.setSinglePrivilege("ConfigureManager");
380 entityPrivileges.addPrivilegesRequiredByMethod(crow::HTTPMethod::GET,
381 requiredPrivileges);
382 EXPECT_FALSE(entityPrivileges.isMethodAllowedWithPrivileges(
383 crow::HTTPMethod::GET, userPrivileges));
384}
385
386TEST_F(PrivilegeTest, PrivilegeCheckForANDCaseSuccess) {
387 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
388
389 auto entityPrivileges = EntityPrivileges();
390 auto userPrivileges = Privileges();
391 auto requiredPrivileges = Privileges();
392
393 userPrivileges.setSinglePrivilege("Login");
394 userPrivileges.setSinglePrivilege("ConfigureManager");
395 userPrivileges.setSinglePrivilege("OEMRoot");
396 requiredPrivileges.setSinglePrivilege("Login");
397 requiredPrivileges.setSinglePrivilege("ConfigureManager");
398 requiredPrivileges.setSinglePrivilege("OEMRoot");
399 entityPrivileges.addPrivilegesRequiredByMethod(crow::HTTPMethod::GET,
400 requiredPrivileges);
401 EXPECT_TRUE(entityPrivileges.isMethodAllowedWithPrivileges(
402 crow::HTTPMethod::GET, userPrivileges));
403}
404
405TEST_F(PrivilegeTest, PrivilegeCheckForANDCaseFailure) {
406 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
407
408 auto entityPrivileges = EntityPrivileges();
409 auto userPrivileges = Privileges();
410 auto requiredPrivileges = Privileges();
411
412 userPrivileges.setSinglePrivilege("Login");
413 userPrivileges.setSinglePrivilege("ConfigureUsers");
414 requiredPrivileges.setSinglePrivilege("Login");
415 requiredPrivileges.setSinglePrivilege("OEMDummy");
416 requiredPrivileges.setSinglePrivilege("ConfigureUsers");
417 entityPrivileges.addPrivilegesRequiredByMethod(crow::HTTPMethod::GET,
418 requiredPrivileges);
419 EXPECT_FALSE(entityPrivileges.isMethodAllowedWithPrivileges(
420 crow::HTTPMethod::GET, userPrivileges));
421}
422
423TEST_F(PrivilegeTest, PrivilegeCheckForORCaseSuccess) {
424 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
425
426 auto entityPrivileges = EntityPrivileges();
427 auto userPrivileges = Privileges();
428 auto requiredPrivileges = Privileges();
429
430 userPrivileges.setSinglePrivilege("OEMRoot");
431 requiredPrivileges.setSinglePrivilege("Login");
432 entityPrivileges.addPrivilegesRequiredByMethod(crow::HTTPMethod::GET,
433 requiredPrivileges);
434 requiredPrivileges = Privileges();
435 requiredPrivileges.setSinglePrivilege("OEMRoot");
436 entityPrivileges.addPrivilegesRequiredByMethod(crow::HTTPMethod::GET,
437 requiredPrivileges);
438 EXPECT_TRUE(entityPrivileges.isMethodAllowedWithPrivileges(
439 crow::HTTPMethod::GET, userPrivileges));
440}
441
442TEST_F(PrivilegeTest, PrivilegeCheckForORCaseFailure) {
443 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
444
445 auto entityPrivileges = EntityPrivileges();
446 auto userPrivileges = Privileges();
447 auto requiredPrivileges = Privileges();
448
449 userPrivileges.setSinglePrivilege("ConfigureComponents");
450 requiredPrivileges.setSinglePrivilege("Login");
451 entityPrivileges.addPrivilegesRequiredByMethod(crow::HTTPMethod::GET,
452 requiredPrivileges);
453 requiredPrivileges = Privileges();
454 requiredPrivileges.setSinglePrivilege("ConfigureManager");
455 entityPrivileges.addPrivilegesRequiredByMethod(crow::HTTPMethod::GET,
456 requiredPrivileges);
457 EXPECT_FALSE(entityPrivileges.isMethodAllowedWithPrivileges(
458 crow::HTTPMethod::GET, userPrivileges));
459}
460
461TEST_F(PrivilegeTest, DefaultPrivilegeBitsetsAreEmpty) {
462 Privileges privileges;
463 EXPECT_TRUE(privileges.getBasePrivilegeBitset() == 0);
464 EXPECT_TRUE(privileges.getOEMPrivilegeBitset() == 0);
465}
466
467TEST_F(PrivilegeTest, UniqueBitsAssignedForAllPrivilegeNames) {
468 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
469
470 Privileges privileges;
471
472 for (const auto& privilege : expectedBasePrivileges) {
473 privileges.setSinglePrivilege(privilege);
474 }
475
476 for (const auto& privilege : expectedOEMPrivileges) {
477 privileges.setSinglePrivilege(privilege);
478 }
479
480 EXPECT_EQ(privileges.getBasePrivilegeBitset().count(),
481 expectedBasePrivileges.size());
482 EXPECT_EQ(privileges.getOEMPrivilegeBitset().count(),
483 expectedOEMPrivileges.size());
484}
485
486TEST_F(PrivilegeTest, GetActiveBasePrivilegeNames) {
487 Privileges privileges;
488
489 EXPECT_EQ(privileges.getActivePrivilegeNames(PrivilegeType::BASE),
490 std::vector<std::string>());
491
492 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
493
494 for (const auto& privilege : expectedBasePrivileges) {
495 privileges.setSinglePrivilege(privilege);
496 }
497
498 std::vector<std::string> activePrivileges =
499 privileges.getActivePrivilegeNames(PrivilegeType::BASE);
500
501 std::sort(expectedBasePrivileges.begin(), expectedBasePrivileges.end());
502 std::sort(activePrivileges.begin(), activePrivileges.end());
503
504 EXPECT_EQ(activePrivileges, expectedBasePrivileges);
505}
506
507TEST_F(PrivilegeTest, GetActiveOEMPrivilegeNames) {
508 Privileges privileges;
509
510 EXPECT_EQ(privileges.getActivePrivilegeNames(PrivilegeType::OEM),
511 std::vector<std::string>());
512
513 PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
514
515 for (const auto& privilege : expectedOEMPrivileges) {
516 privileges.setSinglePrivilege(privilege);
517 }
518
519 std::vector<std::string> activePrivileges =
520 privileges.getActivePrivilegeNames(PrivilegeType::OEM);
521
522 std::sort(expectedOEMPrivileges.begin(), expectedOEMPrivileges.end());
523 std::sort(activePrivileges.begin(), activePrivileges.end());
524
525 EXPECT_EQ(activePrivileges, expectedOEMPrivileges);
526}