Class: Petticoat::Adapter

Inherits:
Object
  • Object
show all
Defined in:
lib/petticoat/adapter.rb

Overview

All access to undocumented CanCanCan internals lives here. Only private copies receive the gem's relevance/alias-cache mutations.

Constant Summary collapse

ID =
'cancancan-3.6.0-18ce8ad80065'
FILES =
{
  'ability.rb' => '6864743679252c07b750630ca4ebbad94117d6367ef6c33d7132a0e1ce2d5bbc',
  'ability/rules.rb' => '4a7f96dd94b606e904718642b1a0a97efa3000be6396fb5f1150be005b02032b',
  'ability/actions.rb' => '97c79d145b0e694cb273c4b7f3915426ead55546295d1ba92d6bb0cdfe08c3f7',
  'rule.rb' => '7a4b0ce56f001a29a66c1051928732a88c893060ed1e11510fa2e1d3c31e7d18',
  'relevant.rb' => 'dbe8ea801fd50a2e6fbb87a65825febb6affdee367c6a52706340bf1a91e55a1',
  'conditions_matcher.rb' => 'f324a2a78788241c6ea53aecd3b9f48b947d42551db3eba84e6f9226c33351b7',
  'class_matcher.rb' => 'b26f464494c2ff1551c4fa004d28fc4c82cad4cacbb04088e55971d47af489e2'
}.freeze
Shell =
Class.new { include CanCan::Ability }
COPIED_FIELDS =
i[actions subjects attributes].freeze
METHOD_OWNERS =
{
  can?: CanCan::Ability,
  alternative_subjects: CanCan::Ability,
  rules: CanCan::Ability::Rules,
  relevant_rules: CanCan::Ability::Rules,
  possible_relevant_rules: CanCan::Ability::Rules,
  expand_actions: CanCan::Ability::Actions,
  aliased_actions: CanCan::Ability::Actions
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ability) ⇒ Adapter

Returns a new instance of Adapter.



44
45
46
47
48
49
50
51
52
53
54
# File 'lib/petticoat/adapter.rb', line 44

def initialize(ability)
  self.class.verify!
  @shell = Shell.new
  @issues = semantic_issues(ability)
  @aliases = copy_aliases(ability)
  validate_aliases!
  @shell.instance_variable_set(:@aliased_actions, @aliases.transform_values(&:dup))
  @rules = copy_rules(ability)
  cache = ability.instance_variable_get(:@expanded_actions) || {}
  @shell.instance_variable_set(:@expanded_actions, cache.to_h { |key, value| [key.dup, value.dup] })
end

Instance Attribute Details

#aliases ⇒ Object (readonly)

Returns the value of attribute aliases.



30
31
32
# File 'lib/petticoat/adapter.rb', line 30

def aliases
  @aliases
end

#issues ⇒ Object (readonly)

Returns the value of attribute issues.



30
31
32
# File 'lib/petticoat/adapter.rb', line 30

def issues
  @issues
end

#rules ⇒ Object (readonly)

Returns the value of attribute rules.



30
31
32
# File 'lib/petticoat/adapter.rb', line 30

def rules
  @rules
end

Class Method Details

.verify! ⇒ Object

Raises:



32
33
34
35
36
37
38
39
40
41
42
# File 'lib/petticoat/adapter.rb', line 32

def self.verify!
  raise Error, 'Unsupported CanCanCan version' unless CanCan::VERSION == '3.6.0'
  return if @verified

  root = File.join(Gem.loaded_specs.fetch('cancancan').full_gem_path, 'lib/cancan')
  unless FILES.all? { |file, digest| Digest::SHA256.file(File.join(root, file)).hexdigest == digest }
    raise Error, 'Unsupported CanCanCan source; review the manifest adapter before exporting'
  end

  @verified = true
end

Instance Method Details

#actions ⇒ Object



60
61
62
# File 'lib/petticoat/adapter.rb', line 60

def actions
  (rules.flat_map(&:actions) + aliases.keys + aliases.values.flatten).uniq
end

#relevant(action, subject) ⇒ Object



56
57
58
# File 'lib/petticoat/adapter.rb', line 56

def relevant(action, subject)
  @shell.send(:relevant_rules, action, subject)
end

#unsupported_subjects? ⇒ Boolean

Returns:

  • (Boolean)


64
65
66
67
68
# File 'lib/petticoat/adapter.rb', line 64

def unsupported_subjects?
  rules.any? do |rule|
    rule.subjects.empty? || rule.subjects.any? { |subject| !subject.is_a?(Module) && !subject.is_a?(Symbol) }
  end
end