ruby on rails - Authorization in multi tenant app -


in railscasts episode 388 - multitenancy scopes, ryan adding default scope ensure security:

alternatively can use authorization library such cancan handle scoping isn’t designed multi-tenant apps , won’t solve problem well. 1 case it’s acceptable use default scope that’s we’ll do.

class tenant < activerecord::base   attr_accessible :name, :subdomain   has_many :topics end  class topic < activerecord::base   attr_accessible :name, :content   belongs_to :user   has_many :posts    default_scope { where(tenant_id: tenant.current_id) } end 

my question is: want implement authorization (for example cancan) , define abilities these:

class ability   include cancan::ability    def initialize(user)     user ||= user.new # guest user (not logged in)     if user.admin?       can :manage, topic     else       can :read, topic     end   end end 

does user have ability manage topics of tenants or within tenants scope?

or more general question: what's right method of authorization multi tenant applications?

you on right track using cancan, or cancancan since cancan deprecated, think.

i don't default_scope reason not threadsafe. user id stored in class variable, means 2 or more concurrent users in app break unless use unicorn or other web server makes sure no more 1 single client connection access same thread.

you should therefore use cancan.

class ability   include cancan::ability    def initialize(user)     user ||= user.new # guest user (not logged in)     if user.admin?       # user's own topics only:       can :manage, topic, user_id: user.id       # or, tenant       can :manage, topic, tenant_id: user.tenant.id if user.tenant # user belongs_to tenant       can :manage, topic, tenant_id: user.tenants.map(&:id) if user.tenants.any? # user has_many tenants     else       can :read, topic # can read topic.     end   end end 

pick strategy need 3 examples above.


edit more complicated example multi-tenant admins @joshdoody's question in comments:


class admin < user; end  class tenantadmin   belongs_to :tenant   belongs_to :admin, class_name: user end  class ability   include cancan::ability    def initialize(user)     user ||= user.new # guest user (not logged in)     if user.admin?       can :manage, topic, tenant_id: tenantadmin.where(admin: user).map(&:tenant_id)     else       can :read, topic # can read topic     end   end end 

now, might not performant like, general idea have tenantadmins able manage topics within tenants.

hope helps.


Comments

Popular posts from this blog

php - SPIP: From Tag directly to an article -

jquery - isAjaxRequest always return false -

ruby on rails - In a controller spec, how to find a specific tag in the generated view? -