1
0

repo.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. package form
  2. import (
  3. "net/url"
  4. "strings"
  5. "github.com/flamego/binding"
  6. "github.com/unknwon/com"
  7. "gogs.io/gogs/internal/conf"
  8. "gogs.io/gogs/internal/database"
  9. "gogs.io/gogs/internal/netutil"
  10. )
  11. // _______________________________________ _________.______________________ _______________.___.
  12. // \______ \_ _____/\______ \_____ \ / _____/| \__ ___/\_____ \\______ \__ | |
  13. // | _/| __)_ | ___// | \ \_____ \ | | | | / | \| _// | |
  14. // | | \| \ | | / | \/ \| | | | / | \ | \\____ |
  15. // |____|_ /_______ / |____| \_______ /_______ /|___| |____| \_______ /____|_ // ______|
  16. // \/ \/ \/ \/ \/ \/ \/
  17. type CreateRepo struct {
  18. UserID int64 `binding:"Required"`
  19. RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"`
  20. Private bool
  21. Unlisted bool
  22. Description string `binding:"MaxSize(512)"`
  23. AutoInit bool
  24. Gitignores string
  25. License string
  26. Readme string
  27. }
  28. func (f *CreateRepo) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  29. return validate(errs, map[string]interface{}{}, f, req.Context().Value("locale"))
  30. type MigrateRepo struct {
  31. CloneAddr string `json:"clone_addr" binding:"Required"`
  32. AuthUsername string `json:"auth_username"`
  33. AuthPassword string `json:"auth_password"`
  34. UID int64 `json:"uid" binding:"Required"`
  35. RepoName string `json:"repo_name" binding:"Required;AlphaDashDot;MaxSize(100)"`
  36. Mirror bool `json:"mirror"`
  37. Private bool `json:"private"`
  38. Unlisted bool `json:"unlisted"`
  39. Description string `json:"description" binding:"MaxSize(512)"`
  40. func (f *MigrateRepo) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  41. // ParseRemoteAddr checks if given remote address is valid,
  42. // and returns composed URL with needed username and password.
  43. // It also checks if given user has permission when remote address
  44. // is actually a local path.
  45. func (f MigrateRepo) ParseRemoteAddr(user *database.User) (string, error) {
  46. remoteAddr := strings.TrimSpace(f.CloneAddr)
  47. // Remote address can be HTTP/HTTPS/Git URL or local path.
  48. if strings.HasPrefix(remoteAddr, "http://") ||
  49. strings.HasPrefix(remoteAddr, "https://") ||
  50. strings.HasPrefix(remoteAddr, "git://") {
  51. u, err := url.Parse(remoteAddr)
  52. if err != nil {
  53. return "", database.ErrInvalidCloneAddr{IsURLError: true}
  54. }
  55. if netutil.IsBlockedLocalHostname(u.Hostname(), conf.Security.LocalNetworkAllowlist) {
  56. return "", database.ErrInvalidCloneAddr{IsBlockedLocalAddress: true}
  57. if len(f.AuthUsername)+len(f.AuthPassword) > 0 {
  58. u.User = url.UserPassword(f.AuthUsername, f.AuthPassword)
  59. // To prevent CRLF injection in git protocol, see https://github.com/gogs/gogs/issues/6413
  60. if u.Scheme == "git" && (strings.Contains(remoteAddr, "%0d") || strings.Contains(remoteAddr, "%0a")) {
  61. remoteAddr = u.String()
  62. } else if !user.CanImportLocal() {
  63. return "", database.ErrInvalidCloneAddr{IsPermissionDenied: true}
  64. } else if !com.IsDir(remoteAddr) {
  65. return "", database.ErrInvalidCloneAddr{IsInvalidPath: true}
  66. }
  67. return remoteAddr, nil
  68. type RepoSetting struct {
  69. RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"`
  70. Description string `binding:"MaxSize(512)"`
  71. Website string `binding:"Url;MaxSize(100)"`
  72. Branch string
  73. Interval int
  74. MirrorAddress string
  75. Private bool
  76. Unlisted bool
  77. EnablePrune bool
  78. // Advanced settings
  79. EnableWiki bool
  80. AllowPublicWiki bool
  81. EnableExternalWiki bool
  82. ExternalWikiURL string
  83. EnableIssues bool
  84. AllowPublicIssues bool
  85. EnableExternalTracker bool
  86. ExternalTrackerURL string
  87. TrackerURLFormat string
  88. TrackerIssueStyle string
  89. EnablePulls bool
  90. PullsIgnoreWhitespace bool
  91. PullsAllowRebase bool
  92. func (f *RepoSetting) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  93. // __________ .__
  94. // \______ \____________ ____ ____ | |__
  95. // | | _/\_ __ \__ \ / \_/ ___\| | \
  96. // | | \ | | \// __ \| | \ \___| Y \
  97. // |______ / |__| (____ /___| /\___ >___| /
  98. // \/ \/ \/ \/ \/
  99. type ProtectBranch struct {
  100. Protected bool
  101. RequirePullRequest bool
  102. EnableWhitelist bool
  103. WhitelistUsers string
  104. WhitelistTeams string
  105. func (f *ProtectBranch) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  106. // __ __ ___. .__ .__ __
  107. // / \ / \ ____\_ |__ | |__ | |__ ____ | | __
  108. // \ \/\/ // __ \| __ \| | \| | \ / _ \| |/ /
  109. // \ /\ ___/| \_\ \ Y \ Y ( <_> ) <
  110. // \__/\ / \___ >___ /___| /___| /\____/|__|_ \
  111. // \/ \/ \/ \/ \/ \/
  112. type Webhook struct {
  113. Events string
  114. Create bool
  115. Delete bool
  116. Fork bool
  117. Push bool
  118. Issues bool
  119. IssueComment bool
  120. PullRequest bool
  121. Release bool
  122. Active bool
  123. func (f Webhook) PushOnly() bool {
  124. return f.Events == "push_only"
  125. func (f Webhook) SendEverything() bool {
  126. return f.Events == "send_everything"
  127. func (f Webhook) ChooseEvents() bool {
  128. return f.Events == "choose_events"
  129. type NewWebhook struct {
  130. PayloadURL string `binding:"Required;Url"`
  131. ContentType int `binding:"Required"`
  132. Secret string
  133. Webhook
  134. func (f *NewWebhook) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  135. type NewSlackHook struct {
  136. PayloadURL string `binding:"Required;Url"`
  137. Channel string `binding:"Required"`
  138. Username string
  139. IconURL string
  140. Color string
  141. func (f *NewSlackHook) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  142. type NewDiscordHook struct {
  143. func (f *NewDiscordHook) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  144. type NewDingtalkHook struct {
  145. func (f *NewDingtalkHook) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  146. // .___
  147. // | | ______ ________ __ ____
  148. // | |/ ___// ___/ | \_/ __ \
  149. // | |\___ \ \___ \| | /\ ___/
  150. // |___/____ >____ >____/ \___ >
  151. // \/ \/ \/
  152. type NewIssue struct {
  153. Title string `binding:"Required;MaxSize(255)"`
  154. LabelIDs string `form:"label_ids"`
  155. MilestoneID int64
  156. AssigneeID int64
  157. Content string
  158. Files []string
  159. func (f *NewIssue) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  160. type CreateComment struct {
  161. Content string
  162. Status string `binding:"OmitEmpty;In(reopen,close)"`
  163. Files []string
  164. func (f *CreateComment) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  165. // _____ .__.__ __
  166. // / \ |__| | ____ _______/ |_ ____ ____ ____
  167. // / \ / \| | | _/ __ \ / ___/\ __\/ _ \ / \_/ __ \
  168. // / Y \ | |_\ ___/ \___ \ | | ( <_> ) | \ ___/
  169. // \____|__ /__|____/\___ >____ > |__| \____/|___| /\___ >
  170. // \/ \/ \/ \/ \/
  171. type CreateMilestone struct {
  172. Title string `binding:"Required;MaxSize(50)"`
  173. Content string
  174. Deadline string
  175. func (f *CreateMilestone) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  176. // .____ ___. .__
  177. // | | _____ \_ |__ ____ | |
  178. // | | \__ \ | __ \_/ __ \| |
  179. // | |___ / __ \| \_\ \ ___/| |__
  180. // |_______ (____ /___ /\___ >____/
  181. // \/ \/ \/ \/
  182. type CreateLabel struct {
  183. ID int64
  184. Title string `binding:"Required;MaxSize(50)" locale:"repo.issues.label_title"`
  185. Color string `binding:"Required;Size(7)" locale:"repo.issues.label_color"`
  186. func (f *CreateLabel) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  187. type InitializeLabels struct {
  188. TemplateName string `binding:"Required"`
  189. func (f *InitializeLabels) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  190. // __________ .__
  191. // \______ \ ____ | | ____ _____ ______ ____
  192. // | _// __ \| | _/ __ \\__ \ / ___// __ \
  193. // | | \ ___/| |_\ ___/ / __ \_\___ \\ ___/
  194. // |____|_ /\___ >____/\___ >____ /____ >\___ >
  195. // \/ \/ \/ \/ \/ \/
  196. type NewRelease struct {
  197. TagName string `binding:"Required"`
  198. Target string `form:"tag_target" binding:"Required"`
  199. Title string `binding:"Required"`
  200. Content string
  201. Draft string
  202. Prerelease bool
  203. Files []string
  204. func (f *NewRelease) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  205. type EditRelease struct {
  206. func (f *EditRelease) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  207. // __ __.__ __ .__
  208. // / \ / \__| | _|__|
  209. // \ \/\/ / | |/ / |
  210. // \ /| | <| |
  211. // \__/\ / |__|__|_ \__|
  212. // \/ \/
  213. type NewWiki struct {
  214. OldTitle string
  215. Title string `binding:"Required"`
  216. Content string `binding:"Required"`
  217. Message string
  218. // FIXME: use code generation to generate this method.
  219. func (f *NewWiki) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  220. // ___________ .___.__ __
  221. // \_ _____/ __| _/|__|/ |_
  222. // | __)_ / __ | | \ __\
  223. // | \/ /_/ | | || |
  224. // /_______ /\____ | |__||__|
  225. // \/ \/
  226. type EditRepoFile struct {
  227. TreePath string `binding:"Required;MaxSize(500)"`
  228. Content string `binding:"Required"`
  229. CommitSummary string `binding:"MaxSize(100)"`
  230. CommitMessage string
  231. CommitChoice string `binding:"Required;MaxSize(50)"`
  232. NewBranchName string `binding:"AlphaDashDotSlash;MaxSize(100)"`
  233. LastCommit string
  234. func (f *EditRepoFile) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  235. func (f *EditRepoFile) IsNewBrnach() bool {
  236. return f.CommitChoice == "commit-to-new-branch"
  237. type EditPreviewDiff struct {
  238. func (f *EditPreviewDiff) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  239. // ____ ___ .__ .___
  240. // | | \______ | | _________ __| _/
  241. // | | /\____ \| | / _ \__ \ / __ |
  242. // | | / | |_> > |_( <_> ) __ \_/ /_/ |
  243. // |______/ | __/|____/\____(____ /\____ |
  244. // |__| \/ \/
  245. //
  246. type UploadRepoFile struct {
  247. TreePath string `binding:"MaxSize(500)"`
  248. NewBranchName string `binding:"AlphaDashDot;MaxSize(100)"`
  249. Files []string
  250. func (f *UploadRepoFile) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  251. func (f *UploadRepoFile) IsNewBrnach() bool {
  252. type RemoveUploadFile struct {
  253. File string `binding:"Required;MaxSize(50)"`
  254. func (f *RemoveUploadFile) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  255. // ________ .__ __
  256. // \______ \ ____ | | _____/ |_ ____
  257. // | | \_/ __ \| | _/ __ \ __\/ __ \
  258. // | ` \ ___/| |_\ ___/| | \ ___/
  259. // /_______ /\___ >____/\___ >__| \___ >
  260. // \/ \/ \/ \/
  261. type DeleteRepoFile struct {
  262. func (f *DeleteRepoFile) Validate(ctx http.ResponseWriter, req *http.Request, errs binding.Errors) binding.Errors {
  263. func (f *DeleteRepoFile) IsNewBrnach() bool {