Modernize the example app: Ruby 3.4, Rails 8.1 and castle-rb 8#17
Merged
Conversation
Bring the demo up to date with the current Castle Ruby SDK and a supported Rails/Ruby stack. - Migrate the Castle integration from the legacy track/authenticate API to the risk/filter/log endpoints. Logins are scored with the policy verdict (allow/challenge/deny) using request tokens minted by the @castleio/castle-js browser SDK; logout and profile updates use the non-blocking log endpoint. - Verify incoming webhooks with Castle::Webhooks::Verify instead of a hand-rolled HMAC check. - Upgrade to Ruby 3.4 and Rails 7.1; bump Devise, OmniAuth (POST request phase) and Bootstrap 5, and refresh the layout and views. - Read configuration from environment variables via dotenv instead of secrets.yml. - Add a hardened multi-stage Dockerfile, entrypoint and .dockerignore. - Update the RSpec suite for the new API and modernize CI to Ruby 3.4.
- Regenerate Gemfile.lock with Bundler 2.7.2 so BUNDLED WITH matches the toolchain and drop the Bundler 4 CHECKSUMS section; pin the version in the Dockerfile and CI. - Flesh out the previously-pending specs (User.find_or_create_for_oauth, ApplicationRecord, ApplicationResponder, ApplicationController auth and the registrations/passwords controllers). - Add coverage for every Castle failure path (risk/filter/log raising) and for webhook requests with a missing or mismatched signature. - Raise the enforced SimpleCov floor to 95%; the app now reports 100% line coverage.
Add a GitHub Actions workflow that sets up the database and runs the RSpec suite on every pull request (and on pushes to master), and drop the CircleCI config that wasn't reporting checks on PRs.
Bump the app to the current Rails (8.1.3) and Devise (5.0.4), load_defaults 8.1, and sqlite3 2.x (required by the Rails 8 SQLite adapter). The sprockets asset pipeline is kept explicitly via sprockets-rails. Full spec suite stays green at 100% line coverage.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
This example app had drifted well behind the current Castle Ruby SDK and Rails
ecosystem (castle-rb 5, the legacy
track/authenticateAPI, the old browsersnippet, Rails 6.1 on Ruby 2.7). This PR brings it back to a current, runnable
state on Ruby 3.4 / Rails 8.1 and demonstrates the SDK the way it's meant to
be used today.
Castle integration
track/authenticatecalls with the risk / filter / logendpoints:
risk, with the session decision driven by the policyverdict (
allow/challenge/deny);filter;logendpoint.@castleio/castle-jsSDK andforward it from the login form to the backend (
castle_request_token).Castle::Webhooks::Verifyinstead of thehand-rolled HMAC check (the bespoke verifier and its spec are removed).
Stack & tooling
move to Bootstrap 5 with a refreshed layout and views.
.env.example)instead of
secrets.yml..dockerignore; theimage runs as a non-root user and serves with Puma.
Gemfile.lock, Dockerfile and CI), whichalso drops the Bundler 4
CHECKSUMSsection.Tests
previously-pending specs (User OAuth lookup, ApplicationRecord/Responder,
the authenticated ApplicationController, and the registrations/passwords
controllers).
risk/filter/lograising) andfor webhook requests with a missing or mismatched signature.
raised to 95%.
Known limitations
the OAuth
riskcall runs without one; anyCastle::Errorthere (and on thefire-and-forget
logcalls) is rescued and treated asallowso Castle cannever lock a user out of the demo.
Usermodel doesn't enable Devise's:recoverablemodule, so there are nopassword-reset routes;
Users::PasswordsControlleris therefore covered at theunit level only. Left as-is to avoid changing behaviour — happy to wire up
password reset in a follow-up if wanted.
as-is), which keeps the Docker image free of a JS runtime.