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