ruby on rails - Best ability based authorization -
i have rails 3 app, use cancan authorization, looking suits needs better. authorizations not role based, more situational.
the application managing daily dinner clubs @ college/dorm, people takes turn making dinner rest. chef have therefore more permissions dinner club responsible (like changing menu), , participant have more permissions (like adding guests) 1 not participating in single dinner club.
what need therefore authorization system depends on relationship between user , dinner club or kitchen (a kitchen have many dinner clubs), not users role.
if helps, current cancan abilities here (as see pretty complex)
# in ability.rb def initialize(user) # edit (like changing time or menu) dinner club can :edit, dinnerclub |dinner_club| dinner_club.is_chef?(user) && !dinner_club.canceled? end # open or close dinner club can [:open, :close], dinnerclub |dinner_club| !dinner_club.passed? && dinner_club.is_chef?(user) end # cancel or resume dinner club can [:cancel, :resume], dinnerclub |dinner_club| !dinner_club.passed? && dinner_club.is_chef?(user) end # register or unregister @ specific dinner club can [:register, :unregister], dinnerclub |dinner_club| dinner_club.open? && (dinner_club.kitchen_id == user.kitchen_id || dinner_club.kitchen.open_registrations?) && !dinner_club.is_chef?(user) end # add guests dinner club can [:add_guests], dinnerclub |dinner_club| dinner_club.open? && (dinner_club.kitchen_id == user.kitchen_id || dinner_club.kitchen.open_registrations?) && dinner_club.registered?(user) end # take dinner club use if dinner club canceled can [:take], dinnerclub |dinner_club| dinner_club.canceled? && (dinner_club.kitchen_id == user.kitchen_id || dinner_club.kitchen.open_registrations?) && !dinner_club.passed? && !dinner_club.is_chef?(user) end # create new dinner club can [:create], dinnerclub |dinner_club| (dinner_club.kitchen_id == user.kitchen_id || dinner_club.kitchen.open_registrations?) end # comment on existing dinner clubs can [:comment], dinnerclub |dinner_club| dinner_club.registered?(user) end # can see dinner clubs kitchen can :read, kitchen |kitchen| (kitchen.id == user.kitchen_id || kitchen.open_registrations?) end # can manage kitchen, changing name , configuration options can :manage, kitchen, admin_id: user.id end
you can rewrite of these blocks in cancan make them lot less complex.
can :edit, dinnerclub, cancelled: false, chef_id: user.id # open or close dinner club can [:open, :close], dinnerclub, passed: false, chef_id: user.id # take dinner club use if dinner club canceled can [:take], dinnerclub, cancelled: true, kitchen_id: user.kitched_id, passed: false can [:take], dinnerclub, cancelled: true, kitchen: { open_registrations: true }, passed: false cannnot [:take], dinnerclub, chef_id: user.id
this assuming cancelled?
, passed?
methods derived boolean attributes on dinnerclub model , is_chef?
method checks chef_id. illustrates idea.
cancan used define abilities based on resources, go that.
Comments
Post a Comment