Module: Walruz::ControllerMixin::ClassMethods

Defined in:
lib/walruz/controller_mixin.rb

Instance Method Summary collapse

Instance Method Details

#before_check_crud_authorizations_on(subject) ⇒ Object

Generates dynamically all the before filters needed for authorizations on a CRUD model.

Requirements:

- The controller must have a method called `current_user` that returns
  the authenticated user
- The subject must implement the four actions (:create, :read,
  :update, :destroy) or have a :default action

Parameters:

- subject: Symbol that indicates an instance variable or method on
           the controller that returns the subject

Example:

class CommentController < ActionController::Base

  before_check_crud_authorizations_on :@comment

  # This would be the same as:
  # before_filter check_authorization!(:create, :@comment),
                  :only => [:new, :create]
  # before_filter check_authorization!(:read, :@comment),
                  :only => :show
  # before_filter check_authorization!(:update, :@comment),
                  :only => [:edit, :update]
  # before_filter check_authorization!(:destroy, :@comment),
                  :only => :destroy

end


167
168
169
170
171
172
173
174
175
176
177
# File 'lib/walruz/controller_mixin.rb', line 167

def before_check_crud_authorizations_on(subject)
  [
    [:create, ['new', 'create']],
    [:read, 'show'],
    [:update, ['edit', 'update']],
    [:destroy, 'destroy']
  ].each do |(actor_action, actions)|
    before_filter(check_authorization!(actor_action, subject),
                  :only => actions)
  end
end

#check_authorization!(action, subject) ⇒ Object

Creates a before filter that will check if the actor returned by the method ‘current_user` can execute the given action on the given subject.

Requirements:

- The controller must have a method called `current_user` that
  returns the authenticated user

Parameters:

- action:  Symbol that represents the action wich will be executed
           on the subject
- subject: Symbol that indicates an instance variable or method on
           the controller that returns the subject

Returns:

A proc that will be executed as a before_filter method

Example:

class UserController < ActionController::Base

  before_filter check_authorization!(:create, :user),
                :only => [:new, :create]
  before_filter check_authorization!(:destroy,
                :complicated_method_that_returns_a_user),
                :only => :destroy

  def complicated_method_that_returns_a_user
    # some complex logic here
    return user
  end
end


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/walruz/controller_mixin.rb', line 61

def check_authorization!(action, subject)
  lambda do |controller|
    # we get the subject
    subject_instance =
              if controller.instance_variable_defined?("@%s" % subject)
                controller.instance_variable_get("@%s" % subject)
              elsif controller.respond_to?(subject)
                controller.send(subject)
              else
                error_message = "There is neither an instance variable \
                @%s nor a instance method %s on the %s instance\
                context" % [subject, subject, controller.class.name]
                raise ArgumentError.new(error_message)
              end
    params = Walruz.authorize!(controller.send(:current_user),
                               action,
                               subject_instance)
    controller.set_policy_params!(params)
  end
end

#check_policy!(policy_label, subject = nil) ⇒ Object

Creates a before filter that will check the policy represented by the given symbol, using ‘current_user` as the actor

Requirements:

- The controller must have a method called `current_user` that
  returns the authenticated user

Parameters:

- policy_label: Symbol that represents the policy wich will be 
                executed on the subject

- subject: Symbol that indicates an instance variable or method on
           the controller that returns the subject

Returns:

A proc that will be executed as a before_filter method

Example:

class UserController < ActionController::Base

  before_filter check_policy!(:is_admin, :user),
                :only => [:new, :create]
  before_filter check_policy!(:can_read_posts,
                :complicated_method_that_returns_a_user),
                :only => :destroy

  def complicated_method_that_returns_a_user
    # some complex logic here
    return user
  end
end


117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/walruz/controller_mixin.rb', line 117

def check_policy!(policy_label, subject = nil)
  lambda do |controller|
    subject_instance = nil
    if subject
      subject_instance =
        if controller.instance_variable_defined?("@%s" % subject)
          controller.instance_variable_get("@%s" % subject)
        elsif controller.respond_to?(:"#{subject}")
          controller.send(:"#{subject}")
        end
    end
    params = Walruz.satisfies!(controller.send(:current_user),
                               policy_label,
                               subject_instance)
    controller.set_policy_params!(params)
  end
end