package webhook import ( "net/http" "strings" "git.ohea.xyz/cursorius/server/config" "git.ohea.xyz/cursorius/server/database" "git.ohea.xyz/cursorius/server/pipeline_executor" "github.com/go-playground/webhooks/v6/gitea" "github.com/google/uuid" "github.com/op/go-logging" ) var log = logging.MustGetLogger("cursorius-server") func webhookHandler(w http.ResponseWriter, r *http.Request, db database.Database, conf config.PipelineConf) { switch r.Method { case "POST": splitUrl := strings.Split(r.URL.Path, "/") if len(splitUrl) != 4 { log.Errorf("Webhook recieved with invalid url \"%v\", ignoring...", r.URL) return } // get URL path after /webhook/ // TODO: verify that this handles all valid URL formats pipelineUUIDStr := splitUrl[2] webhookUUIDStr := splitUrl[3] pipelineUUID, err := uuid.Parse(pipelineUUIDStr) if err != nil { log.Errorf("Could not parse pipeline UUID: %v", err) return } webhookUUID, err := uuid.Parse(webhookUUIDStr) if err != nil { log.Errorf("Could not parse webhook UUID: %v", err) return } pipeline, err := db.GetPipelineById(pipelineUUID) if err != nil { log.Errorf("Could not get webhooks for pipeline with UUID \"%v\": %v", pipelineUUID, err) return } webhooks, err := db.GetWebhooksForPipeline(pipelineUUID) if err != nil { log.Errorf("Could not get webhooks for pipeline with UUID \"%v\": %v", webhookUUID, err) return } if len(webhooks) < 1 { log.Errorf("No webhooks configured for pipeline with UUID \"%v\"", webhookUUID) return } for _, webhook := range webhooks { if webhook.Id == webhookUUID { switch webhook.ServerType { case database.Gitea: hook, err := gitea.New(gitea.Options.Secret(webhook.Secret)) if err != nil { log.Errorf("Could not create Gitea webhook handler: %v", err) return } payload, err := hook.Parse(r, gitea.PushEvent) if err != nil { if err == gitea.ErrEventNotFound { log.Warning("Got webhook \"%v\" for unexpected event type, ignoring...", webhookUUID) break } } switch payload.(type) { case gitea.PushPayload: pushPayload := payload.(gitea.PushPayload) pe := pipeline_executor.PipelineExecution{ Pipeline: pipeline, Ref: pushPayload.Ref, } go pipeline_executor.ExecutePipeline(pe, db, conf) } } } } log.Errorf("No webhook found with ID \"%v\"", webhookUUID) default: log.Errorf("Got request with method \"%v\", ignoring...", r.Method) } } func CreateWebhookHandler(db database.Database, conf config.PipelineConf, mux *http.ServeMux) { mux.HandleFunc("/webhook/", func(w http.ResponseWriter, r *http.Request) { webhookHandler(w, r, db, conf) }) }