xref: /openbmc/bmcweb/redfish-core/src/utils/json_utils.cpp (revision 4859bdbafbb2b78ae414fb050ad197db2f2cb28b)
1 /*
2 // Copyright (c) 2018 Intel Corporation
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 #include "utils/json_utils.hpp"
17 #include <error_messages.hpp>
18 
19 namespace redfish {
20 
21 namespace json_util {
22 
23 Result getString(const char* fieldName, const nlohmann::json& json,
24                  const std::string*& output) {
25   // Find field
26   auto fieldIt = json.find(fieldName);
27 
28   // Verify existence
29   if (fieldIt == json.end()) {
30     return Result::NOT_EXIST;
31   }
32 
33   output = fieldIt->get_ptr<const std::string*>();
34 
35   // Verify type - we know that it exists, so nullptr means wrong type
36   if (output == nullptr) {
37     return Result::WRONG_TYPE;
38   }
39 
40   return Result::SUCCESS;
41 }
42 
43 Result getObject(const char* fieldName, const nlohmann::json& json,
44                  nlohmann::json* output) {
45   // Verify input pointer
46   if (output == nullptr) {
47     return Result::NULL_POINTER;
48   }
49 
50   // Find field
51   auto fieldIt = json.find(fieldName);
52 
53   // Verify existence
54   if (fieldIt == json.end()) {
55     return Result::NOT_EXIST;
56   }
57 
58   // Verify type
59   if (!fieldIt->is_object()) {
60     return Result::WRONG_TYPE;
61   }
62 
63   // Extract value
64   *output = *fieldIt;
65 
66   return Result::SUCCESS;
67 }
68 
69 Result getArray(const char* fieldName, const nlohmann::json& json,
70                 nlohmann::json* output) {
71   // Verify input pointer
72   if (output == nullptr) {
73     return Result::NULL_POINTER;
74   }
75 
76   // Find field
77   auto fieldIt = json.find(fieldName);
78 
79   // Verify existence
80   if (fieldIt == json.end()) {
81     return Result::NOT_EXIST;
82   }
83 
84   // Verify type
85   if (!fieldIt->is_array()) {
86     return Result::WRONG_TYPE;
87   }
88 
89   // Extract value
90   *output = *fieldIt;
91 
92   return Result::SUCCESS;
93 }
94 
95 Result getInt(const char* fieldName, const nlohmann::json& json,
96               int64_t& output) {
97   // Find field
98   auto fieldIt = json.find(fieldName);
99 
100   // Verify existence
101   if (fieldIt == json.end()) {
102     return Result::NOT_EXIST;
103   }
104 
105   const int64_t* retVal = fieldIt->get_ptr<const int64_t*>();
106 
107   // Verify type - we know that it exists, so nullptr means wrong type
108   if (retVal == nullptr) {
109     return Result::WRONG_TYPE;
110   }
111 
112   // Extract value
113   output = *retVal;
114 
115   return Result::SUCCESS;
116 }
117 
118 Result getUnsigned(const char* fieldName, const nlohmann::json& json,
119                    uint64_t& output) {
120   // Find field
121   auto fieldIt = json.find(fieldName);
122 
123   // Verify existence
124   if (fieldIt == json.end()) {
125     return Result::NOT_EXIST;
126   }
127 
128   const uint64_t* retVal = fieldIt->get_ptr<const uint64_t*>();
129 
130   // Verify type - we know that it exists, so nullptr means wrong type
131   if (retVal == nullptr) {
132     return Result::WRONG_TYPE;
133   }
134 
135   // Extract value
136   output = *retVal;
137 
138   return Result::SUCCESS;
139 }
140 
141 Result getBool(const char* fieldName, const nlohmann::json& json,
142                bool& output) {
143   // Find field
144   auto fieldIt = json.find(fieldName);
145 
146   // Verify existence
147   if (fieldIt == json.end()) {
148     return Result::NOT_EXIST;
149   }
150 
151   const bool* retVal = fieldIt->get_ptr<const bool*>();
152 
153   // Verify type - we know that it exists, so nullptr means wrong type
154   if (retVal == nullptr) {
155     return Result::WRONG_TYPE;
156   }
157 
158   // Extract value
159   output = *retVal;
160 
161   return Result::SUCCESS;
162 }
163 
164 Result getDouble(const char* fieldName, const nlohmann::json& json,
165                  double& output) {
166   // Find field
167   auto fieldIt = json.find(fieldName);
168 
169   // Verify existence
170   if (fieldIt == json.end()) {
171     return Result::NOT_EXIST;
172   }
173 
174   const double* retVal = fieldIt->get_ptr<const double*>();
175 
176   // Verify type - we know that it exists, so nullptr means wrong type
177   if (retVal == nullptr) {
178     return Result::WRONG_TYPE;
179   }
180 
181   // Extract value
182   output = *retVal;
183 
184   return Result::SUCCESS;
185 }
186 
187 Result getString(const char* fieldName, const nlohmann::json& json,
188                  const std::string*& output, uint8_t msgCfgMap,
189                  nlohmann::json& msgJson, const std::string&& fieldPath) {
190   // Find field
191   auto fieldIt = json.find(fieldName);
192 
193   // Verify existence
194   if (fieldIt == json.end()) {
195     if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
196       messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
197                                  fieldPath);
198     }
199 
200     return Result::NOT_EXIST;
201   }
202 
203   output = fieldIt->get_ptr<const std::string*>();
204 
205   // Verify type - we know that it exists, so nullptr means wrong type
206   if (output == nullptr) {
207     if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
208       messages::addMessageToJson(
209           msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
210           fieldPath);
211     }
212 
213     return Result::WRONG_TYPE;
214   }
215 
216   return Result::SUCCESS;
217 }
218 
219 Result getObject(const char* fieldName, const nlohmann::json& json,
220                  nlohmann::json* output, uint8_t msgCfgMap,
221                  nlohmann::json& msgJson, const std::string&& fieldPath) {
222   // Verify input pointer
223   if (output == nullptr) {
224     return Result::NULL_POINTER;
225   }
226 
227   // Find field
228   auto fieldIt = json.find(fieldName);
229 
230   // Verify existence
231   if (fieldIt == json.end()) {
232     if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
233       messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
234                                  fieldPath);
235     }
236 
237     return Result::NOT_EXIST;
238   }
239 
240   // Verify type
241   if (!fieldIt->is_object()) {
242     if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
243       messages::addMessageToJson(
244           msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
245           fieldPath);
246     }
247 
248     return Result::WRONG_TYPE;
249   }
250 
251   // Extract value
252   *output = *fieldIt;
253 
254   return Result::SUCCESS;
255 }
256 
257 Result getArray(const char* fieldName, const nlohmann::json& json,
258                 nlohmann::json* output, uint8_t msgCfgMap,
259                 nlohmann::json& msgJson, const std::string&& fieldPath) {
260   // Verify input pointer
261   if (output == nullptr) {
262     return Result::NULL_POINTER;
263   }
264 
265   // Find field
266   auto fieldIt = json.find(fieldName);
267 
268   // Verify existence
269   if (fieldIt == json.end()) {
270     if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
271       messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
272                                  fieldPath);
273     }
274 
275     return Result::NOT_EXIST;
276   }
277 
278   // Verify type
279   if (!fieldIt->is_array()) {
280     if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
281       messages::addMessageToJson(
282           msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
283           fieldPath);
284     }
285 
286     return Result::WRONG_TYPE;
287   }
288 
289   // Extract value
290   *output = *fieldIt;
291 
292   return Result::SUCCESS;
293 }
294 
295 Result getInt(const char* fieldName, const nlohmann::json& json,
296               int64_t& output, uint8_t msgCfgMap, nlohmann::json& msgJson,
297               const std::string&& fieldPath) {
298   // Find field
299   auto fieldIt = json.find(fieldName);
300 
301   // Verify existence
302   if (fieldIt == json.end()) {
303     if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
304       messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
305                                  fieldPath);
306     }
307 
308     return Result::NOT_EXIST;
309   }
310 
311   const int64_t* retVal = fieldIt->get_ptr<const int64_t*>();
312 
313   // Verify type - we know that it exists, so nullptr means wrong type
314   if (retVal == nullptr) {
315     if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
316       messages::addMessageToJson(
317           msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
318           fieldPath);
319     }
320 
321     return Result::WRONG_TYPE;
322   }
323 
324   // Extract value
325   output = *retVal;
326 
327   return Result::SUCCESS;
328 }
329 
330 Result getUnsigned(const char* fieldName, const nlohmann::json& json,
331                    uint64_t& output, uint8_t msgCfgMap, nlohmann::json& msgJson,
332                    const std::string&& fieldPath) {
333   // Find field
334   auto fieldIt = json.find(fieldName);
335 
336   // Verify existence
337   if (fieldIt == json.end()) {
338     if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
339       messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
340                                  fieldPath);
341     }
342 
343     return Result::NOT_EXIST;
344   }
345 
346   const uint64_t* retVal = fieldIt->get_ptr<const uint64_t*>();
347 
348   // Verify type - we know that it exists, so nullptr means wrong type
349   if (retVal == nullptr) {
350     if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
351       messages::addMessageToJson(
352           msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
353           fieldPath);
354     }
355 
356     return Result::WRONG_TYPE;
357   }
358 
359   // Extract value
360   output = *retVal;
361 
362   return Result::SUCCESS;
363 }
364 
365 Result getBool(const char* fieldName, const nlohmann::json& json, bool& output,
366                uint8_t msgCfgMap, nlohmann::json& msgJson,
367                const std::string&& fieldPath) {
368   // Find field
369   auto fieldIt = json.find(fieldName);
370 
371   // Verify existence
372   if (fieldIt == json.end()) {
373     if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
374       messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
375                                  fieldPath);
376     }
377 
378     return Result::NOT_EXIST;
379   }
380 
381   const bool* retVal = fieldIt->get_ptr<const bool*>();
382 
383   // Verify type - we know that it exists, so nullptr means wrong type
384   if (retVal == nullptr) {
385     if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
386       messages::addMessageToJson(
387           msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
388           fieldPath);
389     }
390 
391     return Result::WRONG_TYPE;
392   }
393 
394   // Extract value
395   output = *retVal;
396 
397   return Result::SUCCESS;
398 }
399 
400 Result getDouble(const char* fieldName, const nlohmann::json& json,
401                  double& output, uint8_t msgCfgMap, nlohmann::json& msgJson,
402                  const std::string&& fieldPath) {
403   // Find field
404   auto fieldIt = json.find(fieldName);
405 
406   // Verify existence
407   if (fieldIt == json.end()) {
408     if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
409       messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
410                                  fieldPath);
411     }
412 
413     return Result::NOT_EXIST;
414   }
415 
416   const double* retVal = fieldIt->get_ptr<const double*>();
417 
418   // Verify type - we know that it exists, so nullptr means wrong type
419   if (retVal == nullptr) {
420     if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
421       messages::addMessageToJson(
422           msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
423           fieldPath);
424     }
425 
426     return Result::WRONG_TYPE;
427   }
428 
429   // Extract value
430   output = *retVal;
431 
432   return Result::SUCCESS;
433 }
434 
435 bool processJsonFromRequest(crow::Response& res, const crow::Request& req,
436                             nlohmann::json& reqJson) {
437   reqJson = nlohmann::json::parse(req.body, nullptr, false);
438 
439   if (reqJson.is_discarded()) {
440     messages::addMessageToErrorJson(res.jsonValue, messages::malformedJSON());
441 
442     res.result(boost::beast::http::status::bad_request);
443     res.end();
444 
445     return false;
446   }
447 
448   return true;
449 }
450 
451 }  // namespace json_util
452 
453 }  // namespace redfish
454