Harden input validation and add security documentation #243
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Type
Feature
Lineage
Discovered during PR #241 QA review (property picker for day detail page). Nits surfaced patterns that are consistent across the codebase, not regressions.
Repo
ldraney/landscaping-assistantUser Story
As an admin
I want controllers to gracefully reject invalid input and the team to have a shared understanding of the app's security posture
So that the app handles edge cases cleanly and we can reason about security as we grow
Context
PR #241 QA review surfaced 5 nits, several security-adjacent:
Defensive
property_idlookup -- Controllers passparams[:property_id]directly toWorkQueueItem.new(property_id:). Non-existent IDs raiseActiveRecord::InvalidForeignKey(500 error). This pattern exists inDaysController#add_to_queue,WorkQueueItemsController#create,WorkQueueItemsController#mark_other, andWeeksController#toggle_assign. All are role-gated to admin, so low risk, but a 500 is never the right response for bad user input.Unauthenticated request specs --
before_action :authenticate_user!inApplicationControllerhandles auth globally, but no spec verifies this. Every protected endpoint should have at least one spec confirming unauthenticated users get redirected to login.No security documentation -- The app has auth docs (
auth-strategy.md,keycloak-setup.md) but no unified security posture document. We needdocs/security.mdthat maps: authentication model, authorization model (role hierarchy +require_roleenforcement), attack surface, input validation patterns, CSRF, network security (Tailscale), and secrets management. Include mermaid diagrams for the auth flow and attack surface.Dependency: This ticket depends on PR #241 being merged first. The
DaysController#add_to_queueaction is added by PR #241. TheDaysControllerbase (show action, route, view) was merged in PR #240 and exists on main.File Targets
Files the agent should modify:
app/controllers/days_controller.rb-- add property lookup guard inadd_to_queue(added by PR #241, must be merged first)app/controllers/work_queue_items_controller.rb-- add property lookup guard increateandmark_otherapp/controllers/weeks_controller.rb-- add property lookup guard intoggle_assign(guards<= 0but not non-existent positive IDs)app/controllers/application_controller.rb-- optional sharedfind_property_or_rejecthelperspec/requests/days_spec.rb-- add unauthenticated request spec and invalid property_id specspec/requests/work_queue_items_spec.rb-- add unauthenticated request spec and invalid property_id specspec/requests/weeks_spec.rb-- add unauthenticated request spec and invalid property_id specspec/requests/properties_spec.rb-- add unauthenticated request specspec/requests/crew_spec.rb-- add unauthenticated request specspec/requests/uploads_spec.rb-- add unauthenticated request specspec/requests/profile_spec.rb-- add unauthenticated request specspec/requests/join_crew_spec.rb-- add unauthenticated request specFiles the agent should create:
docs/security.md-- security posture document with mermaid diagramsFiles the agent should NOT touch:
app/javascript/controllers/property_picker_controller.js-- client-side, not relevantapp/controllers/properties_controller.rb-- usesProperty.find(params[:id])which already returns 404 via Rails rescue, this is correct behaviorapp/controllers/sessions_controller.rb-- intentionally skips auth (skip_before_action :authenticate_user!)app/controllers/client_errors_controller.rb-- intentionally skips authFeature Flag
none
Acceptance Criteria
DaysController#add_to_queuereturns 422 with flash whenproperty_iddoes not exist (depends on PR #241)WorkQueueItemsController#createreturns 422 with flash whenproperty_iddoes not exist (and noclient_name)WorkQueueItemsController#mark_otherreturns 422 with flash whenproperty_iddoes not existWeeksController#toggle_assignreturns 422 or appropriate error whenproperty_iddoes not existdocs/security.mdexists with: auth model, authorization model, attack surface mermaid diagram, input validation section, network security sectionTest Expectations
/days/:date/addwith non-existentproperty_idreturns 422 (depends on PR #241)/todaywith non-existentproperty_idreturns 422/today/mark_otherwith non-existentproperty_idreturns 422/weeks/toggle_assignwith non-existentproperty_idreturns 422/days/:datewithout auth redirects to login/todaywithout auth redirects to login/propertieswithout auth redirects to login/crewwithout auth redirects to login/weekswithout auth redirects to login/uploadswithout auth redirects to login/profilewithout auth redirects to login/join-crewwithout auth redirects to logindocker compose run --rm -e RAILS_ENV=test web bundle exec rspec spec/requests/Constraints
respond_topattern with turbo_stream flash + HTML redirect for error responsesProperty.find(params[:id])already get correct 404 behaviorWeeksController#toggle_assignalready guardsproperty_id <= 0-- extend to also guard non-existent positive IDsChecklist
Related
project-landscaping-assistant-- project this affectsScope Review: NEEDS_REFINEMENT
Review note:
review-1476-2026-06-16Issue references a non-existent
DaysControllerand/days/routes -- all "today" functionality lives inWorkQueueItemsControllerat/today. Multiple AC and test expectations target phantom routes.[BODY] fixes required:
DaysController,days_controller.rb,spec/requests/days_spec.rb-- none existDaysController#add_to_queuereturns 422) -- controller/action does not existPOST /days/:date/addandGET /days/:date-- routes do not existWeeksController#toggle_assignto scope -- sameparams[:property_id]vulnerability (current guard only rejects <=0, not non-existent IDs)[SCOPE] items:
arch-rails-app(used by many board items)Scope refinement after review-1476-2026-06-16
Changes to issue body based on scope review findings:
Added
WeeksController#toggle_assignto file targets, acceptance criteria, and test expectations. Reviewer correctly identified this as a blast radius miss -- sameproperty_idvulnerability (guards<= 0but not non-existent positive IDs).Added all protected controllers to unauthenticated spec targets. Original scope only listed days and work_queue_items. Now includes: days, work_queue_items, weeks, properties, crew, uploads.
Added PR #241 dependency note. The
DaysController#add_to_queueaction is added by PR #241 (not yet merged). Clarified thatDaysControllerbase exists on main (merged in PR #240).Clarified reviewer false positive. The reviewer flagged
DaysControlleranddays_spec.rbas phantom files. These DO exist on main --DaysControllerwas merged in PR #240 (commit40044da). Theadd_to_queueaction is from PR #241 which must merge first.Added
sessions_controller.rbandclient_errors_controller.rbto "should NOT touch" list since they intentionally skip auth.Scope Review: APPROVED
Review note:
review-1476-2026-06-16Re-review after NEEDS_REFINEMENT. All previous findings addressed in the updated issue body. Template complete, file targets verified against codebase, PR #241 dependency correctly documented.
Non-blocking notes for implementing agent:
add_to_queuedepends on PR #241 (still open) -- implement remaining 6 AC first if #241 is not mergedjoin_crew_controller.rbandprofile_controller.rbare protected but not listed as unauthenticated spec targets (optional scope expansion)story:securityuser story entry andarch-rails-apparchitecture note are pre-existing gaps, not specific to this ticket