Initial import with modified Dockerfile for env-based config generation
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
package webhook
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrMissingSignature = errors.New("missing X-Gitea-Signature header")
|
||||
ErrInvalidSignature = errors.New("invalid webhook signature")
|
||||
)
|
||||
|
||||
// Validator validates Gitea webhook signatures
|
||||
type Validator struct {
|
||||
secret []byte
|
||||
}
|
||||
|
||||
// NewValidator creates a new webhook validator with the given secret
|
||||
func NewValidator(secret string) *Validator {
|
||||
return &Validator{
|
||||
secret: []byte(secret),
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateRequest validates the signature of an incoming webhook request
|
||||
// It returns the request body if valid, or an error if validation fails
|
||||
func (v *Validator) ValidateRequest(r *http.Request) ([]byte, error) {
|
||||
// Read the body
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get signature from header
|
||||
signature := r.Header.Get("X-Gitea-Signature")
|
||||
if signature == "" {
|
||||
return nil, ErrMissingSignature
|
||||
}
|
||||
|
||||
// Validate signature
|
||||
if !v.validateSignature(body, signature) {
|
||||
return nil, ErrInvalidSignature
|
||||
}
|
||||
|
||||
return body, nil
|
||||
}
|
||||
|
||||
// validateSignature checks if the HMAC-SHA256 signature matches
|
||||
func (v *Validator) validateSignature(payload []byte, signature string) bool {
|
||||
// Gitea sends the signature as a hex-encoded HMAC-SHA256
|
||||
mac := hmac.New(sha256.New, v.secret)
|
||||
mac.Write(payload)
|
||||
expectedMAC := mac.Sum(nil)
|
||||
expectedSignature := hex.EncodeToString(expectedMAC)
|
||||
|
||||
// Handle both with and without "sha256=" prefix
|
||||
signature = strings.TrimPrefix(signature, "sha256=")
|
||||
|
||||
return hmac.Equal([]byte(signature), []byte(expectedSignature))
|
||||
}
|
||||
|
||||
// GetEventType extracts the event type from the request headers
|
||||
func GetEventType(r *http.Request) GiteaEventType {
|
||||
return GiteaEventType(r.Header.Get("X-Gitea-Event"))
|
||||
}
|
||||
|
||||
// GetDeliveryID extracts the unique delivery ID from the request headers
|
||||
func GetDeliveryID(r *http.Request) string {
|
||||
return r.Header.Get("X-Gitea-Delivery")
|
||||
}
|
||||
Reference in New Issue
Block a user