@@ -5,7 +5,7 @@ Gogs - Go Git Service [ | |||
##### Current version: 0.7.31 Beta | |||
##### Current version: 0.7.32 Beta | |||
<table> | |||
<tr> | |||
@@ -397,6 +397,7 @@ func runWeb(ctx *cli.Context) { | |||
m.Post("/gogs/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost) | |||
m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost) | |||
m.Get("/:id", repo.WebHooksEdit) | |||
m.Post("/:id/test", repo.TestWebhook) | |||
m.Post("/gogs/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost) | |||
m.Post("/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost) | |||
@@ -597,6 +597,9 @@ settings.hooks_desc = Webhooks are much like basic HTTP POST event triggers. Whe | |||
settings.webhook_deletion = Delete Webhook | |||
settings.webhook_deletion_desc = Delete this webhook will remove its information and all delivery history. Do you want to continue? | |||
settings.webhook_deletion_success = Webhook has been deleted successfully! | |||
settings.webhook.test_delivery = Test Delivery | |||
settings.webhook.test_delivery_desc = Send a fake push event delivery to test your webhook settings | |||
settings.webhook.test_delivery_success = Test webhook has been added to delivery queue. It may taks few seconds before it shows up in the delivery history. | |||
settings.webhook.request = Request | |||
settings.webhook.response = Response | |||
settings.webhook.headers = Headers | |||
@@ -17,7 +17,7 @@ import ( | |||
"github.com/gogits/gogs/modules/setting" | |||
) | |||
const APP_VER = "0.7.31.1205 Beta" | |||
const APP_VER = "0.7.32.1205 Beta" | |||
func init() { | |||
runtime.GOMAXPROCS(runtime.NumCPU()) | |||
@@ -451,24 +451,9 @@ func CommitRepoAction( | |||
IsPrivate: repo.IsPrivate, | |||
}); err != nil { | |||
return fmt.Errorf("NotifyWatchers: %v", err) | |||
} | |||
repoLink := fmt.Sprintf("%s%s/%s", setting.AppUrl, repoUserName, repoName) | |||
payloadRepo := &api.PayloadRepo{ | |||
ID: repo.ID, | |||
Name: repo.LowerName, | |||
URL: repoLink, | |||
Description: repo.Description, | |||
Website: repo.Website, | |||
Watchers: repo.NumWatches, | |||
Owner: &api.PayloadAuthor{ | |||
Name: repo.Owner.DisplayName(), | |||
Email: repo.Owner.Email, | |||
UserName: repo.Owner.Name, | |||
}, | |||
Private: repo.IsPrivate, | |||
} | |||
payloadRepo := repo.ComposePayload() | |||
pusher_email, pusher_name := "", "" | |||
pusher, err := GetUserByName(userName) | |||
@@ -494,7 +479,7 @@ func CommitRepoAction( | |||
commits[i] = &api.PayloadCommit{ | |||
ID: cmt.Sha1, | |||
Message: cmt.Message, | |||
URL: fmt.Sprintf("%s/commit/%s", repoLink, cmt.Sha1), | |||
URL: fmt.Sprintf("%s/commit/%s", repo.RepoLink(), cmt.Sha1), | |||
Author: &api.PayloadAuthor{ | |||
Name: cmt.AuthorName, | |||
Email: cmt.AuthorEmail, | |||
@@ -28,6 +28,7 @@ import ( | |||
"gopkg.in/ini.v1" | |||
"github.com/gogits/git-shell" | |||
api "github.com/gogits/go-gogs-client" | |||
"github.com/gogits/gogs/modules/base" | |||
"github.com/gogits/gogs/modules/bindata" | |||
@@ -380,6 +381,27 @@ func (repo *Repository) SavePatch(index int64, patch []byte) error { | |||
return nil | |||
} | |||
// ComposePayload composes and returns *api.PayloadRepo corresponding to the repository. | |||
func (repo *Repository) ComposePayload() *api.PayloadRepo { | |||
cl := repo.CloneLink() | |||
return &api.PayloadRepo{ | |||
ID: repo.ID, | |||
Name: repo.LowerName, | |||
URL: repo.RepoLink(), | |||
SSHURL: cl.SSH, | |||
CloneURL: cl.HTTPS, | |||
Description: repo.Description, | |||
Website: repo.Website, | |||
Watchers: repo.NumWatches, | |||
Owner: &api.PayloadAuthor{ | |||
Name: repo.MustOwner().DisplayName(), | |||
Email: repo.MustOwner().Email, | |||
UserName: repo.MustOwner().Name, | |||
}, | |||
Private: repo.IsPrivate, | |||
} | |||
} | |||
func isRepositoryExist(e Engine, u *User, repoName string) (bool, error) { | |||
has, err := e.Get(&Repository{ | |||
OwnerID: u.Id, | |||
@@ -335,7 +335,7 @@ func (t *HookTask) AfterSet(colName string, _ xorm.Cell) { | |||
t.ResponseInfo = &HookResponse{} | |||
if err = json.Unmarshal([]byte(t.ResponseContent), t.ResponseInfo); err != nil { | |||
log.Error(3, "Unmarshal[%d]: %v", t.ID, err) | |||
log.Error(3, "Unmarshal [%d]: %v", t.ID, err) | |||
} | |||
} | |||
} | |||
@@ -343,7 +343,7 @@ func (t *HookTask) AfterSet(colName string, _ xorm.Cell) { | |||
func (t *HookTask) MarshalJSON(v interface{}) string { | |||
p, err := json.Marshal(v) | |||
if err != nil { | |||
log.Error(3, "Marshal[%d]: %v", t.ID, err) | |||
log.Error(3, "Marshal [%d]: %v", t.ID, err) | |||
} | |||
return string(p) | |||
} | |||
@@ -590,24 +590,24 @@ func DeliverHooks() { | |||
// Update hook task status. | |||
for _, t := range tasks { | |||
if err := UpdateHookTask(t); err != nil { | |||
log.Error(4, "UpdateHookTask(%d): %v", t.ID, err) | |||
log.Error(4, "UpdateHookTask [%d]: %v", t.ID, err) | |||
} | |||
} | |||
// Start listening on new hook requests. | |||
for repoID := range HookQueue.Queue() { | |||
log.Trace("DeliverHooks[%v]: processing delivery hooks", repoID) | |||
log.Trace("DeliverHooks [%v]: processing delivery hooks", repoID) | |||
HookQueue.Remove(repoID) | |||
tasks = make([]*HookTask, 0, 5) | |||
if err := x.Where("repo_id=? AND is_delivered=?", repoID, false).Find(&tasks); err != nil { | |||
log.Error(4, "Get repository(%d) hook tasks: %v", repoID, err) | |||
log.Error(4, "Get repository [%d] hook tasks: %v", repoID, err) | |||
continue | |||
} | |||
for _, t := range tasks { | |||
t.deliver() | |||
if err := UpdateHookTask(t); err != nil { | |||
log.Error(4, "UpdateHookTask[%d]: %v", t.ID, err) | |||
log.Error(4, "UpdateHookTask [%d]: %v", t.ID, err) | |||
continue | |||
} | |||
} | |||
@@ -548,6 +548,19 @@ function initWebhook() { | |||
$('.events.fields').hide(); | |||
} | |||
}); | |||
// Test delivery | |||
$('#test-delivery').click(function () { | |||
var $this = $(this); | |||
$this.addClass('loading disabled'); | |||
$.post($this.data('link'), { | |||
"_csrf": csrf | |||
}).done( | |||
setTimeout(function () { | |||
window.location.href = $this.data('redirect'); | |||
}, 5000) | |||
) | |||
}); | |||
} | |||
@@ -5,14 +5,9 @@ | |||
package repo | |||
import ( | |||
"encoding/json" | |||
"errors" | |||
"fmt" | |||
"strings" | |||
"time" | |||
"github.com/Unknwon/com" | |||
"github.com/gogits/gogs/models" | |||
"github.com/gogits/gogs/modules/auth" | |||
"github.com/gogits/gogs/modules/base" | |||
@@ -26,9 +21,6 @@ import ( | |||
const ( | |||
SETTINGS_OPTIONS base.TplName = "repo/settings/options" | |||
COLLABORATION base.TplName = "repo/settings/collaboration" | |||
HOOKS base.TplName = "repo/settings/hooks" | |||
HOOK_NEW base.TplName = "repo/settings/hook_new" | |||
ORG_HOOK_NEW base.TplName = "org/settings/hook_new" | |||
GITHOOKS base.TplName = "repo/settings/githooks" | |||
GITHOOK_EDIT base.TplName = "repo/settings/githook_edit" | |||
DEPLOY_KEYS base.TplName = "repo/settings/deploy_keys" | |||
@@ -270,330 +262,6 @@ func Collaboration(ctx *middleware.Context) { | |||
ctx.HTML(200, COLLABORATION) | |||
} | |||
func Webhooks(ctx *middleware.Context) { | |||
ctx.Data["Title"] = ctx.Tr("repo.settings.hooks") | |||
ctx.Data["PageIsSettingsHooks"] = true | |||
ctx.Data["BaseLink"] = ctx.Repo.RepoLink | |||
ctx.Data["Description"] = ctx.Tr("repo.settings.hooks_desc", "https://github.com/gogits/go-gogs-client/wiki/Repositories-Webhooks") | |||
ws, err := models.GetWebhooksByRepoID(ctx.Repo.Repository.ID) | |||
if err != nil { | |||
ctx.Handle(500, "GetWebhooksByRepoID", err) | |||
return | |||
} | |||
ctx.Data["Webhooks"] = ws | |||
ctx.HTML(200, HOOKS) | |||
} | |||
type OrgRepoCtx struct { | |||
OrgID int64 | |||
RepoID int64 | |||
Link string | |||
NewTemplate base.TplName | |||
} | |||
// getOrgRepoCtx determines whether this is a repo context or organization context. | |||
func getOrgRepoCtx(ctx *middleware.Context) (*OrgRepoCtx, error) { | |||
if len(ctx.Repo.RepoLink) > 0 { | |||
return &OrgRepoCtx{ | |||
RepoID: ctx.Repo.Repository.ID, | |||
Link: ctx.Repo.RepoLink, | |||
NewTemplate: HOOK_NEW, | |||
}, nil | |||
} | |||
if len(ctx.Org.OrgLink) > 0 { | |||
return &OrgRepoCtx{ | |||
OrgID: ctx.Org.Organization.Id, | |||
Link: ctx.Org.OrgLink, | |||
NewTemplate: ORG_HOOK_NEW, | |||
}, nil | |||
} | |||
return nil, errors.New("Unable to set OrgRepo context") | |||
} | |||
func checkHookType(ctx *middleware.Context) string { | |||
hookType := strings.ToLower(ctx.Params(":type")) | |||
if !com.IsSliceContainsStr(setting.Webhook.Types, hookType) { | |||
ctx.Handle(404, "checkHookType", nil) | |||
return "" | |||
} | |||
return hookType | |||
} | |||
func WebhooksNew(ctx *middleware.Context) { | |||
ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook") | |||
ctx.Data["PageIsSettingsHooks"] = true | |||
ctx.Data["PageIsSettingsHooksNew"] = true | |||
ctx.Data["Webhook"] = models.Webhook{HookEvent: &models.HookEvent{}} | |||
orCtx, err := getOrgRepoCtx(ctx) | |||
if err != nil { | |||
ctx.Handle(500, "getOrgRepoCtx", err) | |||
return | |||
} | |||
ctx.Data["HookType"] = checkHookType(ctx) | |||
if ctx.Written() { | |||
return | |||
} | |||
ctx.Data["BaseLink"] = orCtx.Link | |||
ctx.HTML(200, orCtx.NewTemplate) | |||
} | |||
func ParseHookEvent(form auth.WebhookForm) *models.HookEvent { | |||
return &models.HookEvent{ | |||
PushOnly: form.PushOnly(), | |||
SendEverything: form.SendEverything(), | |||
ChooseEvents: form.ChooseEvents(), | |||
HookEvents: models.HookEvents{ | |||
Create: form.Create, | |||
Push: form.Push, | |||
}, | |||
} | |||
} | |||
func WebHooksNewPost(ctx *middleware.Context, form auth.NewWebhookForm) { | |||
ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook") | |||
ctx.Data["PageIsSettingsHooks"] = true | |||
ctx.Data["PageIsSettingsHooksNew"] = true | |||
ctx.Data["Webhook"] = models.Webhook{HookEvent: &models.HookEvent{}} | |||
ctx.Data["HookType"] = "gogs" | |||
orCtx, err := getOrgRepoCtx(ctx) | |||
if err != nil { | |||
ctx.Handle(500, "getOrgRepoCtx", err) | |||
return | |||
} | |||
ctx.Data["BaseLink"] = orCtx.Link | |||
if ctx.HasError() { | |||
ctx.HTML(200, orCtx.NewTemplate) | |||
return | |||
} | |||
contentType := models.JSON | |||
if models.HookContentType(form.ContentType) == models.FORM { | |||
contentType = models.FORM | |||
} | |||
w := &models.Webhook{ | |||
RepoID: orCtx.RepoID, | |||
URL: form.PayloadURL, | |||
ContentType: contentType, | |||
Secret: form.Secret, | |||
HookEvent: ParseHookEvent(form.WebhookForm), | |||
IsActive: form.Active, | |||
HookTaskType: models.GOGS, | |||
OrgID: orCtx.OrgID, | |||
} | |||
if err := w.UpdateEvent(); err != nil { | |||
ctx.Handle(500, "UpdateEvent", err) | |||
return | |||
} else if err := models.CreateWebhook(w); err != nil { | |||
ctx.Handle(500, "CreateWebhook", err) | |||
return | |||
} | |||
ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success")) | |||
ctx.Redirect(orCtx.Link + "/settings/hooks") | |||
} | |||
func SlackHooksNewPost(ctx *middleware.Context, form auth.NewSlackHookForm) { | |||
ctx.Data["Title"] = ctx.Tr("repo.settings") | |||
ctx.Data["PageIsSettingsHooks"] = true | |||
ctx.Data["PageIsSettingsHooksNew"] = true | |||
ctx.Data["Webhook"] = models.Webhook{HookEvent: &models.HookEvent{}} | |||
orCtx, err := getOrgRepoCtx(ctx) | |||
if err != nil { | |||
ctx.Handle(500, "getOrgRepoCtx", err) | |||
return | |||
} | |||
if ctx.HasError() { | |||
ctx.HTML(200, orCtx.NewTemplate) | |||
return | |||
} | |||
meta, err := json.Marshal(&models.SlackMeta{ | |||
Channel: form.Channel, | |||
Username: form.Username, | |||
IconURL: form.IconURL, | |||
Color: form.Color, | |||
}) | |||
if err != nil { | |||
ctx.Handle(500, "Marshal", err) | |||
return | |||
} | |||
w := &models.Webhook{ | |||
RepoID: orCtx.RepoID, | |||
URL: form.PayloadURL, | |||
ContentType: models.JSON, | |||
HookEvent: ParseHookEvent(form.WebhookForm), | |||
IsActive: form.Active, | |||
HookTaskType: models.SLACK, | |||
Meta: string(meta), | |||
OrgID: orCtx.OrgID, | |||
} | |||
if err := w.UpdateEvent(); err != nil { | |||
ctx.Handle(500, "UpdateEvent", err) | |||
return | |||
} else if err := models.CreateWebhook(w); err != nil { | |||
ctx.Handle(500, "CreateWebhook", err) | |||
return | |||
} | |||
ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success")) | |||
ctx.Redirect(orCtx.Link + "/settings/hooks") | |||
} | |||
func checkWebhook(ctx *middleware.Context) (*OrgRepoCtx, *models.Webhook) { | |||
ctx.Data["RequireHighlightJS"] = true | |||
orCtx, err := getOrgRepoCtx(ctx) | |||
if err != nil { | |||
ctx.Handle(500, "getOrgRepoCtx", err) | |||
return nil, nil | |||
} | |||
ctx.Data["BaseLink"] = orCtx.Link | |||
w, err := models.GetWebhookByID(ctx.ParamsInt64(":id")) | |||
if err != nil { | |||
if models.IsErrWebhookNotExist(err) { | |||
ctx.Handle(404, "GetWebhookByID", nil) | |||
} else { | |||
ctx.Handle(500, "GetWebhookByID", err) | |||
} | |||
return nil, nil | |||
} | |||
switch w.HookTaskType { | |||
case models.SLACK: | |||
ctx.Data["SlackHook"] = w.GetSlackHook() | |||
ctx.Data["HookType"] = "slack" | |||
default: | |||
ctx.Data["HookType"] = "gogs" | |||
} | |||
ctx.Data["History"], err = w.History(1) | |||
if err != nil { | |||
ctx.Handle(500, "History", err) | |||
} | |||
return orCtx, w | |||
} | |||
func WebHooksEdit(ctx *middleware.Context) { | |||
ctx.Data["Title"] = ctx.Tr("repo.settings.update_webhook") | |||
ctx.Data["PageIsSettingsHooks"] = true | |||
ctx.Data["PageIsSettingsHooksEdit"] = true | |||
orCtx, w := checkWebhook(ctx) | |||
if ctx.Written() { | |||
return | |||
} | |||
ctx.Data["Webhook"] = w | |||
ctx.HTML(200, orCtx.NewTemplate) | |||
} | |||
func WebHooksEditPost(ctx *middleware.Context, form auth.NewWebhookForm) { | |||
ctx.Data["Title"] = ctx.Tr("repo.settings.update_webhook") | |||
ctx.Data["PageIsSettingsHooks"] = true | |||
ctx.Data["PageIsSettingsHooksEdit"] = true | |||
orCtx, w := checkWebhook(ctx) | |||
if ctx.Written() { | |||
return | |||
} | |||
ctx.Data["Webhook"] = w | |||
if ctx.HasError() { | |||
ctx.HTML(200, orCtx.NewTemplate) | |||
return | |||
} | |||
contentType := models.JSON | |||
if models.HookContentType(form.ContentType) == models.FORM { | |||
contentType = models.FORM | |||
} | |||
w.URL = form.PayloadURL | |||
w.ContentType = contentType | |||
w.Secret = form.Secret | |||
w.HookEvent = ParseHookEvent(form.WebhookForm) | |||
w.IsActive = form.Active | |||
if err := w.UpdateEvent(); err != nil { | |||
ctx.Handle(500, "UpdateEvent", err) | |||
return | |||
} else if err := models.UpdateWebhook(w); err != nil { | |||
ctx.Handle(500, "WebHooksEditPost", err) | |||
return | |||
} | |||
ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success")) | |||
ctx.Redirect(fmt.Sprintf("%s/settings/hooks/%d", orCtx.Link, w.ID)) | |||
} | |||
func SlackHooksEditPost(ctx *middleware.Context, form auth.NewSlackHookForm) { | |||
ctx.Data["Title"] = ctx.Tr("repo.settings") | |||
ctx.Data["PageIsSettingsHooks"] = true | |||
ctx.Data["PageIsSettingsHooksEdit"] = true | |||
orCtx, w := checkWebhook(ctx) | |||
if ctx.Written() { | |||
return | |||
} | |||
ctx.Data["Webhook"] = w | |||
if ctx.HasError() { | |||
ctx.HTML(200, orCtx.NewTemplate) | |||
return | |||
} | |||
meta, err := json.Marshal(&models.SlackMeta{ | |||
Channel: form.Channel, | |||
Username: form.Username, | |||
IconURL: form.IconURL, | |||
Color: form.Color, | |||
}) | |||
if err != nil { | |||
ctx.Handle(500, "Marshal", err) | |||
return | |||
} | |||
w.URL = form.PayloadURL | |||
w.Meta = string(meta) | |||
w.HookEvent = ParseHookEvent(form.WebhookForm) | |||
w.IsActive = form.Active | |||
if err := w.UpdateEvent(); err != nil { | |||
ctx.Handle(500, "UpdateEvent", err) | |||
return | |||
} else if err := models.UpdateWebhook(w); err != nil { | |||
ctx.Handle(500, "UpdateWebhook", err) | |||
return | |||
} | |||
ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success")) | |||
ctx.Redirect(fmt.Sprintf("%s/settings/hooks/%d", orCtx.Link, w.ID)) | |||
} | |||
func DeleteWebhook(ctx *middleware.Context) { | |||
if err := models.DeleteWebhook(ctx.QueryInt64("id")); err != nil { | |||
ctx.Flash.Error("DeleteWebhook: " + err.Error()) | |||
} else { | |||
ctx.Flash.Success(ctx.Tr("repo.settings.webhook_deletion_success")) | |||
} | |||
ctx.JSON(200, map[string]interface{}{ | |||
"redirect": ctx.Repo.RepoLink + "/settings/hooks", | |||
}) | |||
} | |||
func parseOwnerAndRepo(ctx *middleware.Context) (*models.User, *models.Repository) { | |||
owner, err := models.GetUserByName(ctx.Params(":username")) | |||
if err != nil { | |||
@@ -0,0 +1,385 @@ | |||
// Copyright 2015 The Gogs Authors. All rights reserved. | |||
// Use of this source code is governed by a MIT-style | |||
// license that can be found in the LICENSE file. | |||
package repo | |||
import ( | |||
"encoding/json" | |||
"errors" | |||
"fmt" | |||
"strings" | |||
"github.com/Unknwon/com" | |||
api "github.com/gogits/go-gogs-client" | |||
"github.com/gogits/gogs/models" | |||
"github.com/gogits/gogs/modules/auth" | |||
"github.com/gogits/gogs/modules/base" | |||
"github.com/gogits/gogs/modules/middleware" | |||
"github.com/gogits/gogs/modules/setting" | |||
) | |||
const ( | |||
HOOKS base.TplName = "repo/settings/hooks" | |||
HOOK_NEW base.TplName = "repo/settings/hook_new" | |||
ORG_HOOK_NEW base.TplName = "org/settings/hook_new" | |||
) | |||
func Webhooks(ctx *middleware.Context) { | |||
ctx.Data["Title"] = ctx.Tr("repo.settings.hooks") | |||
ctx.Data["PageIsSettingsHooks"] = true | |||
ctx.Data["BaseLink"] = ctx.Repo.RepoLink | |||
ctx.Data["Description"] = ctx.Tr("repo.settings.hooks_desc", "https://github.com/gogits/go-gogs-client/wiki/Repositories-Webhooks") | |||
ws, err := models.GetWebhooksByRepoID(ctx.Repo.Repository.ID) | |||
if err != nil { | |||
ctx.Handle(500, "GetWebhooksByRepoID", err) | |||
return | |||
} | |||
ctx.Data["Webhooks"] = ws | |||
ctx.HTML(200, HOOKS) | |||
} | |||
type OrgRepoCtx struct { | |||
OrgID int64 | |||
RepoID int64 | |||
Link string | |||
NewTemplate base.TplName | |||
} | |||
// getOrgRepoCtx determines whether this is a repo context or organization context. | |||
func getOrgRepoCtx(ctx *middleware.Context) (*OrgRepoCtx, error) { | |||
if len(ctx.Repo.RepoLink) > 0 { | |||
return &OrgRepoCtx{ | |||
RepoID: ctx.Repo.Repository.ID, | |||
Link: ctx.Repo.RepoLink, | |||
NewTemplate: HOOK_NEW, | |||
}, nil | |||
} | |||
if len(ctx.Org.OrgLink) > 0 { | |||
return &OrgRepoCtx{ | |||
OrgID: ctx.Org.Organization.Id, | |||
Link: ctx.Org.OrgLink, | |||
NewTemplate: ORG_HOOK_NEW, | |||
}, nil | |||
} | |||
return nil, errors.New("Unable to set OrgRepo context") | |||
} | |||
func checkHookType(ctx *middleware.Context) string { | |||
hookType := strings.ToLower(ctx.Params(":type")) | |||
if !com.IsSliceContainsStr(setting.Webhook.Types, hookType) { | |||
ctx.Handle(404, "checkHookType", nil) | |||
return "" | |||
} | |||
return hookType | |||
} | |||
func WebhooksNew(ctx *middleware.Context) { | |||
ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook") | |||
ctx.Data["PageIsSettingsHooks"] = true | |||
ctx.Data["PageIsSettingsHooksNew"] = true | |||
ctx.Data["Webhook"] = models.Webhook{HookEvent: &models.HookEvent{}} | |||
orCtx, err := getOrgRepoCtx(ctx) | |||
if err != nil { | |||
ctx.Handle(500, "getOrgRepoCtx", err) | |||
return | |||
} | |||
ctx.Data["HookType"] = checkHookType(ctx) | |||
if ctx.Written() { | |||
return | |||
} | |||
ctx.Data["BaseLink"] = orCtx.Link | |||
ctx.HTML(200, orCtx.NewTemplate) | |||
} | |||
func ParseHookEvent(form auth.WebhookForm) *models.HookEvent { | |||
return &models.HookEvent{ | |||
PushOnly: form.PushOnly(), | |||
SendEverything: form.SendEverything(), | |||
ChooseEvents: form.ChooseEvents(), | |||
HookEvents: models.HookEvents{ | |||
Create: form.Create, | |||
Push: form.Push, | |||
}, | |||
} | |||
} | |||
func WebHooksNewPost(ctx *middleware.Context, form auth.NewWebhookForm) { | |||
ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook") | |||
ctx.Data["PageIsSettingsHooks"] = true | |||
ctx.Data["PageIsSettingsHooksNew"] = true | |||
ctx.Data["Webhook"] = models.Webhook{HookEvent: &models.HookEvent{}} | |||
ctx.Data["HookType"] = "gogs" | |||
orCtx, err := getOrgRepoCtx(ctx) | |||
if err != nil { | |||
ctx.Handle(500, "getOrgRepoCtx", err) | |||
return | |||
} | |||
ctx.Data["BaseLink"] = orCtx.Link | |||
if ctx.HasError() { | |||
ctx.HTML(200, orCtx.NewTemplate) | |||
return | |||
} | |||
contentType := models.JSON | |||
if models.HookContentType(form.ContentType) == models.FORM { | |||
contentType = models.FORM | |||
} | |||
w := &models.Webhook{ | |||
RepoID: orCtx.RepoID, | |||
URL: form.PayloadURL, | |||
ContentType: contentType, | |||
Secret: form.Secret, | |||
HookEvent: ParseHookEvent(form.WebhookForm), | |||
IsActive: form.Active, | |||
HookTaskType: models.GOGS, | |||
OrgID: orCtx.OrgID, | |||
} | |||
if err := w.UpdateEvent(); err != nil { | |||
ctx.Handle(500, "UpdateEvent", err) | |||
return | |||
} else if err := models.CreateWebhook(w); err != nil { | |||
ctx.Handle(500, "CreateWebhook", err) | |||
return | |||
} | |||
ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success")) | |||
ctx.Redirect(orCtx.Link + "/settings/hooks") | |||
} | |||
func SlackHooksNewPost(ctx *middleware.Context, form auth.NewSlackHookForm) { | |||
ctx.Data["Title"] = ctx.Tr("repo.settings") | |||
ctx.Data["PageIsSettingsHooks"] = true | |||
ctx.Data["PageIsSettingsHooksNew"] = true | |||
ctx.Data["Webhook"] = models.Webhook{HookEvent: &models.HookEvent{}} | |||
orCtx, err := getOrgRepoCtx(ctx) | |||
if err != nil { | |||
ctx.Handle(500, "getOrgRepoCtx", err) | |||
return | |||
} | |||
if ctx.HasError() { | |||
ctx.HTML(200, orCtx.NewTemplate) | |||
return | |||
} | |||
meta, err := json.Marshal(&models.SlackMeta{ | |||
Channel: form.Channel, | |||
Username: form.Username, | |||
IconURL: form.IconURL, | |||
Color: form.Color, | |||
}) | |||
if err != nil { | |||
ctx.Handle(500, "Marshal", err) | |||
return | |||
} | |||
w := &models.Webhook{ | |||
RepoID: orCtx.RepoID, | |||
URL: form.PayloadURL, | |||
ContentType: models.JSON, | |||
HookEvent: ParseHookEvent(form.WebhookForm), | |||
IsActive: form.Active, | |||
HookTaskType: models.SLACK, | |||
Meta: string(meta), | |||
OrgID: orCtx.OrgID, | |||
} | |||
if err := w.UpdateEvent(); err != nil { | |||
ctx.Handle(500, "UpdateEvent", err) | |||
return | |||
} else if err := models.CreateWebhook(w); err != nil { | |||
ctx.Handle(500, "CreateWebhook", err) | |||
return | |||
} | |||
ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success")) | |||
ctx.Redirect(orCtx.Link + "/settings/hooks") | |||
} | |||
func checkWebhook(ctx *middleware.Context) (*OrgRepoCtx, *models.Webhook) { | |||
ctx.Data["RequireHighlightJS"] = true | |||
orCtx, err := getOrgRepoCtx(ctx) | |||
if err != nil { | |||
ctx.Handle(500, "getOrgRepoCtx", err) | |||
return nil, nil | |||
} | |||
ctx.Data["BaseLink"] = orCtx.Link | |||
w, err := models.GetWebhookByID(ctx.ParamsInt64(":id")) | |||
if err != nil { | |||
if models.IsErrWebhookNotExist(err) { | |||
ctx.Handle(404, "GetWebhookByID", nil) | |||
} else { | |||
ctx.Handle(500, "GetWebhookByID", err) | |||
} | |||
return nil, nil | |||
} | |||
switch w.HookTaskType { | |||
case models.SLACK: | |||
ctx.Data["SlackHook"] = w.GetSlackHook() | |||
ctx.Data["HookType"] = "slack" | |||
default: | |||
ctx.Data["HookType"] = "gogs" | |||
} | |||
ctx.Data["History"], err = w.History(1) | |||
if err != nil { | |||
ctx.Handle(500, "History", err) | |||
} | |||
return orCtx, w | |||
} | |||
func WebHooksEdit(ctx *middleware.Context) { | |||
ctx.Data["Title"] = ctx.Tr("repo.settings.update_webhook") | |||
ctx.Data["PageIsSettingsHooks"] = true | |||
ctx.Data["PageIsSettingsHooksEdit"] = true | |||
orCtx, w := checkWebhook(ctx) | |||
if ctx.Written() { | |||
return | |||
} | |||
ctx.Data["Webhook"] = w | |||
ctx.HTML(200, orCtx.NewTemplate) | |||
} | |||
func WebHooksEditPost(ctx *middleware.Context, form auth.NewWebhookForm) { | |||
ctx.Data["Title"] = ctx.Tr("repo.settings.update_webhook") | |||
ctx.Data["PageIsSettingsHooks"] = true | |||
ctx.Data["PageIsSettingsHooksEdit"] = true | |||
orCtx, w := checkWebhook(ctx) | |||
if ctx.Written() { | |||
return | |||
} | |||
ctx.Data["Webhook"] = w | |||
if ctx.HasError() { | |||
ctx.HTML(200, orCtx.NewTemplate) | |||
return | |||
} | |||
contentType := models.JSON | |||
if models.HookContentType(form.ContentType) == models.FORM { | |||
contentType = models.FORM | |||
} | |||
w.URL = form.PayloadURL | |||
w.ContentType = contentType | |||
w.Secret = form.Secret | |||
w.HookEvent = ParseHookEvent(form.WebhookForm) | |||
w.IsActive = form.Active | |||
if err := w.UpdateEvent(); err != nil { | |||
ctx.Handle(500, "UpdateEvent", err) | |||
return | |||
} else if err := models.UpdateWebhook(w); err != nil { | |||
ctx.Handle(500, "WebHooksEditPost", err) | |||
return | |||
} | |||
ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success")) | |||
ctx.Redirect(fmt.Sprintf("%s/settings/hooks/%d", orCtx.Link, w.ID)) | |||
} | |||
func SlackHooksEditPost(ctx *middleware.Context, form auth.NewSlackHookForm) { | |||
ctx.Data["Title"] = ctx.Tr("repo.settings") | |||
ctx.Data["PageIsSettingsHooks"] = true | |||
ctx.Data["PageIsSettingsHooksEdit"] = true | |||
orCtx, w := checkWebhook(ctx) | |||
if ctx.Written() { | |||
return | |||
} | |||
ctx.Data["Webhook"] = w | |||
if ctx.HasError() { | |||
ctx.HTML(200, orCtx.NewTemplate) | |||
return | |||
} | |||
meta, err := json.Marshal(&models.SlackMeta{ | |||
Channel: form.Channel, | |||
Username: form.Username, | |||
IconURL: form.IconURL, | |||
Color: form.Color, | |||
}) | |||
if err != nil { | |||
ctx.Handle(500, "Marshal", err) | |||
return | |||
} | |||
w.URL = form.PayloadURL | |||
w.Meta = string(meta) | |||
w.HookEvent = ParseHookEvent(form.WebhookForm) | |||
w.IsActive = form.Active | |||
if err := w.UpdateEvent(); err != nil { | |||
ctx.Handle(500, "UpdateEvent", err) | |||
return | |||
} else if err := models.UpdateWebhook(w); err != nil { | |||
ctx.Handle(500, "UpdateWebhook", err) | |||
return | |||
} | |||
ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success")) | |||
ctx.Redirect(fmt.Sprintf("%s/settings/hooks/%d", orCtx.Link, w.ID)) | |||
} | |||
func TestWebhook(ctx *middleware.Context) { | |||
p := &api.PushPayload{ | |||
Ref: ctx.Repo.Repository.DefaultBranch, | |||
Before: ctx.Repo.CommitID, | |||
After: ctx.Repo.CommitID, | |||
Commits: []*api.PayloadCommit{ | |||
{ | |||
ID: ctx.Repo.CommitID, | |||
Message: ctx.Repo.Commit.Message(), | |||
URL: ctx.Repo.RepoLink + "/commit/" + ctx.Repo.CommitID, | |||
Author: &api.PayloadAuthor{ | |||
Name: ctx.Repo.Commit.Author.Name, | |||
Email: ctx.Repo.Commit.Author.Email, | |||
}, | |||
}, | |||
}, | |||
Repo: ctx.Repo.Repository.ComposePayload(), | |||
Sender: &api.PayloadUser{ | |||
UserName: ctx.User.Name, | |||
ID: ctx.User.Id, | |||
AvatarUrl: setting.AppUrl + ctx.User.RelAvatarLink(), | |||
}, | |||
} | |||
if err := models.PrepareWebhooks(ctx.Repo.Repository, models.HOOK_EVENT_PUSH, p); err != nil { | |||
ctx.Flash.Error("PrepareWebhooks: " + err.Error()) | |||
ctx.Status(500) | |||
} else { | |||
go models.HookQueue.Add(ctx.Repo.Repository.ID) | |||
ctx.Flash.Info(ctx.Tr("repo.settings.webhook.test_delivery_success")) | |||
ctx.Status(200) | |||
} | |||
} | |||
func DeleteWebhook(ctx *middleware.Context) { | |||
if err := models.DeleteWebhook(ctx.QueryInt64("id")); err != nil { | |||
ctx.Flash.Error("DeleteWebhook: " + err.Error()) | |||
} else { | |||
ctx.Flash.Success(ctx.Tr("repo.settings.webhook_deletion_success")) | |||
} | |||
ctx.JSON(200, map[string]interface{}{ | |||
"redirect": ctx.Repo.RepoLink + "/settings/hooks", | |||
}) | |||
} |
@@ -1 +1 @@ | |||
0.7.31.1205 Beta | |||
0.7.32.1205 Beta |
@@ -1,6 +1,12 @@ | |||
{{if .PageIsSettingsHooksEdit}} | |||
<h4 class="ui top attached header"> | |||
{{.i18n.Tr "repo.settings.recent_deliveries"}} | |||
{{if .IsRepositoryAdmin}} | |||
<div class="ui right"> | |||
<button class="ui teal tiny button poping up" id="test-delivery" data-content= | |||
"{{.i18n.Tr "repo.settings.webhook.test_delivery_desc"}}" data-variation="inverted tiny" data-link="{{.Link}}/test" data-redirect="{{.Link}}">{{.i18n.Tr "repo.settings.webhook.test_delivery"}}</button> | |||
</div> | |||
{{end}} | |||
</h4> | |||
<div class="ui attached table segment"> | |||
<div class="ui hook history list"> | |||