Skip to content

Commit 0db44a2

Browse files
committed
.
1 parent 995ce03 commit 0db44a2

File tree

4 files changed

+48
-72
lines changed

4 files changed

+48
-72
lines changed

app.rb

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -86,25 +86,13 @@ def development? = self.class.development?
8686
next exception_page(error) if development?
8787

8888
# Simple error handling for production
89-
status = case error
90-
when UnauthorizedError then 401
91-
when BadRequestError then 400
92-
when ForbiddenError then 403
93-
when NotFoundError then 404
94-
else 500
95-
end
89+
http_status = error.respond_to?(:status) ? error.status : 500
90+
error_code = error.respond_to?(:code) ? error.code : 'INTERNAL_SERVER_ERROR'
9691

97-
response.status = status
92+
response.status = http_status
9893

9994
if request.path.start_with?('/api/v1/')
10095
response['Content-Type'] = 'application/json'
101-
error_code = case error
102-
when UnauthorizedError then 'UNAUTHORIZED'
103-
when BadRequestError then 'BAD_REQUEST'
104-
when ForbiddenError then 'FORBIDDEN'
105-
when NotFoundError then 'NOT_FOUND'
106-
else 'INTERNAL_SERVER_ERROR'
107-
end
10896
JSON.generate({ success: false, error: { message: error.message, code: error_code } })
10997
else
11098
response['Content-Type'] = 'application/xml'

app/auth_utils.rb

Lines changed: 0 additions & 32 deletions
This file was deleted.

app/auto_source.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# frozen_string_literal: true
22

3+
require 'digest'
34
require_relative 'account_manager'
45
require_relative 'auth'
5-
require_relative 'auth_utils'
66
require_relative 'feed_generator'
77
require_relative 'url_validator'
88

@@ -24,7 +24,7 @@ def enabled?
2424
def create_stable_feed(name, url, token_data, strategy = 'ssrf_filter')
2525
return nil unless url_allowed_for_token?(token_data, url)
2626

27-
feed_id = AuthUtils.generate_feed_id(token_data[:username], url, token_data[:token])
27+
feed_id = generate_feed_id(token_data[:username], url, token_data[:token])
2828
feed_token = Auth.generate_feed_token(token_data[:username], url)
2929
return nil unless feed_token
3030

@@ -63,6 +63,11 @@ def url_allowed_for_token?(token_data, url)
6363
UrlValidator.url_allowed?(account, url)
6464
end
6565

66+
def generate_feed_id(username, url, token)
67+
content = "#{username}:#{url}:#{token}"
68+
Digest::SHA256.hexdigest(content)[0..15]
69+
end
70+
6671
def build_feed_data(name, url, token_data, strategy, identifiers)
6772
public_url = "/api/v1/feeds/#{identifiers[:feed_token]}"
6873

app/exceptions.rb

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,46 +6,61 @@ module Web
66
# Custom exceptions for clean error handling
77
# These map to HTTP status codes and are handled by Roda's error_handler
88

9-
# HTTP 401 - Authentication required
10-
class UnauthorizedError < StandardError
11-
def initialize(message = 'Authentication required')
9+
class HttpError < StandardError
10+
DEFAULT_MESSAGE = 'Internal Server Error'
11+
STATUS = 500
12+
CODE = 'INTERNAL_SERVER_ERROR'
13+
14+
def initialize(message = self.class::DEFAULT_MESSAGE)
1215
super
1316
end
17+
18+
def status
19+
self.class::STATUS
20+
end
21+
22+
def code
23+
self.class::CODE
24+
end
25+
end
26+
27+
# HTTP 401 - Authentication required
28+
class UnauthorizedError < HttpError
29+
DEFAULT_MESSAGE = 'Authentication required'
30+
STATUS = 401
31+
CODE = 'UNAUTHORIZED'
1432
end
1533

1634
# HTTP 400 - Invalid request
17-
class BadRequestError < StandardError
18-
def initialize(message = 'Bad Request')
19-
super
20-
end
35+
class BadRequestError < HttpError
36+
DEFAULT_MESSAGE = 'Bad Request'
37+
STATUS = 400
38+
CODE = 'BAD_REQUEST'
2139
end
2240

2341
# HTTP 403 - Access denied
24-
class ForbiddenError < StandardError
25-
def initialize(message = 'Forbidden')
26-
super
27-
end
42+
class ForbiddenError < HttpError
43+
DEFAULT_MESSAGE = 'Forbidden'
44+
STATUS = 403
45+
CODE = 'FORBIDDEN'
2846
end
2947

3048
# HTTP 404 - Resource not found
31-
class NotFoundError < StandardError
32-
def initialize(message = 'Not Found')
33-
super
34-
end
49+
class NotFoundError < HttpError
50+
DEFAULT_MESSAGE = 'Not Found'
51+
STATUS = 404
52+
CODE = 'NOT_FOUND'
3553
end
3654

3755
# HTTP 405 - Method not allowed
38-
class MethodNotAllowedError < StandardError
39-
def initialize(message = 'Method Not Allowed')
40-
super
41-
end
56+
class MethodNotAllowedError < HttpError
57+
DEFAULT_MESSAGE = 'Method Not Allowed'
58+
STATUS = 405
59+
CODE = 'METHOD_NOT_ALLOWED'
4260
end
4361

4462
# HTTP 500 - Server error
45-
class InternalServerError < StandardError
46-
def initialize(message = 'Internal Server Error')
47-
super
48-
end
63+
class InternalServerError < HttpError
4964
end
5065
end
5166
end

0 commit comments

Comments
 (0)