Class: Lesli::RoleDescriptorOperator
- Inherits:
-
ApplicationLesliService
- Object
- ApplicationLesliService
- Lesli::RoleDescriptorOperator
- Defined in:
- app/operators/lesli/role_descriptor_operator.rb
Instance Method Summary collapse
-
#initialize(*roles) ⇒ RoleDescriptorOperator
constructor
A new instance of RoleDescriptorOperator.
-
#synchronize ⇒ Object
Syncronize the descriptor privileges with the role privilege cache table.
Methods inherited from ApplicationLesliService
#create, #delete, #error, #errors, #errors_as_sentence, #find, #found?, #index, #list, #result, #show, #successful?, #update
Constructor Details
#initialize(*roles) ⇒ RoleDescriptorOperator
Returns a new instance of RoleDescriptorOperator.
38 39 40 |
# File 'app/operators/lesli/role_descriptor_operator.rb', line 38 def initialize *roles @roles = roles end |
Instance Method Details
#synchronize ⇒ Object
Syncronize the descriptor privileges with the role privilege cache table
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'app/operators/lesli/role_descriptor_operator.rb', line 43 def synchronize # bulk all the descriptor privileges # this script was built manually for performance, maintenance # and to make it easy to read for future changes, basically what it does # is get the controllers and actions assigned to a descriptor through the # system_descriptor_privileges table and create an array of hashes with # all the raw privileges (this includes duplicated privileges) # IMPORTANT: A descriptor privilege is evaluated as active if: # - the role has assigned the descriptor through the power association # - the descriptor has assigned the privilege through the controller actions table # - the power has active that group of actions, this means that, if the power has # not marked as active the pshow, pindex, etc column the power is not active # even if it is assigned and active to a descriptor records = Descriptor.joins(%( INNER JOIN lesli_descriptor_privileges ON lesli_descriptor_privileges.descriptor_id = lesli_descriptors.id )).joins(%( INNER JOIN lesli_system_controller_actions ON lesli_system_controller_actions.id = lesli_descriptor_privileges.action_id )).joins(%( INNER JOIN lesli_system_controllers ON lesli_system_controllers.id = lesli_system_controller_actions.system_controller_id )).joins(%( INNER JOIN lesli_role_powers ON lesli_role_powers.descriptor_id = lesli_descriptors.id )).select(%( lesli_system_controllers.route as controller, lesli_system_controller_actions.name as action, case when lesli_role_powers.deleted_at is not null then false when NULLIF(lesli_system_controller_actions.name = 'list' and lesli_role_powers.plist = true, false) then true when NULLIF(lesli_system_controller_actions.name = 'index' and lesli_role_powers.pindex = true, false) then true when NULLIF(lesli_system_controller_actions.name = 'show' and lesli_role_powers.pshow = true, false) then true when NULLIF(lesli_system_controller_actions.name = 'new' and lesli_role_powers.pcreate = true, false) then true when NULLIF(lesli_system_controller_actions.name = 'create' and lesli_role_powers.pcreate = true, false) then true when NULLIF(lesli_system_controller_actions.name = 'edit' and lesli_role_powers.pupdate = true, false) then true when NULLIF(lesli_system_controller_actions.name = 'update' and lesli_role_powers.pupdate = true, false) then true when NULLIF(lesli_system_controller_actions.name = 'destroy' and lesli_role_powers.pdestroy = true, false) then true else false end as active, lesli_role_powers.role_id as role_id )).with_deleted # get privileges only for the given role, this is needed to sync only modified roles records = records.where("lesli_role_powers.role_id" => @roles) # we use the deleted_at column to know if a privilege is enable or disable, NULL values # at the deleted_at column means privilege is active, so if we sort by deleted_at column # all the active privileges will be at the top, then the uniq method is going to take # always the active values, to completely disable a privilege for a specific controller/action # we have to disable in all the descriptors records = records.order("lesli_role_powers.deleted_at DESC") # convert the results to json so it is easy to insert/update records = records.as_json(only: [:controller, :action, :role_id, :active]) # IMPORTANT: We must save only uniq privileges in the role_privilege table # this means that it does not matters how many times we defined a privilege dependency # we insert the privilege only once. # Example: If we defined that we need access to UsersController#index in 20 descriptors, # in the role_privileges will be only one record for that specific controller and action records = records.uniq do |privilege| # NOTE: If can disable a privilege that belongs to a descriptor, # however, if the same privilege is define in another active descriptor, # the role that has both descriptor will be able to access the resources # of that privilege, that is a normal and desire behavior. [privilege["controller"], privilege["action"], privilege["role_id"]] end # small check to ensure I have records to update/insert return if records.blank? # bulk update/insert into role privilege cache table # IMPORTANT: Due to the importance and how delicate this process is, it is better # to copy the controller name and actions from the system, instead of # just have a reference to the system_controller_actions table Lesli::Role::Privilege.with_deleted.upsert_all(records, unique_by: [:controller, :action, :role_id]) end |