Module: ActiveSecurity::Finders

Defined in:
lib/active_security/finders.rb

Overview

## Performing Finds with ActiveSecurity

ActiveSecurity offers enhanced finders which will search for your record while ensuring that a particular scope is present. This makes it easy to add ActiveSecurity to an existing application with minimal code modification.

By default, these enhanced finders are available only on the restricted scope:

Restaurant.restricted.find(23)          #=> Will blow up, because no scope!
Restaurant.find(23)                     #=> works

ActiveSecurity overrides the default finder methods to perform secure finds all the time. This requires modifying parts of Rails that do not have a public API, which is hard to maintain and may cause compatibility issues.

class Restaurant < ActiveRecord::Base
  extend ActiveSecurity

  scope :active, -> {where(active: true)}

  active_security use: :finders
end

Restaurant.restricted.find(23)          #=> blows up, because no scope!
Restaurant.find(23)                     #=> also blows up, because no scope!
Restaurant.active.find(23)              #=> works, because scoped!
Restaurant.active.restricted.find(23)   #=> also works, because scoped!

### Updating your application to use ActiveSecurity’s finders

Unless you’ve chosen to use the :finders addon, be sure to modify the finders in your controllers to use the restricted scope. For example:

# before
def set_restaurant
  @restaurant = Restaurant.find(params[:id])
end

# after
def set_restaurant
  @restaurant = Restaurant.restricted.find(params[:id])
end

#### Active Admin

Unless you use the :finders addon, you should modify your admin controllers for models that use ActiveSecurity with something similar to the following:

controller do
  def find_resource
    scoped_collection.restricted.find(params[:id])
  end
end

Defined Under Namespace

Modules: Configuration

Class Method Summary collapse

Class Method Details

.after_config(model_class) ⇒ Object

Sets up behavior and that depends on configuration

Raises:



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/active_security/finders.rb', line 83

def after_config(model_class)
  raise InvalidConfig, ":finders plugin must be used with default_finders set to one of :privileged, or :restricted" unless i[restricted privileged].include?(model_class.active_security_config.default_finders)

  model_class.active_security_config.use(model_class.active_security_config.default_finders)
  model_class.class_eval do
    if active_security_config.default_finders == :privileged
      relation.class.send(:include, active_security_config.privileged_hooks)
      send(:extend, active_security_config.privileged_hooks)
    else
      relation.class.send(:include, active_security_config.restricted_hooks)
      send(:extend, active_security_config.restricted_hooks)
    end
  end
  association_relation_delegate_class = model_class.relation_delegate_class(::ActiveRecord::AssociationRelation)
  if model_class.active_security_config.default_finders == :privileged
    association_relation_delegate_class.send(:include, model_class.active_security_config.privileged_hooks)
  else
    model_class.active_security_config.default_finders
    association_relation_delegate_class.send(:include, model_class.active_security_config.restricted_hooks)
  end
end

.included(model_class) ⇒ Object

Sets up behavior and configuration options for finders feature.



75
76
77
78
79
80
# File 'lib/active_security/finders.rb', line 75

def included(model_class)
  model_class.active_security_config.instance_eval do
    self.class.send(:include, Configuration)
    defaults[:default_finders] ||= :restricted
  end
end

.setup(model_class) ⇒ Object

ActiveSecurity::Config.use will invoke this method when present, to allow loading dependent modules prior to overriding them when necessary.



64
65
66
67
68
69
70
71
72
# File 'lib/active_security/finders.rb', line 64

def setup(model_class)
  model_class.class_eval do
    relation.class.send(:include, active_security_config.finder_methods)
    extend(active_security_config.finder_methods)
  end

  association_relation_delegate_class = model_class.relation_delegate_class(::ActiveRecord::AssociationRelation)
  association_relation_delegate_class.send(:include, model_class.active_security_config.finder_methods)
end