Asterisk - The Open Source Telephony Project  18.5.0
res_ari_model.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * David M. Lee, II <[email protected]>
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 /*! \file
20  *
21  * \brief Implementation Swagger validators.
22  *
23  * \author David M. Lee, II <[email protected]>
24  */
25 
26 /*** MODULEINFO
27  <support_level>core</support_level>
28  ***/
29 
30 #include "asterisk.h"
31 
33 #include "asterisk/logger.h"
34 #include "asterisk/module.h"
35 #include "asterisk/utils.h"
36 
37 #include <regex.h>
38 
39 /* Regex to match date strings */
40 static regex_t date_regex;
41 
42 /* Regex for YYYY-MM-DD */
43 #define REGEX_YMD "[0-9]{4}-[01][0-9]-[0-3][0-9]"
44 
45 /* Regex for hh:mm(:ss(.s)); seconds and subseconds optional
46  * Handles the probably impossible case of a leap second, too */
47 #define REGEX_HMS "[0-2][0-9]:[0-5][0-9](:[0-6][0-9](.[0-9]+)?)?"
48 
49 /* Regex for timezone: (+|-)hh(:mm), with optional colon. */
50 #define REGEX_TZ "(Z|[-+][0-2][0-9](:?[0-5][0-9])?)"
51 
52 /* REGEX for ISO 8601, the time specifier optional */
53 #define ISO8601_PATTERN "^" REGEX_YMD "(T" REGEX_HMS REGEX_TZ ")?$"
54 
55 static int check_type(struct ast_json *json, enum ast_json_type expected)
56 {
57  enum ast_json_type actual;
58 
59  if (!json) {
60  ast_log(LOG_ERROR, "Expected type %s, was NULL\n",
61  ast_json_typename(expected));
62  return 0;
63  }
64 
65  actual = ast_json_typeof(json);
66  if (expected != actual) {
67  ast_log(LOG_ERROR, "Expected type %s, was %s\n",
68  ast_json_typename(expected), ast_json_typename(actual));
69  return 0;
70  }
71  return 1;
72 }
73 
74 static int check_range(intmax_t minval, intmax_t maxval, struct ast_json *json)
75 {
76  intmax_t v;
77 
78  if (!check_type(json, AST_JSON_INTEGER)) {
79  return 0;
80  }
81 
82  v = ast_json_integer_get(json);
83 
84  if (v < minval || maxval < v) {
85  ast_log(LOG_ERROR, "Value out of range. Expected %jd <= %jd <= %jd\n", minval, v, maxval);
86  return 0;
87  }
88  return 1;
89 }
90 
92 {
93  return check_type(json, AST_JSON_NULL);
94 }
95 
97 {
98  return check_type(json, AST_JSON_OBJECT);
99 }
100 
102 {
103  /* Java bytes are signed, which accounts for great fun for all */
104  return check_range(-128, 255, json);
105 }
106 
108 {
109  enum ast_json_type actual = ast_json_typeof(json);
110  switch (actual) {
111  case AST_JSON_TRUE:
112  case AST_JSON_FALSE:
113  return 1;
114  default:
115  ast_log(LOG_ERROR, "Expected type boolean, was %s\n",
116  ast_json_typename(actual));
117  return 0;
118  }
119 }
120 
122 {
123  /* Swagger int's are 32-bit */
124  return check_range(-2147483648LL, 2147483647LL, json);
125 }
126 
128 {
129  /* All integral values are valid longs. No need for range check. */
130  return check_type(json, AST_JSON_INTEGER);
131 }
132 
134 {
135  return check_type(json, AST_JSON_REAL);
136 }
137 
139 {
140  return check_type(json, AST_JSON_REAL);
141 }
142 
144 {
145  return check_type(json, AST_JSON_STRING);
146 }
147 
149 {
150  /* Dates are ISO-8601 strings */
151  const char *str;
152  if (!check_type(json, AST_JSON_STRING)) {
153  return 0;
154  }
155  str = ast_json_string_get(json);
156  ast_assert(str != NULL);
157  if (regexec(&date_regex, str, 0, NULL, 0) != 0) {
158  ast_log(LOG_ERROR, "Date field is malformed: '%s'\n", str);
159  return 0;
160  }
161  return 1;
162 }
163 
164 int ast_ari_validate_list(struct ast_json *json, int (*fn)(struct ast_json *))
165 {
166  int res = 1;
167  size_t i;
168 
169  if (!check_type(json, AST_JSON_ARRAY)) {
170  return 0;
171  }
172 
173  for (i = 0; i < ast_json_array_size(json); ++i) {
174  int member_res;
175  member_res = fn(ast_json_array_get(json, i));
176  if (!member_res) {
178  "Array member %zu failed validation\n", i);
179  res = 0;
180  }
181  }
182 
183  return res;
184 }
185 
186 static int load_module(void)
187 {
188  int res;
189  res = regcomp(&date_regex, ISO8601_PATTERN,
190  REG_EXTENDED | REG_ICASE | REG_NOSUB);
191 
192  if (res != 0) {
194  }
196 }
197 
198 static int unload_module(void)
199 {
200  regfree(&date_regex);
201  return 0;
202 }
203 
205  .support_level = AST_MODULE_SUPPORT_CORE,
206  .load = load_module,
207  .unload = unload_module,
208  .load_pri = AST_MODPRI_APP_DEPEND,
209 );
Asterisk main include file. File version handling, generic pbx functions.
int ast_ari_validate_void(struct ast_json *json)
Validator for native Swagger void.
Definition: res_ari_model.c:91
int ast_ari_validate_long(struct ast_json *json)
Validator for native Swagger long.
ast_json_type
Valid types of a JSON element.
Definition: json.h:162
int ast_ari_validate_float(struct ast_json *json)
Validator for native Swagger float.
static regex_t date_regex
Definition: res_ari_model.c:40
#define ast_assert(a)
Definition: utils.h:695
Generated file - Build validators for ARI model objects.
const char * str
Definition: app_jack.c:147
int ast_ari_validate_byte(struct ast_json *json)
Validator for native Swagger byte.
#define NULL
Definition: resample.c:96
Utility functions.
static int load_module(void)
static int check_type(struct ast_json *json, enum ast_json_type expected)
Definition: res_ari_model.c:55
#define ast_log
Definition: astobj2.c:42
int ast_ari_validate_double(struct ast_json *json)
Validator for native Swagger double.
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:273
int ast_ari_validate_date(struct ast_json *json)
Validator for native Swagger date.
int ast_ari_validate_object(struct ast_json *json)
Validator for native Swagger object.
Definition: res_ari_model.c:96
static int check_range(intmax_t minval, intmax_t maxval, struct ast_json *json)
Definition: res_ari_model.c:74
int ast_ari_validate_int(struct ast_json *json)
Validator for native Swagger int.
#define LOG_ERROR
Definition: logger.h:285
#define ISO8601_PATTERN
Definition: res_ari_model.c:53
int ast_ari_validate_boolean(struct ast_json *json)
Validator for native Swagger boolean.
enum ast_json_type ast_json_typeof(const struct ast_json *value)
Get the type of value.
Definition: json.c:78
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
const char * ast_json_typename(enum ast_json_type type)
Get the string name for the given type.
Definition: json.c:95
Support for logging to various files, console and syslog Configuration in file logger.conf.
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
size_t ast_json_array_size(const struct ast_json *array)
Get the size of a JSON array.
Definition: json.c:356
Abstract JSON element (object, array, string, int, ...).
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Asterisk module definitions.
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
Definition: json.c:322
int ast_ari_validate_list(struct ast_json *json, int(*fn)(struct ast_json *))
Validator for a Swagger List[]/JSON array.
struct ast_json * ast_json_array_get(const struct ast_json *array, size_t index)
Get an element from an array.
Definition: json.c:360
int ast_ari_validate_string(struct ast_json *json)
Validator for native Swagger string.
static int unload_module(void)