Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to set user before require_tenant check? #304

Open
seanarnold opened this issue Jan 9, 2023 · 2 comments
Open

How to set user before require_tenant check? #304

seanarnold opened this issue Jan 9, 2023 · 2 comments

Comments

@seanarnold
Copy link

I want to conditionally set require_tenant based on a user attribute. i.e all non-admins need to have a Tenant explicitly set.

ActsAsTenant.configure do |config|
  config.require_tenant = lambda do
    Current.user && !Current.user.admin?
  end
end
class ApplicationController < ActionController::Base
  set_current_tenant_through_filter
  before_action :authenticate_user!
  before_action :set_tenant_record

  def authenticate_user!
    ActsAsTenant.without_tenant do
      super
      # Set a global var as `current_user` isn't available in initialiser 
      Current.user = current_user
    end
  end

  def set_tenant_record
    set_current_tenant(current_user.tenant)
  end
end

However require_tenant is evaluated when authenticate_user! is called, even though it's within a without_tenant block.
As Current.user is nil, the lamba evaluates to false.

How do I set my Devise user before the require_tenant lambda is evaluated?

@omarluq
Copy link

omarluq commented Jan 17, 2023

running into a similar issue, I have a primary and a secondary tenancy and need to determine which one to apply by looking into the current_user roles first

@TheRealNeil
Copy link

TheRealNeil commented Nov 9, 2024

I had a similar need. This is my solution in case it helps anyone else

The initializer checks if the Current.user has been set. If so, it requires a tenant.
conf/initializers/acs_as_tenant.rb

# Only require the current_tenant to be set once a user has logged in
ActsAsTenant.configure do |config|
  config.require_tenant = lambda do
    Current.user.present?
  end
end

The application controller sets the Current.user from the current_user variable provided by devise in each request.
app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  before_action :authenticate_user!
  before_action :set_current_user

  private

  # Set Current.user from devise
  def set_current_user
    Current.user = current_user
  end
end

Setting the Current.user also sets the Current.account and current_tenant
app/models/current.rb

class Current < ActiveSupport::CurrentAttributes
  attribute :user, :account

  # Sets the user and associated account in the Current object.
  # Also sets the current tenant for ActsAsTenant.
  def user=(user)
    super
    self.account = user&.account
    ActsAsTenant.current_tenant = user&.account
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants