require 'browser' module PandaPal::Helpers::ControllerHelper def save_session current_session.try(:save) end def current_session @current_session ||= PandaPal::Session.find_by(session_key: session_key) if session_key @current_session ||= PandaPal::Session.new(panda_pal_organization_id: current_organization.id) end def current_organization @organization ||= PandaPal::Organization.find_by!(key: organization_key) if organization_key @organization ||= PandaPal::Organization.find_by(id: organization_id) if organization_id @organization ||= PandaPal::Organization.find_by_name(Apartment::Tenant.current) end def current_session_data current_session.data end def session_changed? current_session.changed? && current_session.changes[:data].present? end def validate_launch! authorized = false if @organization = params['oauth_consumer_key'] && PandaPal::Organization.find_by_key(params['oauth_consumer_key']) authenticator = IMS::LTI::Services::MessageAuthenticator.new(request.original_url, request.request_parameters, @organization.secret) authorized = authenticator.valid_signature? end render plain: 'Invalid Credentials, please contact your Administrator.', :status => :unauthorized unless authorized authorized end def switch_tenant(organization = current_organization, &block) return unless organization raise 'This method should be called in an around_action callback' unless block_given? Apartment::Tenant.switch(organization.name) do yield end end # Browsers that prevent 3rd party cookies by default (Safari and IE) run into problems # with CSRF handling because the Rails session cookie isn't set. To fix this, we # redirect the current page to the LTI using JavaScript, which will set the cookie, # and then immediately redirect back to Canvas. def fix_iframe_cookies if params[:safari_cookie_fix].present? session[:safari_cookie_fixed] = true redirect_to params[:return_to] else render 'panda_pal/lti/iframe_cookie_fix', layout: false end end def cookies_need_iframe_fix? (browser.safari? || browser.ie?) && !request.referrer.include?('sessionless_launch') && !session[:safari_cookie_fixed] end def forbid_access_if_lacking_session if cookies_need_iframe_fix? fix_iframe_cookies else render plain: 'You should do an LTI Tool Launch.', status: :unauthorized unless valid_session? end end def valid_session? [ current_session.persisted?, current_organization, current_session.panda_pal_organization_id == current_organization.id, Apartment::Tenant.current == current_organization.name ].all? end private def organization_key params[:oauth_consumer_key] || session[:organization_key] end def organization_id params[:organization_id] end def session_key params[:session_key] || session_key_header || flash[:session_key] || session[:session_key] end def session_key_header if match = request.headers['Authorization'].try(:match, /token=(.+)/) match[1] end end end