From c87fb882b4cbacf17667497a7e5a6aa778054edb Mon Sep 17 00:00:00 2001 From: SebClem Date: Wed, 4 Jan 2023 23:59:09 +0100 Subject: [PATCH] Add base for webhook (need refracto) --- .vscode/launch.json | 3 +- src/backend/controllers/webhook.go | 88 ++++++++++++++++++++++++++++++ src/backend/routes/webhook.go | 11 ++++ src/backend/server/router.go | 1 + src/backend/services/hmac/hmac.go | 14 +++++ 5 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 src/backend/controllers/webhook.go create mode 100644 src/backend/routes/webhook.go create mode 100644 src/backend/services/hmac/hmac.go diff --git a/.vscode/launch.json b/.vscode/launch.json index d8c02cb..e1ef23f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,8 @@ "type": "go", "request": "launch", "mode": "debug", - "program": "${workspaceFolder}/src/backend/main.go" + "program": "${workspaceFolder}/src/backend/main.go", + "console": "integratedTerminal" } ] } \ No newline at end of file diff --git a/src/backend/controllers/webhook.go b/src/backend/controllers/webhook.go new file mode 100644 index 0000000..adb09b5 --- /dev/null +++ b/src/backend/controllers/webhook.go @@ -0,0 +1,88 @@ +package controllers + +import ( + "bytes" + "crypto/hmac" + "io/ioutil" + + hmacService "git.sebclem.fr/sebclem/renovate-manager/services/hmac" + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" +) + +type WebhookController struct{} + +func (ctl WebhookController) HandleGiteaWebhook(c *gin.Context) { + r := c.Request + signature := r.Header.Get("X-Gitea-Signature") + + body, err := ioutil.ReadAll(r.Body) + if err != nil { + c.AbortWithStatus(500) + return + } + + expectedSignature := hmacService.CalculateHMAC("test", body) + + if signature == "" || !hmac.Equal([]byte(signature), []byte(expectedSignature)) { + logrus.Error("Signature missmatch, Abort !") + c.AbortWithStatus(401) + return + } + + // Reset the request body so it can be Bind to json + c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body)) + + switch r.Header.Get("X-Gitea-Event") { + case "push": + logrus.Info("Received PUSH webhook") + case "create": + logrus.Info("Received CREATE webhook") + case "delete": + logrus.Info("Received DELETE webhook") + case "issues": + logrus.Info("Received ISSUES webhook") + case "issue_comment": + logrus.Info("Received ISSUE_COMMENT webhook") + case "pull_request": + logrus.Info("Received PULL_REQUEST webhook") + var data PullRequestWebhook + if err := c.BindJSON(&data); err == nil { + logrus.Info("All good") + c.String(201, "") + } else { + logrus.Error("Fail to parse json") + } + default: + logrus.Warn("Received UNKNOWN webhook") + } + // ctx.String(201, "") +} + +type PullRequestWebhook struct { + Action string `json:"action"` + Number int `json:"number"` + PullRequest PullRequest `json:"pull_request"` + Repository Repository `json:"repository"` + Sender User `json:"sender"` +} + +type PullRequest struct { + Id int `json:"id"` + Url string `json:"url"` + Number uint64 `json:"number"` + User User `json:"user"` +} + +type User struct { + Id int `json:"id"` + Login string `json:"login"` + Username string `json:"username"` +} + +type Repository struct { + Id int `json:"id"` + Owner User `json:"owner"` + Name string `json:"name"` + FullName string `json:"full_name"` +} diff --git a/src/backend/routes/webhook.go b/src/backend/routes/webhook.go new file mode 100644 index 0000000..5a6c981 --- /dev/null +++ b/src/backend/routes/webhook.go @@ -0,0 +1,11 @@ +package routes + +import ( + "git.sebclem.fr/sebclem/renovate-manager/controllers" + "github.com/gin-gonic/gin" +) + +func LoadWebhook(g *gin.RouterGroup) { + controller := new(controllers.WebhookController) + g.POST("gitea", controller.HandleGiteaWebhook) +} diff --git a/src/backend/server/router.go b/src/backend/server/router.go index 65549e2..e8b97fe 100644 --- a/src/backend/server/router.go +++ b/src/backend/server/router.go @@ -9,6 +9,7 @@ func InitRoutes(r *gin.Engine) *gin.Engine { v1 := r.Group("api/v1") { routes.LoadPing(v1) + routes.LoadWebhook(v1.Group("webhook")) } return r } diff --git a/src/backend/services/hmac/hmac.go b/src/backend/services/hmac/hmac.go new file mode 100644 index 0000000..91a5c66 --- /dev/null +++ b/src/backend/services/hmac/hmac.go @@ -0,0 +1,14 @@ +package hmac + +import ( + "crypto/hmac" + "crypto/sha256" + "encoding/hex" +) + +func CalculateHMAC(secret string, message []byte) string { + key := []byte(secret) + h := hmac.New(sha256.New, key) + h.Write(message) + return hex.EncodeToString(h.Sum(nil)) +}