otto 2.0.0.pre7 → 2.0.0.pre9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +1 -1
  3. data/.github/workflows/claude-code-review.yml +1 -1
  4. data/.github/workflows/claude.yml +1 -1
  5. data/.github/workflows/code-smells.yml +5 -8
  6. data/CHANGELOG.rst +87 -2
  7. data/Gemfile.lock +6 -6
  8. data/README.md +20 -0
  9. data/docs/.gitignore +2 -0
  10. data/docs/modern-authentication-authorization-landscape.md +558 -0
  11. data/docs/multi-strategy-authentication-design.md +1401 -0
  12. data/lib/otto/core/error_handler.rb +19 -8
  13. data/lib/otto/core/freezable.rb +0 -2
  14. data/lib/otto/core/middleware_stack.rb +12 -8
  15. data/lib/otto/core/router.rb +25 -31
  16. data/lib/otto/errors.rb +92 -0
  17. data/lib/otto/mcp/rate_limiting.rb +6 -2
  18. data/lib/otto/mcp/schema_validation.rb +1 -1
  19. data/lib/otto/response_handlers/json.rb +1 -3
  20. data/lib/otto/response_handlers/view.rb +1 -1
  21. data/lib/otto/route_handlers/base.rb +86 -1
  22. data/lib/otto/route_handlers/class_method.rb +17 -68
  23. data/lib/otto/route_handlers/instance_method.rb +18 -58
  24. data/lib/otto/route_handlers/logic_class.rb +95 -92
  25. data/lib/otto/security/authentication/auth_strategy.rb +2 -2
  26. data/lib/otto/security/authentication/route_auth_wrapper/response_builder.rb +123 -0
  27. data/lib/otto/security/authentication/route_auth_wrapper/role_authorization.rb +120 -0
  28. data/lib/otto/security/authentication/route_auth_wrapper/strategy_resolver.rb +69 -0
  29. data/lib/otto/security/authentication/route_auth_wrapper.rb +167 -329
  30. data/lib/otto/security/authentication/strategy_result.rb +9 -9
  31. data/lib/otto/security/authorization_error.rb +1 -1
  32. data/lib/otto/security/config.rb +3 -3
  33. data/lib/otto/security/rate_limiter.rb +7 -3
  34. data/lib/otto/version.rb +1 -1
  35. data/lib/otto.rb +47 -3
  36. metadata +7 -3
  37. data/changelog.d/20251103_235431_delano_86_improve_error_logging.rst +0 -15
  38. data/changelog.d/20251109_025012_claude_fix_backtrace_sanitization.rst +0 -37
data/lib/otto.rb CHANGED
@@ -17,6 +17,7 @@ require_relative 'otto/static'
17
17
  require_relative 'otto/helpers'
18
18
  require_relative 'otto/response_handlers'
19
19
  require_relative 'otto/route_handlers'
20
+ require_relative 'otto/errors'
20
21
  require_relative 'otto/locale'
21
22
  require_relative 'otto/mcp'
22
23
  require_relative 'otto/core'
@@ -79,9 +80,10 @@ class Otto
79
80
  load(path) unless path.nil?
80
81
  super()
81
82
 
82
- # Auto-register AuthorizationError for 403 Forbidden responses
83
- # This allows Logic classes to raise AuthorizationError for resource-level access control
84
- register_error_handler(Otto::Security::AuthorizationError, status: 403, log_level: :warn)
83
+ # Auto-register all Otto framework error classes
84
+ # This allows Logic classes and framework code to raise appropriate errors
85
+ # without requiring manual registration in implementing projects
86
+ register_framework_errors
85
87
 
86
88
  # Build the middleware app once after all initialization is complete
87
89
  build_app!
@@ -586,6 +588,48 @@ class Otto
586
588
  configure_mcp(opts)
587
589
  end
588
590
 
591
+ # Register all Otto framework error classes with appropriate status codes
592
+ #
593
+ # This method auto-registers base HTTP error classes and all framework-specific
594
+ # error classes (Security, MCP) so that raising them automatically returns the
595
+ # correct HTTP status code instead of 500.
596
+ #
597
+ # Users can override these registrations by calling register_error_handler
598
+ # after Otto.new with custom status codes or log levels.
599
+ #
600
+ # @return [void]
601
+ # @api private
602
+ def register_framework_errors
603
+ # Base HTTP errors (for direct use or subclassing by implementing projects)
604
+ register_error_from_class(Otto::NotFoundError)
605
+ register_error_from_class(Otto::BadRequestError)
606
+ register_error_from_class(Otto::UnauthorizedError)
607
+ register_error_from_class(Otto::ForbiddenError)
608
+ register_error_from_class(Otto::PayloadTooLargeError)
609
+
610
+ # Security module errors
611
+ register_error_from_class(Otto::Security::AuthorizationError)
612
+ register_error_from_class(Otto::Security::CSRFError)
613
+ register_error_from_class(Otto::Security::RequestTooLargeError)
614
+ register_error_from_class(Otto::Security::ValidationError)
615
+
616
+ # MCP module errors
617
+ register_error_from_class(Otto::MCP::ValidationError)
618
+ end
619
+
620
+ # Register an error handler using the error class as the single source of truth
621
+ #
622
+ # @param error_class [Class] Error class that responds to default_status and default_log_level
623
+ # @return [void]
624
+ # @api private
625
+ def register_error_from_class(error_class)
626
+ register_error_handler(
627
+ error_class,
628
+ status: error_class.default_status,
629
+ log_level: error_class.default_log_level
630
+ )
631
+ end
632
+
589
633
  class << self
