Make iCalendar feed routes return calendar data

Both iCalendar routes were unusable:

* `/conferences/.../schedule.ics` raised
  `NoMethodError: undefined method 'icalendar_proposals'` because the
  `ConferenceHelper#icalendar_proposals` helper isn't auto-included in
  controllers; the action crashed before rendering.

* `/calendar.ics` silently redirected to `/`. The controller goes
  through `load_and_authorize_resource`, which authorises `:calendar`
  on `Conference` and is rejected for anonymous visitors because no
  ability grants it — CanCan's `AccessDenied` rescue redirects to
  root.

The helper is invoked through the controller `helpers` proxy so it
works in both contexts, and the calendar action is opted out of
resource loading and explicitly marked as not requiring authorization
since it serves a public feed across conferences. The helper is also
hardened so that proposals missing a room, difficulty level, track,
event type or scheduled time produce a valid event instead of
crashing the whole feed.
This commit is contained in:
Asish Kumar 2026-05-14 11:02:49 +05:30
parent c8e6fabed1
commit c5e84221c2
5 changed files with 83 additions and 30 deletions

View file

@ -3,7 +3,8 @@
class ConferencesController < ApplicationController
protect_from_forgery with: :null_session
before_action :respond_to_options
load_and_authorize_resource find_by: :short_title, except: :show
load_and_authorize_resource find_by: :short_title, except: %i[show calendar]
skip_authorization_check only: :calendar
def index
@current = Conference.upcoming.reorder(start_date: :asc)
@ -76,7 +77,7 @@ class ConferencesController < ApplicationController
event_schedules = conf.program.selected_event_schedules(
includes: [{ event: %i[event_type speakers submitter] }]
)
calendar = icalendar_proposals(calendar, event_schedules.map(&:event), conf)
calendar = helpers.icalendar_proposals(calendar, event_schedules.map(&:event), conf)
else
calendar.event do |e|
e.dtstart = conf.start_date