super_auth 0.3.3 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +78 -0
  3. data/Gemfile +5 -0
  4. data/Gemfile.lock +8 -1
  5. data/README.md +286 -22
  6. data/USAGE.md +41 -16
  7. data/config/routes.rb +9 -71
  8. data/db/migrate/10_add_super_auth_label_to_resources.rb +13 -0
  9. data/db/migrate/1_users.rb +1 -1
  10. data/db/migrate/5_resources.rb +1 -1
  11. data/db/migrate/7_authorization.rb +2 -2
  12. data/db/migrate/8_add_indexes_to_edges.rb +7 -0
  13. data/db/migrate_activerecord/20250101000001_create_super_auth_users.rb +1 -1
  14. data/db/migrate_activerecord/20250101000005_create_super_auth_resources.rb +1 -1
  15. data/db/migrate_activerecord/20250101000007_create_super_auth_authorizations.rb +2 -2
  16. data/db/migrate_activerecord/20250101000010_add_super_auth_label_to_super_auth_resources.rb +5 -0
  17. data/exe/super_auth-editor +9 -0
  18. data/lib/generators/super_auth/install/templates/README +15 -10
  19. data/lib/generators/super_auth/install/templates/super_auth.rb +16 -5
  20. data/lib/generators/super_auth/rls/rls_generator.rb +22 -0
  21. data/lib/generators/super_auth/rls/templates/migration.rb.erb +15 -0
  22. data/lib/super_auth/active_record/by_current_user.rb +25 -5
  23. data/lib/super_auth/active_record/resource.rb +41 -0
  24. data/lib/super_auth/active_record/user.rb +3 -1
  25. data/lib/super_auth/authorization.rb +12 -0
  26. data/lib/super_auth/edge.rb +65 -100
  27. data/lib/super_auth/editor/cli.rb +91 -0
  28. data/lib/super_auth/editor/index.html +423 -0
  29. data/lib/super_auth/editor/seed.rb +170 -0
  30. data/lib/super_auth/editor.rb +273 -0
  31. data/lib/super_auth/nestable.rb +41 -3
  32. data/lib/super_auth/railtie.rb +0 -2
  33. data/lib/super_auth/rls.rb +256 -0
  34. data/lib/super_auth/user.rb +3 -1
  35. data/lib/super_auth/version.rb +1 -1
  36. data/lib/super_auth.rb +85 -0
  37. data/lib/tasks/super_auth_tasks.rake +28 -0
  38. metadata +15 -9
  39. data/VISUALIZATION.md +0 -58
  40. data/app/controllers/super_auth/graph_controller.rb +0 -654
  41. data/app/views/super_auth/graph/index.html.erb +0 -1408
  42. data/super_auth.gemspec +0 -35
  43. data/visualization.html +0 -747
