Class: Pastore::Guards::Settings

Inherits:
Object
  • Object
show all
Defined in:
lib/pastore/guards/settings.rb

Overview

Implements a structure where to store the settings for the guards.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(superklass) ⇒ Settings

Returns a new instance of Settings.



9
10
11
12
13
# File 'lib/pastore/guards/settings.rb', line 9

def initialize(superklass)
  @super_guards = superklass.pastore_guards if superklass.respond_to?(:pastore_guards)
  @superclass = superklass
  reset!
end

Instance Attribute Details

#forbidden_cbkObject



29
30
31
# File 'lib/pastore/guards/settings.rb', line 29

def forbidden_cbk
  @forbidden_cbk || @super_guards&.forbidden_cbk
end

#role_detectorObject



25
26
27
# File 'lib/pastore/guards/settings.rb', line 25

def role_detector
  @role_detector || @super_guards&.role_detector
end

Instance Method Details

#access_granted?(controller, action_name) ⇒ Boolean

rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity

Returns:

  • (Boolean)


122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/pastore/guards/settings.rb', line 122

def access_granted?(controller, action_name) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
  # Get setting for the current action.
  action = @actions[action_name.to_sym]

  return true if skip_guards?(action_name)

  result = authorize_with_lambda(controller, action)
  return result unless result.nil?

  role = current_role(controller)

  return false if action&.dig(:denied_roles)&.include?(role)

  strategy == :allow || (strategy == :deny && action&.dig(:permitted_roles)&.include?(role)) || false
end

#authorize_with(method_name = nil, &block) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/pastore/guards/settings.rb', line 75

def authorize_with(method_name = nil, &block)
  if @buffer[:permitted_roles].present? || @buffer[:denied_roles].present?
    raise Pastore::Guards::RoleConflictError, 'A role has already been specified with #permit_role or #deny_role'
  end

  custom_lambda = method_name.to_sym if method_name.is_a?(Symbol) || method_name.is_a?(String)
  custom_lambda = block if block_given?

  if custom_lambda.present?
    @buffer[:authorization_lambda] = custom_lambda
  else
    raise ArgumentError, 'A block or a method name must be provided'
  end
end

#current_role(controller) ⇒ Object

Returns the current role for the controller.



116
117
118
119
120
# File 'lib/pastore/guards/settings.rb', line 116

def current_role(controller)
  return nil if role_detector.blank?

  controller.instance_exec(&role_detector)&.to_s
end

#deny_role(*roles) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/pastore/guards/settings.rb', line 60

def deny_role(*roles)
  new_roles = [roles].flatten.compact.uniq.map(&:to_s)
  conflicts = @buffer.fetch(:permitted_roles, []) & new_roles

  unless conflicts.empty?
    raise Pastore::Guards::RoleConflictError, "Roles conflict: #{conflicts} roles already specified with #permit_role"
  end

  if @buffer[:authorization_lambda].present?
    raise Pastore::Guards::RoleConflictError, 'An #authorize_with has already been specified'
  end

  @buffer[:denied_roles] = new_roles
end

#force_guards_for(*actions) ⇒ Object



111
112
113
# File 'lib/pastore/guards/settings.rb', line 111

def force_guards_for(*actions)
  @forced_guards = [actions].flatten.compact.map(&:to_sym)
end

#permit_role(*roles) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/pastore/guards/settings.rb', line 45

def permit_role(*roles)
  new_roles = [roles].flatten.compact.uniq.map(&:to_s)
  conflicts = @buffer.fetch(:denied_roles, []) & new_roles

  unless conflicts.empty?
    raise Pastore::Guards::RoleConflictError, "Roles conflict: #{conflicts} roles already specified with #deny_role"
  end

  if @buffer[:authorization_lambda].present?
    raise Pastore::Guards::RoleConflictError, 'An #authorize_with has already been specified'
  end

  @buffer[:permitted_roles] = new_roles
end

#reset!Object



15
16
17
18
19
20
21
22
23
# File 'lib/pastore/guards/settings.rb', line 15

def reset!
  @strategy = nil
  @role_detector = nil
  @forbidden_cbk = nil
  @actions = {}
  @buffer = {}
  @skipped_guards = []
  @forced_guards = []
end

#reset_buffer!Object



103
104
105
# File 'lib/pastore/guards/settings.rb', line 103

def reset_buffer!
  @buffer = {}
end

#save_guards_for(action_name) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/pastore/guards/settings.rb', line 90

def save_guards_for(action_name)
  return if @buffer.empty?

  name = action_name.to_sym
  @actions[name] ||= {}

  save_permitted_roles!(name)
  save_denied_roles!(name)
  save_authorization_lambda!(name)

  reset_buffer!
end

#skip_guards_for(*actions) ⇒ Object



107
108
109
# File 'lib/pastore/guards/settings.rb', line 107

def skip_guards_for(*actions)
  @skipped_guards = [actions].flatten.compact.map(&:to_sym)
end

#strategyObject



41
42
43
# File 'lib/pastore/guards/settings.rb', line 41

def strategy
  @strategy || @super_guards&.strategy || :deny
end

#use_allow_strategy!Object



33
34
35
# File 'lib/pastore/guards/settings.rb', line 33

def use_allow_strategy!
  @strategy = :allow
end

#use_deny_strategy!Object



37
38
39
# File 'lib/pastore/guards/settings.rb', line 37

def use_deny_strategy!
  @strategy = :deny
end