otto 2.0.0.pre1 → 2.0.0.pre3

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +2 -3
  3. data/.github/workflows/claude-code-review.yml +30 -14
  4. data/.github/workflows/claude.yml +1 -1
  5. data/.rubocop.yml +4 -1
  6. data/CHANGELOG.rst +54 -6
  7. data/CLAUDE.md +537 -0
  8. data/Gemfile +3 -2
  9. data/Gemfile.lock +34 -26
  10. data/benchmark_middleware_wrap.rb +163 -0
  11. data/changelog.d/20251014_144317_delano_54_thats_a_wrapper.rst +36 -0
  12. data/changelog.d/20251014_161526_delano_54_thats_a_wrapper.rst +5 -0
  13. data/docs/.gitignore +2 -0
  14. data/docs/ipaddr-encoding-quirk.md +34 -0
  15. data/docs/migrating/v2.0.0-pre2.md +338 -0
  16. data/examples/authentication_strategies/config.ru +0 -1
  17. data/lib/otto/core/configuration.rb +91 -41
  18. data/lib/otto/core/freezable.rb +93 -0
  19. data/lib/otto/core/middleware_stack.rb +103 -16
  20. data/lib/otto/core/router.rb +8 -7
  21. data/lib/otto/core.rb +8 -0
  22. data/lib/otto/env_keys.rb +118 -0
  23. data/lib/otto/helpers/base.rb +2 -21
  24. data/lib/otto/helpers/request.rb +80 -2
  25. data/lib/otto/helpers/response.rb +25 -3
  26. data/lib/otto/helpers.rb +4 -0
  27. data/lib/otto/locale/config.rb +56 -0
  28. data/lib/otto/mcp/{validation.rb → schema_validation.rb} +3 -2
  29. data/lib/otto/mcp/server.rb +26 -13
  30. data/lib/otto/mcp.rb +3 -0
  31. data/lib/otto/privacy/config.rb +199 -0
  32. data/lib/otto/privacy/geo_resolver.rb +115 -0
  33. data/lib/otto/privacy/ip_privacy.rb +175 -0
  34. data/lib/otto/privacy/redacted_fingerprint.rb +136 -0
  35. data/lib/otto/privacy.rb +29 -0
  36. data/lib/otto/response_handlers/json.rb +6 -0
  37. data/lib/otto/route.rb +44 -48
  38. data/lib/otto/route_handlers/base.rb +1 -2
  39. data/lib/otto/route_handlers/factory.rb +24 -9
  40. data/lib/otto/route_handlers/logic_class.rb +2 -2
  41. data/lib/otto/security/authentication/auth_failure.rb +44 -0
  42. data/lib/otto/security/authentication/auth_strategy.rb +3 -3
  43. data/lib/otto/security/authentication/route_auth_wrapper.rb +260 -0
  44. data/lib/otto/security/authentication/strategies/{public_strategy.rb → noauth_strategy.rb} +6 -2
  45. data/lib/otto/security/authentication/strategy_result.rb +129 -15
  46. data/lib/otto/security/authentication.rb +5 -6
  47. data/lib/otto/security/config.rb +51 -18
  48. data/lib/otto/security/configurator.rb +2 -15
  49. data/lib/otto/security/middleware/ip_privacy_middleware.rb +211 -0
  50. data/lib/otto/security/middleware/rate_limit_middleware.rb +19 -3
  51. data/lib/otto/security.rb +9 -0
  52. data/lib/otto/version.rb +1 -1
  53. data/lib/otto.rb +183 -89
  54. data/otto.gemspec +5 -0
  55. metadata +83 -8
  56. data/changelog.d/20250911_235619_delano_next.rst +0 -28
  57. data/changelog.d/20250912_123055_delano_remove_ostruct.rst +0 -21
  58. data/changelog.d/20250912_175625_claude_delano_remove_ostruct.rst +0 -21
  59. data/lib/otto/security/authentication/authentication_middleware.rb +0 -123
  60. data/lib/otto/security/authentication/failure_result.rb +0 -36
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a3de0a572bb6389f8e3f6b64d3295630c1d2f9872734d5840c5c2e5dc89f1fd4
4
- data.tar.gz: 41caaa99c08d5646d576b5c15d4392757e541ae00218dd7a3831d4532ee7a30c
3
+ metadata.gz: abc8be5b60ac2a33d84dd0b89aec0e30797d36a995fdc26db7d9d2e65b28553f
4
+ data.tar.gz: 003a6c148c47011bbdc185c0035d9788f319b34eaa4bd2067cf06199749abf46
5
5
  SHA512:
