From ec54014832057fbdc5584ca1cf77b0a1cf65735b Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 10 Nov 2025 11:42:18 -0500 Subject: [PATCH] Add account slug middleware and set Current.account --- app/controllers/concerns/authentication.rb | 8 +++- app/controllers/concerns/authorization.rb | 12 +++++- app/models/membership.rb | 6 ++- config/initializers/tenanting/account_slug.rb | 41 +++++++++++++------ 4 files changed, 50 insertions(+), 17 deletions(-) diff --git a/app/controllers/concerns/authentication.rb b/app/controllers/concerns/authentication.rb index 9577ccb1d..b0bce9ac4 100644 --- a/app/controllers/concerns/authentication.rb +++ b/app/controllers/concerns/authentication.rb @@ -52,7 +52,9 @@ module Authentication end def request_authentication - session[:return_to_after_authenticating] = request.url + if request_account_id.present? + session[:return_to_after_authenticating] = request.url + end redirect_to_login_url end @@ -81,4 +83,8 @@ module Authentication Current.session.destroy cookies.delete(:session_token) end + + def request_account_id + request.env["fizzy.external_account_id"] + end end diff --git a/app/controllers/concerns/authorization.rb b/app/controllers/concerns/authorization.rb index dfd0e946d..350a64507 100644 --- a/app/controllers/concerns/authorization.rb +++ b/app/controllers/concerns/authorization.rb @@ -2,7 +2,8 @@ module Authorization extend ActiveSupport::Concern included do - before_action :ensure_can_access_account, if: -> { authenticated? } + prepend_before_action :set_account, if: -> { request_account_id.present? } + before_action :ensure_can_access_account, if: -> { Current.account.present? && authenticated? } end class_methods do @@ -17,6 +18,10 @@ module Authorization end private + def set_account + Current.account = Account.find_by(external_account_id: request_account_id) + end + def ensure_admin head :forbidden unless Current.user.admin? end @@ -26,7 +31,10 @@ module Authorization end def ensure_can_access_account - if Current.membership.blank? + if Current.account.nil? + redirect_to session_menu_url(script_name: nil) + elsif Current.membership.blank? + Rails.logger.debug "MIKE: blank membership, session is #{Current.session.inspect}" redirect_to session_menu_url(script_name: nil) elsif Current.user.nil? && Current.membership.join_code.present? redirect_to new_users_join_path diff --git a/app/models/membership.rb b/app/models/membership.rb index 03fba7d63..cecfa1777 100644 --- a/app/models/membership.rb +++ b/app/models/membership.rb @@ -15,8 +15,12 @@ class Membership < ApplicationRecord end end + def account + Account.find_by_external_account_id(tenant) + end + def account_name - Current.account.name + account&.name end def user diff --git a/config/initializers/tenanting/account_slug.rb b/config/initializers/tenanting/account_slug.rb index 6a4f83eb9..2166a6a89 100644 --- a/config/initializers/tenanting/account_slug.rb +++ b/config/initializers/tenanting/account_slug.rb @@ -3,23 +3,38 @@ module AccountSlug FORMAT = "%07d" PATH_INFO_MATCH = /\A(\/#{AccountSlug::PATTERN})/ - # 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? ? "/" : $' + class Extractor + def initialize(app) + @app = app + end - # Return the account id - AccountSlug.decode($2) + # 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 call(env) + request = ActionDispatch::Request.new(env) + + # $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? ? "/" : $' + + # Stash the account's Queenbee ID. + env["fizzy.external_account_id"] = AccountSlug.decode($2) + Rails.logger.debug "MIKE: Extracted account id #{env["fizzy.external_account_id"].inspect}" + end + + @app.call env end end def self.decode(slug) slug.to_i end def self.encode(id) FORMAT % id end end + +Rails.application.config.middleware.tap do |stack| + stack.insert_before Rails::Rack::Logger, AccountSlug::Extractor +end