Skip to content

Commit 8d27a7f

Browse files
committed
feat: add apiKey flag for passing X-API-Key request header auth
1 parent 7991078 commit 8d27a7f

File tree

5 files changed

+25
-9
lines changed

5 files changed

+25
-9
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ err = SetupWebhook(
8787
log,
8888
ctx,
8989
dbPool,
90+
nil,
9091
"https://your.domain.com/some/entity/webhook",
9192
"https://your.domain.com/some/submission/webhook",
9293
"https://your.domain.com/some/review/webhook",

main.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ func SetupWebhook(
4141
log *slog.Logger,
4242
ctx context.Context,
4343
dbPool *pgxpool.Pool,
44+
apiKey *string, // use a pointer so it's possible to pass 'nil;
4445
updateEntityUrl, newSubmissionUrl, reviewSubmissionUrl string,
4546
) error {
4647
// setup the listener
@@ -84,13 +85,12 @@ func SetupWebhook(
8485
// Only send the request for correctly parsed (supported) events
8586
if parsedData != nil {
8687
if parsedData.Type == "entity.update.version" && updateEntityUrl != "" {
87-
webhook.SendRequest(log, ctx, updateEntityUrl, *parsedData)
88+
webhook.SendRequest(log, ctx, updateEntityUrl, *parsedData, apiKey)
8889
} else if parsedData.Type == "submission.create" && newSubmissionUrl != "" {
89-
webhook.SendRequest(log, ctx, newSubmissionUrl, *parsedData)
90+
webhook.SendRequest(log, ctx, newSubmissionUrl, *parsedData, apiKey)
9091
} else if parsedData.Type == "submission.update" && reviewSubmissionUrl != "" {
91-
webhook.SendRequest(log, ctx, reviewSubmissionUrl, *parsedData)
92+
webhook.SendRequest(log, ctx, reviewSubmissionUrl, *parsedData, apiKey)
9293
} else {
93-
9494
log.Debug(
9595
fmt.Sprintf(
9696
"%s event type was triggered, but no webhook url was provided",
@@ -164,6 +164,9 @@ func main() {
164164
var reviewSubmissionUrl string
165165
flag.StringVar(&reviewSubmissionUrl, "reviewSubmissionUrl", defaultReviewSubmissionUrl, "Webhook URL for review submission events")
166166

167+
var apiKey string
168+
flag.StringVar(&apiKey, "apiKey", "", "X-API-Key header value, for autenticating with webhook API")
169+
167170
var debug bool
168171
flag.BoolVar(&debug, "debug", false, "Enable debug logging")
169172

@@ -200,7 +203,7 @@ func main() {
200203
}
201204

202205
printStartupMsg()
203-
err = SetupWebhook(log, ctx, dbPool, updateEntityUrl, newSubmissionUrl, reviewSubmissionUrl)
206+
err = SetupWebhook(log, ctx, dbPool, &apiKey, updateEntityUrl, newSubmissionUrl, reviewSubmissionUrl)
204207
if err != nil {
205208
fmt.Fprintf(os.Stderr, "error setting up webhook: %v", err)
206209
os.Exit(1)

main_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ package main
114114
// go func() {
115115
// defer wg.Done()
116116
// log.Info("starting webhook listener")
117-
// err := SetupWebhook(log, ctx, dbPool, mockServer.URL, mockServer.URL, mockServer.URL)
117+
// err := SetupWebhook(log, ctx, dbPool, nil, mockServer.URL, mockServer.URL, mockServer.URL)
118118
// if err != nil && ctx.Err() == nil {
119119
// log.Error("webhook listener error", "error", err)
120120
// }

webhook/request.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7+
"io"
78
"log/slog"
89
"net/http"
910
"time"
10-
"io"
1111

1212
"github.com/hotosm/central-webhook/parser"
1313
)
@@ -19,6 +19,7 @@ func SendRequest(
1919
ctx context.Context,
2020
apiEndpoint string,
2121
eventJson parser.ProcessedEvent,
22+
apiKey *string,
2223
) {
2324
// Marshal the payload to JSON
2425
marshaledPayload, err := json.Marshal(eventJson)
@@ -34,6 +35,10 @@ func SendRequest(
3435
return
3536
}
3637
req.Header.Set("Content-Type", "application/json")
38+
// Add X-API-Key header if apiKey is provided
39+
if apiKey != nil {
40+
req.Header.Set("X-API-Key", *apiKey)
41+
}
3742

3843
// Send the request
3944
client := &http.Client{Timeout: 10 * time.Second}

webhook/request_test.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,14 @@ func TestSendRequest(t *testing.T) {
2222

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

30+
// Verify API key was received
31+
receivedApiKey = r.Header.Get("X-API-Key")
32+
2933
// Read and parse request body
3034
body, err := io.ReadAll(r.Body)
3135
is.NoErr(err)
@@ -87,13 +91,16 @@ func TestSendRequest(t *testing.T) {
8791
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
8892
defer cancel()
8993

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

9397
// Validate the received payload
9498
is.Equal(tc.expectedId, receivedPayload.ID)
9599
is.Equal(tc.expectedType, receivedPayload.Type)
96100
is.Equal(tc.expectedData, receivedPayload.Data)
101+
102+
// Validate that the API key header was sent correctly
103+
is.Equal("test-api-key", receivedApiKey)
97104
})
98105
}
99106
}

0 commit comments

Comments
 (0)