@@ -1,654 +0,0 @@
1
- module SuperAuth
2
- class GraphController < ActionController::Base
3
- protect_from_forgery with: :null_session
4
-
5
- before_action :initialize_super_auth
6
-
7
- def index
8
- # Render the interactive graph visualization view
9
- end
10
-
11
- def data
12
- # Check if filters are applied
13
- has_filters = params[:user_id].present? || params[:resource_id].present?
14
-
15
- if has_filters
16
- # Apply filters
17
- edges = edge_class.all
18
- edges = edges.where(user_id: params[:user_id]) if params[:user_id].present?
19
- edges = edges.where(resource_id: params[:resource_id]) if params[:resource_id].present?
20
-
21
- # Get IDs of entities connected by filtered edges
22
- user_ids = edges.map(&:user_id).compact.uniq
23
- group_ids = edges.map(&:group_id).compact.uniq
24
- role_ids = edges.map(&:role_id).compact.uniq
25
- permission_ids = edges.map(&:permission_id).compact.uniq
26
- resource_ids = edges.map(&:resource_id).compact.uniq
27
-
28
- # Include parent groups and roles for hierarchy visualization
29
- groups = group_class.where(id: group_ids)
30
- groups.each do |group|
31
- current = group
32
- while current.parent_id
33
- parent = group_class.find_by(id: current.parent_id)
34
- break unless parent
35
- group_ids << parent.id unless group_ids.include?(parent.id)
36
- current = parent
37
- end
38
- end
39
-
40
- roles = role_class.where(id: role_ids)
41
- roles.each do |role|
42
- current = role
43
- while current.parent_id
44
- parent = role_class.find_by(id: current.parent_id)
45
- break unless parent
46
- role_ids << parent.id unless role_ids.include?(role.id)
47
- current = parent
48
- end
49
- end
50
-
51
- render json: {
52
- all_users: user_class.all.map { |u| { id: u.id, name: u.name } },
53
- all_resources: resource_class.all.map { |r| { id: r.id, name: r.name } },
54
- users: user_class.where(id: user_ids).map { |u| { id: u.id, name: u.name, type: 'user' } },
55
- groups: group_class.where(id: group_ids).map { |g| { id: g.id, name: g.name, parent_id: g.parent_id, type: 'group' } },
56
- roles: role_class.where(id: role_ids).map { |r| { id: r.id, name: r.name, parent_id: r.parent_id, type: 'role' } },
57
- permissions: permission_class.where(id: permission_ids).map { |p| { id: p.id, name: p.name, type: 'permission' } },
58
- resources: resource_class.where(id: resource_ids).map { |r| { id: r.id, name: r.name, type: 'resource' } },
59
- edges: edges.map { |e| {
60
- id: e.id,
61
- user_id: e.user_id,
62
- group_id: e.group_id,
63
- role_id: e.role_id,
64
- permission_id: e.permission_id,
65
- resource_id: e.resource_id
66
- }}
67
- }
68
- else
69
- # No filters - return all entities
70
- render json: {
71
- all_users: user_class.all.map { |u| { id: u.id, name: u.name } },
72
- all_resources: resource_class.all.map { |r| { id: r.id, name: r.name } },
73
- users: user_class.all.map { |u| { id: u.id, name: u.name, type: 'user' } },
74
- groups: group_class.all.map { |g| { id: g.id, name: g.name, parent_id: g.parent_id, type: 'group' } },
75
- roles: role_class.all.map { |r| { id: r.id, name: r.name, parent_id: r.parent_id, type: 'role' } },
76
- permissions: permission_class.all.map { |p| { id: p.id, name: p.name, type: 'permission' } },
77
- resources: resource_class.all.map { |r| { id: r.id, name: r.name, type: 'resource' } },
78
- edges: edge_class.all.map { |e| {
79
- id: e.id,
80
- user_id: e.user_id,
81
- group_id: e.group_id,
82
- role_id: e.role_id,
83
- permission_id: e.permission_id,
84
- resource_id: e.resource_id
85
- }}
86
- }
87
- end
88
- end
89
-
90
- def create_user
91
- user = user_class.create!(user_params)
92
- render json: { success: true, user: { id: user.id, name: user.name, type: 'user' } }
93
- rescue => e
94
- render json: { success: false, error: e.message }, status: 422
95
- end
96
-
97
- def delete_user
98
- user_class.find(params[:id]).destroy!
99
- render json: { success: true }
100
- rescue => e
101
- render json: { success: false, error: e.message }, status: 422
102
- end
103
-
104
- def create_group
105
- group = group_class.create!(group_params)
106
- render json: { success: true, group: { id: group.id, name: group.name, parent_id: group.parent_id, type: 'group' } }
107
- rescue => e
108
- render json: { success: false, error: e.message }, status: 422
109
- end
110
-
111
- def delete_group
112
- group_class.find(params[:id]).destroy!
113
- render json: { success: true }
114
- rescue => e
115
- render json: { success: false, error: e.message }, status: 422
116
- end
117
-
118
- def create_role
119
- role = role_class.create!(role_params)
120
- render json: { success: true, role: { id: role.id, name: role.name, parent_id: role.parent_id, type: 'role' } }
121
- rescue => e
122
- render json: { success: false, error: e.message }, status: 422
123
- end
124
-
125
- def delete_role
126
- role_class.find(params[:id]).destroy!
127
- render json: { success: true }
128
- rescue => e
129
- render json: { success: false, error: e.message }, status: 422
130
- end
131
-
132
- def create_permission
133
- permission = permission_class.create!(permission_params)
134
- render json: { success: true, permission: { id: permission.id, name: permission.name, type: 'permission' } }
135
- rescue => e
136
- render json: { success: false, error: e.message }, status: 422
137
- end
138
-
139
- def delete_permission
140
- permission_class.find(params[:id]).destroy!
141
- render json: { success: true }
142
- rescue => e
143
- render json: { success: false, error: e.message }, status: 422
144
- end
145
-
146
- def create_resource
147
- resource = resource_class.create!(resource_params)
148
- render json: { success: true, resource: { id: resource.id, name: resource.name, type: 'resource' } }
149
- rescue => e
150
- render json: { success: false, error: e.message }, status: 422
151
- end
152
-
153
- def delete_resource
154
- resource_class.find(params[:id]).destroy!
155
- render json: { success: true }
156
- rescue => e
157
- render json: { success: false, error: e.message }, status: 422
158
- end
159
-
160
- def create_edge
161
- edge = edge_class.create!(edge_params)
162
- render json: {
163
- success: true,
164
- edge: {
165
- id: edge.id,
166
- user_id: edge.user_id,
167
- group_id: edge.group_id,
168
- role_id: edge.role_id,
169
- permission_id: edge.permission_id,
170
- resource_id: edge.resource_id
171
- }
172
- }
173
- rescue => e
174
- render json: { success: false, error: e.message }, status: 422
175
- end
176
-
177
- def delete_edge
178
- edge_class.find(params[:id]).destroy!
179
- render json: { success: true }
180
- rescue => e
181
- render json: { success: false, error: e.message }, status: 422
182
- end
183
-
184
- def compile_authorizations
185
- begin
186
- count = authorization_class.compile!
187
-
188
- render json: {
189
- success: true,
190
- message: "Compiled #{count} authorization paths",
191
- count: count
192
- }
193
- rescue => e
194
- render json: { success: false, error: e.message }, status: 422
195
- end
196
- end
197
-
198
- def orphaned
199
- # Find orphaned records that aren't part of any complete authorization path
200
- orphans = {
201
- users: [],
202
- groups: [],
203
- roles: [],
204
- permissions: [],
205
- resources: []
206
- }
207
-
208
- # Get all edges
209
- edges = edge_class.all
210
-
211
- # Check each user - can they reach any resource?
212
- user_class.find_each do |user|
213
- can_reach_resource = can_reach_any_resource?(user.id, edges)
214
- orphans[:users] << { id: user.id, name: user.name, reason: 'Cannot reach any resource' } unless can_reach_resource
215
- end
216
-
217
- # Check each resource - can any user reach it?
218
- resource_class.find_each do |resource|
219
- can_be_reached = can_resource_be_reached?(resource.id, edges)
220
- orphans[:resources] << { id: resource.id, name: resource.name, reason: 'Cannot be reached by any user' } unless can_be_reached
221
- end
222
-
223
- # Check groups - are they part of any user-to-resource path?
224
- group_class.find_each do |group|
225
- has_user_connection = edges.any? { |e| e.user_id && e.group_id == group.id }
226
- has_downstream = edges.any? { |e| e.group_id == group.id && (e.role_id || e.permission_id || e.resource_id) }
227
-
228
- unless has_user_connection && has_downstream
229
- reason = if !has_user_connection
230
- 'Not connected to any user'
231
- elsif !has_downstream
232
- 'Not connected downstream'
233
- end
234
- orphans[:groups] << { id: group.id, name: group.name, reason: reason }
235
- end
236
- end
237
-
238
- # Check roles
239
- role_class.find_each do |role|
240
- has_upstream = edges.any? { |e| (e.user_id || e.group_id) && e.role_id == role.id }
241
- has_downstream = edges.any? { |e| e.role_id == role.id && (e.permission_id || e.resource_id) }
242
-
243
- unless has_upstream && has_downstream
244
- reason = if !has_upstream
245
- 'Not connected to any user or group'
246
- elsif !has_downstream
247
- 'Not connected downstream'
248
- end
249
- orphans[:roles] << { id: role.id, name: role.name, reason: reason }
250
- end
251
- end
252
-
253
- # Check permissions
254
- permission_class.find_each do |permission|
255
- has_upstream = edges.any? { |e| (e.user_id || e.group_id || e.role_id) && e.permission_id == permission.id }
256
- has_downstream = edges.any? { |e| e.permission_id == permission.id && e.resource_id }
257
-
258
- unless has_upstream && has_downstream
259
- reason = if !has_upstream
260
- 'Not connected to any user/group/role'
261
- elsif !has_downstream
262
- 'Not connected to any resource'
263
- end
264
- orphans[:permissions] << { id: permission.id, name: permission.name, reason: reason }
265
- end
266
- end
267
-
268
- render json: { orphans: orphans }
269
- end
270
-
271
- def authorize
272
- user_id = params[:user_id]
273
- resource_id = params[:resource_id]
274
-
275
- if user_id.blank? || resource_id.blank?
276
- render json: { error: 'user_id and resource_id are required' }, status: :bad_request
277
- return
278
- end
279
-
280
- paths = find_authorization_paths(user_id.to_i, resource_id.to_i)
281
-
282
- render json: {
283
- authorized: paths.any?,
284
- paths: paths,
285
- count: paths.length
286
- }
287
- end
288
-
289
- def visualization
290
- html_path = File.join(SuperAuth::Engine.root, 'visualization.html')
291
- send_file html_path, type: 'text/html', disposition: 'inline'
292
- end
293
-
294
- private
295
-
296
- def initialize_super_auth
297
- # Ensure SuperAuth is loaded
298
- SuperAuth.load unless defined?(SuperAuth::User) || defined?(SuperAuth::ActiveRecord::User)
299
- end
300
-
301
- def nodes_data
302
- nodes = []
303
-
304
- # Users
305
- user_class.all.each do |user|
306
- nodes << {
307
- id: "u#{user.id}",
308
- label: user.name,
309
- type: 'user',
310
- database_id: user.id
311
- }
312
- end
313
-
314
- # Groups with hierarchy
315
- group_class.all.each do |group|
316
- nodes << {
317
- id: "g#{group.id}",
318
- label: group.name,
319
- type: 'group',
320
- parent: group.parent_id ? "g#{group.parent_id}" : nil,
321
- database_id: group.id
322
- }
323
- end
324
-
325
- # Roles with hierarchy
326
- role_class.all.each do |role|
327
- nodes << {
328
- id: "r#{role.id}",
329
- label: role.name,
330
- type: 'role',
331
- parent: role.parent_id ? "r#{role.parent_id}" : nil,
332
- database_id: role.id
333
- }
334
- end
335
-
336
- # Permissions
337
- permission_class.all.each do |permission|
338
- nodes << {
339
- id: "p#{permission.id}",
340
- label: permission.name,
341
- type: 'permission',
342
- database_id: permission.id
343
- }
344
- end
345
-
346
- # Resources
347
- resource_class.all.each do |resource|
348
- nodes << {
349
- id: "res#{resource.id}",
350
- label: resource.name,
351
- type: 'resource',
352
- database_id: resource.id
353
- }
354
- end
355
-
356
- nodes
357
- end
358
-
359
- def edges_data
360
- edges = []
361
-
362
- edge_class.all.each do |edge|
363
- # Create edge connections
364
- if edge.user_id && edge.group_id
365
- edges << { from: "u#{edge.user_id}", to: "g#{edge.group_id}", type: 'authorization' }
366
- end
367
-
368
- if edge.user_id && edge.role_id
369
- edges << { from: "u#{edge.user_id}", to: "r#{edge.role_id}", type: 'authorization' }
370
- end
371
-
372
- if edge.user_id && edge.permission_id
373
- edges << { from: "u#{edge.user_id}", to: "p#{edge.permission_id}", type: 'authorization' }
374
- end
375
-
376
- if edge.user_id && edge.resource_id
377
- edges << { from: "u#{edge.user_id}", to: "res#{edge.resource_id}", type: 'authorization' }
378
- end
379
-
380
- if edge.group_id && edge.role_id
381
- edges << { from: "g#{edge.group_id}", to: "r#{edge.role_id}", type: 'authorization' }
382
- end
383
-
384
- if edge.group_id && edge.permission_id
385
- edges << { from: "g#{edge.group_id}", to: "p#{edge.permission_id}", type: 'authorization' }
386
- end
387
-
388
- if edge.role_id && edge.permission_id
389
- edges << { from: "r#{edge.role_id}", to: "p#{edge.permission_id}", type: 'authorization' }
390
- end
391
-
392
- if edge.permission_id && edge.resource_id
393
- edges << { from: "p#{edge.permission_id}", to: "res#{edge.resource_id}", type: 'authorization' }
394
- end
395
- end
396
-
397
- # Add hierarchy edges for groups
398
- group_class.where.not(parent_id: nil).each do |group|
399
- edges << { from: "g#{group.id}", to: "g#{group.parent_id}", type: 'hierarchy' }
400
- end
401
-
402
- # Add hierarchy edges for roles
403
- role_class.where.not(parent_id: nil).each do |role|
404
- edges << { from: "r#{role.id}", to: "r#{role.parent_id}", type: 'hierarchy' }
405
- end
406
-
407
- edges.uniq
408
- end
409
-
410
- def stats_data
411
- {
412
- users: user_class.count,
413
- groups: group_class.count,
414
- roles: role_class.count,
415
- permissions: permission_class.count,
416
- resources: resource_class.count,
417
- edges: edge_class.count
418
- }
419
- end
420
-
421
- def find_authorization_paths(user_id, resource_id)
422
- user_node = "u#{user_id}"
423
- resource_node = "res#{resource_id}"
424
-
425
- # Build adjacency list
426
- adjacency = build_adjacency_list
427
-
428
- # BFS to find all paths
429
- paths = []
430
- queue = [[user_node]]
431
- visited_paths = Set.new
432
-
433
- while queue.any? && paths.length < 100 # Limit to prevent infinite loops
434
- path = queue.shift
435
- current = path.last
436
-
437
- # Skip if we've seen this exact path before
438
- path_key = path.join(',')
439
- next if visited_paths.include?(path_key)
440
- visited_paths.add(path_key)
441
-
442
- # Found a complete path
443
- if current == resource_node
444
- paths << path_with_labels(path)
445
- next
446
- end
447
-
448
- # Prevent too-long paths
449
- next if path.length > 10
450
-
451
- # Explore neighbors
452
- neighbors = adjacency[current] || []
453
- neighbors.each do |neighbor|
454
- next if path.include?(neighbor) # Avoid cycles
455
- queue << path + [neighbor]
456
- end
457
- end
458
-
459
- paths
460
- end
461
-
462
- def build_adjacency_list
463
- adjacency = Hash.new { |h, k| h[k] = [] }
464
-
465
- edges_data.each do |edge|
466
- # Make it bidirectional for path finding
467
- adjacency[edge[:from]] << edge[:to]
468
- adjacency[edge[:to]] << edge[:from]
469
- end
470
-
471
- adjacency
472
- end
473
-
474
- def path_with_labels(path)
475
- path.map do |node_id|
476
- node = nodes_data.find { |n| n[:id] == node_id }
477
- node ? node[:label] : node_id
478
- end
479
- end
480
-
481
- # Dynamic class detection for Sequel vs ActiveRecord
482
- def user_class
483
- if defined?(SuperAuth::ActiveRecord::User)
484
- SuperAuth::ActiveRecord::User
485
- else
486
- SuperAuth::User
487
- end
488
- end
489
-
490
- def group_class
491
- if defined?(SuperAuth::ActiveRecord::Group)
492
- SuperAuth::ActiveRecord::Group
493
- else
494
- SuperAuth::Group
495
- end
496
- end
497
-
498
- def role_class
499
- if defined?(SuperAuth::ActiveRecord::Role)
500
- SuperAuth::ActiveRecord::Role
501
- else
502
- SuperAuth::Role
503
- end
504
- end
505
-
506
- def permission_class
507
- if defined?(SuperAuth::ActiveRecord::Permission)
508
- SuperAuth::ActiveRecord::Permission
509
- else
510
- SuperAuth::Permission
511
- end
512
- end
513
-
514
- def resource_class
515
- if defined?(SuperAuth::ActiveRecord::Resource)
516
- SuperAuth::ActiveRecord::Resource
517
- else
518
- SuperAuth::Resource
519
- end
520
- end
521
-
522
- def edge_class
523
- if defined?(SuperAuth::ActiveRecord::Edge)
524
- SuperAuth::ActiveRecord::Edge
525
- else
526
- SuperAuth::Edge
527
- end
528
- end
529
-
530
- def authorization_class
531
- if defined?(SuperAuth::ActiveRecord::Authorization)
532
- SuperAuth::ActiveRecord::Authorization
533
- else
534
- SuperAuth::Authorization
535
- end
536
- end
537
-
538
- def can_reach_any_resource?(user_id, edges)
539
- # BFS to see if user can reach any resource through any path
540
- visited = Set.new
541
- queue = [{ type: 'user', id: user_id }]
542
-
543
- while queue.any?
544
- current = queue.shift
545
- key = "#{current[:type]}-#{current[:id]}"
546
- next if visited.include?(key)
547
- visited.add(key)
548
-
549
- return true if current[:type] == 'resource'
550
-
551
- case current[:type]
552
- when 'user'
553
- edges.each do |e|
554
- next unless e.user_id == current[:id]
555
- queue << { type: 'group', id: e.group_id } if e.group_id
556
- queue << { type: 'role', id: e.role_id } if e.role_id
557
- queue << { type: 'permission', id: e.permission_id } if e.permission_id
558
- queue << { type: 'resource', id: e.resource_id } if e.resource_id
559
- end
560
- when 'group'
561
- edges.each do |e|
562
- next unless e.group_id == current[:id]
563
- queue << { type: 'role', id: e.role_id } if e.role_id
564
- queue << { type: 'permission', id: e.permission_id } if e.permission_id
565
- queue << { type: 'resource', id: e.resource_id } if e.resource_id
566
- end
567
- when 'role'
568
- edges.each do |e|
569
- next unless e.role_id == current[:id]
570
- queue << { type: 'permission', id: e.permission_id } if e.permission_id
571
- queue << { type: 'resource', id: e.resource_id } if e.resource_id
572
- end
573
- when 'permission'
574
- edges.each do |e|
575
- next unless e.permission_id == current[:id]
576
- queue << { type: 'resource', id: e.resource_id } if e.resource_id
577
- end
578
- end
579
- end
580
-
581
- false
582
- end
583
-
584
- def can_resource_be_reached?(resource_id, edges)
585
- # BFS backwards to see if any user can reach this resource
586
- visited = Set.new
587
- queue = [{ type: 'resource', id: resource_id }]
588
-
589
- while queue.any?
590
- current = queue.shift
591
- key = "#{current[:type]}-#{current[:id]}"
592
- next if visited.include?(key)
593
- visited.add(key)
594
-
595
- return true if current[:type] == 'user'
596
-
597
- case current[:type]
598
- when 'resource'
599
- edges.each do |e|
600
- next unless e.resource_id == current[:id]
601
- queue << { type: 'user', id: e.user_id } if e.user_id
602
- queue << { type: 'group', id: e.group_id } if e.group_id
603
- queue << { type: 'role', id: e.role_id } if e.role_id
604
- queue << { type: 'permission', id: e.permission_id } if e.permission_id
605
- end
606
- when 'permission'
607
- edges.each do |e|
608
- next unless e.permission_id == current[:id]
609
- queue << { type: 'user', id: e.user_id } if e.user_id
610
- queue << { type: 'group', id: e.group_id } if e.group_id
611
- queue << { type: 'role', id: e.role_id } if e.role_id
612
- end
613
- when 'role'
614
- edges.each do |e|
615
- next unless e.role_id == current[:id]
616
- queue << { type: 'user', id: e.user_id } if e.user_id
617
- queue << { type: 'group', id: e.group_id } if e.group_id
618
- end
619
- when 'group'
620
- edges.each do |e|
621
- next unless e.group_id == current[:id]
622
- queue << { type: 'user', id: e.user_id } if e.user_id
623
- end
624
- end
625
- end
626
-
627
- false
628
- end
629
-
630
- def user_params
631
- params.require(:user).permit(:name, :external_id, :external_type)
632
- end
633
-
634
- def group_params
635
- params.require(:group).permit(:name, :parent_id)
636
- end
637
-
638
- def role_params
639
- params.require(:role).permit(:name, :parent_id)
640
- end
641
-
642
- def permission_params
643
- params.require(:permission).permit(:name)
644
- end
645
-
646
- def resource_params
647
- params.require(:resource).permit(:name, :external_id, :external_type)
648
- end
649
-
650
- def edge_params
651
- params.require(:edge).permit(:user_id, :group_id, :role_id, :permission_id, :resource_id)
652
- end
653
- end
654
- end