diff --git a/cmd/web.go b/cmd/web.go index be489c1be4..74da86d40e 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -165,21 +165,22 @@ func runWeb(*cli.Context) { m.Get("/template/**", dev.TemplatePreview) } - reqOwner := middleware.RequireOwner + reqOwner := middleware.RequireOwner() m.Group("/:username/:reponame", func(r martini.Router) { r.Get("/settings", repo.Setting) r.Post("/settings", bindIgnErr(auth.RepoSettingForm{}), repo.SettingPost) r.Get("/settings/collaboration", repo.Collaboration) r.Post("/settings/collaboration", repo.CollaborationPost) - r.Get("/settings/hooks", repo.WebHooks) // TODO + r.Get("/settings/hooks", repo.WebHooks) r.Get("/settings/hooks/add", repo.WebHooksAdd) r.Post("/settings/hooks/add", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksAddPost) - r.Get("/settings/hooks/id", repo.WebHooksEdit) - }, reqSignIn, middleware.RepoAssignment(true), reqOwner()) + r.Get("/settings/hooks/:id", repo.WebHooksEdit) + r.Post("/settings/hooks/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost) + }, reqSignIn, middleware.RepoAssignment(true), reqOwner) m.Group("/:username/:reponame", func(r martini.Router) { - r.Get("/action/:action", repo.Action) + r.Get("/action/:action", repo.Action) // TODO r.Get("/issues/new", repo.CreateIssue) r.Post("/issues/new", bindIgnErr(auth.CreateIssueForm{}), repo.CreateIssuePost) r.Post("/issues/:index", bindIgnErr(auth.CreateIssueForm{}), repo.UpdateIssue) diff --git a/models/repo.go b/models/repo.go index e8baadf6b0..d2b92be487 100644 --- a/models/repo.go +++ b/models/repo.go @@ -690,7 +690,7 @@ func GetRepositoryById(id int64) (*Repository, error) { } else if !has { return nil, ErrRepoNotExist } - return repo, err + return repo, nil } // GetRepositories returns the list of repositories of given user. diff --git a/models/webhook.go b/models/webhook.go index 78d984cfe7..daa4510f2d 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -6,10 +6,15 @@ package models import ( "encoding/json" + "errors" "github.com/gogits/gogs/modules/log" ) +var ( + ErrWebhookNotExist = errors.New("Webhook does not exist") +) + // Content types. const ( CT_JSON = iota + 1 @@ -27,20 +32,20 @@ type Webhook struct { ContentType int Secret string `xorm:"TEXT"` Events string `xorm:"TEXT"` + *HookEvent `xorm:"-"` IsSsl bool IsActive bool } -func (w *Webhook) GetEvent() *HookEvent { - h := &HookEvent{} - if err := json.Unmarshal([]byte(w.Events), h); err != nil { +func (w *Webhook) GetEvent() { + w.HookEvent = &HookEvent{} + if err := json.Unmarshal([]byte(w.Events), w.HookEvent); err != nil { log.Error("webhook.GetEvent(%d): %v", w.Id, err) } - return h } -func (w *Webhook) SaveEvent(h *HookEvent) error { - data, err := json.Marshal(h) +func (w *Webhook) SaveEvent() error { + data, err := json.Marshal(w.HookEvent) w.Events = string(data) return err } @@ -51,8 +56,32 @@ func CreateWebhook(w *Webhook) error { return err } +// UpdateWebhook updates information of webhook. +func UpdateWebhook(w *Webhook) error { + _, err := orm.AllCols().Update(w) + return err +} + +// GetWebhookById returns webhook by given ID. +func GetWebhookById(hookId int64) (*Webhook, error) { + w := &Webhook{Id: hookId} + has, err := orm.Get(w) + if err != nil { + return nil, err + } else if !has { + return nil, ErrWebhookNotExist + } + return w, nil +} + // GetWebhooksByRepoId returns all webhooks of repository. func GetWebhooksByRepoId(repoId int64) (ws []*Webhook, err error) { err = orm.Find(&ws, &Webhook{RepoId: repoId}) return ws, err } + +// DeleteWebhook deletes webhook of repository. +func DeleteWebhook(hookId int64) error { + _, err := orm.Delete(&Webhook{Id: hookId}) + return err +} diff --git a/routers/repo/setting.go b/routers/repo/setting.go index d49c93375b..6937d0b42a 100644 --- a/routers/repo/setting.go +++ b/routers/repo/setting.go @@ -8,6 +8,8 @@ import ( "fmt" "strings" + "github.com/go-martini/martini" + "github.com/gogits/git" "github.com/gogits/gogs/models" @@ -39,13 +41,13 @@ func SettingPost(ctx *middleware.Context, form auth.RepoSettingForm) { if ctx.Repo.Repository.Name != newRepoName { isExist, err := models.IsRepositoryExist(ctx.Repo.Owner, newRepoName) if err != nil { - ctx.Handle(500, "repo.SettingPost(update: check existence)", err) + ctx.Handle(500, "setting.SettingPost(update: check existence)", err) return } else if isExist { ctx.RenderWithErr("Repository name has been taken in your repositories.", "repo/setting", nil) return } else if err = models.ChangeRepositoryName(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name, newRepoName); err != nil { - ctx.Handle(500, "repo.SettingPost(change repository name)", err) + ctx.Handle(500, "setting.SettingPost(change repository name)", err) return } log.Trace("%s Repository name changed: %s/%s -> %s", ctx.Req.RequestURI, ctx.User.Name, ctx.Repo.Repository.Name, newRepoName) @@ -63,7 +65,7 @@ func SettingPost(ctx *middleware.Context, form auth.RepoSettingForm) { ctx.Repo.Repository.IsPrivate = form.Private ctx.Repo.Repository.IsGoget = form.GoGet if err := models.UpdateRepository(ctx.Repo.Repository); err != nil { - ctx.Handle(404, "repo.SettingPost(update)", err) + ctx.Handle(404, "setting.SettingPost(update)", err) return } log.Trace("%s Repository updated: %s/%s", ctx.Req.RequestURI, ctx.Repo.Owner.Name, ctx.Repo.Repository.Name) @@ -72,7 +74,7 @@ func SettingPost(ctx *middleware.Context, form auth.RepoSettingForm) { if form.Interval > 0 { ctx.Repo.Mirror.Interval = form.Interval if err := models.UpdateMirror(ctx.Repo.Mirror); err != nil { - log.Error("repo.SettingPost(UpdateMirror): %v", err) + log.Error("setting.SettingPost(UpdateMirror): %v", err) } } } @@ -89,13 +91,13 @@ func SettingPost(ctx *middleware.Context, form auth.RepoSettingForm) { // Check if new owner exists. isExist, err := models.IsUserExist(newOwner) if err != nil { - ctx.Handle(500, "repo.SettingPost(transfer: check existence)", err) + ctx.Handle(500, "setting.SettingPost(transfer: check existence)", err) return } else if !isExist { ctx.RenderWithErr("Please make sure you entered owner name is correct.", "repo/setting", nil) return } else if err = models.TransferOwnership(ctx.User, newOwner, ctx.Repo.Repository); err != nil { - ctx.Handle(500, "repo.SettingPost(transfer repository)", err) + ctx.Handle(500, "setting.SettingPost(transfer repository)", err) return } log.Trace("%s Repository transfered: %s/%s -> %s", ctx.Req.RequestURI, ctx.User.Name, ctx.Repo.Repository.Name, newOwner) @@ -108,7 +110,7 @@ func SettingPost(ctx *middleware.Context, form auth.RepoSettingForm) { } if err := models.DeleteRepository(ctx.User.Id, ctx.Repo.Repository.Id, ctx.User.LowerName); err != nil { - ctx.Handle(500, "repo.Delete", err) + ctx.Handle(500, "setting.Delete", err) return } log.Trace("%s Repository deleted: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, ctx.Repo.Repository.LowerName) @@ -126,7 +128,7 @@ func Collaboration(ctx *middleware.Context) { remove := strings.ToLower(ctx.Query("remove")) if len(remove) > 0 && remove != ctx.Repo.Owner.LowerName { if err := models.DeleteAccess(&models.Access{UserName: remove, RepoName: repoLink}); err != nil { - ctx.Handle(500, "repo.Collaboration(DeleteAccess)", err) + ctx.Handle(500, "setting.Collaboration(DeleteAccess)", err) return } ctx.Flash.Success("Collaborator has been removed.") @@ -136,7 +138,7 @@ func Collaboration(ctx *middleware.Context) { names, err := models.GetCollaborators(repoLink) if err != nil { - ctx.Handle(500, "repo.Collaboration(GetCollaborators)", err) + ctx.Handle(500, "setting.Collaboration(GetCollaborators)", err) return } @@ -144,7 +146,7 @@ func Collaboration(ctx *middleware.Context) { for i, name := range names { us[i], err = models.GetUserByName(name) if err != nil { - ctx.Handle(500, "repo.Collaboration(GetUserByName)", err) + ctx.Handle(500, "setting.Collaboration(GetUserByName)", err) return } } @@ -162,7 +164,7 @@ func CollaborationPost(ctx *middleware.Context) { } has, err := models.HasAccess(name, repoLink, models.AU_WRITABLE) if err != nil { - ctx.Handle(500, "repo.CollaborationPost(HasAccess)", err) + ctx.Handle(500, "setting.CollaborationPost(HasAccess)", err) return } else if has { ctx.Redirect(ctx.Req.RequestURI) @@ -175,20 +177,20 @@ func CollaborationPost(ctx *middleware.Context) { ctx.Flash.Error("Given user does not exist.") ctx.Redirect(ctx.Req.RequestURI) } else { - ctx.Handle(500, "repo.CollaborationPost(GetUserByName)", err) + ctx.Handle(500, "setting.CollaborationPost(GetUserByName)", err) } return } if err = models.AddAccess(&models.Access{UserName: name, RepoName: repoLink, Mode: models.AU_WRITABLE}); err != nil { - ctx.Handle(500, "repo.CollaborationPost(AddAccess)", err) + ctx.Handle(500, "setting.CollaborationPost(AddAccess)", err) return } if base.Service.NotifyMail { if err = mailer.SendCollaboratorMail(ctx.Render, u, ctx.User, ctx.Repo.Repository); err != nil { - ctx.Handle(500, "repo.CollaborationPost(SendCollaboratorMail)", err) + ctx.Handle(500, "setting.CollaborationPost(SendCollaboratorMail)", err) return } } @@ -201,9 +203,21 @@ func WebHooks(ctx *middleware.Context) { ctx.Data["IsRepoToolbarWebHooks"] = true ctx.Data["Title"] = strings.TrimPrefix(ctx.Repo.RepoLink, "/") + " - Webhooks" + // Delete webhook. + remove, _ := base.StrTo(ctx.Query("remove")).Int64() + if remove > 0 { + if err := models.DeleteWebhook(remove); err != nil { + ctx.Handle(500, "setting.WebHooks(DeleteWebhook)", err) + return + } + ctx.Flash.Success("Webhook has been removed.") + ctx.Redirect(ctx.Repo.RepoLink + "/settings/hooks") + return + } + ws, err := models.GetWebhooksByRepoId(ctx.Repo.Repository.Id) if err != nil { - ctx.Handle(500, "repo.WebHooks(GetWebhooksByRepoId)", err) + ctx.Handle(500, "setting.WebHooks(GetWebhooksByRepoId)", err) return } @@ -227,7 +241,7 @@ func WebHooksAddPost(ctx *middleware.Context, form auth.NewWebhookForm) { } ct := models.CT_JSON - if form.ContentType == "form" { + if form.ContentType == "2" { ct = models.CT_FORM } @@ -236,16 +250,16 @@ func WebHooksAddPost(ctx *middleware.Context, form auth.NewWebhookForm) { Payload: form.Url, ContentType: ct, Secret: form.Secret, - IsActive: form.Active, + HookEvent: &models.HookEvent{ + PushOnly: form.PushOnly, + }, + IsActive: form.Active, } - h := &models.HookEvent{ - PushOnly: form.PushOnly, - } - if err := w.SaveEvent(h); err != nil { - ctx.Handle(500, "repo.WebHooksAddPost(SaveEvent)", err) + if err := w.SaveEvent(); err != nil { + ctx.Handle(500, "setting.WebHooksAddPost(SaveEvent)", err) return } else if err := models.CreateWebhook(w); err != nil { - ctx.Handle(500, "repo.WebHooksAddPost(CreateWebhook)", err) + ctx.Handle(500, "setting.WebHooksAddPost(CreateWebhook)", err) return } @@ -253,8 +267,70 @@ func WebHooksAddPost(ctx *middleware.Context, form auth.NewWebhookForm) { ctx.Redirect(ctx.Repo.RepoLink + "/settings/hooks") } -func WebHooksEdit(ctx *middleware.Context) { +func WebHooksEdit(ctx *middleware.Context, params martini.Params) { ctx.Data["IsRepoToolbarWebHooks"] = true ctx.Data["Title"] = strings.TrimPrefix(ctx.Repo.RepoLink, "/") + " - Webhook" + + hookId, _ := base.StrTo(params["id"]).Int64() + if hookId == 0 { + ctx.Handle(404, "setting.WebHooksEdit", nil) + return + } + + w, err := models.GetWebhookById(hookId) + if err != nil { + if err == models.ErrWebhookNotExist { + ctx.Handle(404, "setting.WebHooksEdit(GetWebhookById)", nil) + } else { + ctx.Handle(500, "setting.WebHooksEdit(GetWebhookById)", err) + } + return + } + + w.GetEvent() + ctx.Data["Webhook"] = w ctx.HTML(200, "repo/hooks_edit") } + +func WebHooksEditPost(ctx *middleware.Context, params martini.Params, form auth.NewWebhookForm) { + ctx.Data["IsRepoToolbarWebHooks"] = true + ctx.Data["Title"] = strings.TrimPrefix(ctx.Repo.RepoLink, "/") + " - Webhook" + + if ctx.HasError() { + ctx.HTML(200, "repo/hooks_add") + return + } + + hookId, _ := base.StrTo(params["id"]).Int64() + if hookId == 0 { + ctx.Handle(404, "setting.WebHooksEditPost", nil) + return + } + + ct := models.CT_JSON + if form.ContentType == "2" { + ct = models.CT_FORM + } + + w := &models.Webhook{ + Id: hookId, + RepoId: ctx.Repo.Repository.Id, + Payload: form.Url, + ContentType: ct, + Secret: form.Secret, + HookEvent: &models.HookEvent{ + PushOnly: form.PushOnly, + }, + IsActive: form.Active, + } + if err := w.SaveEvent(); err != nil { + ctx.Handle(500, "setting.WebHooksEditPost(SaveEvent)", err) + return + } else if err := models.UpdateWebhook(w); err != nil { + ctx.Handle(500, "setting.WebHooksEditPost(WebHooksEditPost)", err) + return + } + + ctx.Flash.Success("Webhook has been updated.") + ctx.Redirect(fmt.Sprintf("%s/settings/hooks/%d", ctx.Repo.RepoLink, hookId)) +} diff --git a/templates/repo/hooks.tmpl b/templates/repo/hooks.tmpl index eed35c3583..e1b36a67e8 100644 --- a/templates/repo/hooks.tmpl +++ b/templates/repo/hooks.tmpl @@ -15,7 +15,7 @@
We will deliver event details when this hook is triggered.