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