Class: CurrentScope::PermissionCatalog
- Inherits:
-
Object
- Object
- CurrentScope::PermissionCatalog
- Defined in:
- lib/current_scope/permission_catalog.rb
Overview
Derives the permission set from the host's routes: one permission per controller#action pair. There is no table to maintain — add a controller and its actions appear in the grid on next boot/reload.
Instance Method Summary collapse
-
#bypass_action ⇒ Object
The ONE parse of config.sod_bypass_permission's action segment — the grid view and the ungated task read it here rather than re-splitting the string themselves (a looser split("#").last silently turns a malformed "reports#" into "reports" and mislabels the break-glass cell; #79 review).
-
#grouped ⇒ Object
{ "reports" => ["approve", "create", ...], ... } for the role-editor grid.
-
#include?(key) ⇒ Boolean
Hot: the Guard asks this on EVERY gated request, and a role save asks it once per staged key.
- #keys ⇒ Object
-
#routed?(key) ⇒ Boolean
Is this key derived from a real route (as opposed to the injected break-glass key)? The distinction matters to anything making an inertness claim: a ROUTED action named like the bypass permission is an ordinary action and gets no exemption, while the injected key is live on any row.
Instance Method Details
#bypass_action ⇒ Object
The ONE parse of config.sod_bypass_permission's action segment — the grid view and the ungated task read it here rather than re-splitting the string themselves (a looser split("#").last silently turns a malformed "reports#" into "reports" and mislabels the break-glass cell; #79 review).
split("#", -1) keeps the trailing empty field, so a malformed "reports#"
yields "" and is caught here rather than silently becoming "reports" and
injecting "reports#reports". Blank raises instead of skipping: the host
turned break-glass ON, so a permission nobody can hold means the veto can
never be lifted and the feature is inert — an undiagnosable deny, which is
exactly what this engine promises not to do. (A boot-time check for this
config belongs with #40.)
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/current_scope/permission_catalog.rb', line 42 def bypass_action segments = CurrentScope.config..to_s.split("#", -1) # Exactly a bare action or one controller#action. More hashes would pass # a last-segment check while the resolver reads the ORIGINAL full string — # the catalog would inject a key nobody can be granted under, and the # veto could never be lifted. (#79 review) if segments.empty? || segments.size > 2 || segments.any?(&:blank?) raise ConfigurationError, "config.allow_sod_bypass is on, but config.sod_bypass_permission " \ "(#{CurrentScope.config..inspect}) is not a bare action or a " \ "single controller#action. Name the permission the record's initiator must hold " \ "to break glass (the default is \"bypass_sod\"), or set config.allow_sod_bypass = false." end segments.last end |
#grouped ⇒ Object
{ "reports" => ["approve", "create", ...], ... } for the role-editor grid.
16 17 18 19 |
# File 'lib/current_scope/permission_catalog.rb', line 16 def grouped keys.group_by { |key| key.split("#").first } .transform_values { |ks| ks.map { |k| k.split("#").last } } end |
#include?(key) ⇒ Boolean
Hot: the Guard asks this on EVERY gated request, and a role save asks it
once per staged key. Set lookup, not Array#include? — the array is sorted
for display, and scanning it linearly made every request pay for the size
of the host's route table. Memoized alongside keys and dropped with it
on reset!.
26 27 28 |
# File 'lib/current_scope/permission_catalog.rb', line 26 def include?(key) key_set.include?(key) end |
#keys ⇒ Object
11 12 13 |
# File 'lib/current_scope/permission_catalog.rb', line 11 def keys @keys ||= derive end |
#routed?(key) ⇒ Boolean
Is this key derived from a real route (as opposed to the injected break-glass key)? The distinction matters to anything making an inertness claim: a ROUTED action named like the bypass permission is an ordinary action and gets no exemption, while the injected key is live on any row. (#79 review)
64 65 66 67 |
# File 'lib/current_scope/permission_catalog.rb', line 64 def routed?(key) keys # derive memoizes @routed_key_set as a side effect @routed_key_set.include?(key) end |