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.
83 84 85 |
# File 'lib/view_model/access_control/composed.rb', line 83 def edit_valid_ifs @edit_valid_ifs end |
.edit_valid_unlesses ⇒ Object (readonly)
Returns the value of attribute edit_valid_unlesses.
83 84 85 |
# File 'lib/view_model/access_control/composed.rb', line 83 def edit_valid_unlesses @edit_valid_unlesses end |
.editable_ifs ⇒ Object (readonly)
Returns the value of attribute editable_ifs.
83 84 85 |
# File 'lib/view_model/access_control/composed.rb', line 83 def editable_ifs @editable_ifs end |
.editable_unlesses ⇒ Object (readonly)
Returns the value of attribute editable_unlesses.
83 84 85 |
# File 'lib/view_model/access_control/composed.rb', line 83 def editable_unlesses @editable_unlesses end |
.visible_ifs ⇒ Object (readonly)
Returns the value of attribute visible_ifs.
83 84 85 |
# File 'lib/view_model/access_control/composed.rb', line 83 def visible_ifs @visible_ifs end |
.visible_unlesses ⇒ Object (readonly)
Returns the value of attribute visible_unlesses.
83 84 85 |
# File 'lib/view_model/access_control/composed.rb', line 83 def visible_unlesses @visible_unlesses end |
Class Method Details
.each_check(check_name, include_ancestor = nil) ⇒ Object
147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/view_model/access_control/composed.rb', line 147 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
133 134 135 |
# File 'lib/view_model/access_control/composed.rb', line 133 def edit_valid_if!(reason, &block) @edit_valid_ifs << (reason, &block) end |
.edit_valid_unless!(reason, &block) ⇒ Object
137 138 139 |
# File 'lib/view_model/access_control/composed.rb', line 137 def edit_valid_unless!(reason, &block) @edit_valid_unlesses << (reason, &block) end |
.editable_if!(reason, &block) ⇒ Object
125 126 127 |
# File 'lib/view_model/access_control/composed.rb', line 125 def editable_if!(reason, &block) @editable_ifs << (reason, &block) end |
.editable_unless!(reason, &block) ⇒ Object
129 130 131 |
# File 'lib/view_model/access_control/composed.rb', line 129 def editable_unless!(reason, &block) @editable_unlesses << (reason, &block) end |
.include_from(ancestor) ⇒ Object
Configuration API
109 110 111 112 113 114 115 |
# File 'lib/view_model/access_control/composed.rb', line 109 def include_from(ancestor) unless ancestor < ViewModel::AccessControl::Composed raise ArgumentError.new("Invalid ancestor: #{ancestor}") end @included_checkers << ancestor end |
.inherited(subclass) ⇒ Object
90 91 92 93 |
# File 'lib/view_model/access_control/composed.rb', line 90 def inherited(subclass) super subclass.initialize_as_composed_access_control end |
.initialize_as_composed_access_control ⇒ Object
95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/view_model/access_control/composed.rb', line 95 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
161 162 163 164 165 166 167 |
# File 'lib/view_model/access_control/composed.rb', line 161 def inspect s = super + '(' s += inspect_checks.join(', ') s += " includes checkers: #{@included_checkers.inspect}" if @included_checkers.present? s += ')' s end |
.inspect_checks ⇒ Object
169 170 171 172 173 174 175 176 177 178 |
# File 'lib/view_model/access_control/composed.rb', line 169 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
143 144 145 |
# File 'lib/view_model/access_control/composed.rb', line 143 def (reason, error_type: ViewModel::AccessControlError, &block) PermissionsCheck.new(self.name&.demodulize, reason, error_type, block) end |
.visible_if!(reason, &block) ⇒ Object
117 118 119 |
# File 'lib/view_model/access_control/composed.rb', line 117 def visible_if!(reason, &block) @visible_ifs << (reason, &block) end |
.visible_unless!(reason, &block) ⇒ Object
121 122 123 |
# File 'lib/view_model/access_control/composed.rb', line 121 def visible_unless!(reason, &block) @visible_unlesses << (reason, &block) end |
Instance Method Details
#editable_check(traversal_env) ⇒ Object
final
187 188 189 |
# File 'lib/view_model/access_control/composed.rb', line 187 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
192 193 194 |
# File 'lib/view_model/access_control/composed.rb', line 192 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
182 183 184 |
# File 'lib/view_model/access_control/composed.rb', line 182 def visible_check(traversal_env) check_delegates(traversal_env, self.class.each_check(:visible_ifs), self.class.each_check(:visible_unlesses)) end |