security_events: Fix error caused by DTD validation error
[asterisk/asterisk.git] / res / res_ari_device_states.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2012 - 2013, Digium, Inc.
5  *
6  * Kevin Harwell <kharwell@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*
20  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
21  * !!!!!                               DO NOT EDIT                        !!!!!
22  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
23  * This file is generated by a mustache template. Please see the original
24  * template in rest-api-templates/res_ari_resource.c.mustache
25  */
26
27 /*! \file
28  *
29  * \brief Device state resources
30  *
31  * \author Kevin Harwell <kharwell@digium.com>
32  */
33
34 /*** MODULEINFO
35         <depend type="module">res_ari</depend>
36         <depend type="module">res_stasis</depend>
37         <support_level>core</support_level>
38  ***/
39
40 #include "asterisk.h"
41
42 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
43
44 #include "asterisk/app.h"
45 #include "asterisk/module.h"
46 #include "asterisk/stasis_app.h"
47 #include "ari/resource_device_states.h"
48 #if defined(AST_DEVMODE)
49 #include "ari/ari_model_validators.h"
50 #endif
51
52 #define MAX_VALS 128
53
54 /*!
55  * \brief Parameter parsing callback for /deviceStates.
56  * \param get_params GET parameters in the HTTP request.
57  * \param path_vars Path variables extracted from the request.
58  * \param headers HTTP headers.
59  * \param[out] response Response to the HTTP request.
60  */
61 static void ast_ari_device_states_list_cb(
62         struct ast_tcptls_session_instance *ser,
63         struct ast_variable *get_params, struct ast_variable *path_vars,
64         struct ast_variable *headers, struct ast_ari_response *response)
65 {
66         struct ast_ari_device_states_list_args args = {};
67         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
68 #if defined(AST_DEVMODE)
69         int is_valid;
70         int code;
71 #endif /* AST_DEVMODE */
72
73         ast_ari_device_states_list(headers, &args, response);
74 #if defined(AST_DEVMODE)
75         code = response->response_code;
76
77         switch (code) {
78         case 0: /* Implementation is still a stub, or the code wasn't set */
79                 is_valid = response->message == NULL;
80                 break;
81         case 500: /* Internal Server Error */
82         case 501: /* Not Implemented */
83                 is_valid = 1;
84                 break;
85         default:
86                 if (200 <= code && code <= 299) {
87                         is_valid = ast_ari_validate_list(response->message,
88                                 ast_ari_validate_device_state_fn());
89                 } else {
90                         ast_log(LOG_ERROR, "Invalid error response %d for /deviceStates\n", code);
91                         is_valid = 0;
92                 }
93         }
94
95         if (!is_valid) {
96                 ast_log(LOG_ERROR, "Response validation failed for /deviceStates\n");
97                 ast_ari_response_error(response, 500,
98                         "Internal Server Error", "Response validation failed");
99         }
100 #endif /* AST_DEVMODE */
101
102 fin: __attribute__((unused))
103         return;
104 }
105 /*!
106  * \brief Parameter parsing callback for /deviceStates/{deviceName}.
107  * \param get_params GET parameters in the HTTP request.
108  * \param path_vars Path variables extracted from the request.
109  * \param headers HTTP headers.
110  * \param[out] response Response to the HTTP request.
111  */
112 static void ast_ari_device_states_get_cb(
113         struct ast_tcptls_session_instance *ser,
114         struct ast_variable *get_params, struct ast_variable *path_vars,
115         struct ast_variable *headers, struct ast_ari_response *response)
116 {
117         struct ast_ari_device_states_get_args args = {};
118         struct ast_variable *i;
119         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
120 #if defined(AST_DEVMODE)
121         int is_valid;
122         int code;
123 #endif /* AST_DEVMODE */
124
125         for (i = path_vars; i; i = i->next) {
126                 if (strcmp(i->name, "deviceName") == 0) {
127                         args.device_name = (i->value);
128                 } else
129                 {}
130         }
131         ast_ari_device_states_get(headers, &args, response);
132 #if defined(AST_DEVMODE)
133         code = response->response_code;
134
135         switch (code) {
136         case 0: /* Implementation is still a stub, or the code wasn't set */
137                 is_valid = response->message == NULL;
138                 break;
139         case 500: /* Internal Server Error */
140         case 501: /* Not Implemented */
141                 is_valid = 1;
142                 break;
143         default:
144                 if (200 <= code && code <= 299) {
145                         is_valid = ast_ari_validate_device_state(
146                                 response->message);
147                 } else {
148                         ast_log(LOG_ERROR, "Invalid error response %d for /deviceStates/{deviceName}\n", code);
149                         is_valid = 0;
150                 }
151         }
152
153         if (!is_valid) {
154                 ast_log(LOG_ERROR, "Response validation failed for /deviceStates/{deviceName}\n");
155                 ast_ari_response_error(response, 500,
156                         "Internal Server Error", "Response validation failed");
157         }
158 #endif /* AST_DEVMODE */
159
160 fin: __attribute__((unused))
161         return;
162 }
163 int ast_ari_device_states_update_parse_body(
164         struct ast_json *body,
165         struct ast_ari_device_states_update_args *args)
166 {
167         struct ast_json *field;
168         /* Parse query parameters out of it */
169         field = ast_json_object_get(body, "deviceState");
170         if (field) {
171                 args->device_state = ast_json_string_get(field);
172         }
173         return 0;
174 }
175
176 /*!
177  * \brief Parameter parsing callback for /deviceStates/{deviceName}.
178  * \param get_params GET parameters in the HTTP request.
179  * \param path_vars Path variables extracted from the request.
180  * \param headers HTTP headers.
181  * \param[out] response Response to the HTTP request.
182  */
183 static void ast_ari_device_states_update_cb(
184         struct ast_tcptls_session_instance *ser,
185         struct ast_variable *get_params, struct ast_variable *path_vars,
186         struct ast_variable *headers, struct ast_ari_response *response)
187 {
188         struct ast_ari_device_states_update_args args = {};
189         struct ast_variable *i;
190         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
191 #if defined(AST_DEVMODE)
192         int is_valid;
193         int code;
194 #endif /* AST_DEVMODE */
195
196         for (i = get_params; i; i = i->next) {
197                 if (strcmp(i->name, "deviceState") == 0) {
198                         args.device_state = (i->value);
199                 } else
200                 {}
201         }
202         for (i = path_vars; i; i = i->next) {
203                 if (strcmp(i->name, "deviceName") == 0) {
204                         args.device_name = (i->value);
205                 } else
206                 {}
207         }
208         /* Look for a JSON request entity */
209         body = ast_http_get_json(ser, headers);
210         if (!body) {
211                 switch (errno) {
212                 case EFBIG:
213                         ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
214                         goto fin;
215                 case ENOMEM:
216                         ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
217                         goto fin;
218                 case EIO:
219                         ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
220                         goto fin;
221                 }
222         }
223         if (ast_ari_device_states_update_parse_body(body, &args)) {
224                 ast_ari_response_alloc_failed(response);
225                 goto fin;
226         }
227         ast_ari_device_states_update(headers, &args, response);
228 #if defined(AST_DEVMODE)
229         code = response->response_code;
230
231         switch (code) {
232         case 0: /* Implementation is still a stub, or the code wasn't set */
233                 is_valid = response->message == NULL;
234                 break;
235         case 500: /* Internal Server Error */
236         case 501: /* Not Implemented */
237         case 404: /* Device name is missing */
238         case 409: /* Uncontrolled device specified */
239                 is_valid = 1;
240                 break;
241         default:
242                 if (200 <= code && code <= 299) {
243                         is_valid = ast_ari_validate_void(
244                                 response->message);
245                 } else {
246                         ast_log(LOG_ERROR, "Invalid error response %d for /deviceStates/{deviceName}\n", code);
247                         is_valid = 0;
248                 }
249         }
250
251         if (!is_valid) {
252                 ast_log(LOG_ERROR, "Response validation failed for /deviceStates/{deviceName}\n");
253                 ast_ari_response_error(response, 500,
254                         "Internal Server Error", "Response validation failed");
255         }
256 #endif /* AST_DEVMODE */
257
258 fin: __attribute__((unused))
259         return;
260 }
261 /*!
262  * \brief Parameter parsing callback for /deviceStates/{deviceName}.
263  * \param get_params GET parameters in the HTTP request.
264  * \param path_vars Path variables extracted from the request.
265  * \param headers HTTP headers.
266  * \param[out] response Response to the HTTP request.
267  */
268 static void ast_ari_device_states_delete_cb(
269         struct ast_tcptls_session_instance *ser,
270         struct ast_variable *get_params, struct ast_variable *path_vars,
271         struct ast_variable *headers, struct ast_ari_response *response)
272 {
273         struct ast_ari_device_states_delete_args args = {};
274         struct ast_variable *i;
275         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
276 #if defined(AST_DEVMODE)
277         int is_valid;
278         int code;
279 #endif /* AST_DEVMODE */
280
281         for (i = path_vars; i; i = i->next) {
282                 if (strcmp(i->name, "deviceName") == 0) {
283                         args.device_name = (i->value);
284                 } else
285                 {}
286         }
287         ast_ari_device_states_delete(headers, &args, response);
288 #if defined(AST_DEVMODE)
289         code = response->response_code;
290
291         switch (code) {
292         case 0: /* Implementation is still a stub, or the code wasn't set */
293                 is_valid = response->message == NULL;
294                 break;
295         case 500: /* Internal Server Error */
296         case 501: /* Not Implemented */
297         case 404: /* Device name is missing */
298         case 409: /* Uncontrolled device specified */
299                 is_valid = 1;
300                 break;
301         default:
302                 if (200 <= code && code <= 299) {
303                         is_valid = ast_ari_validate_void(
304                                 response->message);
305                 } else {
306                         ast_log(LOG_ERROR, "Invalid error response %d for /deviceStates/{deviceName}\n", code);
307                         is_valid = 0;
308                 }
309         }
310
311         if (!is_valid) {
312                 ast_log(LOG_ERROR, "Response validation failed for /deviceStates/{deviceName}\n");
313                 ast_ari_response_error(response, 500,
314                         "Internal Server Error", "Response validation failed");
315         }
316 #endif /* AST_DEVMODE */
317
318 fin: __attribute__((unused))
319         return;
320 }
321
322 /*! \brief REST handler for /api-docs/deviceStates.{format} */
323 static struct stasis_rest_handlers deviceStates_deviceName = {
324         .path_segment = "deviceName",
325         .is_wildcard = 1,
326         .callbacks = {
327                 [AST_HTTP_GET] = ast_ari_device_states_get_cb,
328                 [AST_HTTP_PUT] = ast_ari_device_states_update_cb,
329                 [AST_HTTP_DELETE] = ast_ari_device_states_delete_cb,
330         },
331         .num_children = 0,
332         .children = {  }
333 };
334 /*! \brief REST handler for /api-docs/deviceStates.{format} */
335 static struct stasis_rest_handlers deviceStates = {
336         .path_segment = "deviceStates",
337         .callbacks = {
338                 [AST_HTTP_GET] = ast_ari_device_states_list_cb,
339         },
340         .num_children = 1,
341         .children = { &deviceStates_deviceName, }
342 };
343
344 static int load_module(void)
345 {
346         int res = 0;
347         stasis_app_ref();
348         res |= ast_ari_add_handler(&deviceStates);
349         return res;
350 }
351
352 static int unload_module(void)
353 {
354         ast_ari_remove_handler(&deviceStates);
355         stasis_app_unref();
356         return 0;
357 }
358
359 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Device state resources",
360         .load = load_module,
361         .unload = unload_module,
362         .nonoptreq = "res_ari,res_stasis",
363         );