File tree Expand file tree Collapse file tree 4 files changed +81
-0
lines changed
Expand file tree Collapse file tree 4 files changed +81
-0
lines changed Original file line number Diff line number Diff line change 148148 expect ( body [ "status" ] ) . to eq ( "success" )
149149 end
150150 end
151+
152+ describe "custom auth plugin" do
153+
154+ it "successfully validates using a custom auth plugin" do
155+ payload = { } . to_json
156+ headers = { "Authorization" => "Bearer octoawesome-shared-secret" }
157+ response = http . post ( "/webhooks/with_custom_auth_plugin" , payload , headers )
158+
159+ expect ( response ) . to be_a ( Net ::HTTPSuccess )
160+ body = JSON . parse ( response . body )
161+ expect ( body [ "status" ] ) . to eq ( "test_success" )
162+ expect ( body [ "handler" ] ) . to eq ( "TestHandler" )
163+ end
164+
165+ it "rejects requests with invalid credentials using custom auth plugin" do
166+ payload = { } . to_json
167+ headers = { "Authorization" => "Bearer wrong-secret" }
168+ response = http . post ( "/webhooks/with_custom_auth_plugin" , payload , headers )
169+
170+ expect ( response ) . to be_a ( Net ::HTTPUnauthorized )
171+ expect ( response . body ) . to include ( "authentication failed" )
172+ end
173+
174+ it "rejects requests with missing credentials using custom auth plugin" do
175+ payload = { } . to_json
176+ headers = { }
177+ response = http . post ( "/webhooks/with_custom_auth_plugin" , payload , headers )
178+
179+ expect ( response ) . to be_a ( Net ::HTTPUnauthorized )
180+ expect ( response . body ) . to include ( "authentication failed" )
181+ end
182+ end
151183 end
152184end
Original file line number Diff line number Diff line change 1+ path : /with_custom_auth_plugin
2+ handler : TestHandler
3+
4+ auth :
5+ type : example_auth_plugin
6+ secret_env_key : SHARED_SECRET # the name of the environment variable containing the shared secret
7+ header : Authorization
Original file line number Diff line number Diff line change 1+ # frozen_string_literal: true
2+
3+ # this is just a super simple example of an auth plugin
4+ # it is not secure and should not be used in production
5+ # it is only for demonstration purposes
6+
7+ module Hooks
8+ module Plugins
9+ module Auth
10+ class ExampleAuthPlugin < Base
11+ def self . valid? ( payload :, headers :, config :)
12+ # Get the secret from environment variable as configured with secret_env_key
13+ secret = fetch_secret ( config , secret_env_key_name : :secret_env_key )
14+
15+ # Get the authorization header (case-insensitive)
16+ auth_header = nil
17+ headers . each do |key , value |
18+ if key . downcase == "authorization"
19+ auth_header = value
20+ break
21+ end
22+ end
23+
24+ # Check if the header matches our expected format
25+ return false unless auth_header
26+
27+ # Extract the token from "Bearer <token>" format
28+ return false unless auth_header . start_with? ( "Bearer " )
29+
30+ token = auth_header [ 7 ..-1 ] # Remove "Bearer " prefix
31+
32+ # Simple token comparison (in practice, this might be more complex)
33+ Rack ::Utils . secure_compare ( token , secret )
34+ rescue StandardError => e
35+ log . error ( "ExampleAuthPlugin failed: #{ e . message } " )
36+ false
37+ end
38+ end
39+ end
40+ end
41+ end
Original file line number Diff line number Diff line change @@ -4,6 +4,7 @@ class TestHandler < Hooks::Plugins::Handlers::Base
44 def call ( payload :, headers :, config :)
55 {
66 status : "test_success" ,
7+ handler : "TestHandler" ,
78 payload_received : payload ,
89 config_opts : config [ :opts ] ,
910 timestamp : Time . now . iso8601
You can’t perform that action at this time.
0 commit comments