lib/strongbolt/user_abilities.rb
#----------------------------------------------------------#
#                                                          #
#  Checks if the user can perform 'action' on 'instance'   #
#                                                          #
#----------------------------------------------------------#
Checks if the user can perform 'action' on 'instance'
Checks if the user can perform ' action ' on ' instance '
def capability_in_cache?(action, instance, model_name, attrs = :any, all_instance = false)
        action_model = "#{action}#{model_name}"
        Strongbolt.logger.warn "User has no results cache" if @results_cache.empty?
        Strongbolt.logger.debug { "Authorizing user to perform #{action} on #{instance.inspect}" }
        if instance.is_a?(ActiveRecord::Base) && !instance.new_record?
          return true if @results_cache["#{action_model}all-all"]  
          return true if @results_cache["#{action_model}#{attrs}-all"]  
          id = instance.try(:id)
          return true if @results_cache["#{action_model}all-#{id}"] 
          return true if @results_cache["#{action_model}#{attrs}-#{id}"] 
          valid_tenants = has_access_to_tenants?(instance)
          if instance.class.owned?
            if (own_instance = instance.strongbolt_owner_id == self.id)
              @results_cache["#{action_model}all-#{id}"] = own_instance && valid_tenants && @results_cache["#{action_model}all-owned"]
              @results_cache["#{action_model}#{attrs}-#{id}"] = own_instance && valid_tenants && @results_cache["#{action_model}#{attrs}-owned"]
              return true if @results_cache["#{action_model}all-#{id}"] || @results_cache["#{action_model}#{attrs}-#{id}"]
            else
              @results_cache["#{action_model}all-#{id}"] = false
              @results_cache["#{action_model}#{attrs}-#{id}"] = false
            end
          end
          @results_cache["#{action_model}all-#{id}"] = @results_cache["#{action_model}all-tenanted"] && valid_tenants  
          @results_cache["#{action_model}#{attrs}-#{id}"] =  @results_cache["#{action_model}#{attrs}-tenanted"] && valid_tenants 
          return true if @results_cache["#{action_model}all-#{id}"] || @results_cache["#{action_model}#{attrs}-#{id}"]
        elsif instance.is_a?(ActiveRecord::Base) && instance.new_record?
          return true if @results_cache["#{action_model}all-all"]  
          return true if @results_cache["#{action_model}#{attrs}-all"]  
          valid_tenants = has_access_to_tenants?(instance)
          return true if @results_cache["#{action_model}all-tenanted"] && valid_tenants  
          return true if @results_cache["#{action_model}#{attrs}-tenanted"] && valid_tenants 
          return true if @results_cache["#{action_model}all-any"] && valid_tenants
          return true if @results_cache["#{action_model}#{attrs}-any"] && valid_tenants
        else
          return true if @results_cache["#{action_model}all-all"]  
          return true if @results_cache["#{action_model}#{attrs}-all"]  
          return true if @results_cache["#{action_model}all-any"] && ! all_instance  
          return true if @results_cache["#{action_model}#{attrs}-any"] && ! all_instance  
        end
        return false
      end
def capability_in_cache? ( action , instance , model_name , attrs = :any , all_instance = false ) action_model = "#{action}#{model_name}" Strongbolt . logger . warn "User has no results cache" if @results_cache . empty? Strongbolt . logger . debug { "Authorizing user to perform #{action} on #{instance.inspect}" } if instance . is_a? ( ActiveRecord :: Base ) && ! instance . new_record? return true if @results_cache [ "#{action_model}all-all" ] return true if @results_cache [ "#{action_model}#{attrs}-all" ] id = instance . try ( :id ) return true if @results_cache [ "#{action_model}all-#{id}" ] return true if @results_cache [ "#{action_model}#{attrs}-#{id}" ] valid_tenants = has_access_to_tenants? ( instance ) if instance . class . owned? if ( own_instance = instance . strongbolt_owner_id == self . id ) @results_cache [ "#{action_model}all-#{id}" ] = own_instance && valid_tenants && @results_cache [ "#{action_model}all-owned" ] @results_cache [ "#{action_model}#{attrs}-#{id}" ] = own_instance && valid_tenants && @results_cache [ "#{action_model}#{attrs}-owned" ] return true if @results_cache [ "#{action_model}all-#{id}" ] || @results_cache [ "#{action_model}#{attrs}-#{id}" ] else @results_cache [ "#{action_model}all-#{id}" ] = false @results_cache [ "#{action_model}#{attrs}-#{id}" ] = false end end @results_cache [ "#{action_model}all-#{id}" ] = @results_cache [ "#{action_model}all-tenanted" ] && valid_tenants @results_cache [ "#{action_model}#{attrs}-#{id}" ] = @results_cache [ "#{action_model}#{attrs}-tenanted" ] && valid_tenants return true if @results_cache [ "#{action_model}all-#{id}" ] || @results_cache [ "#{action_model}#{attrs}-#{id}" ] elsif instance . is_a? ( ActiveRecord :: Base ) && instance . new_record? return true if @results_cache [ "#{action_model}all-all" ] return true if @results_cache [ "#{action_model}#{attrs}-all" ] valid_tenants = has_access_to_tenants? ( instance ) return true if @results_cache [ "#{action_model}all-tenanted" ] && valid_tenants return true if @results_cache [ "#{action_model}#{attrs}-tenanted" ] && valid_tenants return true if @results_cache [ "#{action_model}all-any" ] && valid_tenants return true if @results_cache [ "#{action_model}#{attrs}-any" ] && valid_tenants else return true if @results_cache [ "#{action_model}all-all" ] return true if @results_cache [ "#{action_model}#{attrs}-all" ] return true if @results_cache [ "#{action_model}all-any" ] && ! all_instance return true if @results_cache [ "#{action_model}#{attrs}-any" ] && ! all_instance end return false end
Checks if the user can perform 'action' on 'instance'
Checks if the user can perform ' action ' on ' instance '
# we don't know or care about tenants or if this is a new record # First, check if we have a hash/cache hit for User being able to do this action to every instance of the model/class #Access to all attributes on ENTIRE class? #Access to this specific attribute on ENTIRE class? # If we're checking on a specific instance of the class, not the general model, # append the id to the key # Access to all this instance's attributes? #Access to this instance's attribute? # Checking ownership and tenant access # Block access for non tenanted instance # Then if the model is owned but isn't preloaded yet # Tests if the owner id of the instance is the same than the user # Finally we check for tenanted instances #Access to all attributes on tenanted class? #Access to this specific attribute on tenanted class? #Access to all attributes on ENTIRE class? #Access to this specific attribute on ENTIRE class? # Checking if the instance is from valid tenants (if necessary) #Access to all attributes on tenanted class? #Access to this specific attribute on tenanted class? # Finally, in the case where it's a non tenanted model (it still need to have valid_tenants == true) # First, check if we have a hash/cache hit for User being able to do this action to every instance of the model/class #Access to all attributes on ENTIRE class? #Access to this specific attribute on ENTIRE class? #Access to all attributes on at least once instance? #Access to this specific attribute on at least once instance? #logger.info "Cache miss for checking access to #{key}"
action
instance
model_name
attrs
all_instance