Serge Bazanski | cc25bdf | 2018-10-25 14:02:58 +0200 | [diff] [blame] | 1 | // Copyright 2015 go-swagger maintainers |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
| 15 | package validate |
| 16 | |
| 17 | import ( |
| 18 | "net/http" |
| 19 | |
| 20 | "github.com/go-openapi/errors" |
| 21 | ) |
| 22 | |
| 23 | // Error messages related to spec validation and returned as results. |
| 24 | const ( |
| 25 | // ArrayRequiresItemsError ... |
| 26 | ArrayRequiresItemsError = "%s for %q is a collection without an element type (array requires items definition)" |
| 27 | |
| 28 | // ArrayInParamRequiresItemsError ... |
| 29 | ArrayInParamRequiresItemsError = "param %q for %q is a collection without an element type (array requires item definition)" |
| 30 | |
| 31 | // ArrayInHeaderRequiresItemsError ... |
| 32 | ArrayInHeaderRequiresItemsError = "header %q for %q is a collection without an element type (array requires items definition)" |
| 33 | |
| 34 | // BothFormDataAndBodyError indicates that an operation specifies both a body and a formData parameter, which is forbidden |
| 35 | BothFormDataAndBodyError = "operation %q has both formData and body parameters. Only one such In: type may be used for a given operation" |
| 36 | |
| 37 | // CannotResolveRefError when a $ref could not be resolved |
| 38 | CannotResolveReferenceError = "could not resolve reference in %s to $ref %s: %v" |
| 39 | |
| 40 | // CircularAncestryDefinitionError ... |
| 41 | CircularAncestryDefinitionError = "definition %q has circular ancestry: %v" |
| 42 | |
| 43 | // DefaultValueDoesNotValidateError results from an invalid default value provided |
| 44 | DefaultValueDoesNotValidateError = "default value for %s in %s does not validate its schema" |
| 45 | |
| 46 | // DefaultValueItemsDoesNotValidateError results from an invalid default value provided for Items |
| 47 | DefaultValueItemsDoesNotValidateError = "default value for %s.items in %s does not validate its schema" |
| 48 | |
| 49 | // DefaultValueHeaderDoesNotValidateError results from an invalid default value provided in header |
| 50 | DefaultValueHeaderDoesNotValidateError = "in operation %q, default value in header %s for %s does not validate its schema" |
| 51 | |
| 52 | // DefaultValueHeaderItemsDoesNotValidateError results from an invalid default value provided in header.items |
| 53 | DefaultValueHeaderItemsDoesNotValidateError = "in operation %q, default value in header.items %s for %s does not validate its schema" |
| 54 | |
| 55 | // DefaultValueInDoesNotValidateError ... |
| 56 | DefaultValueInDoesNotValidateError = "in operation %q, default value in %s does not validate its schema" |
| 57 | |
| 58 | // DuplicateParamNameError ... |
| 59 | DuplicateParamNameError = "duplicate parameter name %q for %q in operation %q" |
| 60 | |
| 61 | // DuplicatePropertiesError ... |
| 62 | DuplicatePropertiesError = "definition %q contains duplicate properties: %v" |
| 63 | |
| 64 | // ExampleValueDoesNotValidateError results from an invalid example value provided |
| 65 | ExampleValueDoesNotValidateError = "example value for %s in %s does not validate its schema" |
| 66 | |
| 67 | // ExampleValueItemsDoesNotValidateError results from an invalid example value provided for Items |
| 68 | ExampleValueItemsDoesNotValidateError = "example value for %s.items in %s does not validate its schema" |
| 69 | |
| 70 | // ExampleValueHeaderDoesNotValidateError results from an invalid example value provided in header |
| 71 | ExampleValueHeaderDoesNotValidateError = "in operation %q, example value in header %s for %s does not validate its schema" |
| 72 | |
| 73 | // ExampleValueHeaderItemsDoesNotValidateError results from an invalid example value provided in header.items |
| 74 | ExampleValueHeaderItemsDoesNotValidateError = "in operation %q, example value in header.items %s for %s does not validate its schema" |
| 75 | |
| 76 | // ExampleValueInDoesNotValidateError ... |
| 77 | ExampleValueInDoesNotValidateError = "in operation %q, example value in %s does not validate its schema" |
| 78 | |
| 79 | // EmptyPathParameterError means that a path parameter was found empty (e.g. "{}") |
| 80 | EmptyPathParameterError = "%q contains an empty path parameter" |
| 81 | |
| 82 | // InvalidDocumentError states that spec validation only processes spec.Document objects |
| 83 | InvalidDocumentError = "spec validator can only validate spec.Document objects" |
| 84 | |
| 85 | // InvalidItemsPatternError indicates an Items definition with invalid pattern |
| 86 | InvalidItemsPatternError = "%s for %q has invalid items pattern: %q" |
| 87 | |
| 88 | // InvalidParameterDefinitionError indicates an error detected on a parameter definition |
| 89 | InvalidParameterDefinitionError = "invalid definition for parameter %s in %s in operation %q" |
| 90 | |
| 91 | // InvalidParameterDefinitionAsSchemaError indicates an error detected on a parameter definition, which was mistaken with a schema definition. |
| 92 | // Most likely, this situation is encountered whenever a $ref has been added as a sibling of the parameter definition. |
| 93 | InvalidParameterDefinitionAsSchemaError = "invalid definition as Schema for parameter %s in %s in operation %q" |
| 94 | |
| 95 | // InvalidPatternError ... |
| 96 | InvalidPatternError = "pattern %q is invalid in %s" |
| 97 | |
| 98 | // InvalidPatternInError indicates an invalid pattern in a schema or items definition |
| 99 | InvalidPatternInError = "%s in %s has invalid pattern: %q" |
| 100 | |
| 101 | // InvalidPatternInHeaderError indicates a header definition with an invalid pattern |
| 102 | InvalidPatternInHeaderError = "in operation %q, header %s for %s has invalid pattern %q: %v" |
| 103 | |
| 104 | // InvalidPatternInParamError ... |
| 105 | InvalidPatternInParamError = "operation %q has invalid pattern in param %q: %q" |
| 106 | |
| 107 | // InvalidReferenceError indicates that a $ref property could not be resolved |
| 108 | InvalidReferenceError = "invalid ref %q" |
| 109 | |
| 110 | // InvalidResponseDefinitionAsSchemaError indicates an error detected on a response definition, which was mistaken with a schema definition. |
| 111 | // Most likely, this situation is encountered whenever a $ref has been added as a sibling of the response definition. |
| 112 | InvalidResponseDefinitionAsSchemaError = "invalid definition as Schema for response %s in %s" |
| 113 | |
| 114 | // MultipleBodyParamError indicates that an operation specifies multiple parameter with in: body |
| 115 | MultipleBodyParamError = "operation %q has more than 1 body param: %v" |
| 116 | |
| 117 | // NonUniqueOperationIDError indicates that the same operationId has been specified several times |
| 118 | NonUniqueOperationIDError = "%q is defined %d times" |
| 119 | |
| 120 | // NoParameterInPathError indicates that a path was found without any parameter |
| 121 | NoParameterInPathError = "path param %q has no parameter definition" |
| 122 | |
| 123 | // NoValidPathErrorOrWarning indicates that no single path could be validated. If Paths is empty, this message is only a warning. |
| 124 | NoValidPathErrorOrWarning = "spec has no valid path defined" |
| 125 | |
| 126 | // NoValidResponseError indicates that no valid response description could be found for an operation |
| 127 | NoValidResponseError = "operation %q has no valid response" |
| 128 | |
| 129 | // PathOverlapError ... |
| 130 | PathOverlapError = "path %s overlaps with %s" |
| 131 | |
| 132 | // PathParamNotInPathError indicates that a parameter specified with in: path was not found in the path specification |
| 133 | PathParamNotInPathError = "path param %q is not present in path %q" |
| 134 | |
| 135 | // PathParamNotUniqueError ... |
| 136 | PathParamNotUniqueError = "params in path %q must be unique: %q conflicts with %q" |
| 137 | |
| 138 | // PathParamNotRequiredError ... |
| 139 | PathParamRequiredError = "in operation %q,path param %q must be declared as required" |
| 140 | |
| 141 | // RefNotAllowedInHeaderError indicates a $ref was found in a header definition, which is not allowed by Swagger |
| 142 | RefNotAllowedInHeaderError = "IMPORTANT!in %q: $ref are not allowed in headers. In context for header %q%s" |
| 143 | |
| 144 | // RequiredButNotDefinedError ... |
| 145 | RequiredButNotDefinedError = "%q is present in required but not defined as property in definition %q" |
| 146 | |
| 147 | // SomeParametersBrokenError indicates that some parameters could not be resolved, which might result in partial checks to be carried on |
| 148 | SomeParametersBrokenError = "some parameters definitions are broken in %q.%s. Cannot carry on full checks on parameters for operation %s" |
| 149 | |
| 150 | // UnresolvedReferencesError indicates that at least one $ref could not be resolved |
| 151 | UnresolvedReferencesError = "some references could not be resolved in spec. First found: %v" |
| 152 | ) |
| 153 | |
| 154 | // Warning messages related to spec validation and returned as results |
| 155 | const ( |
| 156 | // ExamplesWithoutSchemaWarning indicates that examples are provided for a response,but not schema to validate the example against |
| 157 | ExamplesWithoutSchemaWarning = "Examples provided without schema in operation %q, %s" |
| 158 | |
| 159 | // ExamplesMimeNotSupportedWarning indicates that examples are provided with a mime type different than application/json, which |
| 160 | // the validator dos not support yetl |
| 161 | ExamplesMimeNotSupportedWarning = "No validation attempt for examples for media types other than application/json, in operation %q, %s" |
| 162 | |
| 163 | // PathParamGarbledWarning ... |
| 164 | PathParamGarbledWarning = "in path %q, param %q contains {,} or white space. Albeit not stricly illegal, this is probably no what you want" |
| 165 | |
| 166 | // PathStrippedParamGarbledWarning ... |
| 167 | PathStrippedParamGarbledWarning = "path stripped from path parameters %s contains {,} or white space. This is probably no what you want." |
| 168 | |
| 169 | // ReadOnlyAndRequiredWarning ... |
| 170 | ReadOnlyAndRequiredWarning = "Required property %s in %q should not be marked as both required and readOnly" |
| 171 | |
| 172 | // RefShouldNotHaveSiblingsWarning indicates that a $ref was found with a sibling definition. This results in the $ref taking over its siblings, |
| 173 | // which is most likely not wanted. |
| 174 | RefShouldNotHaveSiblingsWarning = "$ref property should have no sibling in %q.%s" |
| 175 | |
| 176 | // RequiredHasDefaultWarning indicates that a required parameter property should not have a default |
| 177 | RequiredHasDefaultWarning = "%s in %s has a default value and is required as parameter" |
| 178 | |
| 179 | // UnusedDefinitionWarning ... |
| 180 | UnusedDefinitionWarning = "definition %q is not used anywhere" |
| 181 | |
| 182 | // UnusedParamWarning ... |
| 183 | UnusedParamWarning = "parameter %q is not used anywhere" |
| 184 | |
| 185 | // UnusedResponseWarning ... |
| 186 | UnusedResponseWarning = "response %q is not used anywhere" |
| 187 | ) |
| 188 | |
| 189 | // Additional error codes |
| 190 | const ( |
| 191 | // InternalErrorCode reports an internal technical error |
| 192 | InternalErrorCode = http.StatusInternalServerError |
| 193 | // NotFoundErrorCode indicates that a resource (e.g. a $ref) could not be found |
| 194 | NotFoundErrorCode = http.StatusNotFound |
| 195 | ) |
| 196 | |
| 197 | func invalidDocumentMsg() errors.Error { |
| 198 | return errors.New(InternalErrorCode, InvalidDocumentError) |
| 199 | } |
| 200 | func invalidRefMsg(path string) errors.Error { |
| 201 | return errors.New(NotFoundErrorCode, InvalidReferenceError, path) |
| 202 | } |
| 203 | func unresolvedReferencesMsg(err error) errors.Error { |
| 204 | return errors.New(errors.CompositeErrorCode, UnresolvedReferencesError, err) |
| 205 | } |
| 206 | func noValidPathMsg() errors.Error { |
| 207 | return errors.New(errors.CompositeErrorCode, NoValidPathErrorOrWarning) |
| 208 | } |
| 209 | func emptyPathParameterMsg(path string) errors.Error { |
| 210 | return errors.New(errors.CompositeErrorCode, EmptyPathParameterError, path) |
| 211 | } |
| 212 | func nonUniqueOperationIDMsg(path string, i int) errors.Error { |
| 213 | return errors.New(errors.CompositeErrorCode, NonUniqueOperationIDError, path, i) |
| 214 | } |
| 215 | func circularAncestryDefinitionMsg(path string, args interface{}) errors.Error { |
| 216 | return errors.New(errors.CompositeErrorCode, CircularAncestryDefinitionError, path, args) |
| 217 | } |
| 218 | func duplicatePropertiesMsg(path string, args interface{}) errors.Error { |
| 219 | return errors.New(errors.CompositeErrorCode, DuplicatePropertiesError, path, args) |
| 220 | } |
| 221 | func pathParamNotInPathMsg(path, param string) errors.Error { |
| 222 | return errors.New(errors.CompositeErrorCode, PathParamNotInPathError, param, path) |
| 223 | } |
| 224 | func arrayRequiresItemsMsg(path, operation string) errors.Error { |
| 225 | return errors.New(errors.CompositeErrorCode, ArrayRequiresItemsError, path, operation) |
| 226 | } |
| 227 | func arrayInParamRequiresItemsMsg(path, operation string) errors.Error { |
| 228 | return errors.New(errors.CompositeErrorCode, ArrayInParamRequiresItemsError, path, operation) |
| 229 | } |
| 230 | func arrayInHeaderRequiresItemsMsg(path, operation string) errors.Error { |
| 231 | return errors.New(errors.CompositeErrorCode, ArrayInHeaderRequiresItemsError, path, operation) |
| 232 | } |
| 233 | func invalidItemsPatternMsg(path, operation, pattern string) errors.Error { |
| 234 | return errors.New(errors.CompositeErrorCode, InvalidItemsPatternError, path, operation, pattern) |
| 235 | } |
| 236 | func invalidPatternMsg(pattern, path string) errors.Error { |
| 237 | return errors.New(errors.CompositeErrorCode, InvalidPatternError, pattern, path) |
| 238 | } |
| 239 | func requiredButNotDefinedMsg(path, definition string) errors.Error { |
| 240 | return errors.New(errors.CompositeErrorCode, RequiredButNotDefinedError, path, definition) |
| 241 | } |
| 242 | func pathParamGarbledMsg(path, param string) errors.Error { |
| 243 | return errors.New(errors.CompositeErrorCode, PathParamGarbledWarning, path, param) |
| 244 | } |
| 245 | func pathStrippedParamGarbledMsg(path string) errors.Error { |
| 246 | return errors.New(errors.CompositeErrorCode, PathStrippedParamGarbledWarning, path) |
| 247 | } |
| 248 | func pathOverlapMsg(path, arg string) errors.Error { |
| 249 | return errors.New(errors.CompositeErrorCode, PathOverlapError, path, arg) |
| 250 | } |
| 251 | func invalidPatternInParamMsg(operation, param, pattern string) errors.Error { |
| 252 | return errors.New(errors.CompositeErrorCode, InvalidPatternInParamError, operation, param, pattern) |
| 253 | } |
| 254 | func pathParamRequiredMsg(operation, param string) errors.Error { |
| 255 | return errors.New(errors.CompositeErrorCode, PathParamRequiredError, operation, param) |
| 256 | } |
| 257 | func bothFormDataAndBodyMsg(operation string) errors.Error { |
| 258 | return errors.New(errors.CompositeErrorCode, BothFormDataAndBodyError, operation) |
| 259 | } |
| 260 | func multipleBodyParamMsg(operation string, args interface{}) errors.Error { |
| 261 | return errors.New(errors.CompositeErrorCode, MultipleBodyParamError, operation, args) |
| 262 | } |
| 263 | func pathParamNotUniqueMsg(path, param, arg string) errors.Error { |
| 264 | return errors.New(errors.CompositeErrorCode, PathParamNotUniqueError, path, param, arg) |
| 265 | } |
| 266 | func duplicateParamNameMsg(path, param, operation string) errors.Error { |
| 267 | return errors.New(errors.CompositeErrorCode, DuplicateParamNameError, param, path, operation) |
| 268 | } |
| 269 | func unusedParamMsg(arg string) errors.Error { |
| 270 | return errors.New(errors.CompositeErrorCode, UnusedParamWarning, arg) |
| 271 | } |
| 272 | func unusedDefinitionMsg(arg string) errors.Error { |
| 273 | return errors.New(errors.CompositeErrorCode, UnusedDefinitionWarning, arg) |
| 274 | } |
| 275 | func unusedResponseMsg(arg string) errors.Error { |
| 276 | return errors.New(errors.CompositeErrorCode, UnusedResponseWarning, arg) |
| 277 | } |
| 278 | func readOnlyAndRequiredMsg(path, param string) errors.Error { |
| 279 | return errors.New(errors.CompositeErrorCode, ReadOnlyAndRequiredWarning, param, path) |
| 280 | } |
| 281 | func noParameterInPathMsg(param string) errors.Error { |
| 282 | return errors.New(errors.CompositeErrorCode, NoParameterInPathError, param) |
| 283 | } |
| 284 | func requiredHasDefaultMsg(param, path string) errors.Error { |
| 285 | return errors.New(errors.CompositeErrorCode, RequiredHasDefaultWarning, param, path) |
| 286 | } |
| 287 | func defaultValueDoesNotValidateMsg(param, path string) errors.Error { |
| 288 | return errors.New(errors.CompositeErrorCode, DefaultValueDoesNotValidateError, param, path) |
| 289 | } |
| 290 | func defaultValueItemsDoesNotValidateMsg(param, path string) errors.Error { |
| 291 | return errors.New(errors.CompositeErrorCode, DefaultValueItemsDoesNotValidateError, param, path) |
| 292 | } |
| 293 | func noValidResponseMsg(operation string) errors.Error { |
| 294 | return errors.New(errors.CompositeErrorCode, NoValidResponseError, operation) |
| 295 | } |
| 296 | func defaultValueHeaderDoesNotValidateMsg(operation, header, path string) errors.Error { |
| 297 | return errors.New(errors.CompositeErrorCode, DefaultValueHeaderDoesNotValidateError, operation, header, path) |
| 298 | } |
| 299 | func defaultValueHeaderItemsDoesNotValidateMsg(operation, header, path string) errors.Error { |
| 300 | return errors.New(errors.CompositeErrorCode, DefaultValueHeaderItemsDoesNotValidateError, operation, header, path) |
| 301 | } |
| 302 | func invalidPatternInHeaderMsg(operation, header, path, pattern string, args interface{}) errors.Error { |
| 303 | return errors.New(errors.CompositeErrorCode, InvalidPatternInHeaderError, operation, header, path, pattern, args) |
| 304 | } |
| 305 | func invalidPatternInMsg(path, in, pattern string) errors.Error { |
| 306 | return errors.New(errors.CompositeErrorCode, InvalidPatternInError, path, in, pattern) |
| 307 | } |
| 308 | func defaultValueInDoesNotValidateMsg(operation, path string) errors.Error { |
| 309 | return errors.New(errors.CompositeErrorCode, DefaultValueInDoesNotValidateError, operation, path) |
| 310 | } |
| 311 | func exampleValueDoesNotValidateMsg(param, path string) errors.Error { |
| 312 | return errors.New(errors.CompositeErrorCode, ExampleValueDoesNotValidateError, param, path) |
| 313 | } |
| 314 | func exampleValueItemsDoesNotValidateMsg(param, path string) errors.Error { |
| 315 | return errors.New(errors.CompositeErrorCode, ExampleValueItemsDoesNotValidateError, param, path) |
| 316 | } |
| 317 | func exampleValueHeaderDoesNotValidateMsg(operation, header, path string) errors.Error { |
| 318 | return errors.New(errors.CompositeErrorCode, ExampleValueHeaderDoesNotValidateError, operation, header, path) |
| 319 | } |
| 320 | func exampleValueHeaderItemsDoesNotValidateMsg(operation, header, path string) errors.Error { |
| 321 | return errors.New(errors.CompositeErrorCode, ExampleValueHeaderItemsDoesNotValidateError, operation, header, path) |
| 322 | } |
| 323 | func exampleValueInDoesNotValidateMsg(operation, path string) errors.Error { |
| 324 | return errors.New(errors.CompositeErrorCode, ExampleValueInDoesNotValidateError, operation, path) |
| 325 | } |
| 326 | func examplesWithoutSchemaMsg(operation, response string) errors.Error { |
| 327 | return errors.New(errors.CompositeErrorCode, ExamplesWithoutSchemaWarning, operation, response) |
| 328 | } |
| 329 | func examplesMimeNotSupportedMsg(operation, response string) errors.Error { |
| 330 | return errors.New(errors.CompositeErrorCode, ExamplesMimeNotSupportedWarning, operation, response) |
| 331 | } |
| 332 | func refNotAllowedInHeaderMsg(path, header, ref string) errors.Error { |
| 333 | return errors.New(errors.CompositeErrorCode, RefNotAllowedInHeaderError, path, header, ref) |
| 334 | } |
| 335 | func cannotResolveRefMsg(path, ref string, err error) errors.Error { |
| 336 | return errors.New(errors.CompositeErrorCode, CannotResolveReferenceError, path, ref, err) |
| 337 | } |
| 338 | func invalidParameterDefinitionMsg(path, method, operationID string) errors.Error { |
| 339 | return errors.New(errors.CompositeErrorCode, InvalidParameterDefinitionError, path, method, operationID) |
| 340 | } |
| 341 | func invalidParameterDefinitionAsSchemaMsg(path, method, operationID string) errors.Error { |
| 342 | return errors.New(errors.CompositeErrorCode, InvalidParameterDefinitionAsSchemaError, path, method, operationID) |
| 343 | } |
| 344 | |
| 345 | // disabled |
| 346 | //func invalidResponseDefinitionAsSchemaMsg(path, method string) errors.Error { |
| 347 | // return errors.New(errors.CompositeErrorCode, InvalidResponseDefinitionAsSchemaError, path, method) |
| 348 | //} |
| 349 | func someParametersBrokenMsg(path, method, operationID string) errors.Error { |
| 350 | return errors.New(errors.CompositeErrorCode, SomeParametersBrokenError, path, method, operationID) |
| 351 | } |
| 352 | func refShouldNotHaveSiblingsMsg(path, operationID string) errors.Error { |
| 353 | return errors.New(errors.CompositeErrorCode, RefShouldNotHaveSiblingsWarning, operationID, path) |
| 354 | } |