Files
sure/app/controllers/retirement_controller.rb
Guillem Arias 65d8129cf2 fix(retirement): review fixes — IDOR, adjustment cap, bucket access
Addresses PR #2046 review (superagent P1, Codex P2, jjmata):

- IDOR (P1): a statement could reference another plan's pension_source
  via a crafted pension_source_id, leaking the source name + points
  history. Goal::RetirementStatement now validates the source belongs
  to the same plan.
- Adjustment cap was bypassable: the limit lived only on Goal::Retirement
  (parent validations don't run on child saves), so the CRUD path allowed
  an 11th. Goal::RetirementAdjustment now enforces it on create.
- Bucket account selection (and the show-page candidate list) now filter
  through accounts.accessible_by(Current.user), so a private account
  shared away from the user can't be added via a crafted POST.
- Comment clarifying the deliberate update_column in soft_replace!.

Tests for the IDOR guard + the child-level cap.
2026-05-30 09:39:31 +02:00

16 lines
563 B
Ruby

class RetirementController < ApplicationController
include RetirementScoped
def show
@pension_sources = @plan.pension_sources.order(:start_age)
@adjustments = @plan.adjustments.ordered
@statements = @plan.statements.chronological.reverse
@bucket_account_ids = @plan.retirement_bucket_entries.pluck(:account_id).to_set
@bucket_candidates = Current.family.accounts.visible.accessible_by(Current.user).alphabetically
@breadcrumbs = [
[ t("breadcrumbs.home"), root_path ],
[ t("breadcrumbs.retirement"), nil ]
]
end
end