mirror of https://github.com/gogs/gogs.git
webhook: send secret with SHA256 HMAC hex digest (#3692)
parent
452551fa23
commit
6ec859f2b0
|
@ -745,6 +745,7 @@ settings.add_webhook_desc = Gogs will send a <code>POST</code> request to the UR
|
|||
settings.payload_url = Payload URL
|
||||
settings.content_type = Content Type
|
||||
settings.secret = Secret
|
||||
settings.secret_desc = Secret will be sent as SHA256 HMAC hex digest of payload via <code>X-Gogs-Signature</code> header.
|
||||
settings.slack_username = Username
|
||||
settings.slack_icon_url = Icon URL
|
||||
settings.slack_color = Color
|
||||
|
|
|
@ -5,7 +5,10 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"crypto/tls"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
@ -358,6 +361,7 @@ type HookTask struct {
|
|||
UUID string
|
||||
Type HookTaskType
|
||||
URL string `xorm:"TEXT"`
|
||||
Signature string `xorm:"TEXT"`
|
||||
api.Payloader `xorm:"-"`
|
||||
PayloadContent string `xorm:"TEXT"`
|
||||
ContentType HookContentType
|
||||
|
@ -481,15 +485,26 @@ func prepareWebhooks(repo *Repository, event HookEventType, p api.Payloader, web
|
|||
return fmt.Errorf("GetDiscordPayload: %v", err)
|
||||
}
|
||||
default:
|
||||
p.SetSecret(w.Secret)
|
||||
payloader = p
|
||||
}
|
||||
|
||||
var signature string
|
||||
if len(w.Secret) > 0 {
|
||||
data, err := payloader.JSONPayload()
|
||||
if err != nil {
|
||||
log.Error(2, "prepareWebhooks.JSONPayload: %v", err)
|
||||
}
|
||||
sig := hmac.New(sha256.New, []byte(w.Secret))
|
||||
sig.Write(data)
|
||||
signature = hex.EncodeToString(sig.Sum(nil))
|
||||
}
|
||||
|
||||
if err = CreateHookTask(&HookTask{
|
||||
RepoID: repo.ID,
|
||||
HookID: w.ID,
|
||||
Type: w.HookTaskType,
|
||||
URL: w.URL,
|
||||
Signature: signature,
|
||||
Payloader: payloader,
|
||||
ContentType: w.ContentType,
|
||||
EventType: event,
|
||||
|
@ -535,6 +550,7 @@ func (t *HookTask) deliver() {
|
|||
timeout := time.Duration(setting.Webhook.DeliverTimeout) * time.Second
|
||||
req := httplib.Post(t.URL).SetTimeout(timeout, timeout).
|
||||
Header("X-Gogs-Delivery", t.UUID).
|
||||
Header("X-Gogs-Signature", t.Signature).
|
||||
Header("X-Gogs-Event", string(t.EventType)).
|
||||
SetTLSClientConfig(&tls.Config{InsecureSkipVerify: setting.Webhook.SkipTLSVerify})
|
||||
|
||||
|
|
|
@ -48,8 +48,6 @@ type DiscordPayload struct {
|
|||
Embeds []*DiscordEmbedObject `json:"embeds"`
|
||||
}
|
||||
|
||||
func (p *DiscordPayload) SetSecret(_ string) {}
|
||||
|
||||
func (p *DiscordPayload) JSONPayload() ([]byte, error) {
|
||||
data, err := json.MarshalIndent(p, "", " ")
|
||||
if err != nil {
|
||||
|
|
|
@ -39,8 +39,6 @@ type SlackPayload struct {
|
|||
Attachments []*SlackAttachment `json:"attachments"`
|
||||
}
|
||||
|
||||
func (p *SlackPayload) SetSecret(_ string) {}
|
||||
|
||||
func (p *SlackPayload) JSONPayload() ([]byte, error) {
|
||||
data, err := json.MarshalIndent(p, "", " ")
|
||||
if err != nil {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -2319,6 +2319,9 @@ footer .ui.language .menu {
|
|||
.repository.settings.webhooks .types .menu .item {
|
||||
padding: 10px !important;
|
||||
}
|
||||
.repository.settings.webhook .text.desc {
|
||||
margin-top: 5px;
|
||||
}
|
||||
.repository.settings.webhook .events .column {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
|
|
@ -1349,6 +1349,9 @@
|
|||
}
|
||||
|
||||
&.webhook {
|
||||
.text.desc {
|
||||
margin-top: 5px;
|
||||
}
|
||||
.events {
|
||||
.column {
|
||||
padding-bottom: 0;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
<div class="field {{if .Err_Secret}}error{{end}}">
|
||||
<label for="secret">{{.i18n.Tr "repo.settings.secret"}}</label>
|
||||
<input id="secret" name="secret" type="password" value="{{.Webhook.Secret}}" autocomplete="off">
|
||||
<p class="text grey desc">{{.i18n.Tr "repo.settings.secret_desc" | Safe}}</p>
|
||||
</div>
|
||||
{{template "repo/settings/webhook_settings" .}}
|
||||
</form>
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
)
|
||||
|
||||
func Version() string {
|
||||
return "0.12.5"
|
||||
return "0.12.6"
|
||||
}
|
||||
|
||||
// Client represents a Gogs API client.
|
||||
|
|
|
@ -70,7 +70,6 @@ func (c *Client) DeleteRepoHook(user, repo string, id int64) error {
|
|||
}
|
||||
|
||||
type Payloader interface {
|
||||
SetSecret(string)
|
||||
JSONPayload() ([]byte, error)
|
||||
}
|
||||
|
||||
|
@ -104,17 +103,12 @@ var (
|
|||
// \/ \/ \/ \/
|
||||
|
||||
type CreatePayload struct {
|
||||
Secret string `json:"secret"`
|
||||
Ref string `json:"ref"`
|
||||
RefType string `json:"ref_type"`
|
||||
Repo *Repository `json:"repository"`
|
||||
Sender *User `json:"sender"`
|
||||
}
|
||||
|
||||
func (p *CreatePayload) SetSecret(secret string) {
|
||||
p.Secret = secret
|
||||
}
|
||||
|
||||
func (p *CreatePayload) JSONPayload() ([]byte, error) {
|
||||
return json.MarshalIndent(p, "", " ")
|
||||
}
|
||||
|
@ -148,7 +142,6 @@ func ParseCreateHook(raw []byte) (*CreatePayload, error) {
|
|||
|
||||
// PushPayload represents a payload information of push event.
|
||||
type PushPayload struct {
|
||||
Secret string `json:"secret"`
|
||||
Ref string `json:"ref"`
|
||||
Before string `json:"before"`
|
||||
After string `json:"after"`
|
||||
|
@ -159,10 +152,6 @@ type PushPayload struct {
|
|||
Sender *User `json:"sender"`
|
||||
}
|
||||
|
||||
func (p *PushPayload) SetSecret(secret string) {
|
||||
p.Secret = secret
|
||||
}
|
||||
|
||||
func (p *PushPayload) JSONPayload() ([]byte, error) {
|
||||
return json.MarshalIndent(p, "", " ")
|
||||
}
|
||||
|
@ -227,7 +216,6 @@ type ChangesPayload struct {
|
|||
|
||||
// PullRequestPayload represents a payload information of pull request event.
|
||||
type PullRequestPayload struct {
|
||||
Secret string `json:"secret"`
|
||||
Action HookIssueAction `json:"action"`
|
||||
Index int64 `json:"number"`
|
||||
Changes *ChangesPayload `json:"changes,omitempty"`
|
||||
|
@ -236,10 +224,6 @@ type PullRequestPayload struct {
|
|||
Sender *User `json:"sender"`
|
||||
}
|
||||
|
||||
func (p *PullRequestPayload) SetSecret(secret string) {
|
||||
p.Secret = secret
|
||||
}
|
||||
|
||||
func (p *PullRequestPayload) JSONPayload() ([]byte, error) {
|
||||
return json.MarshalIndent(p, "", " ")
|
||||
}
|
||||
|
|
|
@ -165,10 +165,10 @@
|
|||
"revisionTime": "2017-02-19T18:16:29Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "xvG+RgJODQqlmdAkHUQK2TyLR88=",
|
||||
"checksumSHA1": "exKX51W/Hieq7OOmYK2gYn+Huuw=",
|
||||
"path": "github.com/gogits/go-gogs-client",
|
||||
"revision": "89ff140a38c057e71a1012af6d666fbc037ba606",
|
||||
"revisionTime": "2017-02-14T02:02:40Z"
|
||||
"revision": "f12fbacb5495120dc62dae7cfdf140d39bf6f715",
|
||||
"revisionTime": "2017-02-24T06:16:35Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "p4yoFWgDiTfpu1JYgh26t6+VDTk=",
|
||||
|
|
Loading…
Reference in New Issue