diff --git a/config/initializers/tenanting.rb b/config/initializers/tenanting.rb index 85ef97ba7..a63b37caa 100644 --- a/config/initializers/tenanting.rb +++ b/config/initializers/tenanting.rb @@ -1,19 +1,37 @@ -Rails.application.config.after_initialize do - # in production and staging, we're using a two-level subdomain like "tenant.fizzy.37signals.com". - # in development and beta it's only a single-level subdomain. - Rails.application.config.active_record_tenanted.tenant_resolver = ->(request) do - tld_length = [ "37signals.com", "37signals-staging.com" ].include?(request.domain) ? 2 : 1 +module AccountSlug + PATTERN = /(\d{7,})/ + FORMAT = "%07d" + PATH_INFO_MATCH = /\A(\/#{AccountSlug::PATTERN})/ - if request.path == "/up" - nil - elsif subdomain = request.subdomain(tld_length).presence - subdomain - elsif request.path =~ %r{^/(queenbee|signup)\b} - nil - else - "return-404" # this is a quick fix for now + # We're using account id prefixes in the URL path. Rather than namespace + # all our routes, we're "mounting" the Rails app at this URL prefix. + def self.extract(request) + # $1, $2, $' == script_name, slug, path_info + if request.script_name && request.script_name =~ PATH_INFO_MATCH + # Likely due to restarting the action cable connection after upgrade + AccountSlug.decode($2) + elsif request.path_info =~ PATH_INFO_MATCH + # Yanks the prefix off PATH_INFO and move it to SCRIPT_NAME + request.engine_script_name = request.script_name = $1 + request.path_info = $'.empty? ? "/" : $' + + # Limit session cookies to the slug path. + # TODO TEST ME + request.env["rack.session.options"][:path] = $1 + + # Return the account id for tenanting. + AccountSlug.decode($2) end end + + def self.decode(slug) slug.to_i end + def self.encode(id) FORMAT % id end +end + +Rails.application.config.after_initialize do + Rails.application.config.active_record_tenanted.tenant_resolver = ->(request) do + AccountSlug.extract(request) + end end ActiveSupport.on_load(:action_controller_base) do