Skip to content

Commit 5b097d3

Browse files
committed
ruby clean
1 parent 695fb5a commit 5b097d3

File tree

4 files changed

+53
-68
lines changed

4 files changed

+53
-68
lines changed

app/auth.rb

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,7 @@ def validate_feed_token(feed_token, url)
103103
return nil unless feed_token && url
104104

105105
token_data = decode_feed_token(feed_token)
106-
return nil unless token_data
107-
108-
return nil unless verify_token_signature(token_data)
109-
return nil unless token_valid?(token_data, url)
106+
return nil unless token_data && verify_token_signature(token_data) && token_valid?(token_data, url)
110107

111108
get_account_by_username(token_data[:payload][:username])
112109
rescue StandardError
@@ -141,9 +138,7 @@ def token_valid?(token_data, url)
141138
# @param url [String] the full URL with query parameters
142139
# @return [String, nil] feed token if found, nil otherwise
143140
def extract_feed_token_from_url(url)
144-
uri = URI.parse(url)
145-
params = URI.decode_www_form(uri.query || '').to_h
146-
params['token']
141+
URI.parse(url).then { |uri| URI.decode_www_form(uri.query || '').to_h['token'] }
147142
rescue StandardError
148143
nil
149144
end
@@ -165,13 +160,10 @@ def feed_url_allowed?(feed_token, url)
165160
# @param request [Roda::Request] the request object
166161
# @return [String, nil] token if found, nil otherwise
167162
def extract_token(request)
168-
# Try Authorization header (Bearer token)
169163
auth_header = request.env['HTTP_AUTHORIZATION']
170-
if auth_header&.start_with?('Bearer ')
171-
return auth_header[7..] # Remove 'Bearer ' prefix
172-
end
164+
return unless auth_header&.start_with?('Bearer ')
173165

174-
nil
166+
auth_header.delete_prefix('Bearer ')
175167
end
176168

177169
##
@@ -217,7 +209,7 @@ def load_accounts
217209
# Get the secret key for HMAC signing
218210
# @return [String, nil] secret key if configured, nil otherwise
219211
def secret_key
220-
ENV.fetch('HTML2RSS_SECRET_KEY', nil)
212+
ENV.fetch('HTML2RSS_SECRET_KEY')
221213
end
222214