590
634
  attr_accessor :debug, :logger # rubocop:disable ThreadSafety/ClassAndModuleAttributes
591
635
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: otto
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.pre7
4
+ version: 2.0.0.pre9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Delano Mandelbaum
@@ -169,14 +169,14 @@ files:
169
169
  - LICENSE.txt
170
170
  - README.md
171
171
  - bin/rspec
172
- - changelog.d/20251103_235431_delano_86_improve_error_logging.rst
173
- - changelog.d/20251109_025012_claude_fix_backtrace_sanitization.rst
174
172
  - changelog.d/README.md
175
173
  - changelog.d/scriv.ini
176
174
  - docs/.gitignore
177
175
  - docs/ipaddr-encoding-quirk.md
178
176
  - docs/migrating/v2.0.0-pre1.md
179
177
  - docs/migrating/v2.0.0-pre2.md
178
+ - docs/modern-authentication-authorization-landscape.md
179
+ - docs/multi-strategy-authentication-design.md
180
180
  - examples/.gitignore
181
181
  - examples/advanced_routes/README.md
182
182
  - examples/advanced_routes/app.rb
@@ -245,6 +245,7 @@ files:
245
245
  - lib/otto/core/uri_generator.rb
246
246
  - lib/otto/design_system.rb
247
247
  - lib/otto/env_keys.rb
248
+ - lib/otto/errors.rb
248
249
  - lib/otto/helpers.rb
249
250
  - lib/otto/helpers/base.rb
250
251
  - lib/otto/helpers/request.rb
@@ -289,6 +290,9 @@ files:
289
290
  - lib/otto/security/authentication/auth_failure.rb
290
291
  - lib/otto/security/authentication/auth_strategy.rb
291
292
  - lib/otto/security/authentication/route_auth_wrapper.rb
293
+ - lib/otto/security/authentication/route_auth_wrapper/response_builder.rb
294
+ - lib/otto/security/authentication/route_auth_wrapper/role_authorization.rb
295
+ - lib/otto/security/authentication/route_auth_wrapper/strategy_resolver.rb
292
296
  - lib/otto/security/authentication/strategies/api_key_strategy.rb
293
297
  - lib/otto/security/authentication/strategies/noauth_strategy.rb
294
298
  - lib/otto/security/authentication/strategies/permission_strategy.rb
@@ -1,15 +0,0 @@
1
- Added
2
- -----
3
-
4
- - Error handler registration system for expected business logic errors. Register handlers with ``otto.register_error_handler(ErrorClass, status: 404, log_level: :info)`` to return proper HTTP status codes and avoid logging expected errors as 500s with backtraces. Supports custom response handlers via blocks for complete control over error responses.
5
-
6
- Changed
7
- -------
8
-
9
- - Backtrace logging now always logs at ERROR level (was DEBUG) with sanitized file paths for security. Backtraces for unhandled 500 errors are always logged regardless of ``OTTO_DEBUG`` setting, with paths sanitized to prevent exposing system information (project files show relative paths, gems show ``[GEM] name-version/path``, Ruby stdlib shows ``[RUBY] filename``).
10
- - Increased backtrace limit from 10 to 20 lines for critical errors to provide better debugging context.
11
-
12
- AI Assistance
13
- -------------
14
-
15
- - Implemented error handler registration architecture with comprehensive test coverage (17 test cases) using sequential thinking to work through security implications and design decisions. AI assisted with path sanitization strategy, error classification patterns, and ensuring backward compatibility with existing error handling.
@@ -1,37 +0,0 @@
1
- .. Changed in: otto
2
- .. Fixes issue:
3
-
4
- Improved backtrace sanitization security and readability
5
- ---------------------------------------------------------
6
-
7
- **Security Enhancements:**
8
-
9
- - Fixed bundler gem path detection to correctly sanitize git-based gems
10
- - Now properly handles nested gem paths like ``/gems/3.4.0/bundler/gems/otto-abc123/``
11
- - Strips git hash suffixes from bundler gems (``otto-abc123def456`` → ``otto``)
12
- - Removes version numbers from regular gems (``rack-3.2.4`` → ``rack``)
13
- - Prevents exposure of absolute paths, usernames, and project names in logs
14
-
15
- **Improvements:**
16
-
17
- - Bundler gems now show as ``[GEM] otto/lib/otto/route.rb:142`` instead of ``[GEM] 3.4.0/bundler/gems/...``
18
- - Regular gems show cleaner output: ``[GEM] rack/lib/rack.rb:20`` instead of ``[GEM] rack-3.2.4/lib/rack.rb:20``
19
- - Multi-hyphenated gem names handled correctly (``active-record-import-1.5.0`` → ``active-record-import``)
20
- - Better handling of version-only directory names in gem paths
21
-
22
- **Documentation:**
23
-
24
- - Added comprehensive backtrace sanitization section to CLAUDE.md
25
- - Documented security guarantees and sanitization rules
26
- - Added examples showing before/after path transformations
27
- - Created comprehensive test suite for backtrace sanitization
28
-
29
- **Rationale:**
30
-
31
- Raw backtraces expose sensitive information:
32
- - Usernames (``/Users/alice/``, ``/home/admin/``)
33
- - Project structure and internal organization
34
- - Gem installation paths and Ruby versions
35
- - System architecture details
36
-
37
- This improvement ensures all backtraces are sanitized automatically, preventing accidental leakage of sensitive system information while maintaining readability for debugging.