repo.go 13 KB

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