repo.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package form
  5. import (
  6. "net/url"
  7. "strings"
  8. "github.com/go-macaron/binding"
  9. "github.com/unknwon/com"
  10. "gopkg.in/macaron.v1"
  11. "gogs.io/gogs/internal/db"
  12. )
  13. // _______________________________________ _________.______________________ _______________.___.
  14. // \______ \_ _____/\______ \_____ \ / _____/| \__ ___/\_____ \\______ \__ | |
  15. // | _/| __)_ | ___// | \ \_____ \ | | | | / | \| _// | |
  16. // | | \| \ | | / | \/ \| | | | / | \ | \\____ |
  17. // |____|_ /_______ / |____| \_______ /_______ /|___| |____| \_______ /____|_ // ______|
  18. // \/ \/ \/ \/ \/ \/ \/
  19. type CreateRepo struct {
  20. UserID int64 `binding:"Required"`
  21. RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"`
  22. Private bool
  23. Unlisted bool
  24. Description string `binding:"MaxSize(512)"`
  25. AutoInit bool
  26. Gitignores string
  27. License string
  28. Readme string
  29. }
  30. func (f *CreateRepo) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  31. return validate(errs, ctx.Data, f, ctx.Locale)
  32. }
  33. type MigrateRepo struct {
  34. CloneAddr string `json:"clone_addr" binding:"Required"`
  35. AuthUsername string `json:"auth_username"`
  36. AuthPassword string `json:"auth_password"`
  37. Uid int64 `json:"uid" binding:"Required"`
  38. RepoName string `json:"repo_name" binding:"Required;AlphaDashDot;MaxSize(100)"`
  39. Mirror bool `json:"mirror"`
  40. Private bool `json:"private"`
  41. Unlisted bool `json:"unlisted"`
  42. Description string `json:"description" binding:"MaxSize(512)"`
  43. }
  44. func (f *MigrateRepo) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  45. return validate(errs, ctx.Data, f, ctx.Locale)
  46. }
  47. // ParseRemoteAddr checks if given remote address is valid,
  48. // and returns composed URL with needed username and password.
  49. // It also checks if given user has permission when remote address
  50. // is actually a local path.
  51. func (f MigrateRepo) ParseRemoteAddr(user *db.User) (string, error) {
  52. remoteAddr := strings.TrimSpace(f.CloneAddr)
  53. // Remote address can be HTTP/HTTPS/Git URL or local path.
  54. if strings.HasPrefix(remoteAddr, "http://") ||
  55. strings.HasPrefix(remoteAddr, "https://") ||
  56. strings.HasPrefix(remoteAddr, "git://") {
  57. u, err := url.Parse(remoteAddr)
  58. if err != nil {
  59. return "", db.ErrInvalidCloneAddr{IsURLError: true}
  60. }
  61. if len(f.AuthUsername)+len(f.AuthPassword) > 0 {
  62. u.User = url.UserPassword(f.AuthUsername, f.AuthPassword)
  63. }
  64. // To prevent CRLF injection in git protocol, see https://github.com/gogs/gogs/issues/6413
  65. if u.Scheme == "git" && (strings.Contains(remoteAddr, "%0d") || strings.Contains(remoteAddr, "%0a")) {
  66. return "", db.ErrInvalidCloneAddr{IsURLError: true}
  67. }
  68. remoteAddr = u.String()
  69. } else if !user.CanImportLocal() {
  70. return "", db.ErrInvalidCloneAddr{IsPermissionDenied: true}
  71. } else if !com.IsDir(remoteAddr) {
  72. return "", db.ErrInvalidCloneAddr{IsInvalidPath: true}
  73. }
  74. return remoteAddr, nil
  75. }
  76. type RepoSetting struct {
  77. RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"`
  78. Description string `binding:"MaxSize(512)"`
  79. Website string `binding:"Url;MaxSize(100)"`
  80. Branch string
  81. Interval int
  82. MirrorAddress string
  83. Private bool
  84. Unlisted bool
  85. EnablePrune bool
  86. // Advanced settings
  87. EnableWiki bool
  88. AllowPublicWiki bool
  89. EnableExternalWiki bool
  90. ExternalWikiURL string
  91. EnableIssues bool
  92. AllowPublicIssues bool
  93. EnableExternalTracker bool
  94. ExternalTrackerURL string
  95. TrackerURLFormat string
  96. TrackerIssueStyle string
  97. EnablePulls bool
  98. PullsIgnoreWhitespace bool
  99. PullsAllowRebase bool
  100. }
  101. func (f *RepoSetting) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  102. return validate(errs, ctx.Data, f, ctx.Locale)
  103. }
  104. // __________ .__
  105. // \______ \____________ ____ ____ | |__
  106. // | | _/\_ __ \__ \ / \_/ ___\| | \
  107. // | | \ | | \// __ \| | \ \___| Y \
  108. // |______ / |__| (____ /___| /\___ >___| /
  109. // \/ \/ \/ \/ \/
  110. type ProtectBranch struct {
  111. Protected bool
  112. RequirePullRequest bool
  113. EnableWhitelist bool
  114. WhitelistUsers string
  115. WhitelistTeams string
  116. }
  117. func (f *ProtectBranch) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  118. return validate(errs, ctx.Data, f, ctx.Locale)
  119. }
  120. // __ __ ___. .__ .__ __
  121. // / \ / \ ____\_ |__ | |__ | |__ ____ | | __
  122. // \ \/\/ // __ \| __ \| | \| | \ / _ \| |/ /
  123. // \ /\ ___/| \_\ \ Y \ Y ( <_> ) <
  124. // \__/\ / \___ >___ /___| /___| /\____/|__|_ \
  125. // \/ \/ \/ \/ \/ \/
  126. type Webhook struct {
  127. Events string
  128. Create bool
  129. Delete bool
  130. Fork bool
  131. Push bool
  132. Issues bool
  133. IssueComment bool
  134. PullRequest bool
  135. Release bool
  136. Active bool
  137. }
  138. func (f Webhook) PushOnly() bool {
  139. return f.Events == "push_only"
  140. }
  141. func (f Webhook) SendEverything() bool {
  142. return f.Events == "send_everything"
  143. }
  144. func (f Webhook) ChooseEvents() bool {
  145. return f.Events == "choose_events"
  146. }
  147. type NewWebhook struct {
  148. PayloadURL string `binding:"Required;Url"`
  149. ContentType int `binding:"Required"`
  150. Secret string
  151. Webhook
  152. }
  153. func (f *NewWebhook) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  154. return validate(errs, ctx.Data, f, ctx.Locale)
  155. }
  156. type NewSlackHook struct {
  157. PayloadURL string `binding:"Required;Url"`
  158. Channel string `binding:"Required"`
  159. Username string
  160. IconURL string
  161. Color string
  162. Webhook
  163. }
  164. func (f *NewSlackHook) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  165. return validate(errs, ctx.Data, f, ctx.Locale)
  166. }
  167. type NewDiscordHook struct {
  168. PayloadURL string `binding:"Required;Url"`
  169. Username string
  170. IconURL string
  171. Color string
  172. Webhook
  173. }
  174. func (f *NewDiscordHook) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  175. return validate(errs, ctx.Data, f, ctx.Locale)
  176. }
  177. type NewDingtalkHook struct {
  178. PayloadURL string `binding:"Required;Url"`
  179. Webhook
  180. }
  181. func (f *NewDingtalkHook) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  182. return validate(errs, ctx.Data, f, ctx.Locale)
  183. }
  184. // .___
  185. // | | ______ ________ __ ____
  186. // | |/ ___// ___/ | \_/ __ \
  187. // | |\___ \ \___ \| | /\ ___/
  188. // |___/____ >____ >____/ \___ >
  189. // \/ \/ \/
  190. type NewIssue struct {
  191. Title string `binding:"Required;MaxSize(255)"`
  192. LabelIDs string `form:"label_ids"`
  193. MilestoneID int64
  194. AssigneeID int64
  195. Content string
  196. Files []string
  197. }
  198. func (f *NewIssue) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  199. return validate(errs, ctx.Data, f, ctx.Locale)
  200. }
  201. type CreateComment struct {
  202. Content string
  203. Status string `binding:"OmitEmpty;In(reopen,close)"`
  204. Files []string
  205. }
  206. func (f *CreateComment) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  207. return validate(errs, ctx.Data, f, ctx.Locale)
  208. }
  209. // _____ .__.__ __
  210. // / \ |__| | ____ _______/ |_ ____ ____ ____
  211. // / \ / \| | | _/ __ \ / ___/\ __\/ _ \ / \_/ __ \
  212. // / Y \ | |_\ ___/ \___ \ | | ( <_> ) | \ ___/
  213. // \____|__ /__|____/\___ >____ > |__| \____/|___| /\___ >
  214. // \/ \/ \/ \/ \/
  215. type CreateMilestone struct {
  216. Title string `binding:"Required;MaxSize(50)"`
  217. Content string
  218. Deadline string
  219. }
  220. func (f *CreateMilestone) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  221. return validate(errs, ctx.Data, f, ctx.Locale)
  222. }
  223. // .____ ___. .__
  224. // | | _____ \_ |__ ____ | |
  225. // | | \__ \ | __ \_/ __ \| |
  226. // | |___ / __ \| \_\ \ ___/| |__
  227. // |_______ (____ /___ /\___ >____/
  228. // \/ \/ \/ \/
  229. type CreateLabel struct {
  230. ID int64
  231. Title string `binding:"Required;MaxSize(50)" locale:"repo.issues.label_title"`
  232. Color string `binding:"Required;Size(7)" locale:"repo.issues.label_color"`
  233. }
  234. func (f *CreateLabel) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  235. return validate(errs, ctx.Data, f, ctx.Locale)
  236. }
  237. type InitializeLabels struct {
  238. TemplateName string `binding:"Required"`
  239. }
  240. func (f *InitializeLabels) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  241. return validate(errs, ctx.Data, f, ctx.Locale)
  242. }
  243. // __________ .__
  244. // \______ \ ____ | | ____ _____ ______ ____
  245. // | _// __ \| | _/ __ \\__ \ / ___// __ \
  246. // | | \ ___/| |_\ ___/ / __ \_\___ \\ ___/
  247. // |____|_ /\___ >____/\___ >____ /____ >\___ >
  248. // \/ \/ \/ \/ \/ \/
  249. type NewRelease struct {
  250. TagName string `binding:"Required"`
  251. Target string `form:"tag_target" binding:"Required"`
  252. Title string `binding:"Required"`
  253. Content string
  254. Draft string
  255. Prerelease bool
  256. Files []string
  257. }
  258. func (f *NewRelease) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  259. return validate(errs, ctx.Data, f, ctx.Locale)
  260. }
  261. type EditRelease struct {
  262. Title string `binding:"Required"`
  263. Content string
  264. Draft string
  265. Prerelease bool
  266. Files []string
  267. }
  268. func (f *EditRelease) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  269. return validate(errs, ctx.Data, f, ctx.Locale)
  270. }
  271. // __ __.__ __ .__
  272. // / \ / \__| | _|__|
  273. // \ \/\/ / | |/ / |
  274. // \ /| | <| |
  275. // \__/\ / |__|__|_ \__|
  276. // \/ \/
  277. type NewWiki struct {
  278. OldTitle string
  279. Title string `binding:"Required"`
  280. Content string `binding:"Required"`
  281. Message string
  282. }
  283. // FIXME: use code generation to generate this method.
  284. func (f *NewWiki) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  285. return validate(errs, ctx.Data, f, ctx.Locale)
  286. }
  287. // ___________ .___.__ __
  288. // \_ _____/ __| _/|__|/ |_
  289. // | __)_ / __ | | \ __\
  290. // | \/ /_/ | | || |
  291. // /_______ /\____ | |__||__|
  292. // \/ \/
  293. type EditRepoFile struct {
  294. TreePath string `binding:"Required;MaxSize(500)"`
  295. Content string `binding:"Required"`
  296. CommitSummary string `binding:"MaxSize(100)"`
  297. CommitMessage string
  298. CommitChoice string `binding:"Required;MaxSize(50)"`
  299. NewBranchName string `binding:"AlphaDashDotSlash;MaxSize(100)"`
  300. LastCommit string
  301. }
  302. func (f *EditRepoFile) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  303. return validate(errs, ctx.Data, f, ctx.Locale)
  304. }
  305. func (f *EditRepoFile) IsNewBrnach() bool {
  306. return f.CommitChoice == "commit-to-new-branch"
  307. }
  308. type EditPreviewDiff struct {
  309. Content string
  310. }
  311. func (f *EditPreviewDiff) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  312. return validate(errs, ctx.Data, f, ctx.Locale)
  313. }
  314. // ____ ___ .__ .___
  315. // | | \______ | | _________ __| _/
  316. // | | /\____ \| | / _ \__ \ / __ |
  317. // | | / | |_> > |_( <_> ) __ \_/ /_/ |
  318. // |______/ | __/|____/\____(____ /\____ |
  319. // |__| \/ \/
  320. //
  321. type UploadRepoFile struct {
  322. TreePath string `binding:"MaxSize(500)"`
  323. CommitSummary string `binding:"MaxSize(100)"`
  324. CommitMessage string
  325. CommitChoice string `binding:"Required;MaxSize(50)"`
  326. NewBranchName string `binding:"AlphaDashDot;MaxSize(100)"`
  327. Files []string
  328. }
  329. func (f *UploadRepoFile) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  330. return validate(errs, ctx.Data, f, ctx.Locale)
  331. }
  332. func (f *UploadRepoFile) IsNewBrnach() bool {
  333. return f.CommitChoice == "commit-to-new-branch"
  334. }
  335. type RemoveUploadFile struct {
  336. File string `binding:"Required;MaxSize(50)"`
  337. }
  338. func (f *RemoveUploadFile) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  339. return validate(errs, ctx.Data, f, ctx.Locale)
  340. }
  341. // ________ .__ __
  342. // \______ \ ____ | | _____/ |_ ____
  343. // | | \_/ __ \| | _/ __ \ __\/ __ \
  344. // | ` \ ___/| |_\ ___/| | \ ___/
  345. // /_______ /\___ >____/\___ >__| \___ >
  346. // \/ \/ \/ \/
  347. type DeleteRepoFile struct {
  348. CommitSummary string `binding:"MaxSize(100)"`
  349. CommitMessage string
  350. CommitChoice string `binding:"Required;MaxSize(50)"`
  351. NewBranchName string `binding:"AlphaDashDot;MaxSize(100)"`
  352. }
  353. func (f *DeleteRepoFile) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  354. return validate(errs, ctx.Data, f, ctx.Locale)
  355. }
  356. func (f *DeleteRepoFile) IsNewBrnach() bool {
  357. return f.CommitChoice == "commit-to-new-branch"
  358. }