Reputation: 1976
I'm trying to build a multi tenanted app in which which different banks are separated by subdomain. This part is working fine. Now there is one more level of multitenancy for bank products.
This is how I'm trying to implement above solution
around_filter :scope_current_bank, :scope_current_product
before_filter :authenticate_user!
helper_method :current_bank, :current_product
def current_bank
@current_bank = Bank.find_by_subdomain!(request.subdomains.first)
end
def current_product
if user_signed_in?
@current_product = current_bank.products.find_by_id(params[:product_id])
else
@current_product = current_user.product
end
end
def scope_current_bank
Bank.current_id = current_bank.id
yield
ensure
Bank.current_id = nil
end
def scope_current_product
Product.current_id = (current_product.id rescue nil)
yield
ensure
Product.current_id = nil
end
Now the problem is while user is sigining in, the scope_current_product method calls user_signed_in?, obviously it fails because product_id is nil. Now it enters the else block after which I expect it to call authenticate_user! as its a before_filter but it does not happen as authentication was already done. So I get a message saying authentication failed.
Is their any way to call authenticate_user again?
Upvotes: 1
Views: 1366
Reputation: 76774
Although not a direct answer, hopefully this will give you some ideas:
Authorization
Perhaps you should look at - Is there a difference between authentication and authorization? - there's a good RailsCast about this
I think your issue comes down to the idea you need to authenticate the user once (login / logout), but should then authorize that user to work with different resources
Code
A devise user can belong to only on product
- I would recommend this:
#app/models/product_user.rb
Class ProductUser < ActiveRecord::Base
belongs_to :product
belongs_to :user
end
#app/models/product.rb
Class Product < ActiveRecord::Base
has_many :product_users
has_many :users, through: :product_users
end
#app/models/user.rb
Class User < ActiveRecord::Base
has_many :product_users
has_many :products, through: :product_users
end
This is a typical has_many :through association:
@user.products
@product.users
CanCan
It means you can use CanCan to do something like this:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user
can :manage, Product, users.exists?(user.id)
else
can :read, :all
end
end
end
This allows you to control which products the user can edit / access. Obviously my code needs to be tweaked, but I hope it shows you the value of authorization over trying to do multiple authentications
Upvotes: 1