|
2 | 2 |
|
3 | 3 | require 'spec_helper' |
4 | 4 | require 'rack/test' |
| 5 | +require 'cgi' |
5 | 6 | require 'json' |
6 | 7 | require 'securerandom' |
7 | 8 | require_relative '../../../app' |
|
13 | 14 |
|
14 | 15 | let(:feed_url) { 'https://example.com/articles' } |
15 | 16 | let(:feed_token) { "valid-feed-token-#{SecureRandom.hex(4)}" } |
| 17 | + let(:encoded_feed_token) { CGI.escape(feed_token) } |
16 | 18 |
|
17 | 19 | let(:account) do |
18 | 20 | { |
|
94 | 96 | expect(last_response.body).to eq('<rss version="2.0"></rss>') |
95 | 97 | end |
96 | 98 |
|
| 99 | + it 'accepts URL-escaped public feed tokens', :aggregate_failures do |
| 100 | + padded_feed_token = 'signed-public-token=' |
| 101 | + encoded_padded_feed_token = CGI.escape(padded_feed_token) |
| 102 | + |
| 103 | + stub_escaped_feed_token(raw_token: padded_feed_token, encoded_token: encoded_padded_feed_token) |
| 104 | + |
| 105 | + get "/api/v1/feeds/#{encoded_padded_feed_token}", {}, { 'HTTP_ACCEPT' => 'application/xml' } |
| 106 | + |
| 107 | + expect(last_response.status).to eq(200) |
| 108 | + expect(last_response.headers['Content-Type']).to eq('application/xml') |
| 109 | + end |
| 110 | + |
97 | 111 | it 'renders the JSON feed when requested by extension', :aggregate_failures do |
98 | 112 | get "/api/v1/feeds/#{feed_token}.json" |
99 | 113 |
|
|
166 | 180 | [401, 'application/feed+json', { 'version' => 'https://jsonfeed.org/version/1.1', 'title' => 'Error' }] |
167 | 181 | ) |
168 | 182 | end |
| 183 | + |
| 184 | + # rubocop:disable Metrics/AbcSize, Metrics/MethodLength |
| 185 | + def stub_escaped_feed_token(raw_token:, encoded_token:) |
| 186 | + escaped_token_payload = instance_double( |
| 187 | + Html2rss::Web::FeedToken, |
| 188 | + url: feed_url, |
| 189 | + username: account[:username], |
| 190 | + strategy: 'ssrf_filter' |
| 191 | + ) |
| 192 | + |
| 193 | + allow(Html2rss::Web::FeedToken).to receive(:decode).with(raw_token).and_return(escaped_token_payload) |
| 194 | + allow(Html2rss::Web::FeedToken).to receive(:decode).with(encoded_token).and_return(nil) |
| 195 | + allow(Html2rss::Web::FeedToken) |
| 196 | + .to receive(:validate_and_decode).with(raw_token, feed_url, anything) |
| 197 | + .and_return(escaped_token_payload) |
| 198 | + end |
| 199 | + # rubocop:enable Metrics/AbcSize, Metrics/MethodLength |
169 | 200 | end |
170 | 201 |
|
171 | 202 | describe 'POST /api/v1/feeds' do # rubocop:disable RSpec/MultipleMemoizedHelpers |
|
0 commit comments