class Ekylibre::MultiTenancy::Middleware::ContainerAwareRackMiddleware
Provides a rack based tenant switching solution based on request
Attributes
excluded_subdomains[W]
Public Class Methods
excluded_subdomains()
click to toggle source
# File lib/ekylibre/multi_tenancy/middleware/container_aware_rack_middleware.rb, line 15 def excluded_subdomains @excluded_subdomains ||= [] end
new(app)
click to toggle source
# File lib/ekylibre/multi_tenancy/middleware/container_aware_rack_middleware.rb, line 20 def initialize(app) @app = app end
Public Instance Methods
call(env)
click to toggle source
# File lib/ekylibre/multi_tenancy/middleware/container_aware_rack_middleware.rb, line 24 def call(env) request = Rack::Request.new(env) container = env.fetch('container').dup PluginSystem::GlobalContainer.replace_with(container) do env['container'] = container database = extract_tenant(request) begin if database container .get(TenantSwitcher) .switch(database) { @app.call(env) } else @app.call(env) end rescue ::Apartment::TenantNotFound Rails.logger.error "Apartment Tenant not found: #{subdomain(request.host)}" return [404, { 'Content-Type' => 'text/html' }, [File.read(Rails.root.join('public', '404.html'))]] end end end
extract_tenant(request)
click to toggle source
# File lib/ekylibre/multi_tenancy/middleware/container_aware_rack_middleware.rb, line 48 def extract_tenant(request) if (tenant = ENV['tenant']) tenant elsif ::Rails.env.test? 'test' elsif ENV['ELEVATOR'] == 'header' request.env['HTTP_X_TENANT'] else extract_subdomain(request) end end
Private Instance Methods
domain_valid?(host)
click to toggle source
# File lib/ekylibre/multi_tenancy/middleware/container_aware_rack_middleware.rb, line 95 def domain_valid?(host) PublicSuffix.valid?(host, ignore_private: true) end
extract_subdomain(request)
click to toggle source
# File lib/ekylibre/multi_tenancy/middleware/container_aware_rack_middleware.rb, line 62 def extract_subdomain(request) request_subdomain = subdomain(request.host) # If the domain acquired is set to be excluded, set the tenant to whatever is currently # next in line in the schema search path. tenant = if self.class.excluded_subdomains.include?(request_subdomain) nil else request_subdomain end tenant.presence end
host_valid?(host)
click to toggle source
# File lib/ekylibre/multi_tenancy/middleware/container_aware_rack_middleware.rb, line 87 def host_valid?(host) !ip_host?(host) && domain_valid?(host) end
ip_host?(host)
click to toggle source
# File lib/ekylibre/multi_tenancy/middleware/container_aware_rack_middleware.rb, line 91 def ip_host?(host) !/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/.match(host).nil? end
parse_host(host)
click to toggle source
# File lib/ekylibre/multi_tenancy/middleware/container_aware_rack_middleware.rb, line 99 def parse_host(host) (PublicSuffix.parse(host, ignore_private: true).trd || '').split('.') end
subdomain(host)
click to toggle source
Only care about the first subdomain for the database name
# File lib/ekylibre/multi_tenancy/middleware/container_aware_rack_middleware.rb, line 79 def subdomain(host) subdomains(host).first end
subdomains(host)
click to toggle source
# File lib/ekylibre/multi_tenancy/middleware/container_aware_rack_middleware.rb, line 83 def subdomains(host) host_valid?(host) ? parse_host(host) : [] end