<commit_before>require 'securerandom'

class Devise::MasqueradesController < DeviseController
  Devise.mappings.each do |name, _|
    class_eval <<-METHODS, __FILE__, __LINE__ + 1
      skip_before_action :masquerade_#{name}!, raise: false
    METHODS
  end
  skip_before_action :masquerade!, raise: false

  prepend_before_action :authenticate_scope!, only: :show
  prepend_before_action :masquerade_authorize!

  def show
    if send("#{masqueraded_resource_name}_masquerade?")
      resource = masquerading_current_user

      go_back(resource, path: after_masquerade_full_path_for(resource))
    else
      masqueradable_resource = find_masqueradable_resource

      save_masquerade_owner_session(masqueradable_resource)

      resource = masqueradable_resource
      sign_out(masquerading_current_user)

      unless resource
        flash[:error] = "#{masqueraded_resource_class} not found."
        redirect_to(send("new_#{masqueraded_resource_name}_session_path")) and return
      end

      request.env['devise.skip_trackable'] = '1'

      masquerade_sign_in(resource)

      go_back(resource, path: after_masquerade_full_path_for(resource))
    end
  end

  def back
    unless send("#{masqueraded_resource_name}_masquerade?")
      resource = send("current_#{masqueraded_resource_name}")
      go_back(resource, path: after_back_masquerade_path_for(resource))
    else
      masqueradable_resource = send("current_#{masqueraded_resource_name}")

      unless send("#{masqueraded_resource_name}_signed_in?")
        head(401) and return
      end

      resource = find_owner_resource(masqueradable_resource)
      sign_out(send("current_#{masqueraded_resource_name}"))

      sign_in(resource)
      request.env['devise.skip_trackable'] = nil

      go_back(resource, path: after_back_masquerade_path_for(resource))

      cleanup_masquerade_owner_session(masqueradable_resource)
    end
  end

  protected

  def masquerade_authorize!
    head(403) unless masquerade_authorized?
  end

  def masquerade_authorized?
    true
  end

  def find_masqueradable_resource
    GlobalID::Locator.locate_signed(params[Devise.masquerade_param], for: 'masquerade')
  end

  def find_owner_resource(masqueradable_resource)
    skey = session_key(masqueradable_resource, masquerading_guid)

    if Devise.masquerade_storage_method_session?
      resource_id = session[skey]

      masqueraded_resource_class.find(resource_id)
    else
      data = Rails.cache.read(skey)

      GlobalID::Locator.locate_signed(data, for: 'masquerade')
    end
  end

  def go_back(user, path:)
    if Devise.masquerade_routes_back
      redirect_back(fallback_location: path)
    else
      redirect_to path
    end
  end

  private

  def masqueraded_resource_name
    Devise.masqueraded_resource_name || masqueraded_resource_class.model_name.param_key
  end

  def masquerading_resource_class
    @masquerading_resource_class ||= begin
      unless params[:masquerading_resource_class].blank?
        params[:masquerading_resource_class].constantize<commit_msg>Fix broken back_masquerade_path<commit_after>require 'securerandom'

class Devise::MasqueradesController < DeviseController
  Devise.mappings.each do |name, _|
    class_eval <<-METHODS, __FILE__, __LINE__ + 1
      skip_before_action :masquerade_#{name}!, raise: false
    METHODS
  end
  skip_before_action :masquerade!, raise: false

  prepend_before_action :authenticate_scope!, only: :show
  prepend_before_action :masquerade_authorize!

  def show
    if send("#{masqueraded_resource_name}_masquerade?")
      resource = masquerading_current_user

      go_back(resource, path: after_masquerade_full_path_for(resource))
    else
      masqueradable_resource = find_masqueradable_resource

      save_masquerade_owner_session(masqueradable_resource)

      resource = masqueradable_resource
      sign_out(masquerading_current_user)

      unless resource
        flash[:error] = "#{masqueraded_resource_class} not found."
        redirect_to(send("new_#{masqueraded_resource_name}_session_path")) and return
      end

      request.env['devise.skip_trackable'] = '1'

      masquerade_sign_in(resource)

      go_back(resource, path: after_masquerade_full_path_for(resource))
    end
  end

  def back
    unless send("#{masqueraded_resource_name}_masquerade?")
      resource = send("current_#{masqueraded_resource_name}")
      go_back(resource, path: after_back_masquerade_path_for(resource))
    else
      masqueradable_resource = send("current_#{masqueraded_resource_name}")

      unless send("#{masqueraded_resource_name}_signed_in?")
        head(401) and return
      end

      resource = find_owner_resource(masqueradable_resource)
      sign_out(send("current_#{masqueraded_resource_name}"))

      sign_in(resource)
      request.env['devise.skip_trackable'] = nil

      go_back(resource, path: after_back_masquerade_path_for(resource))

      cleanup_masquerade_owner_session(masqueradable_resource)
    end
  end

  protected

  def masquerade_authorize!
    head(403) unless masquerade_authorized?
  end

  def masquerade_authorized?
    true
  end

  def find_masqueradable_resource
    GlobalID::Locator.locate_signed(params[Devise.masquerade_param], for: 'masquerade')
  end

  def find_owner_resource(masqueradable_resource)
    skey = session_key(masqueradable_resource, masquerading_guid)

    if Devise.masquerade_storage_method_session?
      resource_id = session[skey]

      masquerading_resource_class.find(resource_id)
    else
      data = Rails.cache.read(skey)

      GlobalID::Locator.locate_signed(data, for: 'masquerade')
    end
  end

  def go_back(user, path:)
    if Devise.masquerade_routes_back
      redirect_back(fallback_location: path)
    else
      redirect_to path
    end
  end

  private

  def masqueraded_resource_name
    Devise.masqueraded_resource_name || masqueraded_resource_class.model_name.param_key
  end

  def masquerading_resource_class
    @masquerading_resource_class ||= begin
      unless params[:masquerading_resource_class].blank?
        params[:masquerading_resource_class].constantize
{'fraction_non_alphanumeric': 0.07658321060382917, 'fraction_numerical': 0.0026182294223531335, 'mean_word_length': 4.462019660411081, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5037105', 'n_tokens_mistral': 2013, 'n_tokens_neox': 1944, 'n_words': 307}