[R] add URL validation (#13570)

* add url validation in r client

* update samples
This commit is contained in:
William Cheng 2022-10-02 23:57:33 +08:00 committed by GitHub
parent 9cc23dd09d
commit c939894711
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 230 additions and 7 deletions

View File

@ -65,10 +65,10 @@
stopifnot(is.numeric(`{{name}}`), length(`{{name}}`) == 1)
{{/isInteger}}
{{#isLong}}
stopifnot(is.numeric(`{{name}}`), length(`{{nme}}`) == 1)
stopifnot(is.numeric(`{{name}}`), length(`{{name}}`) == 1)
{{/isLong}}
{{#isFloat}}
stopifnot(is.numeric(`{{nme}}`), length(`{{nme}}`) == 1)
stopifnot(is.numeric(`{{name}}`), length(`{{name}}`) == 1)
{{/isFloat}}
{{#isDouble}}
stopifnot(is.numeric(`{{name}}`), length(`{{name}}`) == 1)
@ -85,6 +85,12 @@
{{#isDateTime}}
stopifnot(is.character(`{{name}}`), length(`{{name}}`) == 1)
{{/isDateTime}}
{{#isUri}}
# validate URL using https://github.com/cran/librarian/blob/master/R/internal_functions.R#L131 credit: Desi Quintans
if (!any(grepl("(https?|ftp)://[^\\s/$.?#].[^\\s]*", `{{name}}`))) {
stop(paste("Error! Invalid URL:", `{{name}}`))
}
{{/isUri}}
{{^isPrimitiveType}}
stopifnot(R6::is.R6(`{{name}}`))
{{/isPrimitiveType}}
@ -135,6 +141,12 @@
{{#isDateTime}}
stopifnot(is.character(`{{name}}`), length(`{{name}}`) == 1)
{{/isDateTime}}
{{#isUri}}
# validate URL using https://github.com/cran/librarian/blob/master/R/internal_functions.R#L131 credit: Desi Quintans
if (!any(grepl("(https?|ftp)://[^\\s/$.?#].[^\\s]*", `{{name}}`))) {
stop(paste("Error! Invalid URL:", `{{name}}`))
}
{{/isUri}}
{{^isPrimitiveType}}
stopifnot(R6::is.R6(`{{name}}`))
{{/isPrimitiveType}}
@ -238,6 +250,12 @@
stop(paste("Error! \"", this_object$`{{baseName}}`, "\" cannot be assigned to `{{baseName}}`. Must be {{#_enum}}\"{{{.}}}\"{{^-last}}, {{/-last}}{{/_enum}}.", sep = ""))
}
{{/isEnum}}
{{#isUri}}
# validate URL using https://github.com/cran/librarian/blob/master/R/internal_functions.R#L131 credit: Desi Quintans
if (!any(grepl("(https?|ftp)://[^\\s/$.?#].[^\\s]*", this_object$`{{baseName}}`))) {
stop(paste("Error! Invalid URL:", this_object$`{{baseName}}`))
}
{{/isUri}}
self$`{{name}}` <- this_object$`{{baseName}}`
{{/isPrimitiveType}}
{{^isPrimitiveType}}
@ -364,6 +382,12 @@
stop(paste("Error! \"", this_object$`{{baseName}}`, "\" cannot be assigned to `{{baseName}}`. Must be {{#_enum}}\"{{{.}}}\"{{^-last}}, {{/-last}}{{/_enum}}.", sep = ""))
}
{{/isEnum}}
{{#isUri}}
# validate URL using https://github.com/cran/librarian/blob/master/R/internal_functions.R#L131 credit: Desi Quintans
if (!any(grepl("(https?|ftp)://[^\\s/$.?#].[^\\s]*", this_object$`{{name}}`))) {
stop(paste("Error! Invalid URL:", this_object$`{{name}}`))
}
{{/isUri}}
self$`{{name}}` <- this_object$`{{name}}`
{{/isPrimitiveType}}
{{^isPrimitiveType}}
@ -419,6 +443,12 @@
{{#isDateTime}}
stopifnot(is.character(input_json$`{{name}}`), length(input_json$`{{name}}`) == 1)
{{/isDateTime}}
{{#isUri}}
# validate URL using https://github.com/cran/librarian/blob/master/R/internal_functions.R#L131 credit: Desi Quintans
if (!any(grepl("(https?|ftp)://[^\\s/$.?#].[^\\s]*", input_json$`{{name}}`))) {
stop(paste("Error! Invalid URL:", input_json$`{{name}}`))
}
{{/isUri}}
{{^isPrimitiveType}}
stopifnot(R6::is.R6(input_json$`{{name}}`))
{{/isPrimitiveType}}
@ -493,6 +523,12 @@
return(FALSE)
}
{{/pattern}}
{{#isUri}}
# validate URL using https://github.com/cran/librarian/blob/master/R/internal_functions.R#L131 credit: Desi Quintans
if (!any(grepl("(https?|ftp)://[^\\s/$.?#].[^\\s]*", self$`{{{name}}}`))) {
return(FALSE)
}
{{/isUri}}
{{#maxItems}}
if (length(self$`{{{name}}}`) > {{maxItems}}) {
return(FALSE)
@ -553,6 +589,12 @@
invalid_fields["{{{name}}}"] <- "Invalid value for `{{{name}}}`, must conform to the pattern {{{pattern}}}."
}
{{/pattern}}
{{#isUri}}
# validate URL using https://github.com/cran/librarian/blob/master/R/internal_functions.R#L131 credit: Desi Quintans
if (!any(grepl("(https?|ftp)://[^\\s/$.?#].[^\\s]*", self$`{{name}}`))) {
invalid_fields["{{{name}}}"] <- "Invalid value for `{{{name}}}`, must be URL."
}
{{/isUri}}
{{#maxItems}}
if (length(self$`{{{name}}}`) > {{maxItems}}) {
invalid_fields["{{{name}}}"] <- "Invalid length for `{{{name}}}`, number of items must be less than or equal to {{maxItems}}."

View File

@ -1115,5 +1115,9 @@ components:
percent_description:
description: using % in the description
type: string
url_property:
type: string
format: uri
required:
- className
- url_property

View File

@ -9,6 +9,7 @@
#' @format An \code{R6Class} generator object
#' @field className character
#' @field percent_description using \% in the description character [optional]
#' @field url_property character
#' @field _field_list a list of fields list(character)
#' @field additional_properties additional properties list(character) [optional]
#' @importFrom R6 R6Class
@ -19,7 +20,8 @@ Date <- R6::R6Class(
public = list(
`className` = NULL,
`percent_description` = NULL,
`_field_list` = c("className", "percent_description"),
`url_property` = NULL,
`_field_list` = c("className", "percent_description", "url_property"),
`additional_properties` = list(),
#' Initialize a new Date class.
#'
@ -27,17 +29,26 @@ Date <- R6::R6Class(
#' Initialize a new Date class.
#'
#' @param className className
#' @param url_property url_property
#' @param percent_description using \% in the description
#' @param additional_properties additonal properties (optional)
#' @param ... Other optional arguments.
#' @export
initialize = function(
`className`, `percent_description` = NULL, additional_properties = NULL, ...
`className`, `url_property`, `percent_description` = NULL, additional_properties = NULL, ...
) {
if (!missing(`className`)) {
stopifnot(is.character(`className`), length(`className`) == 1)
self$`className` <- `className`
}
if (!missing(`url_property`)) {
stopifnot(is.character(`url_property`), length(`url_property`) == 1)
# validate URL using https://github.com/cran/librarian/blob/master/R/internal_functions.R#L131 credit: Desi Quintans
if (!any(grepl("(https?|ftp)://[^\\s/$.?#].[^\\s]*", `url_property`))) {
stop(paste("Error! Invalid URL:", `url_property`))
}
self$`url_property` <- `url_property`
}
if (!is.null(`percent_description`)) {
stopifnot(is.character(`percent_description`), length(`percent_description`) == 1)
self$`percent_description` <- `percent_description`
@ -65,6 +76,10 @@ Date <- R6::R6Class(
DateObject[["percent_description"]] <-
self$`percent_description`
}
if (!is.null(self$`url_property`)) {
DateObject[["url_property"]] <-
self$`url_property`
}
for (key in names(self$additional_properties)) {
DateObject[[key]] <- self$additional_properties[[key]]
}
@ -87,6 +102,13 @@ Date <- R6::R6Class(
if (!is.null(this_object$`percent_description`)) {
self$`percent_description` <- this_object$`percent_description`
}
if (!is.null(this_object$`url_property`)) {
# validate URL using https://github.com/cran/librarian/blob/master/R/internal_functions.R#L131 credit: Desi Quintans
if (!any(grepl("(https?|ftp)://[^\\s/$.?#].[^\\s]*", this_object$`url_property`))) {
stop(paste("Error! Invalid URL:", this_object$`url_property`))
}
self$`url_property` <- this_object$`url_property`
}
# process additional properties/fields in the payload
for (key in names(this_object)) {
if (!(key %in% self$`_field_list`)) { # json key not in list of fields
@ -120,6 +142,14 @@ Date <- R6::R6Class(
',
self$`percent_description`
)
},
if (!is.null(self$`url_property`)) {
sprintf(
'"url_property":
"%s"
',
self$`url_property`
)
}
)
jsoncontent <- paste(jsoncontent, collapse = ",")
@ -142,6 +172,11 @@ Date <- R6::R6Class(
this_object <- jsonlite::fromJSON(input_json)
self$`className` <- this_object$`className`
self$`percent_description` <- this_object$`percent_description`
# validate URL using https://github.com/cran/librarian/blob/master/R/internal_functions.R#L131 credit: Desi Quintans
if (!any(grepl("(https?|ftp)://[^\\s/$.?#].[^\\s]*", this_object$`url_property`))) {
stop(paste("Error! Invalid URL:", this_object$`url_property`))
}
self$`url_property` <- this_object$`url_property`
# process additional properties/fields in the payload
for (key in names(this_object)) {
if (!(key %in% self$`_field_list`)) { # json key not in list of fields
@ -166,6 +201,16 @@ Date <- R6::R6Class(
} else {
stop(paste("The JSON input `", input, "` is invalid for Date: the required field `className` is missing."))
}
# check the required field `url_property`
if (!is.null(input_json$`url_property`)) {
stopifnot(is.character(input_json$`url_property`), length(input_json$`url_property`) == 1)
# validate URL using https://github.com/cran/librarian/blob/master/R/internal_functions.R#L131 credit: Desi Quintans
if (!any(grepl("(https?|ftp)://[^\\s/$.?#].[^\\s]*", input_json$`url_property`))) {
stop(paste("Error! Invalid URL:", input_json$`url_property`))
}
} else {
stop(paste("The JSON input `", input, "` is invalid for Date: the required field `url_property` is missing."))
}
},
#' To string (JSON format)
#'
@ -190,6 +235,11 @@ Date <- R6::R6Class(
return(FALSE)
}
# check if the required `url_property` is null
if (is.null(self$`url_property`)) {
return(FALSE)
}
TRUE
},
#' Return a list of invalid fields (if any).
@ -206,6 +256,11 @@ Date <- R6::R6Class(
invalid_fields["className"] <- "Non-nullable required field `className` cannot be null."
}
# check if the required `url_property` is null
if (is.null(self$`url_property`)) {
invalid_fields["url_property"] <- "Non-nullable required field `url_property` cannot be null."
}
invalid_fields
},
#' Print the object

View File

@ -7,5 +7,6 @@ Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**className** | **character** | |
**percent_description** | **character** | using % in the description | [optional]
**url_property** | **character** | |

View File

@ -591,3 +591,12 @@ test_that("Tests anyOf", {
expect_error(pig$validateJSON('{}'), 'No match found when deserializing the payload into AnyOfPig with anyOf schemas BasquePig, DanishPig. Details: The JSON input ` \\{\\} ` is invalid for BasquePig: the required field `className` is missing\\., The JSON input ` \\{\\} ` is invalid for DanishPig: the required field `className` is missing\\.')
})
test_that("Tests URL validation", {
valid_json <- '{"className":"date","percent_description":"abc","url_property":"https://abc.com/a/1/b/2"}'
Date$public_methods$validateJSON(valid_json) # shouldn't throw exception
invalid_json <- '{"className":"date","percent_description":"abc","url_property":"invalid_url"}'
expect_error(Date$public_methods$validateJSON(invalid_json), 'Error! Invalid URL: invalid_url') # should throw exception
})

View File

@ -9,6 +9,7 @@
#' @format An \code{R6Class} generator object
#' @field className character
#' @field percent_description using \% in the description character [optional]
#' @field url_property character
#' @importFrom R6 R6Class
#' @importFrom jsonlite fromJSON toJSON
#' @export
@ -17,22 +18,32 @@ Date <- R6::R6Class(
public = list(
`className` = NULL,
`percent_description` = NULL,
`url_property` = NULL,
#' Initialize a new Date class.
#'
#' @description
#' Initialize a new Date class.
#'
#' @param className className
#' @param url_property url_property
#' @param percent_description using \% in the description
#' @param ... Other optional arguments.
#' @export
initialize = function(
`className`, `percent_description` = NULL, ...
`className`, `url_property`, `percent_description` = NULL, ...
) {
if (!missing(`className`)) {
stopifnot(is.character(`className`), length(`className`) == 1)
self$`className` <- `className`
}
if (!missing(`url_property`)) {
stopifnot(is.character(`url_property`), length(`url_property`) == 1)
# validate URL using https://github.com/cran/librarian/blob/master/R/internal_functions.R#L131 credit: Desi Quintans
if (!any(grepl("(https?|ftp)://[^\\s/$.?#].[^\\s]*", `url_property`))) {
stop(paste("Error! Invalid URL:", `url_property`))
}
self$`url_property` <- `url_property`
}
if (!is.null(`percent_description`)) {
stopifnot(is.character(`percent_description`), length(`percent_description`) == 1)
self$`percent_description` <- `percent_description`
@ -55,6 +66,10 @@ Date <- R6::R6Class(
DateObject[["percent_description"]] <-
self$`percent_description`
}
if (!is.null(self$`url_property`)) {
DateObject[["url_property"]] <-
self$`url_property`
}
DateObject
},
#' Deserialize JSON string into an instance of Date
@ -73,6 +88,13 @@ Date <- R6::R6Class(
if (!is.null(this_object$`percent_description`)) {
self$`percent_description` <- this_object$`percent_description`
}
if (!is.null(this_object$`url_property`)) {
# validate URL using https://github.com/cran/librarian/blob/master/R/internal_functions.R#L131 credit: Desi Quintans
if (!any(grepl("(https?|ftp)://[^\\s/$.?#].[^\\s]*", this_object$`url_property`))) {
stop(paste("Error! Invalid URL:", this_object$`url_property`))
}
self$`url_property` <- this_object$`url_property`
}
self
},
#' To JSON string
@ -99,6 +121,14 @@ Date <- R6::R6Class(
',
self$`percent_description`
)
},
if (!is.null(self$`url_property`)) {
sprintf(
'"url_property":
"%s"
',
self$`url_property`
)
}
)
jsoncontent <- paste(jsoncontent, collapse = ",")
@ -116,6 +146,11 @@ Date <- R6::R6Class(
this_object <- jsonlite::fromJSON(input_json)
self$`className` <- this_object$`className`
self$`percent_description` <- this_object$`percent_description`
# validate URL using https://github.com/cran/librarian/blob/master/R/internal_functions.R#L131 credit: Desi Quintans
if (!any(grepl("(https?|ftp)://[^\\s/$.?#].[^\\s]*", this_object$`url_property`))) {
stop(paste("Error! Invalid URL:", this_object$`url_property`))
}
self$`url_property` <- this_object$`url_property`
self
},
#' Validate JSON input with respect to Date
@ -133,6 +168,16 @@ Date <- R6::R6Class(
} else {
stop(paste("The JSON input `", input, "` is invalid for Date: the required field `className` is missing."))
}
# check the required field `url_property`
if (!is.null(input_json$`url_property`)) {
stopifnot(is.character(input_json$`url_property`), length(input_json$`url_property`) == 1)
# validate URL using https://github.com/cran/librarian/blob/master/R/internal_functions.R#L131 credit: Desi Quintans
if (!any(grepl("(https?|ftp)://[^\\s/$.?#].[^\\s]*", input_json$`url_property`))) {
stop(paste("Error! Invalid URL:", input_json$`url_property`))
}
} else {
stop(paste("The JSON input `", input, "` is invalid for Date: the required field `url_property` is missing."))
}
},
#' To string (JSON format)
#'
@ -157,6 +202,11 @@ Date <- R6::R6Class(
return(FALSE)
}
# check if the required `url_property` is null
if (is.null(self$`url_property`)) {
return(FALSE)
}
TRUE
},
#' Return a list of invalid fields (if any).
@ -173,6 +223,11 @@ Date <- R6::R6Class(
invalid_fields["className"] <- "Non-nullable required field `className` cannot be null."
}
# check if the required `url_property` is null
if (is.null(self$`url_property`)) {
invalid_fields["url_property"] <- "Non-nullable required field `url_property` cannot be null."
}
invalid_fields
},
#' Print the object

View File

@ -7,5 +7,6 @@ Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**className** | **character** | |
**percent_description** | **character** | using % in the description | [optional]
**url_property** | **character** | |

View File

@ -9,6 +9,7 @@
#' @format An \code{R6Class} generator object
#' @field className character
#' @field percent_description using \% in the description character [optional]
#' @field url_property character
#' @field _field_list a list of fields list(character)
#' @field additional_properties additional properties list(character) [optional]
#' @importFrom R6 R6Class
@ -19,7 +20,8 @@ Date <- R6::R6Class(
public = list(
`className` = NULL,
`percent_description` = NULL,
`_field_list` = c("className", "percent_description"),
`url_property` = NULL,
`_field_list` = c("className", "percent_description", "url_property"),
`additional_properties` = list(),
#' Initialize a new Date class.
#'
@ -27,17 +29,26 @@ Date <- R6::R6Class(
#' Initialize a new Date class.
#'
#' @param className className
#' @param url_property url_property
#' @param percent_description using \% in the description
#' @param additional_properties additonal properties (optional)
#' @param ... Other optional arguments.
#' @export
initialize = function(
`className`, `percent_description` = NULL, additional_properties = NULL, ...
`className`, `url_property`, `percent_description` = NULL, additional_properties = NULL, ...
) {
if (!missing(`className`)) {
stopifnot(is.character(`className`), length(`className`) == 1)
self$`className` <- `className`
}
if (!missing(`url_property`)) {
stopifnot(is.character(`url_property`), length(`url_property`) == 1)
# validate URL using https://github.com/cran/librarian/blob/master/R/internal_functions.R#L131 credit: Desi Quintans
if (!any(grepl("(https?|ftp)://[^\\s/$.?#].[^\\s]*", `url_property`))) {
stop(paste("Error! Invalid URL:", `url_property`))
}
self$`url_property` <- `url_property`
}
if (!is.null(`percent_description`)) {
stopifnot(is.character(`percent_description`), length(`percent_description`) == 1)
self$`percent_description` <- `percent_description`
@ -65,6 +76,10 @@ Date <- R6::R6Class(
DateObject[["percent_description"]] <-
self$`percent_description`
}
if (!is.null(self$`url_property`)) {
DateObject[["url_property"]] <-
self$`url_property`
}
for (key in names(self$additional_properties)) {
DateObject[[key]] <- self$additional_properties[[key]]
}
@ -87,6 +102,13 @@ Date <- R6::R6Class(
if (!is.null(this_object$`percent_description`)) {
self$`percent_description` <- this_object$`percent_description`
}
if (!is.null(this_object$`url_property`)) {
# validate URL using https://github.com/cran/librarian/blob/master/R/internal_functions.R#L131 credit: Desi Quintans
if (!any(grepl("(https?|ftp)://[^\\s/$.?#].[^\\s]*", this_object$`url_property`))) {
stop(paste("Error! Invalid URL:", this_object$`url_property`))
}
self$`url_property` <- this_object$`url_property`
}
# process additional properties/fields in the payload
for (key in names(this_object)) {
if (!(key %in% self$`_field_list`)) { # json key not in list of fields
@ -120,6 +142,14 @@ Date <- R6::R6Class(
',
self$`percent_description`
)
},
if (!is.null(self$`url_property`)) {
sprintf(
'"url_property":
"%s"
',
self$`url_property`
)
}
)
jsoncontent <- paste(jsoncontent, collapse = ",")
@ -142,6 +172,11 @@ Date <- R6::R6Class(
this_object <- jsonlite::fromJSON(input_json)
self$`className` <- this_object$`className`
self$`percent_description` <- this_object$`percent_description`
# validate URL using https://github.com/cran/librarian/blob/master/R/internal_functions.R#L131 credit: Desi Quintans
if (!any(grepl("(https?|ftp)://[^\\s/$.?#].[^\\s]*", this_object$`url_property`))) {
stop(paste("Error! Invalid URL:", this_object$`url_property`))
}
self$`url_property` <- this_object$`url_property`
# process additional properties/fields in the payload
for (key in names(this_object)) {
if (!(key %in% self$`_field_list`)) { # json key not in list of fields
@ -166,6 +201,16 @@ Date <- R6::R6Class(
} else {
stop(paste("The JSON input `", input, "` is invalid for Date: the required field `className` is missing."))
}
# check the required field `url_property`
if (!is.null(input_json$`url_property`)) {
stopifnot(is.character(input_json$`url_property`), length(input_json$`url_property`) == 1)
# validate URL using https://github.com/cran/librarian/blob/master/R/internal_functions.R#L131 credit: Desi Quintans
if (!any(grepl("(https?|ftp)://[^\\s/$.?#].[^\\s]*", input_json$`url_property`))) {
stop(paste("Error! Invalid URL:", input_json$`url_property`))
}
} else {
stop(paste("The JSON input `", input, "` is invalid for Date: the required field `url_property` is missing."))
}
},
#' To string (JSON format)
#'
@ -190,6 +235,11 @@ Date <- R6::R6Class(
return(FALSE)
}
# check if the required `url_property` is null
if (is.null(self$`url_property`)) {
return(FALSE)
}
TRUE
},
#' Return a list of invalid fields (if any).
@ -206,6 +256,11 @@ Date <- R6::R6Class(
invalid_fields["className"] <- "Non-nullable required field `className` cannot be null."
}
# check if the required `url_property` is null
if (is.null(self$`url_property`)) {
invalid_fields["url_property"] <- "Non-nullable required field `url_property` cannot be null."
}
invalid_fields
},
#' Print the object

View File

@ -7,5 +7,6 @@ Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**className** | **character** | |
**percent_description** | **character** | using % in the description | [optional]
**url_property** | **character** | |