Module: SuperAuth::Editor::Seed
- Defined in:
- lib/super_auth/editor/seed.rb
Overview
Sample graph for the editor. "Acme Cloud": three departments that are deliberately DISJOINT. Engineering, Finance, and Support each have their own users, roles, permissions, and resources with no shared nodes, so traversal is obvious: click anyone in Engineering and only Engineering lights up.
The hierarchy matches how grants inherit:
- The shared "Developer" role is attached to the Engineering PARENT
group, so every engineer (Backend + Frontend) inherits it, while
Backend and Frontend each also hold a child-group grant the other
does not.
- "Support Lead" is the PARENT role of "Support Agent": a lead inherits
the agent's abilities plus refunds; an agent does not get refunds.
- "clusters" is a CONTAINER resource holding production_cluster and
staging_cluster. deploy is granted on the container and reaches both
clusters through the tree; restart_server and Morgan's direct grant
name production_cluster alone, so the tree shows a container grant
and a leaf grant side by side.
Special people:
- Riley (Auditor): read-only into BOTH Finance and Support
- Morgan (Admin): direct user->resource access across departments
- Nina (New Hire): no access at all
Destructive: run! replaces the whole graph, including the compiled authorizations. Only ever runs on request (super_auth-editor --seed).
Class Method Summary collapse
-
.clear! ⇒ Object
Empties the graph and the compiled table.
- .counts ⇒ Object
-
.run! ⇒ Object
Returns the row counts per table.
Class Method Details
.clear! ⇒ Object
Empties the graph and the compiled table. Parents are detached first: MySQL checks the self-referencing key row by row.
159 160 161 162 163 164 165 166 |
# File 'lib/super_auth/editor/seed.rb', line 159 def clear! SuperAuth::Edge.dataset.delete SuperAuth::Authorization.dataset.delete [SuperAuth::Group, SuperAuth::Role, SuperAuth::Resource].each { |m| m.dataset.update(parent_id: nil) } [SuperAuth::Group, SuperAuth::Role, SuperAuth::User, SuperAuth::Permission, SuperAuth::Resource].each do |m| m.dataset.delete end end |
.counts ⇒ Object
168 169 170 171 172 173 |
# File 'lib/super_auth/editor/seed.rb', line 168 def counts { groups: SuperAuth::Group.count, roles: SuperAuth::Role.count, users: SuperAuth::User.count, permissions: SuperAuth::Permission.count, resources: SuperAuth::Resource.count, edges: SuperAuth::Edge.count, } end |
.run! ⇒ Object
Returns the row counts per table.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/super_auth/editor/seed.rb', line 35 def run! SuperAuth.db.transaction do clear! grp = SuperAuth::Group rol = SuperAuth::Role usr = SuperAuth::User perm_m = SuperAuth::Permission res_m = SuperAuth::Resource edg = SuperAuth::Edge # ===== GROUPS (Engineering is a parent of Backend + Frontend) ===== engineering = grp.create(name: "Engineering") backend = grp.create(name: "Backend", parent_id: engineering.id) frontend = grp.create(name: "Frontend", parent_id: engineering.id) finance = grp.create(name: "Finance") support = grp.create(name: "Customer Support") # ===== ROLES (Support Lead is the parent of Support Agent) ===== developer = rol.create(name: "Developer") sre = rol.create(name: "SRE") accountant = rol.create(name: "Accountant") support_lead = rol.create(name: "Support Lead") support_agent = rol.create(name: "Support Agent", parent_id: support_lead.id) # ===== PERMISSIONS (disjoint per department) ===== merge_code = perm_m.create(name: "merge_code") read_repo = perm_m.create(name: "read_repo") deploy = perm_m.create(name: "deploy") run_migrations = perm_m.create(name: "run_migrations") # Backend-only publish_site = perm_m.create(name: "publish_site") # Frontend-only restart_server = perm_m.create(name: "restart_server") # SRE-only view_ledger = perm_m.create(name: "view_ledger") issue_invoice = perm_m.create(name: "issue_invoice") run_payroll = perm_m.create(name: "run_payroll") view_ticket = perm_m.create(name: "view_ticket") close_ticket = perm_m.create(name: "close_ticket") issue_refund = perm_m.create(name: "issue_refund") # Support Lead-only # ===== RESOURCES (disjoint per department) ===== source_repo = res_m.create(name: "source_repo") clusters = res_m.create(name: "clusters") # container production_cluster = res_m.create(name: "production_cluster", parent_id: clusters.id) res_m.create(name: "staging_cluster", parent_id: clusters.id) # reached only through clusters app_database = res_m.create(name: "app_database") # Backend marketing_site = res_m.create(name: "marketing_site") # Frontend general_ledger = res_m.create(name: "general_ledger") invoices = res_m.create(name: "invoices") support_tickets = res_m.create(name: "support_tickets") customer_accounts = res_m.create(name: "customer_accounts") # ===== USERS ===== alice = usr.create(name: "Alice") # Backend dev bob = usr.create(name: "Bob") # Frontend dev sam = usr.create(name: "Sam") # SRE carol = usr.create(name: "Carol") # Accountant dave = usr.create(name: "Dave") # Accountant erin = usr.create(name: "Erin") # Support agent frank = usr.create(name: "Frank") # Support lead riley = usr.create(name: "Riley") # Auditor (cross-department, read-only) morgan = usr.create(name: "Morgan") # Admin (direct resource access) usr.create(name: "Nina") # New hire, no access yet # ===== ENGINEERING ===== edg.create(user_id: alice.id, group_id: backend.id) edg.create(user_id: bob.id, group_id: frontend.id) # Shared Developer role on the PARENT group: both Alice and Bob inherit it edg.create(group_id: engineering.id, role_id: developer.id) edg.create(role_id: developer.id, permission_id: merge_code.id) edg.create(role_id: developer.id, permission_id: read_repo.id) edg.create(role_id: developer.id, permission_id: deploy.id) edg.create(permission_id: merge_code.id, resource_id: source_repo.id) edg.create(permission_id: read_repo.id, resource_id: source_repo.id) # One grant on the container reaches both clusters. edg.create(permission_id: deploy.id, resource_id: clusters.id) # Child-group-specific grants (Alice gets one, Bob the other) edg.create(group_id: backend.id, permission_id: run_migrations.id) edg.create(permission_id: run_migrations.id, resource_id: app_database.id) edg.create(group_id: frontend.id, permission_id: publish_site.id) edg.create(permission_id: publish_site.id, resource_id: marketing_site.id) # Sam is an SRE via a direct role assignment edg.create(user_id: sam.id, role_id: sre.id) edg.create(role_id: sre.id, permission_id: restart_server.id) edg.create(role_id: sre.id, permission_id: deploy.id) edg.create(permission_id: restart_server.id, resource_id: production_cluster.id) # ===== FINANCE ===== edg.create(user_id: carol.id, group_id: finance.id) edg.create(user_id: dave.id, group_id: finance.id) edg.create(group_id: finance.id, role_id: accountant.id) edg.create(role_id: accountant.id, permission_id: view_ledger.id) edg.create(role_id: accountant.id, permission_id: issue_invoice.id) edg.create(role_id: accountant.id, permission_id: run_payroll.id) edg.create(permission_id: view_ledger.id, resource_id: general_ledger.id) edg.create(permission_id: issue_invoice.id, resource_id: invoices.id) edg.create(permission_id: run_payroll.id, resource_id: general_ledger.id) # ===== SUPPORT (Lead inherits Agent's abilities via the role hierarchy) ===== edg.create(user_id: erin.id, group_id: support.id) edg.create(user_id: frank.id, group_id: support.id) edg.create(user_id: frank.id, role_id: support_lead.id) # Frank is a lead edg.create(group_id: support.id, role_id: support_agent.id) # everyone is at least an agent edg.create(role_id: support_agent.id, permission_id: view_ticket.id) edg.create(role_id: support_agent.id, permission_id: close_ticket.id) edg.create(role_id: support_lead.id, permission_id: issue_refund.id) edg.create(permission_id: view_ticket.id, resource_id: support_tickets.id) edg.create(permission_id: close_ticket.id, resource_id: support_tickets.id) edg.create(permission_id: issue_refund.id, resource_id: customer_accounts.id) # ===== CROSS-CUTTERS ===== # Riley audits both the ledger and tickets (direct permission grants). edg.create(user_id: riley.id, permission_id: view_ledger.id) edg.create(user_id: riley.id, permission_id: view_ticket.id) # Morgan has direct resource access across departments (simplest path). edg.create(user_id: morgan.id, resource_id: production_cluster.id) edg.create(user_id: morgan.id, resource_id: general_ledger.id) edg.create(user_id: morgan.id, resource_id: support_tickets.id) counts end end |