223215
##
@@ -226,20 +218,25 @@ def secret_key
226218
# @param patterns [Array<String>] allowed URL patterns
227219
# @return [Boolean] true if URL matches any pattern
228220
def url_matches_patterns?(url, patterns)
229-
patterns.any? do |pattern|
230-
if pattern.include?('*')
231-
# Convert wildcard pattern to regex with proper escaping
232-
escaped_pattern = Regexp.escape(pattern).gsub('\\*', '.*')
233-
url.match?(/\A#{escaped_pattern}\z/)
234-
else
235-
# Exact match or substring match
236-
url.include?(pattern)
237-
end
238-
end
221+
patterns.any? { |pattern| url_matches_pattern?(url, pattern) }
239222
rescue RegexpError
240223
false
241224
end
242225

226+
##
227+
# Check if URL matches a single pattern
228+
# @param url [String] URL to check
229+
# @param pattern [String] pattern to match against
230+
# @return [Boolean] true if URL matches pattern
231+
def url_matches_pattern?(url, pattern)
232+
if pattern.include?('*')
233+
escaped_pattern = Regexp.escape(pattern).gsub('\\*', '.*')
234+
url.match?(/\A#{escaped_pattern}\z/)
235+
else
236+
url.include?(pattern)
237+
end
238+
end
239+
243240
##
244241
# Sanitize text for safe inclusion in XML output
245242
# Escapes XML special characters to prevent injection attacks
@@ -256,15 +253,11 @@ def sanitize_xml(text)
256253
# @param url [String] URL to validate
257254
# @return [Boolean] true if URL is valid and allowed, false otherwise
258255
def valid_url?(url)
259-
return false unless url.is_a?(String)
260-
return false if url.empty?
261-
return false if url.length > 2048 # Prevent extremely long URLs
262-
263-
begin
264-
!Html2rss::Url.for_channel(url).nil?
265-
rescue StandardError
266-
false
267-
end
256+
return false unless url.is_a?(String) && !url.empty? && url.length <= 2048
257+
258+
!Html2rss::Url.for_channel(url).nil?
259+
rescue StandardError
260+
false
268261
end
269262
end
270263
end

app/auto_source.rb

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require 'uri'
44
require_relative 'auth'
55
require_relative 'xml_builder'
6+
require_relative 'local_config'
67

78
module Html2rss
89
module Web
@@ -13,13 +14,10 @@ module AutoSource
1314

1415
def enabled?
1516
# Enable by default in development, require explicit setting in production
16-
rack_env = ENV.fetch('RACK_ENV', nil)
17-
auto_source_enabled = ENV.fetch('AUTO_SOURCE_ENABLED', nil)
18-
19-
if rack_env == 'development'
20-
auto_source_enabled != 'false'
17+
if development?
18+
ENV.fetch('AUTO_SOURCE_ENABLED', nil) != 'false'
2119
else
22-
auto_source_enabled == 'true'
20+
ENV.fetch('AUTO_SOURCE_ENABLED', nil) == 'true'
2321
end
2422
end
2523

@@ -34,7 +32,7 @@ def allowed_origin?(request)
3432
end
3533

3634
def allowed_origins
37-
if ENV.fetch('RACK_ENV', nil) == 'development'
35+
if development?
3836
default_origins = 'localhost:3000,localhost:3001,127.0.0.1:3000,127.0.0.1:3001'
3937
origins = ENV.fetch('AUTO_SOURCE_ALLOWED_ORIGINS', default_origins)
4038
else
@@ -61,29 +59,31 @@ def create_stable_feed(name, url, token_data, strategy = 'ssrf_filter')
6159
build_feed_data(name, url, token_data, strategy, feed_id, feed_token)
6260
end
6361

64-
def build_feed_data(name, url, token_data, strategy, feed_id, feed_token)
65-
public_url = "/feeds/#{feed_id}?token=#{feed_token}&url=#{URI.encode_www_form_component(url)}"
62+
def generate_feed_from_stable_id(feed_id, token_data)
63+
return nil unless token_data
6664

65+
# Reconstruct feed data from token and feed_id
66+
# This is stateless - we don't store anything permanently
6767
{
6868
id: feed_id,
69-
name: name,
70-
url: url,
69+
url: nil, # Will be provided in request
7170
username: token_data[:username],
72-
strategy: strategy,
73-
public_url: public_url
71+
strategy: 'ssrf_filter'
7472
}
7573
end
7674

77-
def generate_feed_from_stable_id(feed_id, token_data)
78-
return nil unless token_data
75+
private
76+
77+
def build_feed_data(name, url, token_data, strategy, feed_id, feed_token)
78+
public_url = "/feeds/#{feed_id}?token=#{feed_token}&url=#{URI.encode_www_form_component(url)}"
7979

80-
# Reconstruct feed data from token and feed_id
81-
# This is stateless - we don't store anything permanently
8280
{
8381
id: feed_id,
84-
url: nil, # Will be provided in request
82+
name: name,
83+
url: url,
8584
username: token_data[:username],
86-
strategy: 'ssrf_filter'
85+
strategy: strategy,
86+
public_url: public_url
8787
}
8888
end
8989

@@ -111,14 +111,15 @@ def create_empty_feed_warning(url, strategy)
111111
)
112112
end
113113

114-
# rubocop:disable Metrics/MethodLength
115114
def call_strategy(url, strategy)
115+
global_config = LocalConfig.global
116+
116117
config = {
117-
stylesheets: [{ href: '/rss.xsl', type: 'text/xsl' }],
118+
stylesheets: global_config[:stylesheets],
119+
headers: global_config[:headers],
118120
strategy: strategy.to_sym,
119121
channel: {
120-
url: url,
121-
title: extract_channel_title(url)
122+
url: url
122123
},
123124
auto_source: {
124125
# Auto source configuration for automatic content detection
@@ -128,11 +129,6 @@ def call_strategy(url, strategy)
128129

129130
Html2rss.feed(config)
130131
end
131-
# rubocop:enable Metrics/MethodLength
132-
133-
def extract_channel_title(url)
134-
Html2rss::Url.for_channel(url).channel_titleized || 'RSS Feed'
135-
end
136132

137133
def extract_site_title(url)
138134
Html2rss::Url.for_channel(url).channel_titleized
@@ -147,6 +143,10 @@ def error_feed(message)
147143
def access_denied_feed(url)
148144
XmlBuilder.build_access_denied_feed(url)
149145
end
146+
147+
def development?
148+
ENV.fetch('RACK_ENV', nil) == 'development'
149+
end
150150
end
151151
end
152152
end

app/local_config.rb

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,6 @@ def global
3434
yaml.reject { |key| key == :feeds }
3535
end
3636

37-
##
38-
# @return [Array<Hash>] configured auth accounts
39-
def auth_accounts
40-
global.dig(:auth, :accounts) || []
41-
end
42-
4337
##
4438
# @return [Array<Symbol>] names of locally available feeds
4539
def feed_names

docker-compose.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ services:
3131
browserless:
3232
image: "ghcr.io/browserless/chromium"
3333
restart: unless-stopped
34-
ports:
35-
- "127.0.0.1:3001:3001"
3634
environment:
3735
PORT: 3001
3836
CONCURRENT: 10

0 commit comments

Comments
 (0)