gitea源码

binding.go 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. // Copyright 2017 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package validation
  4. import (
  5. "fmt"
  6. "regexp"
  7. "strings"
  8. "code.gitea.io/gitea/modules/auth"
  9. "code.gitea.io/gitea/modules/git"
  10. "code.gitea.io/gitea/modules/glob"
  11. "code.gitea.io/gitea/modules/util"
  12. "gitea.com/go-chi/binding"
  13. )
  14. const (
  15. // ErrGitRefName is git reference name error
  16. ErrGitRefName = "GitRefNameError"
  17. // ErrGlobPattern is returned when glob pattern is invalid
  18. ErrGlobPattern = "GlobPattern"
  19. // ErrRegexPattern is returned when a regex pattern is invalid
  20. ErrRegexPattern = "RegexPattern"
  21. // ErrUsername is username error
  22. ErrUsername = "UsernameError"
  23. // ErrInvalidGroupTeamMap is returned when a group team mapping is invalid
  24. ErrInvalidGroupTeamMap = "InvalidGroupTeamMap"
  25. )
  26. // AddBindingRules adds additional binding rules
  27. func AddBindingRules() {
  28. addGitRefNameBindingRule()
  29. addValidURLListBindingRule()
  30. addValidURLBindingRule()
  31. addValidSiteURLBindingRule()
  32. addGlobPatternRule()
  33. addRegexPatternRule()
  34. addGlobOrRegexPatternRule()
  35. addUsernamePatternRule()
  36. addValidGroupTeamMapRule()
  37. }
  38. func addGitRefNameBindingRule() {
  39. // Git refname validation rule
  40. binding.AddRule(&binding.Rule{
  41. IsMatch: func(rule string) bool {
  42. return rule == "GitRefName"
  43. },
  44. IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) {
  45. str := fmt.Sprintf("%v", val)
  46. if !git.IsValidRefPattern(str) {
  47. errs.Add([]string{name}, ErrGitRefName, "GitRefName")
  48. return false, errs
  49. }
  50. return true, errs
  51. },
  52. })
  53. }
  54. func addValidURLListBindingRule() {
  55. // URL validation rule
  56. binding.AddRule(&binding.Rule{
  57. IsMatch: func(rule string) bool {
  58. return rule == "ValidUrlList"
  59. },
  60. IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) {
  61. str := fmt.Sprintf("%v", val)
  62. if len(str) == 0 {
  63. errs.Add([]string{name}, binding.ERR_URL, "Url")
  64. return false, errs
  65. }
  66. ok := true
  67. urls := util.SplitTrimSpace(str, "\n")
  68. for _, u := range urls {
  69. if !IsValidURL(u) {
  70. ok = false
  71. errs.Add([]string{name}, binding.ERR_URL, u)
  72. }
  73. }
  74. return ok, errs
  75. },
  76. })
  77. }
  78. func addValidURLBindingRule() {
  79. // URL validation rule
  80. binding.AddRule(&binding.Rule{
  81. IsMatch: func(rule string) bool {
  82. return rule == "ValidUrl"
  83. },
  84. IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) {
  85. str := fmt.Sprintf("%v", val)
  86. if len(str) != 0 && !IsValidURL(str) {
  87. errs.Add([]string{name}, binding.ERR_URL, "Url")
  88. return false, errs
  89. }
  90. return true, errs
  91. },
  92. })
  93. }
  94. func addValidSiteURLBindingRule() {
  95. // URL validation rule
  96. binding.AddRule(&binding.Rule{
  97. IsMatch: func(rule string) bool {
  98. return rule == "ValidSiteUrl"
  99. },
  100. IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) {
  101. str := fmt.Sprintf("%v", val)
  102. if len(str) != 0 && !IsValidSiteURL(str) {
  103. errs.Add([]string{name}, binding.ERR_URL, "Url")
  104. return false, errs
  105. }
  106. return true, errs
  107. },
  108. })
  109. }
  110. func addGlobPatternRule() {
  111. binding.AddRule(&binding.Rule{
  112. IsMatch: func(rule string) bool {
  113. return rule == "GlobPattern"
  114. },
  115. IsValid: globPatternValidator,
  116. })
  117. }
  118. func globPatternValidator(errs binding.Errors, name string, val any) (bool, binding.Errors) {
  119. str := fmt.Sprintf("%v", val)
  120. if len(str) != 0 {
  121. if _, err := glob.Compile(str); err != nil {
  122. errs.Add([]string{name}, ErrGlobPattern, err.Error())
  123. return false, errs
  124. }
  125. }
  126. return true, errs
  127. }
  128. func addRegexPatternRule() {
  129. binding.AddRule(&binding.Rule{
  130. IsMatch: func(rule string) bool {
  131. return rule == "RegexPattern"
  132. },
  133. IsValid: regexPatternValidator,
  134. })
  135. }
  136. func regexPatternValidator(errs binding.Errors, name string, val any) (bool, binding.Errors) {
  137. str := fmt.Sprintf("%v", val)
  138. if _, err := regexp.Compile(str); err != nil {
  139. errs.Add([]string{name}, ErrRegexPattern, err.Error())
  140. return false, errs
  141. }
  142. return true, errs
  143. }
  144. func addGlobOrRegexPatternRule() {
  145. binding.AddRule(&binding.Rule{
  146. IsMatch: func(rule string) bool {
  147. return rule == "GlobOrRegexPattern"
  148. },
  149. IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) {
  150. str := strings.TrimSpace(fmt.Sprintf("%v", val))
  151. if len(str) >= 2 && strings.HasPrefix(str, "/") && strings.HasSuffix(str, "/") {
  152. return regexPatternValidator(errs, name, str[1:len(str)-1])
  153. }
  154. return globPatternValidator(errs, name, val)
  155. },
  156. })
  157. }
  158. func addUsernamePatternRule() {
  159. binding.AddRule(&binding.Rule{
  160. IsMatch: func(rule string) bool {
  161. return rule == "Username"
  162. },
  163. IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) {
  164. str := fmt.Sprintf("%v", val)
  165. if !IsValidUsername(str) {
  166. errs.Add([]string{name}, ErrUsername, "invalid username")
  167. return false, errs
  168. }
  169. return true, errs
  170. },
  171. })
  172. }
  173. func addValidGroupTeamMapRule() {
  174. binding.AddRule(&binding.Rule{
  175. IsMatch: func(rule string) bool {
  176. return rule == "ValidGroupTeamMap"
  177. },
  178. IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) {
  179. _, err := auth.UnmarshalGroupTeamMapping(fmt.Sprintf("%v", val))
  180. if err != nil {
  181. errs.Add([]string{name}, ErrInvalidGroupTeamMap, err.Error())
  182. return false, errs
  183. }
  184. return true, errs
  185. },
  186. })
  187. }
  188. func portOnly(hostport string) string {
  189. colon := strings.IndexByte(hostport, ':')
  190. if colon == -1 {
  191. return ""
  192. }
  193. if i := strings.Index(hostport, "]:"); i != -1 {
  194. return hostport[i+len("]:"):]
  195. }
  196. if strings.Contains(hostport, "]") {
  197. return ""
  198. }
  199. return hostport[colon+len(":"):]
  200. }
  201. func validPort(p string) bool {
  202. for _, r := range []byte(p) {
  203. if r < '0' || r > '9' {
  204. return false
  205. }
  206. }
  207. return true
  208. }