6
- metadata.gz: bbef30e2f11091b5b74c7c20aeead0b118b22bd5a52b77cc23c8901f8dcc58f9465748b1d3c46ae1c2cf0a75b7736d07248d9150a6b9fe28ddc02ef23543ca83
7
- data.tar.gz: 765a1cc021e278ca5ff484dd55e49695176c8aac998a3374677026857c27643c237088347fd3b04bbae69f4d6eae2ffec089bffbb7019f339c43c85f6e035668
6
+ metadata.gz: 0b27bf0132a8648a0b7ba14c33e1c1553196447a34a826463572c2fb005c644cdcbadd9987b1b71787c41cc70332771034ac52bda39e76aaa2947c0b73138470
7
+ data.tar.gz: c45a50e6420a3a6a072abdbb03177228132359cc52193fdcbac230ea0b6f6aac8c86613190d4cb6be192125db6999510467a3a4a5abe0f1fee46e07e202448aa
@@ -28,8 +28,6 @@ jobs:
28
28
  fail-fast: false
29
29
  matrix:
30
30
  include:
31
- - ruby: "3.2"
32
- experimental: false
33
31
  - ruby: "3.3"
34
32
  experimental: false
35
33
  - ruby: "3.4"
@@ -41,9 +39,10 @@ jobs:
41
39
  - uses: actions/checkout@v5
42
40
  - name: Set up Ruby
43
41
  uses: ruby/setup-ruby@v1
42
+ continue-on-error: ${{ matrix.experimental }}
44
43
  with:
45
44
  ruby-version: ${{ matrix.ruby }}
46
- bundler-cache: true
45
+ bundler-cache: ${{ !matrix.experimental }}
47
46
 
48
47
  - name: Setup tmate session
49
48
  uses: mxschmitt/action-tmate@7b6a61a73bbb9793cb80ad69b8dd8ac19261834c # v3
@@ -2,13 +2,8 @@ name: Claude Code Review
2
2
 
3
3
  on:
4
4
  pull_request:
5
- types: [opened, synchronize]
6
- # Optional: Only run on specific file changes
7
- # paths:
8
- # - "src/**/*.ts"
9
- # - "src/**/*.tsx"
10
- # - "src/**/*.js"
11
- # - "src/**/*.jsx"
5
+ types: [opened, synchronize, labeled]
6
+ workflow_dispatch:
12
7
 
13
8
  jobs:
14
9
  claude-review:
@@ -19,6 +14,11 @@ jobs:
19
14
  # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
20
15
 
21
16
  runs-on: ubuntu-latest
17
+ if: |
18
+ (github.event.action == 'opened') ||
19
+ (github.event.action == 'labeled' && github.event.label.name == 'claude-review') ||
20
+ (github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'claude-review'))
21
+
22
22
  permissions:
23
23
  contents: read
24
24
  pull-requests: read
@@ -27,16 +27,18 @@ jobs:
27
27
 
28
28
  steps:
29
29
  - name: Checkout repository
30
- uses: actions/checkout@v4
30
+ uses: actions/checkout@v5
31
31
  with:
32
32
  fetch-depth: 1
33
33
 
34
34
  - name: Run Claude Code Review
35
35
  id: claude-review
36
- uses: anthropics/claude-code-action@v1
36
+ uses: anthropics/claude-code-action@beta
37
37
  with:
38
38
  claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
39
- prompt: |
39
+
40
+ # Direct prompt for automated review (no @claude mention needed)
41
+ direct_prompt: |
40
42
  Please review this pull request and provide feedback on:
41
43
  - Code quality and best practices
42
44
  - Potential bugs or issues
@@ -46,8 +48,22 @@ jobs:
46
48
 
47
49
  Use the repository's CLAUDE.md for guidance on style and conventions. Be constructive and helpful in your feedback.
48
50
 
49
- Use `gh pr comment` with your Bash tool to leave your review as a comment on the PR.
51
+ # Use sticky comments to reuse the same comment on subsequent pushes to the same PR
52
+ use_sticky_comment: true
50
53
 
51
- # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
52
- # or https://docs.anthropic.com/en/docs/claude-code/sdk#command-line for available options
53
- claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"'
54
+ - name: Remove claude-review label
55
+ # Remove label whether success or failure - prevents getting stuck
56
+ if: always() && github.event.action != 'opened'
57
+ uses: actions/github-script@v7
58
+ with:
59
+ script: |
60
+ try {
61
+ await github.rest.issues.removeLabel({
62
+ owner: context.repo.owner,
63
+ repo: context.repo.repo,
64
+ issue_number: context.issue.number,
65
+ name: 'claude-review'
66
+ });
67
+ } catch (error) {
68
+ console.log('Label not found or already removed');
69
+ }
@@ -26,7 +26,7 @@ jobs:
26
26
  actions: read # Required for Claude to read CI results on PRs
