setting.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  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 repo
  5. import (
  6. "encoding/json"
  7. "errors"
  8. "fmt"
  9. "strings"
  10. "time"
  11. "github.com/Unknwon/com"
  12. "github.com/gogits/gogs/models"
  13. "github.com/gogits/gogs/modules/auth"
  14. "github.com/gogits/gogs/modules/base"
  15. "github.com/gogits/gogs/modules/git"
  16. "github.com/gogits/gogs/modules/log"
  17. "github.com/gogits/gogs/modules/mailer"
  18. "github.com/gogits/gogs/modules/middleware"
  19. "github.com/gogits/gogs/modules/setting"
  20. )
  21. const (
  22. SETTINGS_OPTIONS base.TplName = "repo/settings/options"
  23. COLLABORATION base.TplName = "repo/settings/collaboration"
  24. HOOKS base.TplName = "repo/settings/hooks"
  25. GITHOOKS base.TplName = "repo/settings/githooks"
  26. GITHOOK_EDIT base.TplName = "repo/settings/githook_edit"
  27. HOOK_NEW base.TplName = "repo/settings/hook_new"
  28. ORG_HOOK_NEW base.TplName = "org/settings/hook_new"
  29. )
  30. func Settings(ctx *middleware.Context) {
  31. ctx.Data["Title"] = ctx.Tr("repo.settings")
  32. ctx.Data["PageIsSettingsOptions"] = true
  33. ctx.HTML(200, SETTINGS_OPTIONS)
  34. }
  35. func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
  36. ctx.Data["Title"] = ctx.Tr("repo.settings")
  37. ctx.Data["PageIsSettingsOptions"] = true
  38. switch ctx.Query("action") {
  39. case "update":
  40. if ctx.HasError() {
  41. ctx.HTML(200, SETTINGS_OPTIONS)
  42. return
  43. }
  44. newRepoName := form.RepoName
  45. // Check if repository name has been changed.
  46. if ctx.Repo.Repository.Name != newRepoName {
  47. if models.IsRepositoryExist(ctx.Repo.Owner, newRepoName) {
  48. ctx.Data["Err_RepoName"] = true
  49. ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), SETTINGS_OPTIONS, nil)
  50. return
  51. } else if err := models.ChangeRepositoryName(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name, newRepoName); err != nil {
  52. if err == models.ErrRepoNameIllegal {
  53. ctx.Data["Err_RepoName"] = true
  54. ctx.RenderWithErr(ctx.Tr("form.illegal_repo_name"), SETTINGS_OPTIONS, nil)
  55. } else {
  56. ctx.Handle(500, "ChangeRepositoryName", err)
  57. }
  58. return
  59. }
  60. log.Trace("Repository name changed: %s/%s -> %s", ctx.Repo.Owner.Name, ctx.Repo.Repository.Name, newRepoName)
  61. ctx.Repo.Repository.Name = newRepoName
  62. ctx.Repo.Repository.LowerName = strings.ToLower(newRepoName)
  63. }
  64. br := form.Branch
  65. if ctx.Repo.GitRepo.IsBranchExist(br) {
  66. ctx.Repo.Repository.DefaultBranch = br
  67. }
  68. ctx.Repo.Repository.Description = form.Description
  69. ctx.Repo.Repository.Website = form.Website
  70. ctx.Repo.Repository.IsPrivate = form.Private
  71. if err := models.UpdateRepository(ctx.Repo.Repository); err != nil {
  72. ctx.Handle(404, "UpdateRepository", err)
  73. return
  74. }
  75. log.Trace("Repository updated: %s/%s", ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
  76. if ctx.Repo.Repository.IsMirror {
  77. if form.Interval > 0 {
  78. ctx.Repo.Mirror.Interval = form.Interval
  79. ctx.Repo.Mirror.NextUpdate = time.Now().Add(time.Duration(form.Interval) * time.Hour)
  80. if err := models.UpdateMirror(ctx.Repo.Mirror); err != nil {
  81. log.Error(4, "UpdateMirror: %v", err)
  82. }
  83. }
  84. }
  85. ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
  86. ctx.Redirect(fmt.Sprintf("%s/%s/%s/settings", setting.AppSubUrl, ctx.Repo.Owner.Name, ctx.Repo.Repository.Name))
  87. case "transfer":
  88. if ctx.Repo.Repository.Name != form.RepoName {
  89. ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_repo_name"), SETTINGS_OPTIONS, nil)
  90. return
  91. }
  92. newOwner := ctx.Query("new_owner_name")
  93. isExist, err := models.IsUserExist(0, newOwner)
  94. if err != nil {
  95. ctx.Handle(500, "IsUserExist", err)
  96. return
  97. } else if !isExist {
  98. ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_owner_name"), SETTINGS_OPTIONS, nil)
  99. return
  100. }
  101. if _, err = models.UserSignIn(ctx.User.Name, ctx.Query("password")); err != nil {
  102. if err == models.ErrUserNotExist {
  103. ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_password"), SETTINGS_OPTIONS, nil)
  104. } else {
  105. ctx.Handle(500, "UserSignIn", err)
  106. }
  107. return
  108. }
  109. if err = models.TransferOwnership(ctx.User, newOwner, ctx.Repo.Repository); err != nil {
  110. if err == models.ErrRepoAlreadyExist {
  111. ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), SETTINGS_OPTIONS, nil)
  112. } else {
  113. ctx.Handle(500, "TransferOwnership", err)
  114. }
  115. return
  116. }
  117. log.Trace("Repository transfered: %s/%s -> %s", ctx.Repo.Owner.Name, ctx.Repo.Repository.Name, newOwner)
  118. ctx.Flash.Success(ctx.Tr("repo.settings.transfer_succeed"))
  119. ctx.Redirect(setting.AppSubUrl + "/")
  120. case "delete":
  121. if ctx.Repo.Repository.Name != form.RepoName {
  122. ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_repo_name"), SETTINGS_OPTIONS, nil)
  123. return
  124. }
  125. if ctx.Repo.Owner.IsOrganization() {
  126. if !ctx.Repo.Owner.IsOwnedBy(ctx.User.Id) {
  127. ctx.Error(404)
  128. return
  129. }
  130. }
  131. if _, err := models.UserSignIn(ctx.User.Name, ctx.Query("password")); err != nil {
  132. if err == models.ErrUserNotExist {
  133. ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_password"), SETTINGS_OPTIONS, nil)
  134. } else {
  135. ctx.Handle(500, "UserSignIn", err)
  136. }
  137. return
  138. }
  139. if err := models.DeleteRepository(ctx.Repo.Owner.Id, ctx.Repo.Repository.Id, ctx.Repo.Owner.Name); err != nil {
  140. ctx.Handle(500, "DeleteRepository", err)
  141. return
  142. }
  143. log.Trace("Repository deleted: %s/%s", ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
  144. if ctx.Repo.Owner.IsOrganization() {
  145. ctx.Redirect(setting.AppSubUrl + "/org/" + ctx.Repo.Owner.Name + "/dashboard")
  146. } else {
  147. ctx.Redirect(setting.AppSubUrl + "/")
  148. }
  149. }
  150. }
  151. func SettingsCollaboration(ctx *middleware.Context) {
  152. ctx.Data["Title"] = ctx.Tr("repo.settings")
  153. ctx.Data["PageIsSettingsCollaboration"] = true
  154. if ctx.Req.Method == "POST" {
  155. name := strings.ToLower(ctx.Query("collaborator"))
  156. if len(name) == 0 || ctx.Repo.Owner.LowerName == name {
  157. ctx.Redirect(setting.AppSubUrl + ctx.Req.URL.Path)
  158. return
  159. }
  160. u, err := models.GetUserByName(name)
  161. if err != nil {
  162. if err == models.ErrUserNotExist {
  163. ctx.Flash.Error(ctx.Tr("form.user_not_exist"))
  164. ctx.Redirect(setting.AppSubUrl + ctx.Req.URL.Path)
  165. } else {
  166. ctx.Handle(500, "GetUserByName", err)
  167. }
  168. return
  169. }
  170. // Check if user is organization member.
  171. if ctx.Repo.Owner.IsOrganization() && ctx.Repo.Owner.IsOrgMember(u.Id) {
  172. ctx.Flash.Info(ctx.Tr("repo.settings.user_is_org_member"))
  173. ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
  174. return
  175. }
  176. if err = ctx.Repo.Repository.AddCollaborator(u); err != nil {
  177. ctx.Handle(500, "AddCollaborator", err)
  178. return
  179. }
  180. if setting.Service.EnableNotifyMail {
  181. if err = mailer.SendCollaboratorMail(ctx.Render, u, ctx.User, ctx.Repo.Repository); err != nil {
  182. ctx.Handle(500, "SendCollaboratorMail", err)
  183. return
  184. }
  185. }
  186. ctx.Flash.Success(ctx.Tr("repo.settings.add_collaborator_success"))
  187. ctx.Redirect(setting.AppSubUrl + ctx.Req.URL.Path)
  188. return
  189. }
  190. // Delete collaborator.
  191. remove := strings.ToLower(ctx.Query("remove"))
  192. if len(remove) > 0 && remove != ctx.Repo.Owner.LowerName {
  193. u, err := models.GetUserByName(remove)
  194. if err != nil {
  195. ctx.Handle(500, "GetUserByName", err)
  196. return
  197. }
  198. if err := ctx.Repo.Repository.DeleteCollaborator(u); err != nil {
  199. ctx.Handle(500, "DeleteCollaborator", err)
  200. return
  201. }
  202. ctx.Flash.Success(ctx.Tr("repo.settings.remove_collaborator_success"))
  203. ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
  204. return
  205. }
  206. users, err := ctx.Repo.Repository.GetCollaborators()
  207. if err != nil {
  208. ctx.Handle(500, "GetCollaborators", err)
  209. return
  210. }
  211. ctx.Data["Collaborators"] = users
  212. ctx.HTML(200, COLLABORATION)
  213. }
  214. func Webhooks(ctx *middleware.Context) {
  215. ctx.Data["Title"] = ctx.Tr("repo.settings")
  216. ctx.Data["PageIsSettingsHooks"] = true
  217. // Delete web hook.
  218. remove := com.StrTo(ctx.Query("remove")).MustInt64()
  219. if remove > 0 {
  220. if err := models.DeleteWebhook(remove); err != nil {
  221. ctx.Handle(500, "DeleteWebhook", err)
  222. return
  223. }
  224. ctx.Flash.Success(ctx.Tr("repo.settings.remove_hook_success"))
  225. ctx.Redirect(ctx.Repo.RepoLink + "/settings/hooks")
  226. return
  227. }
  228. ws, err := models.GetWebhooksByRepoId(ctx.Repo.Repository.Id)
  229. if err != nil {
  230. ctx.Handle(500, "GetWebhooksByRepoId", err)
  231. return
  232. }
  233. ctx.Data["Webhooks"] = ws
  234. ctx.HTML(200, HOOKS)
  235. }
  236. func renderHookTypes(ctx *middleware.Context) {
  237. ctx.Data["HookTypes"] = []string{"Gogs", "Slack"}
  238. ctx.Data["HookType"] = "Gogs"
  239. }
  240. func WebHooksNew(ctx *middleware.Context) {
  241. ctx.Data["Title"] = ctx.Tr("repo.settings")
  242. ctx.Data["PageIsSettingsHooks"] = true
  243. ctx.Data["PageIsSettingsHooksNew"] = true
  244. ctx.Data["Webhook"] = models.Webhook{HookEvent: &models.HookEvent{}}
  245. renderHookTypes(ctx)
  246. orCtx, err := getOrgRepoCtx(ctx)
  247. if err != nil {
  248. ctx.Handle(500, "WebHooksNew(getOrgRepoCtx)", err)
  249. return
  250. }
  251. ctx.HTML(200, orCtx.NewTemplate)
  252. }
  253. func WebHooksNewPost(ctx *middleware.Context, form auth.NewWebhookForm) {
  254. ctx.Data["Title"] = ctx.Tr("repo.settings")
  255. ctx.Data["PageIsSettingsHooks"] = true
  256. ctx.Data["PageIsSettingsHooksNew"] = true
  257. ctx.Data["Webhook"] = models.Webhook{HookEvent: &models.HookEvent{}}
  258. orCtx, err := getOrgRepoCtx(ctx)
  259. if err != nil {
  260. ctx.Handle(500, "WebHooksNewPost(getOrgRepoCtx)", err)
  261. return
  262. }
  263. if ctx.HasError() {
  264. ctx.HTML(200, orCtx.NewTemplate)
  265. return
  266. }
  267. // FIXME: code too old here, sync with APIs
  268. ct := models.JSON
  269. if form.ContentType == "2" {
  270. ct = models.FORM
  271. }
  272. w := &models.Webhook{
  273. RepoId: orCtx.RepoId,
  274. Url: form.PayloadUrl,
  275. ContentType: ct,
  276. Secret: form.Secret,
  277. HookEvent: &models.HookEvent{
  278. PushOnly: form.PushOnly,
  279. },
  280. IsActive: form.Active,
  281. HookTaskType: models.GOGS,
  282. Meta: "",
  283. OrgId: orCtx.OrgId,
  284. }
  285. if err := w.UpdateEvent(); err != nil {
  286. ctx.Handle(500, "UpdateEvent", err)
  287. return
  288. } else if err := models.CreateWebhook(w); err != nil {
  289. ctx.Handle(500, "CreateWebhook", err)
  290. return
  291. }
  292. ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success"))
  293. ctx.Redirect(orCtx.Link + "/settings/hooks")
  294. }
  295. func WebHooksEdit(ctx *middleware.Context) {
  296. ctx.Data["Title"] = ctx.Tr("repo.settings")
  297. ctx.Data["PageIsSettingsHooks"] = true
  298. ctx.Data["PageIsSettingsHooksEdit"] = true
  299. hookId := com.StrTo(ctx.Params(":id")).MustInt64()
  300. if hookId == 0 {
  301. ctx.Handle(404, "setting.WebHooksEdit", nil)
  302. return
  303. }
  304. w, err := models.GetWebhookById(hookId)
  305. if err != nil {
  306. if err == models.ErrWebhookNotExist {
  307. ctx.Handle(404, "GetWebhookById", nil)
  308. } else {
  309. ctx.Handle(500, "GetWebhookById", err)
  310. }
  311. return
  312. }
  313. // set data per HookTaskType
  314. switch w.HookTaskType {
  315. case models.SLACK:
  316. {
  317. ctx.Data["SlackHook"] = w.GetSlackHook()
  318. ctx.Data["HookType"] = "Slack"
  319. }
  320. default:
  321. {
  322. ctx.Data["HookType"] = "Gogs"
  323. }
  324. }
  325. w.GetEvent()
  326. ctx.Data["Webhook"] = w
  327. orCtx, err := getOrgRepoCtx(ctx)
  328. if err != nil {
  329. ctx.Handle(500, "WebHooksEdit(getOrgRepoCtx)", err)
  330. return
  331. }
  332. ctx.HTML(200, orCtx.NewTemplate)
  333. }
  334. func WebHooksEditPost(ctx *middleware.Context, form auth.NewWebhookForm) {
  335. ctx.Data["Title"] = ctx.Tr("repo.settings")
  336. ctx.Data["PageIsSettingsHooks"] = true
  337. ctx.Data["PageIsSettingsHooksEdit"] = true
  338. hookId := com.StrTo(ctx.Params(":id")).MustInt64()
  339. if hookId == 0 {
  340. ctx.Handle(404, "setting.WebHooksEditPost", nil)
  341. return
  342. }
  343. w, err := models.GetWebhookById(hookId)
  344. if err != nil {
  345. if err == models.ErrWebhookNotExist {
  346. ctx.Handle(404, "GetWebhookById", nil)
  347. } else {
  348. ctx.Handle(500, "GetWebhookById", err)
  349. }
  350. return
  351. }
  352. w.GetEvent()
  353. ctx.Data["Webhook"] = w
  354. orCtx, err := getOrgRepoCtx(ctx)
  355. if err != nil {
  356. ctx.Handle(500, "WebHooksEditPost(getOrgRepoCtx)", err)
  357. return
  358. }
  359. if ctx.HasError() {
  360. ctx.HTML(200, orCtx.NewTemplate)
  361. return
  362. }
  363. ct := models.JSON
  364. if form.ContentType == "2" {
  365. ct = models.FORM
  366. }
  367. w.Url = form.PayloadUrl
  368. w.ContentType = ct
  369. w.Secret = form.Secret
  370. w.HookEvent = &models.HookEvent{
  371. PushOnly: form.PushOnly,
  372. }
  373. w.IsActive = form.Active
  374. if err := w.UpdateEvent(); err != nil {
  375. ctx.Handle(500, "UpdateEvent", err)
  376. return
  377. } else if err := models.UpdateWebhook(w); err != nil {
  378. ctx.Handle(500, "WebHooksEditPost", err)
  379. return
  380. }
  381. ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success"))
  382. ctx.Redirect(fmt.Sprintf("%s/settings/hooks/%d", orCtx.Link, hookId))
  383. }
  384. func SlackHooksNewPost(ctx *middleware.Context, form auth.NewSlackHookForm) {
  385. ctx.Data["Title"] = ctx.Tr("repo.settings")
  386. ctx.Data["PageIsSettingsHooks"] = true
  387. ctx.Data["PageIsSettingsHooksNew"] = true
  388. ctx.Data["Webhook"] = models.Webhook{HookEvent: &models.HookEvent{}}
  389. orCtx, err := getOrgRepoCtx(ctx)
  390. if err != nil {
  391. ctx.Handle(500, "SlackHooksNewPost(getOrgRepoCtx)", err)
  392. return
  393. }
  394. if ctx.HasError() {
  395. ctx.HTML(200, orCtx.NewTemplate)
  396. return
  397. }
  398. meta, err := json.Marshal(&models.Slack{
  399. Channel: form.Channel,
  400. })
  401. if err != nil {
  402. ctx.Handle(500, "SlackHooksNewPost: JSON marshal failed: ", err)
  403. return
  404. }
  405. w := &models.Webhook{
  406. RepoId: orCtx.RepoId,
  407. Url: form.PayloadUrl,
  408. ContentType: models.JSON,
  409. Secret: "",
  410. HookEvent: &models.HookEvent{
  411. PushOnly: form.PushOnly,
  412. },
  413. IsActive: form.Active,
  414. HookTaskType: models.SLACK,
  415. Meta: string(meta),
  416. OrgId: orCtx.OrgId,
  417. }
  418. if err := w.UpdateEvent(); err != nil {
  419. ctx.Handle(500, "UpdateEvent", err)
  420. return
  421. } else if err := models.CreateWebhook(w); err != nil {
  422. ctx.Handle(500, "CreateWebhook", err)
  423. return
  424. }
  425. ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success"))
  426. ctx.Redirect(orCtx.Link + "/settings/hooks")
  427. }
  428. func SlackHooksEditPost(ctx *middleware.Context, form auth.NewSlackHookForm) {
  429. ctx.Data["Title"] = ctx.Tr("repo.settings")
  430. ctx.Data["PageIsSettingsHooks"] = true
  431. ctx.Data["PageIsSettingsHooksEdit"] = true
  432. hookId := com.StrTo(ctx.Params(":id")).MustInt64()
  433. if hookId == 0 {
  434. ctx.Handle(404, "SlackHooksEditPost(hookId)", nil)
  435. return
  436. }
  437. orCtx, err := getOrgRepoCtx(ctx)
  438. if err != nil {
  439. ctx.Handle(500, "SlackHooksEditPost(getOrgRepoCtx)", err)
  440. return
  441. }
  442. w, err := models.GetWebhookById(hookId)
  443. if err != nil {
  444. if err == models.ErrWebhookNotExist {
  445. ctx.Handle(404, "GetWebhookById", nil)
  446. } else {
  447. ctx.Handle(500, "GetWebhookById", err)
  448. }
  449. return
  450. }
  451. w.GetEvent()
  452. ctx.Data["Webhook"] = w
  453. if ctx.HasError() {
  454. ctx.HTML(200, orCtx.NewTemplate)
  455. return
  456. }
  457. meta, err := json.Marshal(&models.Slack{
  458. Channel: form.Channel,
  459. })
  460. if err != nil {
  461. ctx.Handle(500, "SlackHooksNewPost: JSON marshal failed: ", err)
  462. return
  463. }
  464. w.Url = form.PayloadUrl
  465. w.Meta = string(meta)
  466. w.HookEvent = &models.HookEvent{
  467. PushOnly: form.PushOnly,
  468. }
  469. w.IsActive = form.Active
  470. if err := w.UpdateEvent(); err != nil {
  471. ctx.Handle(500, "UpdateEvent", err)
  472. return
  473. } else if err := models.UpdateWebhook(w); err != nil {
  474. ctx.Handle(500, "SlackHooksEditPost", err)
  475. return
  476. }
  477. ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success"))
  478. ctx.Redirect(fmt.Sprintf("%s/settings/hooks/%d", orCtx.Link, hookId))
  479. }
  480. type OrgRepoCtx struct {
  481. OrgId int64
  482. RepoId int64
  483. Link string
  484. NewTemplate base.TplName
  485. }
  486. // determines whether this is a repo context or organization context
  487. func getOrgRepoCtx(ctx *middleware.Context) (*OrgRepoCtx, error) {
  488. if _, ok := ctx.Data["RepoLink"]; ok {
  489. return &OrgRepoCtx{
  490. OrgId: int64(0),
  491. RepoId: ctx.Repo.Repository.Id,
  492. Link: ctx.Repo.RepoLink,
  493. NewTemplate: HOOK_NEW,
  494. }, nil
  495. } else if _, ok := ctx.Data["OrgLink"]; ok {
  496. return &OrgRepoCtx{
  497. OrgId: ctx.Org.Organization.Id,
  498. RepoId: int64(0),
  499. Link: ctx.Org.OrgLink,
  500. NewTemplate: ORG_HOOK_NEW,
  501. }, nil
  502. } else {
  503. return &OrgRepoCtx{}, errors.New("Unable to set OrgRepo context")
  504. }
  505. }
  506. func GitHooks(ctx *middleware.Context) {
  507. ctx.Data["Title"] = ctx.Tr("repo.settings")
  508. ctx.Data["PageIsSettingsGitHooks"] = true
  509. hooks, err := ctx.Repo.GitRepo.Hooks()
  510. if err != nil {
  511. ctx.Handle(500, "Hooks", err)
  512. return
  513. }
  514. ctx.Data["Hooks"] = hooks
  515. ctx.HTML(200, GITHOOKS)
  516. }
  517. func GitHooksEdit(ctx *middleware.Context) {
  518. ctx.Data["Title"] = ctx.Tr("repo.settings")
  519. ctx.Data["PageIsSettingsGitHooks"] = true
  520. name := ctx.Params(":name")
  521. hook, err := ctx.Repo.GitRepo.GetHook(name)
  522. if err != nil {
  523. if err == git.ErrNotValidHook {
  524. ctx.Handle(404, "GetHook", err)
  525. } else {
  526. ctx.Handle(500, "GetHook", err)
  527. }
  528. return
  529. }
  530. ctx.Data["Hook"] = hook
  531. ctx.HTML(200, GITHOOK_EDIT)
  532. }
  533. func GitHooksEditPost(ctx *middleware.Context) {
  534. name := ctx.Params(":name")
  535. hook, err := ctx.Repo.GitRepo.GetHook(name)
  536. if err != nil {
  537. if err == git.ErrNotValidHook {
  538. ctx.Handle(404, "GetHook", err)
  539. } else {
  540. ctx.Handle(500, "GetHook", err)
  541. }
  542. return
  543. }
  544. hook.Content = ctx.Query("content")
  545. if err = hook.Update(); err != nil {
  546. ctx.Handle(500, "hook.Update", err)
  547. return
  548. }
  549. ctx.Redirect(ctx.Repo.RepoLink + "/settings/hooks/git")
  550. }