PageRenderTime 96ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/ecs-cli/vendor/github.com/xeipuuv/gojsonschema/format_checkers.go

https://gitlab.com/github-cloud-corporation/amazon-ecs-cli
Go | 194 lines | 114 code | 37 blank | 43 comment | 18 complexity | 2a02e61500244d7a5e769c186b27d864 MD5 | raw file
  1. package gojsonschema
  2. import (
  3. "net"
  4. "net/url"
  5. "reflect"
  6. "regexp"
  7. "strings"
  8. "time"
  9. )
  10. type (
  11. // FormatChecker is the interface all formatters added to FormatCheckerChain must implement
  12. FormatChecker interface {
  13. IsFormat(input string) bool
  14. }
  15. // FormatCheckerChain holds the formatters
  16. FormatCheckerChain struct {
  17. formatters map[string]FormatChecker
  18. }
  19. // EmailFormatter verifies email address formats
  20. EmailFormatChecker struct{}
  21. // IPV4FormatChecker verifies IP addresses in the ipv4 format
  22. IPV4FormatChecker struct{}
  23. // IPV6FormatChecker verifies IP addresses in the ipv6 format
  24. IPV6FormatChecker struct{}
  25. // DateTimeFormatChecker verifies date/time formats per RFC3339 5.6
  26. //
  27. // Valid formats:
  28. // Partial Time: HH:MM:SS
  29. // Full Date: YYYY-MM-DD
  30. // Full Time: HH:MM:SSZ-07:00
  31. // Date Time: YYYY-MM-DDTHH:MM:SSZ-0700
  32. //
  33. // Where
  34. // YYYY = 4DIGIT year
  35. // MM = 2DIGIT month ; 01-12
  36. // DD = 2DIGIT day-month ; 01-28, 01-29, 01-30, 01-31 based on month/year
  37. // HH = 2DIGIT hour ; 00-23
  38. // MM = 2DIGIT ; 00-59
  39. // SS = 2DIGIT ; 00-58, 00-60 based on leap second rules
  40. // T = Literal
  41. // Z = Literal
  42. //
  43. // Note: Nanoseconds are also suported in all formats
  44. //
  45. // http://tools.ietf.org/html/rfc3339#section-5.6
  46. DateTimeFormatChecker struct{}
  47. // URIFormatCheckers validates a URI with a valid Scheme per RFC3986
  48. URIFormatChecker struct{}
  49. // HostnameFormatChecker validates a hostname is in the correct format
  50. HostnameFormatChecker struct{}
  51. // UUIDFormatChecker validates a UUID is in the correct format
  52. UUIDFormatChecker struct{}
  53. // RegexFormatChecker validates a regex is in the correct format
  54. RegexFormatChecker struct{}
  55. )
  56. var (
  57. // Formatters holds the valid formatters, and is a public variable
  58. // so library users can add custom formatters
  59. FormatCheckers = FormatCheckerChain{
  60. formatters: map[string]FormatChecker{
  61. "date-time": DateTimeFormatChecker{},
  62. "hostname": HostnameFormatChecker{},
  63. "email": EmailFormatChecker{},
  64. "ipv4": IPV4FormatChecker{},
  65. "ipv6": IPV6FormatChecker{},
  66. "uri": URIFormatChecker{},
  67. "uuid": UUIDFormatChecker{},
  68. "regex": UUIDFormatChecker{},
  69. },
  70. }
  71. // Regex credit: https://github.com/asaskevich/govalidator
  72. rxEmail = regexp.MustCompile("^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$")
  73. // Regex credit: https://www.socketloop.com/tutorials/golang-validate-hostname
  74. rxHostname = regexp.MustCompile(`^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$`)
  75. rxUUID = regexp.MustCompile("^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$")
  76. )
  77. // Add adds a FormatChecker to the FormatCheckerChain
  78. // The name used will be the value used for the format key in your json schema
  79. func (c *FormatCheckerChain) Add(name string, f FormatChecker) *FormatCheckerChain {
  80. c.formatters[name] = f
  81. return c
  82. }
  83. // Remove deletes a FormatChecker from the FormatCheckerChain (if it exists)
  84. func (c *FormatCheckerChain) Remove(name string) *FormatCheckerChain {
  85. delete(c.formatters, name)
  86. return c
  87. }
  88. // Has checks to see if the FormatCheckerChain holds a FormatChecker with the given name
  89. func (c *FormatCheckerChain) Has(name string) bool {
  90. _, ok := c.formatters[name]
  91. return ok
  92. }
  93. // IsFormat will check an input against a FormatChecker with the given name
  94. // to see if it is the correct format
  95. func (c *FormatCheckerChain) IsFormat(name string, input interface{}) bool {
  96. f, ok := c.formatters[name]
  97. if !ok {
  98. return false
  99. }
  100. if !isKind(input, reflect.String) {
  101. return false
  102. }
  103. inputString := input.(string)
  104. return f.IsFormat(inputString)
  105. }
  106. func (f EmailFormatChecker) IsFormat(input string) bool {
  107. return rxEmail.MatchString(input)
  108. }
  109. // Credit: https://github.com/asaskevich/govalidator
  110. func (f IPV4FormatChecker) IsFormat(input string) bool {
  111. ip := net.ParseIP(input)
  112. return ip != nil && strings.Contains(input, ".")
  113. }
  114. // Credit: https://github.com/asaskevich/govalidator
  115. func (f IPV6FormatChecker) IsFormat(input string) bool {
  116. ip := net.ParseIP(input)
  117. return ip != nil && strings.Contains(input, ":")
  118. }
  119. func (f DateTimeFormatChecker) IsFormat(input string) bool {
  120. formats := []string{
  121. "15:04:05",
  122. "15:04:05Z07:00",
  123. "2006-01-02",
  124. time.RFC3339,
  125. time.RFC3339Nano,
  126. }
  127. for _, format := range formats {
  128. if _, err := time.Parse(format, input); err == nil {
  129. return true
  130. }
  131. }
  132. return false
  133. }
  134. func (f URIFormatChecker) IsFormat(input string) bool {
  135. u, err := url.Parse(input)
  136. if err != nil || u.Scheme == "" {
  137. return false
  138. }
  139. return true
  140. }
  141. func (f HostnameFormatChecker) IsFormat(input string) bool {
  142. return rxHostname.MatchString(input) && len(input) < 256
  143. }
  144. func (f UUIDFormatChecker) IsFormat(input string) bool {
  145. return rxUUID.MatchString(input)
  146. }
  147. // IsFormat implements FormatChecker interface.
  148. func (f RegexFormatChecker) IsFormat(input string) bool {
  149. if input == "" {
  150. return true
  151. }
  152. _, err := regexp.Compile(input)
  153. if err != nil {
  154. return false
  155. }
  156. return true
  157. }