Class: Seams::Generators::PermissionsGenerator

Inherits:
Rails::Generators::Base
  • Object
show all
Includes:
EjectAware, HostInjector
Defined in:
lib/generators/seams/permissions/permissions_generator.rb

Overview

Writes ONE host-editable initializer that spells out the default role -> ability grant map and assigns it through Seams.configure { |c| c.permission_grants = {...} }.

This is the deferred-friendly seam of the permissions layer (Wave 11B / issue #37): there is no database table and no YAML DSL — a host changes who-can-do-what by editing this one Ruby file. The generated map is a readable copy of Seams::Permissions::DEFAULT_GRANTS rendered at generate time, so the host starts from the same defaults the gem ships and edits from there.

The catalog of ability CODES is engine-owned: each engine registers the resource.action.engine codes it understands from its engine.rb (mirroring the event bus). This file only decides which ROLES hold which already-registered codes. Referencing a code no engine has registered makes Seams::Permissions.can? raise — deny-by-default, loudly.

Run with: bin/seams permissions (or bin/rails generate seams:permissions)

Constant Summary collapse

INITIALIZER_RELATIVE =
"config/initializers/seams_permissions.rb"

Constants included from EjectAware

EjectAware::EJECT_HEADER_PREFIX

Instance Method Summary collapse

Methods included from EjectAware

#ejected?, #template_unless_ejected

Methods included from HostInjector

#host_inject_gem, #host_inject_include_in_application_controller, #host_inject_include_in_user, #host_inject_mount, #host_uninject_gem, #host_uninject_include, #host_uninject_mount, #routes_draw_anchor

Instance Method Details

#create_initializer ⇒ Object

The single deliverable: the host-editable grant map. Eject-aware so a host that has stamped the eject header (to fully own the file and never be prompted again) keeps their version on a re-run.



41
42
43
44
# File 'lib/generators/seams/permissions/permissions_generator.rb', line 41

def create_initializer
  template_unless_ejected "config/initializers/seams_permissions.rb.tt",
                          host_path(INITIALIZER_RELATIVE)
end

#report_summary ⇒ Object



46
47
48
# File 'lib/generators/seams/permissions/permissions_generator.rb', line 46

def report_summary
  say report_summary_text, :green
end

#report_summary_text ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/generators/seams/permissions/permissions_generator.rb', line 50

def report_summary_text
  <<~TXT

    Permissions grant map generated at #{INITIALIZER_RELATIVE}

    Next steps:
      1. Edit the role -> ability map in
           #{INITIALIZER_RELATIVE}
         Each role lists the registered ability codes it holds. Roles
         inherit downward (owner inherits admin inherits member), so a
         code only needs to appear at the lowest role that should hold it.

      2. List the ability codes every installed engine registers:
           bin/rails runner 'pp Seams::PermissionRegistry.all'
         You can only grant codes that appear there — `can?` raises on
         an unregistered code (deny-by-default, loudly).

      3. Guard a controller action with a code:
           before_action -> { authorize_permission!("invoice.read.billing") }

    To fully own this file (skip it on future generator runs):
      bin/seams resolve --eject (or add the `# seams:ejected from` header).

    See doc/reference/PERMISSIONS.md for the model, the role hierarchy, the bypass
    tiers, and what is deliberately deferred (YAML DSL, DB custom roles,
    per-ability grants).

  TXT
end