27
27
  steps:
28
28
  - name: Checkout repository
29
- uses: actions/checkout@v4
29
+ uses: actions/checkout@v5
30
30
  with:
31
31
  fetch-depth: 1
32
32
 
data/.rubocop.yml CHANGED
@@ -48,7 +48,10 @@ Gemspec/DevelopmentDependencies:
48
48
  Enabled: true
49
49
 
50
50
  Layout/HashAlignment:
51
- Enabled: false
51
+ Enabled: true
52
+ EnforcedHashRocketStyle: key
53
+ EnforcedColonStyle: separator
54
+ EnforcedLastArgumentHashStyle: always_ignore # Changed from ignore_implicit
52
55
 
53
56
  Lint/Void:
54
57
  Enabled: false
data/CHANGELOG.rst CHANGED
@@ -1,17 +1,65 @@
1
1
  CHANGELOG.rst
2
2
  =============
3
3
 
4
- All notable changes to Otto are documented here.
5
-
6
- The format is based on `Keep a
7
- Changelog <https://keepachangelog.com/en/1.1.0/>`__, and this project
8
- adheres to `Semantic
9
- Versioning <https://semver.org/spec/v2.0.0.html>`__.
4
+ The format is based on `Keep a Changelog <https://keepachangelog.com/en/1.1.0/>`__, and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`__.
10
5
 
11
6
  .. raw:: html
12
7
 
13
8
  <!--scriv-insert-here-->
14
9
 
10
+ .. _changelog-2.0.0.pre2:
11
+
12
+ 2.0.0.pre2 — 2025-10-11
13
+ =======================
14
+
15
+ Added
16
+ -----
17
+
18
+ - Added `StrategyResult` class with improved user model compatibility and cleaner API
19
+ - Helper methods ``authenticated?``, ``has_role?``, ``has_permission?``, ``user_name``, ``session_id`` for cleaner Logic class implementation
20
+ - Added JSON request body parsing support in Logic class handlers
21
+ - Added new modular directory structure under ``lib/otto/security/``
22
+ - Added backward compatibility aliases to maintain existing API compatibility
23
+ - Added proper namespacing for authentication components and middleware classes
24
+
25
+ Changed
26
+ -------
27
+
28
+ - **BREAKING**: Logic class constructor signature changed from ``initialize(session, user, params, locale)`` to ``initialize(context, params, locale)``
29
+ - Logic classes now receive an immutable context object instead of separate session/user parameters
30
+ - LogicClassHandler simplified to single arity pattern, removing backward compatibility code
31
+ - Authentication middleware now creates `StrategyResult` instances for all requests
32
+ - Replaced `RequestContext` with `StrategyResult` class for better authentication handling
33
+ - Simplified authentication strategy API to return `StrategyResult` or `nil` for success/failure
34
+ - Enhanced route handlers to support JSON request body parsing
35
+ - Updated authentication middleware to use `StrategyResult` throughout
36
+ - Reorganized Otto security module structure for better maintainability and separation of concerns
37
+ - Moved authentication strategies to ``Otto::Security::Authentication::Strategies`` namespace
38
+ - Moved security middleware to ``Otto::Security::Middleware`` namespace
39
+ - Moved ``StrategyResult`` and ``FailureResult`` to ``Otto::Security::Authentication`` namespace
40
+
41
+ Removed
42
+ -------
43
+
44
+ - Removed `RequestContext` class (which was introduced and then replaced by `StrategyResult` during this development cycle)
45
+ - Removed `AuthResult` class from authentication system
46
+ - Removed `ConcurrentCacheStore` example class for an ActiveSupport::Cache::MemoryStore-compatible interface with Rack::Attack
47
+ - Removed OpenStruct dependency across the framework
48
+
49
+ Documentation
50
+ -------------
51
+
52
+ - Updated migration guide with comprehensive examples for the new context object and step-by-step conversion instructions
53
+ - Updated Logic class examples in advanced_routes and authentication_strategies to demonstrate new pattern
54
+ - Enhanced documentation with API reference and helper method examples for the new context object
55
+
56
+ AI Assistance
57
+ -------------
58
+
59
+ - AI-assisted architectural design for RequestContext Data class and security module reorganization
60
+ - Comprehensive migration of Logic classes and documentation with AI guidance for consistency
61
+ - Automated test validation and intelligent file organization following Ruby conventions
62
+
15
63
  .. _changelog-2.0.0-pre1:
16
64
 
17
65
  2.0.0-pre1 — 2025-09-10