Skip to content

Commit 84dd5d9

Browse files
committed
Add custom IP filtering auth plugin and acceptance tests
1 parent c6098eb commit 84dd5d9

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

spec/acceptance/acceptance_tests.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,5 +568,24 @@ def expired_unix_timestamp(seconds_ago = 600)
568568
expect_response(response, Net::HTTPUnauthorized, "authentication failed")
569569
end
570570
end
571+
572+
describe "custom ip filtering auth plugin" do
573+
it "successfully validates using a custom IP filtering auth plugin" do
574+
payload = {}.to_json
575+
headers = { "Content-Type" => "application/json", "X-Forwarded-For" => "999.999.999.999" }
576+
response = make_request(:post, "/webhooks/ip_filtering_example", payload, headers)
577+
578+
expect_response(response, Net::HTTPSuccess)
579+
body = parse_json_response(response)
580+
expect(body["status"]).to eq("success")
581+
end
582+
583+
it "rejects requests with invalid IP using custom IP filtering auth plugin" do
584+
payload = {}.to_json
585+
headers = { "Content-Type" => "application/json", "X-Forwarded-For" => "123.456.789.000" }
586+
response = make_request(:post, "/webhooks/ip_filtering_example", payload, headers)
587+
expect_response(response, Net::HTTPUnauthorized, "authentication failed")
588+
end
589+
end
571590
end
572591
end
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
path: /ip_filtering_example
2+
handler: Hello
3+
4+
auth:
5+
type: ip_filtering_example
6+
7+
opts:
8+
allowed_ips:
9+
- "999.999.999.999" # intentionally invalid IP
10+
- "888.888.888.888" # intentionally invalid IP
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# frozen_string_literal: true
2+
# Example custom auth plugin for IP filtering
3+
module Hooks
4+
module Plugins
5+
module Auth
6+
class IpFilteringExample < Base
7+
def self.valid?(payload:, headers:, config:)
8+
# Get the allowed IPs from the configuration (opts is a hash containing additional options that can be set in any endpoint configuration)
9+
allowed_ips = config.dig(:opts, :allowed_ips) || []
10+
11+
# Get the request IP from headers or payload
12+
# Find the IP via the request headers with case-insensitive matching - this is a helper method available in the base class
13+
# so it is available to all auth plugins.
14+
# This example assumes the IP is in the "X-Forwarded-For" header, which is common for proxied requests
15+
request_ip = find_header_value(headers, "X-Forwarded-For")
16+
17+
# If the request IP is not found, return false
18+
return false unless request_ip
19+
20+
# Return true if the request IP is in the allowed IPs list
21+
allowed_ips.include?(request_ip)
22+
end
23+
end
24+
end
25+
end
26+
end

0 commit comments

Comments
 (0)