You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

repo_form.go 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Copyright 2017 The Gitea Authors. All rights reserved.
  3. // Use of this source code is governed by a MIT-style
  4. // license that can be found in the LICENSE file.
  5. package auth
  6. import (
  7. "net/url"
  8. "strings"
  9. "code.gitea.io/gitea/models"
  10. "github.com/Unknwon/com"
  11. "github.com/go-macaron/binding"
  12. "gopkg.in/macaron.v1"
  13. )
  14. // _______________________________________ _________.______________________ _______________.___.
  15. // \______ \_ _____/\______ \_____ \ / _____/| \__ ___/\_____ \\______ \__ | |
  16. // | _/| __)_ | ___// | \ \_____ \ | | | | / | \| _// | |
  17. // | | \| \ | | / | \/ \| | | | / | \ | \\____ |
  18. // |____|_ /_______ / |____| \_______ /_______ /|___| |____| \_______ /____|_ // ______|
  19. // \/ \/ \/ \/ \/ \/ \/
  20. // CreateRepoForm form for creating repository
  21. type CreateRepoForm struct {
  22. UID int64 `binding:"Required"`
  23. RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"`
  24. Private bool
  25. Description string `binding:"MaxSize(255)"`
  26. AutoInit bool
  27. Gitignores string
  28. License string
  29. Readme string
  30. }
  31. // Validate validates the fields
  32. func (f *CreateRepoForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  33. return validate(errs, ctx.Data, f, ctx.Locale)
  34. }
  35. // MigrateRepoForm form for migrating repository
  36. type MigrateRepoForm struct {
  37. // required: true
  38. CloneAddr string `json:"clone_addr" binding:"Required"`
  39. AuthUsername string `json:"auth_username"`
  40. AuthPassword string `json:"auth_password"`
  41. // required: true
  42. UID int64 `json:"uid" binding:"Required"`
  43. // required: true
  44. RepoName string `json:"repo_name" binding:"Required;AlphaDashDot;MaxSize(100)"`
  45. Mirror bool `json:"mirror"`
  46. Private bool `json:"private"`
  47. Description string `json:"description" binding:"MaxSize(255)"`
  48. }
  49. // Validate validates the fields
  50. func (f *MigrateRepoForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  51. return validate(errs, ctx.Data, f, ctx.Locale)
  52. }
  53. // ParseRemoteAddr checks if given remote address is valid,
  54. // and returns composed URL with needed username and password.
  55. // It also checks if given user has permission when remote address
  56. // is actually a local path.
  57. func (f MigrateRepoForm) ParseRemoteAddr(user *models.User) (string, error) {
  58. remoteAddr := strings.TrimSpace(f.CloneAddr)
  59. // Remote address can be HTTP/HTTPS/Git URL or local path.
  60. if strings.HasPrefix(remoteAddr, "http://") ||
  61. strings.HasPrefix(remoteAddr, "https://") ||
  62. strings.HasPrefix(remoteAddr, "git://") {
  63. u, err := url.Parse(remoteAddr)
  64. if err != nil {
  65. return "", models.ErrInvalidCloneAddr{IsURLError: true}
  66. }
  67. if len(f.AuthUsername)+len(f.AuthPassword) > 0 {
  68. u.User = url.UserPassword(f.AuthUsername, f.AuthPassword)
  69. }
  70. remoteAddr = u.String()
  71. } else if !user.CanImportLocal() {
  72. return "", models.ErrInvalidCloneAddr{IsPermissionDenied: true}
  73. } else if !com.IsDir(remoteAddr) {
  74. return "", models.ErrInvalidCloneAddr{IsInvalidPath: true}
  75. }
  76. return remoteAddr, nil
  77. }
  78. // RepoSettingForm form for changing repository settings
  79. type RepoSettingForm struct {
  80. RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"`
  81. Description string `binding:"MaxSize(255)"`
  82. Website string `binding:"ValidUrl;MaxSize(255)"`
  83. Interval string
  84. MirrorAddress string
  85. Private bool
  86. EnablePrune bool
  87. // Advanced settings
  88. EnableWiki bool
  89. EnableExternalWiki bool
  90. ExternalWikiURL string
  91. EnableIssues bool
  92. EnableExternalTracker bool
  93. ExternalTrackerURL string
  94. TrackerURLFormat string
  95. TrackerIssueStyle string
  96. EnablePulls bool
  97. PullsIgnoreWhitespace bool
  98. PullsAllowMerge bool
  99. PullsAllowRebase bool
  100. PullsAllowSquash bool
  101. EnableTimetracker bool
  102. AllowOnlyContributorsToTrackTime bool
  103. EnableIssueDependencies bool
  104. // Admin settings
  105. EnableHealthCheck bool
  106. }
  107. // Validate validates the fields
  108. func (f *RepoSettingForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  109. return validate(errs, ctx.Data, f, ctx.Locale)
  110. }
  111. // __________ .__
  112. // \______ \____________ ____ ____ | |__
  113. // | | _/\_ __ \__ \ / \_/ ___\| | \
  114. // | | \ | | \// __ \| | \ \___| Y \
  115. // |______ / |__| (____ /___| /\___ >___| /
  116. // \/ \/ \/ \/ \/
  117. // ProtectBranchForm form for changing protected branch settings
  118. type ProtectBranchForm struct {
  119. Protected bool
  120. EnableWhitelist bool
  121. WhitelistUsers string
  122. WhitelistTeams string
  123. EnableMergeWhitelist bool
  124. MergeWhitelistUsers string
  125. MergeWhitelistTeams string
  126. }
  127. // Validate validates the fields
  128. func (f *ProtectBranchForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  129. return validate(errs, ctx.Data, f, ctx.Locale)
  130. }
  131. // __ __ ___. .__ .__ __
  132. // / \ / \ ____\_ |__ | |__ | |__ ____ | | __
  133. // \ \/\/ // __ \| __ \| | \| | \ / _ \| |/ /
  134. // \ /\ ___/| \_\ \ Y \ Y ( <_> ) <
  135. // \__/\ / \___ >___ /___| /___| /\____/|__|_ \
  136. // \/ \/ \/ \/ \/ \/
  137. // WebhookForm form for changing web hook
  138. type WebhookForm struct {
  139. Events string
  140. Create bool
  141. Delete bool
  142. Fork bool
  143. Issues bool
  144. IssueComment bool
  145. Release bool
  146. Push bool
  147. PullRequest bool
  148. Repository bool
  149. Active bool
  150. }
  151. // PushOnly if the hook will be triggered when push
  152. func (f WebhookForm) PushOnly() bool {
  153. return f.Events == "push_only"
  154. }
  155. // SendEverything if the hook will be triggered any event
  156. func (f WebhookForm) SendEverything() bool {
  157. return f.Events == "send_everything"
  158. }
  159. // ChooseEvents if the hook will be triggered choose events
  160. func (f WebhookForm) ChooseEvents() bool {
  161. return f.Events == "choose_events"
  162. }
  163. // NewWebhookForm form for creating web hook
  164. type NewWebhookForm struct {
  165. PayloadURL string `binding:"Required;ValidUrl"`
  166. ContentType int `binding:"Required"`
  167. Secret string
  168. WebhookForm
  169. }
  170. // Validate validates the fields
  171. func (f *NewWebhookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  172. return validate(errs, ctx.Data, f, ctx.Locale)
  173. }
  174. // NewGogshookForm form for creating gogs hook
  175. type NewGogshookForm struct {
  176. PayloadURL string `binding:"Required;ValidUrl"`
  177. ContentType int `binding:"Required"`
  178. Secret string
  179. WebhookForm
  180. }
  181. // Validate validates the fields
  182. func (f *NewGogshookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  183. return validate(errs, ctx.Data, f, ctx.Locale)
  184. }
  185. // NewSlackHookForm form for creating slack hook
  186. type NewSlackHookForm struct {
  187. PayloadURL string `binding:"Required;ValidUrl"`
  188. Channel string `binding:"Required"`
  189. Username string
  190. IconURL string
  191. Color string
  192. WebhookForm
  193. }
  194. // Validate validates the fields
  195. func (f *NewSlackHookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  196. return validate(errs, ctx.Data, f, ctx.Locale)
  197. }
  198. // NewDiscordHookForm form for creating discord hook
  199. type NewDiscordHookForm struct {
  200. PayloadURL string `binding:"Required;ValidUrl"`
  201. Username string
  202. IconURL string
  203. WebhookForm
  204. }
  205. // Validate validates the fields
  206. func (f *NewDiscordHookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  207. return validate(errs, ctx.Data, f, ctx.Locale)
  208. }
  209. // NewDingtalkHookForm form for creating dingtalk hook
  210. type NewDingtalkHookForm struct {
  211. PayloadURL string `binding:"Required;ValidUrl"`
  212. WebhookForm
  213. }
  214. // Validate validates the fields
  215. func (f *NewDingtalkHookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  216. return validate(errs, ctx.Data, f, ctx.Locale)
  217. }
  218. // .___
  219. // | | ______ ________ __ ____
  220. // | |/ ___// ___/ | \_/ __ \
  221. // | |\___ \ \___ \| | /\ ___/
  222. // |___/____ >____ >____/ \___ >
  223. // \/ \/ \/
  224. // CreateIssueForm form for creating issue
  225. type CreateIssueForm struct {
  226. Title string `binding:"Required;MaxSize(255)"`
  227. LabelIDs string `form:"label_ids"`
  228. AssigneeIDs string `form:"assignee_ids"`
  229. Ref string `form:"ref"`
  230. MilestoneID int64
  231. AssigneeID int64
  232. Content string
  233. Files []string
  234. }
  235. // Validate validates the fields
  236. func (f *CreateIssueForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  237. return validate(errs, ctx.Data, f, ctx.Locale)
  238. }
  239. // CreateCommentForm form for creating comment
  240. type CreateCommentForm struct {
  241. Content string
  242. Status string `binding:"OmitEmpty;In(reopen,close)"`
  243. Files []string
  244. }
  245. // Validate validates the fields
  246. func (f *CreateCommentForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  247. return validate(errs, ctx.Data, f, ctx.Locale)
  248. }
  249. // ReactionForm form for adding and removing reaction
  250. type ReactionForm struct {
  251. Content string `binding:"Required;In(+1,-1,laugh,confused,heart,hooray)"`
  252. }
  253. // Validate validates the fields
  254. func (f *ReactionForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  255. return validate(errs, ctx.Data, f, ctx.Locale)
  256. }
  257. // _____ .__.__ __
  258. // / \ |__| | ____ _______/ |_ ____ ____ ____
  259. // / \ / \| | | _/ __ \ / ___/\ __\/ _ \ / \_/ __ \
  260. // / Y \ | |_\ ___/ \___ \ | | ( <_> ) | \ ___/
  261. // \____|__ /__|____/\___ >____ > |__| \____/|___| /\___ >
  262. // \/ \/ \/ \/ \/
  263. // CreateMilestoneForm form for creating milestone
  264. type CreateMilestoneForm struct {
  265. Title string `binding:"Required;MaxSize(50)"`
  266. Content string
  267. Deadline string
  268. }
  269. // Validate validates the fields
  270. func (f *CreateMilestoneForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  271. return validate(errs, ctx.Data, f, ctx.Locale)
  272. }
  273. // .____ ___. .__
  274. // | | _____ \_ |__ ____ | |
  275. // | | \__ \ | __ \_/ __ \| |
  276. // | |___ / __ \| \_\ \ ___/| |__
  277. // |_______ (____ /___ /\___ >____/
  278. // \/ \/ \/ \/
  279. // CreateLabelForm form for creating label
  280. type CreateLabelForm struct {
  281. ID int64
  282. Title string `binding:"Required;MaxSize(50)" locale:"repo.issues.label_title"`
  283. Description string `binding:"MaxSize(200)" locale:"repo.issues.label_description"`
  284. Color string `binding:"Required;Size(7)" locale:"repo.issues.label_color"`
  285. }
  286. // Validate validates the fields
  287. func (f *CreateLabelForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  288. return validate(errs, ctx.Data, f, ctx.Locale)
  289. }
  290. // InitializeLabelsForm form for initializing labels
  291. type InitializeLabelsForm struct {
  292. TemplateName string `binding:"Required"`
  293. }
  294. // Validate validates the fields
  295. func (f *InitializeLabelsForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  296. return validate(errs, ctx.Data, f, ctx.Locale)
  297. }
  298. // __________ .__ .__ __________ __
  299. // \______ \__ __| | | | \______ \ ____ ________ __ ____ _______/ |_
  300. // | ___/ | \ | | | | _// __ \/ ____/ | \_/ __ \ / ___/\ __\
  301. // | | | | / |_| |__ | | \ ___< <_| | | /\ ___/ \___ \ | |
  302. // |____| |____/|____/____/ |____|_ /\___ >__ |____/ \___ >____ > |__|
  303. // \/ \/ |__| \/ \/
  304. // MergePullRequestForm form for merging Pull Request
  305. type MergePullRequestForm struct {
  306. Do string `binding:"Required;In(merge,rebase,squash)"`
  307. MergeTitleField string
  308. MergeMessageField string
  309. }
  310. // Validate validates the fields
  311. func (f *MergePullRequestForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  312. return validate(errs, ctx.Data, f, ctx.Locale)
  313. }
  314. // CodeCommentForm form for adding code comments for PRs
  315. type CodeCommentForm struct {
  316. Content string `binding:"Required"`
  317. Side string `binding:"Required;In(previous,proposed)"`
  318. Line int64
  319. TreePath string `form:"path" binding:"Required"`
  320. IsReview bool `form:"is_review"`
  321. }
  322. // Validate validates the fields
  323. func (f *CodeCommentForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  324. return validate(errs, ctx.Data, f, ctx.Locale)
  325. }
  326. // SubmitReviewForm for submitting a finished code review
  327. type SubmitReviewForm struct {
  328. Content string
  329. Type string `binding:"Required;In(approve,comment,reject)"`
  330. }
  331. // Validate validates the fields
  332. func (f *SubmitReviewForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  333. return validate(errs, ctx.Data, f, ctx.Locale)
  334. }
  335. // ReviewType will return the corresponding reviewtype for type
  336. func (f SubmitReviewForm) ReviewType() models.ReviewType {
  337. switch f.Type {
  338. case "approve":
  339. return models.ReviewTypeApprove
  340. case "comment":
  341. return models.ReviewTypeComment
  342. case "reject":
  343. return models.ReviewTypeReject
  344. default:
  345. return models.ReviewTypeUnknown
  346. }
  347. }
  348. // __________ .__
  349. // \______ \ ____ | | ____ _____ ______ ____
  350. // | _// __ \| | _/ __ \\__ \ / ___// __ \
  351. // | | \ ___/| |_\ ___/ / __ \_\___ \\ ___/
  352. // |____|_ /\___ >____/\___ >____ /____ >\___ >
  353. // \/ \/ \/ \/ \/ \/
  354. // NewReleaseForm form for creating release
  355. type NewReleaseForm struct {
  356. TagName string `binding:"Required;GitRefName"`
  357. Target string `form:"tag_target" binding:"Required"`
  358. Title string `binding:"Required"`
  359. Content string
  360. Draft string
  361. Prerelease bool
  362. Files []string
  363. }
  364. // Validate validates the fields
  365. func (f *NewReleaseForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  366. return validate(errs, ctx.Data, f, ctx.Locale)
  367. }
  368. // EditReleaseForm form for changing release
  369. type EditReleaseForm struct {
  370. Title string `form:"title" binding:"Required"`
  371. Content string `form:"content"`
  372. Draft string `form:"draft"`
  373. Prerelease bool `form:"prerelease"`
  374. Files []string
  375. }
  376. // Validate validates the fields
  377. func (f *EditReleaseForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  378. return validate(errs, ctx.Data, f, ctx.Locale)
  379. }
  380. // __ __.__ __ .__
  381. // / \ / \__| | _|__|
  382. // \ \/\/ / | |/ / |
  383. // \ /| | <| |
  384. // \__/\ / |__|__|_ \__|
  385. // \/ \/
  386. // NewWikiForm form for creating wiki
  387. type NewWikiForm struct {
  388. Title string `binding:"Required"`
  389. Content string `binding:"Required"`
  390. Message string
  391. }
  392. // Validate validates the fields
  393. // FIXME: use code generation to generate this method.
  394. func (f *NewWikiForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  395. return validate(errs, ctx.Data, f, ctx.Locale)
  396. }
  397. // ___________ .___.__ __
  398. // \_ _____/ __| _/|__|/ |_
  399. // | __)_ / __ | | \ __\
  400. // | \/ /_/ | | || |
  401. // /_______ /\____ | |__||__|
  402. // \/ \/
  403. // EditRepoFileForm form for changing repository file
  404. type EditRepoFileForm struct {
  405. TreePath string `binding:"Required;MaxSize(500)"`
  406. Content string `binding:"Required"`
  407. CommitSummary string `binding:"MaxSize(100)"`
  408. CommitMessage string
  409. CommitChoice string `binding:"Required;MaxSize(50)"`
  410. NewBranchName string `binding:"GitRefName;MaxSize(100)"`
  411. LastCommit string
  412. }
  413. // Validate validates the fields
  414. func (f *EditRepoFileForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  415. return validate(errs, ctx.Data, f, ctx.Locale)
  416. }
  417. // EditPreviewDiffForm form for changing preview diff
  418. type EditPreviewDiffForm struct {
  419. Content string
  420. }
  421. // Validate validates the fields
  422. func (f *EditPreviewDiffForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  423. return validate(errs, ctx.Data, f, ctx.Locale)
  424. }
  425. // ____ ___ .__ .___
  426. // | | \______ | | _________ __| _/
  427. // | | /\____ \| | / _ \__ \ / __ |
  428. // | | / | |_> > |_( <_> ) __ \_/ /_/ |
  429. // |______/ | __/|____/\____(____ /\____ |
  430. // |__| \/ \/
  431. //
  432. // UploadRepoFileForm form for uploading repository file
  433. type UploadRepoFileForm struct {
  434. TreePath string `binding:"MaxSize(500)"`
  435. CommitSummary string `binding:"MaxSize(100)"`
  436. CommitMessage string
  437. CommitChoice string `binding:"Required;MaxSize(50)"`
  438. NewBranchName string `binding:"GitRefName;MaxSize(100)"`
  439. Files []string
  440. }
  441. // Validate validates the fields
  442. func (f *UploadRepoFileForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  443. return validate(errs, ctx.Data, f, ctx.Locale)
  444. }
  445. // RemoveUploadFileForm form for removing uploaded file
  446. type RemoveUploadFileForm struct {
  447. File string `binding:"Required;MaxSize(50)"`
  448. }
  449. // Validate validates the fields
  450. func (f *RemoveUploadFileForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  451. return validate(errs, ctx.Data, f, ctx.Locale)
  452. }
  453. // ________ .__ __
  454. // \______ \ ____ | | _____/ |_ ____
  455. // | | \_/ __ \| | _/ __ \ __\/ __ \
  456. // | ` \ ___/| |_\ ___/| | \ ___/
  457. // /_______ /\___ >____/\___ >__| \___ >
  458. // \/ \/ \/ \/
  459. // DeleteRepoFileForm form for deleting repository file
  460. type DeleteRepoFileForm struct {
  461. CommitSummary string `binding:"MaxSize(100)"`
  462. CommitMessage string
  463. CommitChoice string `binding:"Required;MaxSize(50)"`
  464. NewBranchName string `binding:"GitRefName;MaxSize(100)"`
  465. }
  466. // Validate validates the fields
  467. func (f *DeleteRepoFileForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  468. return validate(errs, ctx.Data, f, ctx.Locale)
  469. }
  470. // ___________.__ ___________ __
  471. // \__ ___/|__| _____ ____ \__ ___/___________ ____ | | __ ___________
  472. // | | | |/ \_/ __ \ | | \_ __ \__ \ _/ ___\| |/ // __ \_ __ \
  473. // | | | | Y Y \ ___/ | | | | \// __ \\ \___| <\ ___/| | \/
  474. // |____| |__|__|_| /\___ > |____| |__| (____ /\___ >__|_ \\___ >__|
  475. // \/ \/ \/ \/ \/ \/
  476. // AddTimeManuallyForm form that adds spent time manually.
  477. type AddTimeManuallyForm struct {
  478. Hours int `binding:"Range(0,1000)"`
  479. Minutes int `binding:"Range(0,1000)"`
  480. }
  481. // Validate validates the fields
  482. func (f *AddTimeManuallyForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  483. return validate(errs, ctx.Data, f, ctx.Locale)
  484. }
  485. // SaveTopicForm form for save topics for repository
  486. type SaveTopicForm struct {
  487. Topics []string `binding:"topics;Required;"`
  488. }
  489. // DeadlineForm hold the validation rules for deadlines
  490. type DeadlineForm struct {
  491. DateString string `form:"date" binding:"Required;Size(10)"`
  492. }
  493. // Validate validates the fields
  494. func (f *DeadlineForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
  495. return validate(errs, ctx.Data, f, ctx.Locale)
  496. }