class OAuth < ApplicationRecord include ApplicationHelper include Rails.application.routes.url_helpers include TenantOwnable extend FriendlyId has_many :tenant_default_o_auths, dependent: :destroy attr_accessor :state validates :name, presence: true, uniqueness: { scope: :tenant_id } validates :is_enabled, inclusion: { in: [true, false] } validates :client_id, presence: true validates :client_secret, presence: true validates :authorize_url, presence: true validates :token_url, presence: true validates :profile_url, presence: true validates :scope, presence: true validates :json_user_email_path, presence: true friendly_id :generate_random_slug, use: :slugged def is_default? tenant_id == nil end def callback_url # Default OAuths are available to all tenants # but must have a single callback url: # for this reason, we don't preprend tenant subdomain # but rather use the "login" subdomain if self.is_default? get_url_for(method(:o_auth_callback_url), resource: self, disallow_custom_domain: true, options: { subdomain: "login", host: Rails.application.base_url }) else get_url_for(method(:o_auth_callback_url), resource: self, disallow_custom_domain: true) end end def authorize_url_with_query_params "#{authorize_url}?"\ "response_type=code&"\ "client_id=#{client_id}&"\ "redirect_uri=#{callback_url()}&"\ "scope=#{scope}&"\ "state=#{state}" end def default_o_auth_is_enabled is_default? and tenant_default_o_auths.exists? end def generate_random_slug loop do self.slug = SecureRandom.hex(8) break unless self.class.exists?(slug: slug) end slug end class << self # returns all tenant-specific o_auths plus all default o_auths that are enabled site-wide def include_all_defaults unscoped.where(tenant_id: nil, is_enabled: true).or(where(tenant_id: Current.tenant)) end # returns all tenant-specific o_auths plus all default o_auths that are enabled both site-wide and for the current tenant def include_defaults unscoped.left_outer_joins(:tenant_default_o_auths).where(tenant_default_o_auths: { tenant_id: Current.tenant }, is_enabled: true).or(where(tenant_id: Current.tenant)) end # returns all default o_auths that are enabled site-wide def include_only_defaults unscoped.where(tenant_id: nil, is_enabled: true) end end end