Skip to content

Commit

Permalink
feat: add apiKey flag for passing X-API-Key request header auth
Browse files Browse the repository at this point in the history
  • Loading branch information
spwoodcock committed Jan 29, 2025
1 parent 7991078 commit 8d27a7f
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 9 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ err = SetupWebhook(
log,
ctx,
dbPool,
nil,
"https://your.domain.com/some/entity/webhook",
"https://your.domain.com/some/submission/webhook",
"https://your.domain.com/some/review/webhook",
Expand Down
13 changes: 8 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ func SetupWebhook(
log *slog.Logger,
ctx context.Context,
dbPool *pgxpool.Pool,
apiKey *string, // use a pointer so it's possible to pass 'nil;
updateEntityUrl, newSubmissionUrl, reviewSubmissionUrl string,
) error {
// setup the listener
Expand Down Expand Up @@ -84,13 +85,12 @@ func SetupWebhook(
// Only send the request for correctly parsed (supported) events
if parsedData != nil {
if parsedData.Type == "entity.update.version" && updateEntityUrl != "" {
webhook.SendRequest(log, ctx, updateEntityUrl, *parsedData)
webhook.SendRequest(log, ctx, updateEntityUrl, *parsedData, apiKey)
} else if parsedData.Type == "submission.create" && newSubmissionUrl != "" {
webhook.SendRequest(log, ctx, newSubmissionUrl, *parsedData)
webhook.SendRequest(log, ctx, newSubmissionUrl, *parsedData, apiKey)
} else if parsedData.Type == "submission.update" && reviewSubmissionUrl != "" {
webhook.SendRequest(log, ctx, reviewSubmissionUrl, *parsedData)
webhook.SendRequest(log, ctx, reviewSubmissionUrl, *parsedData, apiKey)
} else {

log.Debug(
fmt.Sprintf(
"%s event type was triggered, but no webhook url was provided",
Expand Down Expand Up @@ -164,6 +164,9 @@ func main() {
var reviewSubmissionUrl string
flag.StringVar(&reviewSubmissionUrl, "reviewSubmissionUrl", defaultReviewSubmissionUrl, "Webhook URL for review submission events")

var apiKey string
flag.StringVar(&apiKey, "apiKey", "", "X-API-Key header value, for autenticating with webhook API")

var debug bool
flag.BoolVar(&debug, "debug", false, "Enable debug logging")

Expand Down Expand Up @@ -200,7 +203,7 @@ func main() {
}

printStartupMsg()
err = SetupWebhook(log, ctx, dbPool, updateEntityUrl, newSubmissionUrl, reviewSubmissionUrl)
err = SetupWebhook(log, ctx, dbPool, &apiKey, updateEntityUrl, newSubmissionUrl, reviewSubmissionUrl)
if err != nil {
fmt.Fprintf(os.Stderr, "error setting up webhook: %v", err)
os.Exit(1)
Expand Down
2 changes: 1 addition & 1 deletion main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ package main
// go func() {
// defer wg.Done()
// log.Info("starting webhook listener")
// err := SetupWebhook(log, ctx, dbPool, mockServer.URL, mockServer.URL, mockServer.URL)
// err := SetupWebhook(log, ctx, dbPool, nil, mockServer.URL, mockServer.URL, mockServer.URL)
// if err != nil && ctx.Err() == nil {
// log.Error("webhook listener error", "error", err)
// }
Expand Down
7 changes: 6 additions & 1 deletion webhook/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import (
"bytes"
"context"
"encoding/json"
"io"
"log/slog"
"net/http"
"time"
"io"

"github.com/hotosm/central-webhook/parser"
)
Expand All @@ -19,6 +19,7 @@ func SendRequest(
ctx context.Context,
apiEndpoint string,
eventJson parser.ProcessedEvent,
apiKey *string,
) {
// Marshal the payload to JSON
marshaledPayload, err := json.Marshal(eventJson)
Expand All @@ -34,6 +35,10 @@ func SendRequest(
return
}
req.Header.Set("Content-Type", "application/json")
// Add X-API-Key header if apiKey is provided
if apiKey != nil {
req.Header.Set("X-API-Key", *apiKey)
}

// Send the request
client := &http.Client{Timeout: 10 * time.Second}
Expand Down
11 changes: 9 additions & 2 deletions webhook/request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,14 @@ func TestSendRequest(t *testing.T) {

// Set up a mock server
var receivedPayload parser.ProcessedEvent
var receivedApiKey string
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Verify content type
is.Equal("application/json", r.Header.Get("Content-Type"))

// Verify API key was received
receivedApiKey = r.Header.Get("X-API-Key")

// Read and parse request body
body, err := io.ReadAll(r.Body)
is.NoErr(err)
Expand Down Expand Up @@ -87,13 +91,16 @@ func TestSendRequest(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

// Call the SendRequest function
SendRequest(log, ctx, server.URL, tc.event)
testApiKey := "test-api-key"
SendRequest(log, ctx, server.URL, tc.event, &testApiKey)

// Validate the received payload
is.Equal(tc.expectedId, receivedPayload.ID)
is.Equal(tc.expectedType, receivedPayload.Type)
is.Equal(tc.expectedData, receivedPayload.Data)

// Validate that the API key header was sent correctly
is.Equal("test-api-key", receivedApiKey)
})
}
}

0 comments on commit 8d27a7f

Please sign in to comment.