mirror of
https://github.com/simon987/task_tracker.git
synced 2025-12-12 06:28:50 +00:00
Implement per-project webhook secret
This commit is contained in:
@@ -3,6 +3,7 @@ package test
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/simon987/task_tracker/api"
|
||||
"github.com/simon987/task_tracker/config"
|
||||
"golang.org/x/net/publicsuffix"
|
||||
@@ -177,3 +178,15 @@ func getSessionCtx(username string, password string, admin bool) *http.Client {
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
func setRoleOnProject(req api.SetManagerRoleOnProjectRequest, pid int64, s *http.Client) (ar api.JsonResponse) {
|
||||
r := Post(fmt.Sprintf("/manager/set_role_for_project/%d", pid), req, nil, s)
|
||||
UnmarshalResponse(r, &ar)
|
||||
return
|
||||
}
|
||||
|
||||
func getAccountDetails(s *http.Client) (ar AccountAR) {
|
||||
r := Get("/account", nil, s)
|
||||
UnmarshalResponse(r, &ar)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ func TestWebHookNoSignature(t *testing.T) {
|
||||
|
||||
r := Post("/git/receivehook", api.GitPayload{}, nil, nil)
|
||||
|
||||
if r.StatusCode != 403 {
|
||||
if r.StatusCode == 200 {
|
||||
t.Error()
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ func TestWebHookInvalidSignature(t *testing.T) {
|
||||
client := http.Client{}
|
||||
r, _ := client.Do(req)
|
||||
|
||||
if r.StatusCode != 403 {
|
||||
if r.StatusCode == 200 {
|
||||
t.Error()
|
||||
}
|
||||
}
|
||||
@@ -41,10 +41,12 @@ func TestWebHookDontUpdateVersion(t *testing.T) {
|
||||
GitRepo: "username/not_this_one",
|
||||
}).Content
|
||||
|
||||
webhookSecret := getWebhookSecret(resp.Id, testAdminCtx).Content.WebhookSecret
|
||||
|
||||
body := []byte(`{"ref": "refs/heads/master", "after": "new", "repository": {"full_name": "username/repo_name"}}`)
|
||||
bodyReader := bytes.NewReader(body)
|
||||
|
||||
mac := hmac.New(crypto.SHA1.New, config.Cfg.WebHookSecret)
|
||||
mac := hmac.New(crypto.SHA1.New, []byte(webhookSecret))
|
||||
mac.Write(body)
|
||||
signature := hex.EncodeToString(mac.Sum(nil))
|
||||
signature = "sha1=" + signature
|
||||
@@ -53,11 +55,7 @@ func TestWebHookDontUpdateVersion(t *testing.T) {
|
||||
req.Header.Add("X-Hub-Signature", signature)
|
||||
|
||||
client := http.Client{}
|
||||
r, _ := client.Do(req)
|
||||
|
||||
if r.StatusCode != 200 {
|
||||
t.Error()
|
||||
}
|
||||
_, _ = client.Do(req)
|
||||
|
||||
getResp := getProjectAsAdmin(resp.Id).Content
|
||||
|
||||
@@ -76,7 +74,9 @@ func TestWebHookUpdateVersion(t *testing.T) {
|
||||
body := []byte(`{"ref": "refs/heads/master", "after": "new", "repository": {"full_name": "username/repo_name"}}`)
|
||||
bodyReader := bytes.NewReader(body)
|
||||
|
||||
mac := hmac.New(crypto.SHA1.New, config.Cfg.WebHookSecret)
|
||||
webhookSecret := getWebhookSecret(resp.Id, testAdminCtx).Content.WebhookSecret
|
||||
|
||||
mac := hmac.New(crypto.SHA1.New, []byte(webhookSecret))
|
||||
mac.Write(body)
|
||||
signature := hex.EncodeToString(mac.Sum(nil))
|
||||
signature = "sha1=" + signature
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/simon987/task_tracker/api"
|
||||
"github.com/simon987/task_tracker/storage"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"testing"
|
||||
@@ -465,6 +466,82 @@ func TestPausedProjectShouldNotDispatchTasks(t *testing.T) {
|
||||
}, testProject, testAdminCtx)
|
||||
}
|
||||
|
||||
func TestGetWebhookSecret(t *testing.T) {
|
||||
|
||||
resp := getWebhookSecret(testProject, testAdminCtx)
|
||||
|
||||
if resp.Ok != true {
|
||||
t.Error()
|
||||
}
|
||||
if len(resp.Content.WebhookSecret) <= 0 {
|
||||
t.Error()
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetWebhookSecret(t *testing.T) {
|
||||
|
||||
resp1 := setWebhookSecret(api.SetWebhookSecretRequest{
|
||||
WebhookSecret: "new",
|
||||
}, testProject, testAdminCtx)
|
||||
|
||||
if resp1.Ok != true {
|
||||
t.Error()
|
||||
}
|
||||
|
||||
resp := getWebhookSecret(testProject, testAdminCtx)
|
||||
|
||||
if resp.Ok != true {
|
||||
t.Error()
|
||||
}
|
||||
if resp.Content.WebhookSecret != "new" {
|
||||
t.Error()
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetWebhookRequiresRole(t *testing.T) {
|
||||
|
||||
otherUser := getSessionCtx("testwebhookrole", "testwebhookrole", false)
|
||||
otherUserId := getAccountDetails(otherUser).Content.Id
|
||||
|
||||
user := getSessionCtx("testwebhookroleu", "testwebhookroleu", false)
|
||||
userId := getAccountDetails(user).Content.Id
|
||||
|
||||
resp := setRoleOnProject(api.SetManagerRoleOnProjectRequest{
|
||||
Role: storage.RoleEdit | storage.RoleManageAccess | storage.RoleRead,
|
||||
Manager: otherUserId,
|
||||
}, testProject, testAdminCtx)
|
||||
if resp.Ok != true {
|
||||
t.Fail()
|
||||
}
|
||||
resp = setRoleOnProject(api.SetManagerRoleOnProjectRequest{
|
||||
Role: storage.RoleSecret,
|
||||
Manager: userId,
|
||||
}, testProject, testAdminCtx)
|
||||
if resp.Ok != true {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
rUser := setWebhookSecret(api.SetWebhookSecretRequest{
|
||||
WebhookSecret: "test",
|
||||
}, testProject, user)
|
||||
rOther := setWebhookSecret(api.SetWebhookSecretRequest{
|
||||
WebhookSecret: "test",
|
||||
}, testProject, otherUser)
|
||||
rGuest := setWebhookSecret(api.SetWebhookSecretRequest{
|
||||
WebhookSecret: "test",
|
||||
}, testProject, nil)
|
||||
|
||||
if rUser.Ok != true {
|
||||
t.Error()
|
||||
}
|
||||
if rOther.Ok != false {
|
||||
t.Error()
|
||||
}
|
||||
if rGuest.Ok != false {
|
||||
t.Error()
|
||||
}
|
||||
}
|
||||
|
||||
func createProjectAsAdmin(req api.CreateProjectRequest) CreateProjectAR {
|
||||
return createProject(req, testAdminCtx)
|
||||
}
|
||||
@@ -502,3 +579,15 @@ func getProjectList(s *http.Client) (ar ProjectListAR) {
|
||||
UnmarshalResponse(r, &ar)
|
||||
return
|
||||
}
|
||||
|
||||
func getWebhookSecret(pid int64, s *http.Client) (ar WebhookSecretAR) {
|
||||
r := Get(fmt.Sprintf("/project/webhook_secret/%d", pid), nil, s)
|
||||
UnmarshalResponse(r, &ar)
|
||||
return
|
||||
}
|
||||
|
||||
func setWebhookSecret(req api.SetWebhookSecretRequest, pid int64, s *http.Client) (ar api.JsonResponse) {
|
||||
r := Post(fmt.Sprintf("/project/webhook_secret/%d", pid), req, nil, s)
|
||||
UnmarshalResponse(r, &ar)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -172,3 +172,19 @@ type ReleaseAR struct {
|
||||
Updated bool `json:"updated"`
|
||||
} `json:"content"`
|
||||
}
|
||||
|
||||
type WebhookSecretAR struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message"`
|
||||
Content struct {
|
||||
WebhookSecret string `json:"webhook_secret"`
|
||||
} `json:"content"`
|
||||
}
|
||||
|
||||
type AccountAR struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message"`
|
||||
Content struct {
|
||||
*storage.Manager `json:"manager"`
|
||||
} `json:"content"`
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ database:
|
||||
log_levels: ["debug", "error", "trace", "info", "warn"]
|
||||
|
||||
git:
|
||||
webhook_secret: "very_secret_secret"
|
||||
webhook_hash: "sha1"
|
||||
webhook_sig_header: "X-Hub-Signature"
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ CREATE TABLE project
|
||||
git_repo TEXT NOT NULL,
|
||||
version TEXT NOT NULL,
|
||||
motd TEXT NOT NULL,
|
||||
secret TEXT NOT NULL DEFAULT '{}'
|
||||
secret TEXT NOT NULL DEFAULT '{}',
|
||||
webhook_secret TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE worker_access
|
||||
|
||||
Reference in New Issue
Block a user