feat: initial dummy webhook support. use gitea VerifyWebhookSignatureMiddleware instead.

This commit is contained in:
Derrick Hammer 2024-02-11 00:58:47 -05:00
parent 26f497f062
commit 9262bb0555
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
4 changed files with 52 additions and 53 deletions

View File

@ -1,16 +1,11 @@
package api package api
import ( import (
"bytes"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"context" "context"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"git.lumeweb.com/LumeWeb/gitea-github-proxy/config" "git.lumeweb.com/LumeWeb/gitea-github-proxy/config"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"go.uber.org/zap" "go.uber.org/zap"
"io"
"net/http" "net/http"
"strings" "strings"
) )
@ -90,52 +85,6 @@ func loggingMiddleware(logger *zap.Logger) mux.MiddlewareFunc {
}) })
} }
} }
func giteaVerifyWebhookMiddleware(cfg *config.Config, logger *zap.Logger) mux.MiddlewareFunc {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
signature := r.Header.Get("X-Gitea-Signature")
if signature == "" {
http.Error(w, "No signature provided", http.StatusBadRequest)
return
}
decodedSignature, err := hex.DecodeString(signature)
if err != nil {
http.Error(w, "Error decoding signature", http.StatusBadRequest)
logger.Error("Error decoding signature", zap.Error(err))
return
}
payload, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "Error reading body", http.StatusBadRequest)
logger.Error("Error reading body", zap.Error(err))
return
}
defer func(body io.ReadCloser) {
err := body.Close()
if err != nil {
logger.Error("Error closing body", zap.Error(err))
}
}(r.Body)
r.Body = io.NopCloser(bytes.NewBuffer(payload))
mac := hmac.New(sha256.New, []byte(cfg.GiteaWebHookSecret))
mac.Write(payload)
expectedMAC := mac.Sum(nil)
if !hmac.Equal(decodedSignature, expectedMAC) {
http.Error(w, "Invalid signature", http.StatusForbidden)
return
}
next.ServeHTTP(w, r)
})
}
}
func addAuthStatusToRequestServ(status bool, r *http.Request, w http.ResponseWriter, next http.Handler) { func addAuthStatusToRequestServ(status bool, r *http.Request, w http.ResponseWriter, next http.Handler) {
ctx := context.WithValue(r.Context(), AUTHED_CONTEXT_KEY, status) ctx := context.WithValue(r.Context(), AUTHED_CONTEXT_KEY, status)
r = r.WithContext(ctx) r = r.WithContext(ctx)

View File

@ -27,6 +27,7 @@ func SetupRoutes(params RouteParams) {
setupSettingsRoutes(params) setupSettingsRoutes(params)
setupManifestsRoutes(params) setupManifestsRoutes(params)
setupAppRoutes(params) setupAppRoutes(params)
setupWebhookRoutes(params)
} }
type ClientParams struct { type ClientParams struct {

49
api/routes_webhooks.go Normal file
View File

@ -0,0 +1,49 @@
package api
import (
"code.gitea.io/sdk/gitea"
"encoding/json"
"git.lumeweb.com/LumeWeb/gitea-github-proxy/config"
"go.uber.org/zap"
"gorm.io/gorm"
"io"
"net/http"
)
type webhookApi struct {
config *config.Config
logger *zap.Logger
db *gorm.DB
}
func newWebhookApi(cfg *config.Config, db *gorm.DB, logger *zap.Logger) *webhookApi {
return &webhookApi{config: cfg, db: db, logger: logger}
}
func (a *webhookApi) handleWebhook(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
var webhook map[string]interface{}
err := json.Unmarshal(body, &webhook)
if err != nil {
a.logger.Error("Failed to unmarshal webhook", zap.Error(err))
w.WriteHeader(http.StatusInternalServerError)
return
}
a.logger.Debug("Received webhook", zap.Any("webhook", webhook))
}
func setupWebhookRoutes(params RouteParams) {
cfg := params.Config
db := params.Db
logger := params.Logger
r := params.R
webhookApi := newWebhookApi(cfg, db, logger)
webhookRouter := r.PathPrefix("/api").Subrouter()
webhookRouter.Use(gitea.VerifyWebhookSignatureMiddleware(cfg.GiteaWebHookSecret))
webhookRouter.HandleFunc("/webhook", webhookApi.handleWebhook).Methods("POST")
}

4
go.mod
View File

@ -3,9 +3,10 @@ module git.lumeweb.com/LumeWeb/gitea-github-proxy
go 1.21 go 1.21
require ( require (
code.gitea.io/gitea/modules/structs v0.0.0-20190610152049-835b53fc259c
code.gitea.io/sdk/gitea v0.17.1 code.gitea.io/sdk/gitea v0.17.1
github.com/golang-jwt/jwt/v5 v5.2.0
github.com/gorilla/mux v1.8.1 github.com/gorilla/mux v1.8.1
github.com/mitchellh/mapstructure v1.5.0
github.com/spf13/viper v1.18.2 github.com/spf13/viper v1.18.2
go.uber.org/fx v1.20.1 go.uber.org/fx v1.20.1
go.uber.org/zap v1.23.0 go.uber.org/zap v1.23.0
@ -25,7 +26,6 @@ require (
github.com/jinzhu/now v1.1.5 // indirect github.com/jinzhu/now v1.1.5 // indirect
github.com/magiconair/properties v1.8.7 // indirect github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-sqlite3 v1.14.17 // indirect github.com/mattn/go-sqlite3 v1.14.17 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect