Class: CanCanCan::AssignmentAndAuthorization

Inherits:
Object
  • Object
show all
Defined in:
lib/cancancan/services/assignment_and_authorization.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(current_ability, action_name, parent_object, params) ⇒ AssignmentAndAuthorization

to handle updating nested attributes NESTED_ATTRIB_PERMISSION_KEY_GEN = Proc.new { |assoc_key| “#assoc_key_attributes”.to_sym } NESTED_ACTION_PERMISSION_KEY_GEN = Proc.new { |assoc_key| “can_update_association#CanCanCan::AssignmentAndAuthorization.assoc_keyassoc_key.to_s”.to_sym }



15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/cancancan/services/assignment_and_authorization.rb', line 15

def initialize(current_ability, action_name, parent_object, params)
  @ability = current_ability
  @parent_object = parent_object
  @params = params
  if CanCanCan::NestedAssignmentAndAuthorization.configuration.use_resource_key_in_params
    @params = @params[parent_object.model_name.singular.to_sym]
  end
  if @params.kind_of?(ActionController::Parameters)
    @params = @params.permit!.to_h
  end
  @action_name = action_name.to_sym
end

Instance Attribute Details

#abilityObject (readonly)

Returns the value of attribute ability.



5
6
7
# File 'lib/cancancan/services/assignment_and_authorization.rb', line 5

def ability
  @ability
end

#action_nameObject (readonly)

Returns the value of attribute action_name.



5
6
7
# File 'lib/cancancan/services/assignment_and_authorization.rb', line 5

def action_name
  @action_name
end

#paramsObject (readonly)

Returns the value of attribute params.



5
6
7
# File 'lib/cancancan/services/assignment_and_authorization.rb', line 5

def params
  @params
end

#parent_objectObject (readonly)

Returns the value of attribute parent_object.



5
6
7
# File 'lib/cancancan/services/assignment_and_authorization.rb', line 5

def parent_object
  @parent_object
end

Instance Method Details

#callObject



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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
# File 'lib/cancancan/services/assignment_and_authorization.rb', line 28

def call
  # Pre-assignment auth check
  first_authorize = @ability.can?(@action_name, @parent_object)
  unless first_authorize || CanCanCan::NestedAssignmentAndAuthorization.configuration.silence_raised_errors
    raise CanCan::AccessDenied.new("Not authorized!", @action_name, @parent_object)
  end

  return false unless first_authorize

  second_authorize = false

  # sanitized_attribs = ActionController::Parameters.new(
  #   @params
  # ).permit(@ability.permitted_attributes(@action_name, @parent_object))

  # sanitized_attribs will only contain attributes, not permitted associations
  sanitized_attribs = sanitize_parameters(@params, @ability.permitted_attributes(@action_name, @parent_object))

  ActiveRecord::Base.transaction do
    # Attributes
    @parent_object.assign_attributes(
      sanitized_attribs.except(
        *@parent_object.class.nested_attributes_options.keys.collect { |v| "#{v}_attributes".to_sym }
      )
    )
    # Associations
    instantiate_and_assign_nested_associations(
      @parent_object,
      sanitize_parameters(sanitized_attribs, @parent_object.class.nested_attributes_options.keys.collect { |v| "#{v}_attributes".to_sym })
    )
    # Post-assignment auth check
    second_authorize = @ability.can?(@action_name, @parent_object)
    unless second_authorize
      # NOTE: Does not halt the controller process, just rolls back the DB
      raise ActiveRecord::Rollback
    end
  end

  unless second_authorize || CanCanCan::NestedAssignmentAndAuthorization.configuration.silence_raised_errors
    raise CanCan::AccessDenied.new("Not authorized!", @action_name, @parent_object)
  end

  return false unless second_authorize

  save_result = @parent_object.save
  return save_result
end