Class: ViewModel::AccessControl::Composed
- Inherits:
-
ViewModel::AccessControl
- Object
- ViewModel::AccessControl
- ViewModel::AccessControl::Composed
- Defined in:
- lib/view_model/access_control/composed.rb
Overview
Provides access control as a combination of ‘x_if!` and `x_unless!` checks for each access check (visible, editable, edit_valid). An action is permitted if at least one `if` check and no `unless` checks succeed. For example:
edit_valid_if!("logged in as specified user") { ... }
edit_valid_unless!("user is on fire") { ... }
Direct Known Subclasses
Defined Under Namespace
Classes: ComposedResult, NoRequiredConditionsError, PermissionsCheck
Constant Summary
Constants included from Callbacks
Class Attribute Summary collapse
-
.edit_valid_ifs ⇒ Object
readonly
Returns the value of attribute edit_valid_ifs.
-
.edit_valid_unlesses ⇒ Object
readonly
Returns the value of attribute edit_valid_unlesses.
-
.editable_ifs ⇒ Object
readonly
Returns the value of attribute editable_ifs.
-
.editable_unlesses ⇒ Object
readonly
Returns the value of attribute editable_unlesses.
-
.visible_ifs ⇒ Object
readonly
Returns the value of attribute visible_ifs.
-
.visible_unlesses ⇒ Object
readonly
Returns the value of attribute visible_unlesses.
Class Method Summary collapse
- .each_check(check_name, include_ancestor = nil) ⇒ Object
- .edit_valid_if!(reason, &block) ⇒ Object
- .edit_valid_unless!(reason, &block) ⇒ Object
- .editable_if!(reason, &block) ⇒ Object
- .editable_unless!(reason, &block) ⇒ Object
-
.include_from(ancestor) ⇒ Object
Configuration API.
- .inherited(subclass) ⇒ Object
- .initialize_as_composed_access_control ⇒ Object
- .inspect ⇒ Object
- .inspect_checks ⇒ Object
-
.new_permission_check(reason, error_type: ViewModel::AccessControlError, &block) ⇒ Object
Implementation.
- .visible_if!(reason, &block) ⇒ Object
- .visible_unless!(reason, &block) ⇒ Object
Instance Method Summary collapse
-
#editable_check(traversal_env) ⇒ Object
final.
-
#valid_edit_check(traversal_env) ⇒ Object
final.
-
#visible_check(traversal_env) ⇒ Object
final.
Methods inherited from ViewModel::AccessControl
#editable!, #initialize, #visible!
Methods included from Callbacks
#ineligible, #run_callback, wrap_deserialize, wrap_serialize
Constructor Details
This class inherits a constructor from ViewModel::AccessControl
Class Attribute Details
.edit_valid_ifs ⇒ Object (readonly)
Returns the value of attribute edit_valid_ifs.
82 83 84 |
# File 'lib/view_model/access_control/composed.rb', line 82 def edit_valid_ifs @edit_valid_ifs end |
.edit_valid_unlesses ⇒ Object (readonly)
Returns the value of attribute edit_valid_unlesses.
82 83 84 |
# File 'lib/view_model/access_control/composed.rb', line 82 def edit_valid_unlesses @edit_valid_unlesses end |
.editable_ifs ⇒ Object (readonly)
Returns the value of attribute editable_ifs.
82 83 84 |
# File 'lib/view_model/access_control/composed.rb', line 82 def editable_ifs @editable_ifs end |
.editable_unlesses ⇒ Object (readonly)
Returns the value of attribute editable_unlesses.
82 83 84 |
# File 'lib/view_model/access_control/composed.rb', line 82 def editable_unlesses @editable_unlesses end |
.visible_ifs ⇒ Object (readonly)
Returns the value of attribute visible_ifs.
82 83 84 |
# File 'lib/view_model/access_control/composed.rb', line 82 def visible_ifs @visible_ifs end |
.visible_unlesses ⇒ Object (readonly)
Returns the value of attribute visible_unlesses.
82 83 84 |
# File 'lib/view_model/access_control/composed.rb', line 82 def visible_unlesses @visible_unlesses end |
Class Method Details
.each_check(check_name, include_ancestor = nil) ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/view_model/access_control/composed.rb', line 146 def each_check(check_name, include_ancestor = nil) return enum_for(:each_check, check_name, include_ancestor) unless block_given? self.public_send(check_name).each { |x| yield x } visited = Set.new @included_checkers.each do |ancestor| next unless visited.add?(ancestor) next if include_ancestor && !include_ancestor.call(ancestor) ancestor.each_check(check_name) { |x| yield x } end end |
.edit_valid_if!(reason, &block) ⇒ Object
132 133 134 |
# File 'lib/view_model/access_control/composed.rb', line 132 def edit_valid_if!(reason, &block) @edit_valid_ifs << (reason, &block) end |
.edit_valid_unless!(reason, &block) ⇒ Object
136 137 138 |
# File 'lib/view_model/access_control/composed.rb', line 136 def edit_valid_unless!(reason, &block) @edit_valid_unlesses << (reason, &block) end |
.editable_if!(reason, &block) ⇒ Object
124 125 126 |
# File 'lib/view_model/access_control/composed.rb', line 124 def editable_if!(reason, &block) @editable_ifs << (reason, &block) end |
.editable_unless!(reason, &block) ⇒ Object
128 129 130 |
# File 'lib/view_model/access_control/composed.rb', line 128 def editable_unless!(reason, &block) @editable_unlesses << (reason, &block) end |
.include_from(ancestor) ⇒ Object
Configuration API
108 109 110 111 112 113 114 |
# File 'lib/view_model/access_control/composed.rb', line 108 def include_from(ancestor) unless ancestor < ViewModel::AccessControl::Composed raise ArgumentError.new("Invalid ancestor: #{ancestor}") end @included_checkers << ancestor end |
.inherited(subclass) ⇒ Object
89 90 91 92 |
# File 'lib/view_model/access_control/composed.rb', line 89 def inherited(subclass) super subclass.initialize_as_composed_access_control end |
.initialize_as_composed_access_control ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/view_model/access_control/composed.rb', line 94 def initialize_as_composed_access_control @included_checkers = [] @edit_valid_ifs = [] @edit_valid_unlesses = [] @editable_ifs = [] @editable_unlesses = [] @visible_ifs = [] @visible_unlesses = [] end |
.inspect ⇒ Object
159 160 161 162 163 164 165 |
# File 'lib/view_model/access_control/composed.rb', line 159 def inspect s = super + "(" s += inspect_checks.join(", ") s += " includes checkers: #{@included_checkers.inspect}" if @included_checkers.present? s += ")" s end |
.inspect_checks ⇒ Object
167 168 169 170 171 172 173 174 175 176 |
# File 'lib/view_model/access_control/composed.rb', line 167 def inspect_checks checks = [] checks << "visible_if: #{@visible_ifs.map(&:reason)}" if @visible_ifs.present? checks << "visible_unless: #{@visible_unlesses.map(&:reason)}" if @visible_unlesses.present? checks << "editable_if: #{@editable_ifs.map(&:reason)}" if @editable_ifs.present? checks << "editable_unless: #{@editable_unlesses.map(&:reason)}" if @editable_unlesses.present? checks << "edit_valid_if: #{@edit_valid_ifs.map(&:reason)}" if @edit_valid_ifs.present? checks << "edit_valid_unless: #{@edit_valid_unlesses.map(&:reason)}" if @edit_valid_unlesses.present? checks end |
.new_permission_check(reason, error_type: ViewModel::AccessControlError, &block) ⇒ Object
Implementation
142 143 144 |
# File 'lib/view_model/access_control/composed.rb', line 142 def (reason, error_type: ViewModel::AccessControlError, &block) PermissionsCheck.new(self.name&.demodulize, reason, error_type, block) end |
.visible_if!(reason, &block) ⇒ Object
116 117 118 |
# File 'lib/view_model/access_control/composed.rb', line 116 def visible_if!(reason, &block) @visible_ifs << (reason, &block) end |
.visible_unless!(reason, &block) ⇒ Object
120 121 122 |
# File 'lib/view_model/access_control/composed.rb', line 120 def visible_unless!(reason, &block) @visible_unlesses << (reason, &block) end |
Instance Method Details
#editable_check(traversal_env) ⇒ Object
final
186 187 188 |
# File 'lib/view_model/access_control/composed.rb', line 186 def editable_check(traversal_env) check_delegates(traversal_env, self.class.each_check(:editable_ifs), self.class.each_check(:editable_unlesses)) end |
#valid_edit_check(traversal_env) ⇒ Object
final
191 192 193 |
# File 'lib/view_model/access_control/composed.rb', line 191 def valid_edit_check(traversal_env) check_delegates(traversal_env, self.class.each_check(:edit_valid_ifs), self.class.each_check(:edit_valid_unlesses)) end |
#visible_check(traversal_env) ⇒ Object
final
181 182 183 |
# File 'lib/view_model/access_control/composed.rb', line 181 def visible_check(traversal_env) check_delegates(traversal_env, self.class.each_check(:visible_ifs), self.class.each_check(:visible_unlesses)) end |