Twitch Webhook Fixes (#2692)
* Twitch Webhook Registration Fix This fixes the broken twitch webhook registration. I previously added the `to_json` when I was switching to using HTTParty and working through WebMock. I apparently forgot to test this manually however after and relied on the specs that had some baked in bad assumptions. This removes the `to_json` and configures the mocking properly in the spec setup. I tested locally that this can now succesfully register for webhooks with Twitch! * Fix Webhook verification digesting as well, hardcode the specs for durability * Refactor to use shorter digest method * Add cache buster lines from Bens branch
This commit is contained in:
parent
fa3f4dcd0f
commit
23ded947e3
5 changed files with 31 additions and 61 deletions
|
|
@ -35,10 +35,8 @@ class TwitchStreamUpdatesController < ApplicationController
|
|||
|
||||
def secret_verified?
|
||||
twitch_sha = request.headers["x-hub-signature"]
|
||||
digest = Digest::SHA256.new
|
||||
digest << ApplicationConfig["TWITCH_WEBHOOK_SECRET"]
|
||||
digest << request.raw_post
|
||||
digest = OpenSSL::HMAC.hexdigest("SHA256", ApplicationConfig["TWITCH_WEBHOOK_SECRET"], request.raw_post)
|
||||
|
||||
twitch_sha == "sha256=#{digest.hexdigest}"
|
||||
twitch_sha == "sha256=#{digest}"
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -504,6 +504,9 @@ class User < ApplicationRecord
|
|||
|
||||
def bust_cache
|
||||
CacheBuster.new.bust("/#{username}")
|
||||
CacheBuster.new.bust("/#{username}?i=i")
|
||||
CacheBuster.new.bust("/live/#{username}")
|
||||
CacheBuster.new.bust("/live/#{username}?i=i")
|
||||
CacheBuster.new.bust("/feed/#{username}")
|
||||
end
|
||||
handle_asynchronously :bust_cache
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ module Streams
|
|||
"hub.lease_seconds" => WEBHOOK_LEASE_SECONDS,
|
||||
"hub.topic" => "https://api.twitch.tv/helix/streams?user_id=#{twitch_user_id}",
|
||||
"hub.secret" => ApplicationConfig["TWITCH_WEBHOOK_SECRET"]
|
||||
}.to_json
|
||||
}
|
||||
end
|
||||
|
||||
def authentication_request_headers
|
||||
|
|
|
|||
|
|
@ -41,35 +41,23 @@ RSpec.describe "TwitchStramUpdates", type: :request do
|
|||
end
|
||||
|
||||
describe "POST /users/:user_id/twitch_stream_updates" do
|
||||
before do
|
||||
allow(ApplicationConfig).to receive(:[]).and_call_original
|
||||
allow(ApplicationConfig).to receive(:[]).with("TWITCH_WEBHOOK_SECRET").and_return("FAKE_TWITCH_WEBHOOK_SECRET")
|
||||
end
|
||||
|
||||
context "when the user was not streaming and starts streaming" do
|
||||
let(:currently_streaming_on) { nil }
|
||||
|
||||
let(:twitch_webhook_params) do
|
||||
{
|
||||
data: [{
|
||||
id: "0123456789",
|
||||
user_id: "5678",
|
||||
user_name: "wjdtkdqhs",
|
||||
game_id: "21779",
|
||||
community_ids: [],
|
||||
type: "live",
|
||||
title: "Best Stream Ever",
|
||||
viewer_count: 417,
|
||||
started_at: "2017-12-01T10:09:45Z",
|
||||
language: "en",
|
||||
thumbnail_url: "https://link/to/thumbnail.jpg"
|
||||
}]
|
||||
}
|
||||
'{"data":[{"id":"0123456789","user_id":"5678","user_name":"wjdtkdqhs","game_id":"21779","community_ids":[],"type":"live","title":"Best Stream Ever","viewer_count":417,"started_at":"2017-12-01T10:09:45Z","language":"en","thumbnail_url":"https://link/to/thumbnail.jpg"}]}'
|
||||
end
|
||||
let(:twitch_webhook_secret_sha) do
|
||||
digest = Digest::SHA256.new
|
||||
digest << ApplicationConfig["TWITCH_WEBHOOK_SECRET"]
|
||||
digest << twitch_webhook_params.to_json
|
||||
"sha256=#{digest.hexdigest}"
|
||||
"sha256=96840ed4d83666551e43b384d94ac481367504564d6474b5dea710cedde5ce18"
|
||||
end
|
||||
|
||||
it "updates the Users twitch streaming status" do
|
||||
expect { post "/users/#{user.id}/twitch_stream_updates", params: twitch_webhook_params.to_json, headers: { "Content-Type" => "application/json", "X-Hub-Signature" => twitch_webhook_secret_sha } }.
|
||||
expect { post "/users/#{user.id}/twitch_stream_updates", params: twitch_webhook_params, headers: { "Content-Type" => "application/json", "X-Hub-Signature" => twitch_webhook_secret_sha } }.
|
||||
to change { user.reload.currently_streaming? }.from(false).to(true).
|
||||
and change { user.reload.currently_streaming_on_twitch? }.from(false).to(true)
|
||||
end
|
||||
|
|
@ -77,51 +65,32 @@ RSpec.describe "TwitchStramUpdates", type: :request do
|
|||
|
||||
context "when the webhook secret was NOT verified" do
|
||||
let(:twitch_webhook_params) do
|
||||
{
|
||||
data: [{
|
||||
id: "0123456789",
|
||||
user_id: "5678",
|
||||
user_name: "wjdtkdqhs",
|
||||
game_id: "21779",
|
||||
community_ids: [],
|
||||
type: "live",
|
||||
title: "Best Stream Ever",
|
||||
viewer_count: 417,
|
||||
started_at: "2017-12-01T10:09:45Z",
|
||||
language: "en",
|
||||
thumbnail_url: "https://link/to/thumbnail.jpg"
|
||||
}]
|
||||
}
|
||||
'{"data":[{"id":"0123456789","user_id":"5678","user_name":"wjdtkdqhs","game_id":"21779","community_ids":[],"type":"live","title":"Best Stream Ever","viewer_count":417,"started_at":"2017-12-01T10:09:45Z","language":"en","thumbnail_url":"https://link/to/thumbnail.jpg"}]}'
|
||||
end
|
||||
let(:twitch_webhook_secret_sha) { "sha256=BAD_HASH" }
|
||||
|
||||
it "noops" do
|
||||
expect { post "/users/#{user.id}/twitch_stream_updates", params: twitch_webhook_params.to_json, headers: { "Content-Type" => "application/json", "X-Hub-Signature" => twitch_webhook_secret_sha } }.
|
||||
expect { post "/users/#{user.id}/twitch_stream_updates", params: twitch_webhook_params, headers: { "Content-Type" => "application/json", "X-Hub-Signature" => twitch_webhook_secret_sha } }.
|
||||
to not_change { user.reload.currently_streaming? }.from(false).
|
||||
and not_change { user.reload.currently_streaming_on_twitch? }.from(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when the user was streaming and stops" do
|
||||
let(:currently_streaming_on) { :twitch }
|
||||
context "when the user was streaming and stops" do
|
||||
let(:currently_streaming_on) { :twitch }
|
||||
|
||||
let(:twitch_webhook_params) do
|
||||
{
|
||||
data: []
|
||||
}
|
||||
end
|
||||
let(:twitch_webhook_secret_sha) do
|
||||
digest = Digest::SHA256.new
|
||||
digest << ApplicationConfig["TWITCH_WEBHOOK_SECRET"]
|
||||
digest << twitch_webhook_params.to_json
|
||||
"sha256=#{digest.hexdigest}"
|
||||
end
|
||||
let(:twitch_webhook_params) do
|
||||
'{"data":[]}'
|
||||
end
|
||||
let(:twitch_webhook_secret_sha) do
|
||||
"sha256=3222cdd929339a296712edf3ec820266b1e29c0e4eeb715dd18d98c0c2294ca3"
|
||||
end
|
||||
|
||||
it "updates the Users twitch streaming status" do
|
||||
expect { post "/users/#{user.id}/twitch_stream_updates", params: twitch_webhook_params.to_json, headers: { "Content-Type" => "application/json", "X-Hub-Signature" => twitch_webhook_secret_sha } }.
|
||||
to change { user.reload.currently_streaming? }.from(true).to(false).
|
||||
and change { user.reload.currently_streaming_on_twitch? }.from(true).to(false)
|
||||
it "updates the Users twitch streaming status" do
|
||||
expect { post "/users/#{user.id}/twitch_stream_updates", params: twitch_webhook_params, headers: { "Content-Type" => "application/json", "X-Hub-Signature" => twitch_webhook_secret_sha } }.
|
||||
to change { user.reload.currently_streaming? }.from(true).to(false).
|
||||
and change { user.reload.currently_streaming_on_twitch? }.from(true).to(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -15,11 +15,11 @@ RSpec.describe Streams::TwitchWebhook::Register, type: :service do
|
|||
"hub.lease_seconds" => 604_800,
|
||||
"hub.topic" => "https://api.twitch.tv/helix/streams?user_id=654321",
|
||||
"hub.secret" => ApplicationConfig["TWITCH_WEBHOOK_SECRET"]
|
||||
}.to_json
|
||||
}
|
||||
end
|
||||
let!(:twitch_webhook_registration_stubbed_route) do
|
||||
stub_request(:post, "https://api.twitch.tv/helix/webhooks/hub").
|
||||
with(body: expected_twitch_webhook_params, headers: expected_headers).
|
||||
with(body: URI.encode_www_form(expected_twitch_webhook_params), headers: expected_headers).
|
||||
and_return(status: 204)
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue