<commit_before>class ApplicationInstance < ApplicationRecord

  serialize :config, HashSerializer
  serialize :lti_config, HashSerializer

  belongs_to :application, counter_cache: true
  belongs_to :site
  belongs_to :bundle_instance

  has_many :authentications, dependent: :destroy, inverse_of: :application_instance
  has_many :lti_deployments, dependent: :destroy

  validates :lti_key, presence: true, uniqueness: true
  validates :lti_secret, presence: true
  validates :site_id, presence: true
  validates :application_id, presence: true

  before_validation :set_lti
  before_validation :set_domain

  before_validation on: [:update] do
    errors.add(:lti_key, "cannot be changed after creation") if lti_key_changed?
  end

  # example store_accessor for config
  # This allows access to instance.config[:foo] like instance.foo
  # Or instance.bar
  # If foo is not set in the config json, it will return nil
  # store_accessor :config, :foo, :bar

  attr_encrypted :canvas_token, key: Rails.application.secrets.encryption_key, mode: :per_attribute_iv_and_salt

  after_commit :create_schema, on: :create
  before_create :create_config

  scope :for_tenant, ->(tenant) { where(tenant: tenant) }
  scope :by_newest, -> { order(created_at: :desc) }
  scope :by_oldest, -> { order(created_at: :asc) }
  scope :by_latest, -> { order(updated_at: :desc) }

  # Create a new application instance if the deployment id isn't found
  # TODO add a setting on the application to indicate if it's freely available, trial, or restricted
  def self.by_client_and_deployment(client_id, deployment_id, iss, canvas_url)
    LtiInstall.joins(:applications).joins(:application_instances).joins(:lti_deployments)
    if lti_install = LtiInstall.find_by(client_id: client_id, iss: iss)
      application_instances = lti_install.application.application_instances.
        joins(:lti_deployments).
        where("lti_deployments.deployment_id =?", deployment_id)

      # There should only be one that matches
      application_instance = application_instances.first

      if application_instance.blank?
        # Create a new application instance for the deployment id
        site = Site.find_by(url: canvas_url)
        # Create a new application instance and lti_deployment
        lti_key = "#{site.key}-#{lti_install.application.key}-#{deployment_id}"
        application_instance = lti_install.application.create_instance(site: site, lti_key: lti_key)
        application_instance.lti_deployments.create!(deployment_id: deployment_id)
      end

      application_instance
    end
  end

  def lti_defaults
    domain = self.domain || Rails.application.secrets.application_main_domain
    config = lti_config.dup
    if config.present?
      config[:launch_url] ||= "https://#{domain}/lti_launches"
      config[:secure_launch_url] ||= "https://#{domain}/lti_launches"
      config[:domain] ||= domain
      config[:export_url] ||= "https://#{domain}/api/ims_exports.json"
      config[:import_url] ||= "https://#{domain}/api/ims_imports.json"
      config[:icon] ||= "https://#{domain}/#{config[:icon]}"
      config[:privacy_level] = "anonymous" if anonymous?
    end
    config
  end

  def lti_config_xml
    config = lti_defaults
    Lti::Config.xml(config) if config
  end

  def oauth_precedence
    application.oauth_precedence.split(",")
  end

  def key(application_key_override = nil)
    return lti_key if lti_key.present?
    return "" if site.blank? || application.blank?

    "#{site.key}-#{application_key_override || application.key}"
  end
<commit_msg>Fix check for empty config<commit_after>class ApplicationInstance < ApplicationRecord

  serialize :config, HashSerializer
  serialize :lti_config, HashSerializer

  belongs_to :application, counter_cache: true
  belongs_to :site
  belongs_to :bundle_instance

  has_many :authentications, dependent: :destroy, inverse_of: :application_instance
  has_many :lti_deployments, dependent: :destroy

  validates :lti_key, presence: true, uniqueness: true
  validates :lti_secret, presence: true
  validates :site_id, presence: true
  validates :application_id, presence: true

  before_validation :set_lti
  before_validation :set_domain

  before_validation on: [:update] do
    errors.add(:lti_key, "cannot be changed after creation") if lti_key_changed?
  end

  # example store_accessor for config
  # This allows access to instance.config[:foo] like instance.foo
  # Or instance.bar
  # If foo is not set in the config json, it will return nil
  # store_accessor :config, :foo, :bar

  attr_encrypted :canvas_token, key: Rails.application.secrets.encryption_key, mode: :per_attribute_iv_and_salt

  after_commit :create_schema, on: :create
  before_create :create_config

  scope :for_tenant, ->(tenant) { where(tenant: tenant) }
  scope :by_newest, -> { order(created_at: :desc) }
  scope :by_oldest, -> { order(created_at: :asc) }
  scope :by_latest, -> { order(updated_at: :desc) }

  # Create a new application instance if the deployment id isn't found
  # TODO add a setting on the application to indicate if it's freely available, trial, or restricted
  def self.by_client_and_deployment(client_id, deployment_id, iss, canvas_url)
    LtiInstall.joins(:applications).joins(:application_instances).joins(:lti_deployments)
    if lti_install = LtiInstall.find_by(client_id: client_id, iss: iss)
      application_instances = lti_install.application.application_instances.
        joins(:lti_deployments).
        where("lti_deployments.deployment_id =?", deployment_id)

      # There should only be one that matches
      application_instance = application_instances.first

      if application_instance.blank?
        # Create a new application instance for the deployment id
        site = Site.find_by(url: canvas_url)
        # Create a new application instance and lti_deployment
        lti_key = "#{site.key}-#{lti_install.application.key}-#{deployment_id}"
        application_instance = lti_install.application.create_instance(site: site, lti_key: lti_key)
        application_instance.lti_deployments.create!(deployment_id: deployment_id)
      end

      application_instance
    end
  end

  def lti_defaults
    domain = self.domain || Rails.application.secrets.application_main_domain
    config = lti_config.dup
    if config.present?
      config[:launch_url] ||= "https://#{domain}/lti_launches"
      config[:secure_launch_url] ||= "https://#{domain}/lti_launches"
      config[:domain] ||= domain
      config[:export_url] ||= "https://#{domain}/api/ims_exports.json"
      config[:import_url] ||= "https://#{domain}/api/ims_imports.json"
      config[:icon] ||= "https://#{domain}/#{config[:icon]}"
      config[:privacy_level] = "anonymous" if anonymous?
    end
    config
  end

  def lti_config_xml
    config = lti_defaults
    Lti::Config.xml(config) if config.present?
  end

  def oauth_precedence
    application.oauth_precedence.split(",")
  end

  def key(application_key_override = nil)
    return lti_key if lti_key.present?
    return "" if site.blank? || application.blank?

    "#{site.key}-#{application_key_override || application.key}"
  end

{'fraction_non_alphanumeric': 0.10153846153846154, 'fraction_numerical': 0.0, 'mean_word_length': 4.297037037037037, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 10, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, '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': '3378404', 'n_tokens_mistral': 2250, 'n_tokens_neox': 2205, 'n_words': 530}