package gitea import ( "crypto/hmac" "crypto/sha256" "encoding/hex" "encoding/json" "fmt" "git.unkin.net/unkin/forgebot/internal/provider" ) type webhookPayload struct { Action string `json:"action"` Comment *commentPayload `json:"comment,omitempty"` Issue *issuePayload `json:"issue,omitempty"` Repository *repoPayload `json:"repository"` PullRequest *prPayload `json:"pull_request,omitempty"` } type commentPayload struct { ID int64 `json:"id"` Body string `json:"body"` User struct { Login string `json:"login"` } `json:"user"` } type issuePayload struct { Number int `json:"number"` PullRequest *struct{} `json:"pull_request,omitempty"` } type prPayload struct { Number int `json:"number"` Head struct { Ref string `json:"ref"` } `json:"head"` } type repoPayload struct { FullName string `json:"full_name"` DefaultBranch string `json:"default_branch"` } func (c *Client) ParseWebhook(body []byte, secret string) (*provider.WebhookEvent, error) { var payload webhookPayload if err := json.Unmarshal(body, &payload); err != nil { return nil, fmt.Errorf("unmarshal webhook: %w", err) } if payload.Action != "created" || payload.Comment == nil { return nil, nil } event := &provider.WebhookEvent{ Action: payload.Action, Repository: payload.Repository.FullName, CommentID: payload.Comment.ID, Body: payload.Comment.Body, Author: payload.Comment.User.Login, } if payload.Issue != nil { if payload.Issue.PullRequest != nil { event.Type = "pull_request_comment" event.PRNum = payload.Issue.Number if payload.PullRequest != nil { event.Ref = payload.PullRequest.Head.Ref } } else { event.Type = "issue_comment" event.IssueNum = payload.Issue.Number } event.Ref = payload.Repository.DefaultBranch } return event, nil } func VerifySignature(body []byte, secret, signature string) bool { if secret == "" { return true } mac := hmac.New(sha256.New, []byte(secret)) mac.Write(body) expected := hex.EncodeToString(mac.Sum(nil)) return hmac.Equal([]byte(expected), []byte(signature)) }