Преглед на файлове

webhook: send secret with SHA256 HMAC hex digest (#3692)

Unknwon преди 7 години
родител
ревизия
6ec859f2b0

+ 1 - 0
conf/locale/locale_en-US.ini

@@ -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

+ 17 - 1
models/webhook.go

@@ -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})
 

+ 0 - 2
models/webhook_discord.go

@@ -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 {

+ 0 - 2
models/webhook_slack.go

@@ -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 {

Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
modules/bindata/bindata.go


+ 3 - 0
public/css/gogs.css

@@ -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;
 }

+ 3 - 0
public/less/_repository.less

@@ -1349,6 +1349,9 @@
 		}
 
 		&.webhook {
+			.text.desc {
+				margin-top: 5px;
+			}
 			.events {
 				.column {
 					padding-bottom: 0;

+ 1 - 0
templates/repo/settings/webhook_gogs.tmpl

@@ -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>

+ 1 - 1
vendor/github.com/gogits/go-gogs-client/gogs.go

@@ -14,7 +14,7 @@ import (
 )
 
 func Version() string {
-	return "0.12.5"
+	return "0.12.6"
 }
 
 // Client represents a Gogs API client.

+ 0 - 16
vendor/github.com/gogits/go-gogs-client/repo_hook.go

@@ -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, "", "  ")
 }

+ 3 - 3
vendor/vendor.json

@@ -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=",

Някои файлове не бяха показани, защото твърде много файлове са промени