strongbolt 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +33 -0
  3. data/.gitignore +18 -0
  4. data/.rspec +1 -0
  5. data/.ruby-gemset +1 -0
  6. data/.ruby-version +1 -0
  7. data/Gemfile +4 -0
  8. data/Gemfile.lock +130 -0
  9. data/LICENSE.txt +22 -0
  10. data/README.md +182 -0
  11. data/Rakefile +1 -0
  12. data/app/assets/javascripts/strongbolt.js +1 -0
  13. data/app/assets/javascripts/strongbolt/role-capabilities.js +80 -0
  14. data/app/controllers/strongbolt/capabilities_controller.rb +77 -0
  15. data/app/controllers/strongbolt/roles_controller.rb +92 -0
  16. data/app/controllers/strongbolt/security_controller.rb +8 -0
  17. data/app/controllers/strongbolt/user_groups_controller.rb +76 -0
  18. data/app/controllers/strongbolt/user_groups_users_controller.rb +35 -0
  19. data/app/controllers/strongbolt_controller.rb +2 -0
  20. data/app/views/strongbolt/_menu.html.erb +13 -0
  21. data/app/views/strongbolt/capabilities/index.html.erb +53 -0
  22. data/app/views/strongbolt/capabilities/show.html.erb +53 -0
  23. data/app/views/strongbolt/roles/_capabilities.html.erb +47 -0
  24. data/app/views/strongbolt/roles/_capability.html.erb +21 -0
  25. data/app/views/strongbolt/roles/_form.html.erb +12 -0
  26. data/app/views/strongbolt/roles/edit.html.erb +14 -0
  27. data/app/views/strongbolt/roles/index.html.erb +54 -0
  28. data/app/views/strongbolt/roles/new.html.erb +11 -0
  29. data/app/views/strongbolt/roles/show.html.erb +52 -0
  30. data/app/views/strongbolt/user_groups/_form.html.erb +12 -0
  31. data/app/views/strongbolt/user_groups/edit.html.erb +14 -0
  32. data/app/views/strongbolt/user_groups/index.html.erb +46 -0
  33. data/app/views/strongbolt/user_groups/new.html.erb +13 -0
  34. data/app/views/strongbolt/user_groups/show.html.erb +88 -0
  35. data/lib/generators/strongbolt/fix_generator.rb +23 -0
  36. data/lib/generators/strongbolt/indexes_generator.rb +19 -0
  37. data/lib/generators/strongbolt/install_generator.rb +29 -0
  38. data/lib/generators/strongbolt/templates/fix.rb +5 -0
  39. data/lib/generators/strongbolt/templates/indexes.rb +21 -0
  40. data/lib/generators/strongbolt/templates/migration.rb +73 -0
  41. data/lib/generators/strongbolt/templates/strongbolt.rb +45 -0
  42. data/lib/generators/strongbolt/views_generator.rb +26 -0
  43. data/lib/strongbolt.rb +219 -0
  44. data/lib/strongbolt/base.rb +7 -0
  45. data/lib/strongbolt/bolted.rb +125 -0
  46. data/lib/strongbolt/bolted_controller.rb +297 -0
  47. data/lib/strongbolt/capabilities_role.rb +15 -0
  48. data/lib/strongbolt/capability.rb +165 -0
  49. data/lib/strongbolt/configuration.rb +111 -0
  50. data/lib/strongbolt/controllers/url_helpers.rb +37 -0
  51. data/lib/strongbolt/engine.rb +44 -0
  52. data/lib/strongbolt/errors.rb +38 -0
  53. data/lib/strongbolt/generators/migration.rb +35 -0
  54. data/lib/strongbolt/helpers.rb +18 -0
  55. data/lib/strongbolt/rails/routes.rb +20 -0
  56. data/lib/strongbolt/role.rb +46 -0
  57. data/lib/strongbolt/roles_user_group.rb +15 -0
  58. data/lib/strongbolt/rspec.rb +29 -0
  59. data/lib/strongbolt/rspec/user.rb +90 -0
  60. data/lib/strongbolt/tenantable.rb +304 -0
  61. data/lib/strongbolt/user_abilities.rb +292 -0
  62. data/lib/strongbolt/user_group.rb +24 -0
  63. data/lib/strongbolt/user_groups_user.rb +16 -0
  64. data/lib/strongbolt/users_tenant.rb +12 -0
  65. data/lib/strongbolt/version.rb +3 -0
  66. data/lib/tasks/strongbolt_tasks.rake +29 -0
  67. data/spec/controllers/strongbolt/capabilities_controller_spec.rb +254 -0
  68. data/spec/controllers/strongbolt/roles_controller_spec.rb +228 -0
  69. data/spec/controllers/strongbolt/user_groups_controller_spec.rb +216 -0
  70. data/spec/controllers/strongbolt/user_groups_users_controller_spec.rb +69 -0
  71. data/spec/controllers/without_authorization_controller_spec.rb +20 -0
  72. data/spec/dummy/.rspec +2 -0
  73. data/spec/dummy/README.rdoc +28 -0
  74. data/spec/dummy/Rakefile +6 -0
  75. data/spec/dummy/app/assets/images/.keep +0 -0
  76. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  77. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  78. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  79. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  80. data/spec/dummy/app/controllers/posts_controller.rb +18 -0
  81. data/spec/dummy/app/controllers/test_controller.rb +3 -0
  82. data/spec/dummy/app/controllers/without_authorization_controller.rb +5 -0
  83. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  84. data/spec/dummy/app/mailers/.keep +0 -0
  85. data/spec/dummy/app/models/.keep +0 -0
  86. data/spec/dummy/app/models/concerns/.keep +0 -0
  87. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  88. data/spec/dummy/bin/bundle +3 -0
  89. data/spec/dummy/bin/rails +4 -0
  90. data/spec/dummy/bin/rake +4 -0
  91. data/spec/dummy/config.ru +4 -0
  92. data/spec/dummy/config/application.rb +29 -0
  93. data/spec/dummy/config/boot.rb +5 -0
  94. data/spec/dummy/config/database.yml +25 -0
  95. data/spec/dummy/config/environment.rb +5 -0
  96. data/spec/dummy/config/environments/development.rb +37 -0
  97. data/spec/dummy/config/environments/production.rb +78 -0
  98. data/spec/dummy/config/environments/test.rb +39 -0
  99. data/spec/dummy/config/initializers/assets.rb +8 -0
  100. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  101. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  102. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  103. data/spec/dummy/config/initializers/inflections.rb +16 -0
  104. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  105. data/spec/dummy/config/initializers/session_store.rb +3 -0
  106. data/spec/dummy/config/initializers/strongbolt.rb +32 -0
  107. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  108. data/spec/dummy/config/locales/en.yml +23 -0
  109. data/spec/dummy/config/routes.rb +12 -0
  110. data/spec/dummy/config/secrets.yml +22 -0
  111. data/spec/dummy/db/development.sqlite3 +0 -0
  112. data/spec/dummy/db/migrate/20150630212236_create_strongbolt_tables.rb +54 -0
  113. data/spec/dummy/db/migrate/20150630212251_create_strongbolt_tables_indexes.rb +21 -0
  114. data/spec/dummy/db/schema.rb +84 -0
  115. data/spec/dummy/db/test.sqlite3 +0 -0
  116. data/spec/dummy/lib/assets/.keep +0 -0
  117. data/spec/dummy/public/404.html +67 -0
  118. data/spec/dummy/public/422.html +67 -0
  119. data/spec/dummy/public/500.html +66 -0
  120. data/spec/dummy/public/favicon.ico +0 -0
  121. data/spec/fabricators/capability_fabricator.rb +4 -0
  122. data/spec/fabricators/role_fabricator.rb +9 -0
  123. data/spec/fabricators/user_fabricator.rb +3 -0
  124. data/spec/fabricators/user_group_fabricator.rb +9 -0
  125. data/spec/fixtures/application.rb +28 -0
  126. data/spec/fixtures/controllers.rb +5 -0
  127. data/spec/spec_helper.rb +89 -0
  128. data/spec/strongbolt/bolted_controller_spec.rb +706 -0
  129. data/spec/strongbolt/bolted_spec.rb +136 -0
  130. data/spec/strongbolt/capability_spec.rb +251 -0
  131. data/spec/strongbolt/configuration_spec.rb +119 -0
  132. data/spec/strongbolt/controllers/url_helpers_spec.rb +34 -0
  133. data/spec/strongbolt/helpers_spec.rb +43 -0
  134. data/spec/strongbolt/role_spec.rb +90 -0
  135. data/spec/strongbolt/tenantable_spec.rb +281 -0
  136. data/spec/strongbolt/user_abilities_spec.rb +509 -0
  137. data/spec/strongbolt/user_group_spec.rb +37 -0
  138. data/spec/strongbolt/users_tenant_spec.rb +36 -0
  139. data/spec/strongbolt_spec.rb +274 -0
  140. data/spec/support/controller_macros.rb +11 -0
  141. data/spec/support/db_setup.rb +134 -0
  142. data/spec/support/helpers.rb +62 -0
  143. data/spec/support/transactional_specs.rb +17 -0
  144. data/strongbolt.gemspec +32 -0
  145. metadata +407 -0
@@ -0,0 +1,77 @@
1
+ module Strongbolt
2
+
3
+ class CapabilitiesController < ::StrongboltController
4
+
5
+ def index
6
+ @capabilities = Capability.all
7
+ end
8
+
9
+ def show
10
+ @capability = Capability.find params[:id]
11
+ end
12
+
13
+ def create
14
+ begin
15
+ @capability = Capability.where(capability_params).first_or_create
16
+
17
+ # If we have a role id, we add the capability to the role
18
+ if params[:role_id].present?
19
+ @role = Role.find params[:role_id]
20
+ @role.capabilities << @capability
21
+
22
+ respond_to do |format|
23
+ format.html { redirect_to role_path(@role) }
24
+ format.json { head :ok }
25
+ end
26
+ else
27
+ redirect_to capabilities_path
28
+ end
29
+ rescue ActionController::ParameterMissing => e
30
+ flash[:danger] = "Permission could not be created: ERROR #{e}"
31
+ redirect_to capabilities_path
32
+ end
33
+ end
34
+
35
+ def destroy
36
+ begin
37
+
38
+ # If we're passed a role id
39
+ if params[:role_id].present?
40
+ @role = Role.find params[:role_id]
41
+
42
+ if params[:id].present?
43
+ conditions = {id: params[:id]}
44
+ else
45
+ conditions = capability_params
46
+ end
47
+
48
+ @capability = @role.capabilities.find_by(conditions)
49
+ @role.capabilities.delete @capability
50
+
51
+ respond_to do |format|
52
+ format.html { redirect_to role_path(@role) }
53
+ format.json { head :ok }
54
+ end
55
+ else
56
+ @capability = Capability.find params[:id]
57
+ @capability.destroy
58
+
59
+ redirect_to capabilities_path
60
+ end
61
+ rescue ActiveRecord::DeleteRestrictionError
62
+ flash[:danger] = "Permission has roles using it, delete relationships before deleting it"
63
+
64
+ redirect_to capability_path(@capability)
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+ def capability_params
71
+ params.require(:capability).permit(:model, :action,
72
+ :require_ownership, :require_tenant_access)
73
+ end
74
+
75
+ end
76
+
77
+ end
@@ -0,0 +1,92 @@
1
+ module Strongbolt
2
+ class RolesController < ::StrongboltController
3
+
4
+ def index
5
+ @roles = Role.includes(:parent)
6
+ .order('parent_id IS NOT NULL', 'parent_id', 'name')
7
+ end
8
+
9
+ def new
10
+ @role = Role.new
11
+ end
12
+
13
+ def show
14
+ @role = Role.find params[:id]
15
+
16
+ @capabilities = @role.capabilities.to_hash
17
+ @inherited_capabilities = @role.inherited_capabilities.to_hash
18
+ # All the models we have
19
+ @keys = (@capabilities.keys | @inherited_capabilities.keys)
20
+
21
+ @descendants = @role.descendants
22
+ end
23
+
24
+ def edit
25
+ @role = Role.find params[:id]
26
+ end
27
+
28
+ def create
29
+ begin
30
+ @role = Role.create! role_params
31
+
32
+ flash[:success] = "Role was successfully created!"
33
+ redirect_to role_path(@role)
34
+ rescue ActiveRecord::RecordInvalid => e
35
+ flash[:danger] = "Role could not be created, please review the errors below"
36
+ redirect_to new_role_path
37
+ rescue ActionController::ParameterMissing => e
38
+ flash[:danger] = "Role could not be created: ERROR #{e}"
39
+ redirect_to new_role_path
40
+ rescue ActiveRecord::ActiveRecordError => e
41
+ flash[:danger] = "The parent you selected leads to an impossible configuration"
42
+ redirect_to edit_role_path(@role)
43
+ end
44
+ end
45
+
46
+ def update
47
+ begin
48
+ @role = Role.find params[:id]
49
+ @role.update_attributes! role_params
50
+
51
+ flash[:success] = "Role was successfully updated!"
52
+ redirect_to role_path(@role)
53
+ rescue ActiveRecord::RecordInvalid => e
54
+ flash[:danger] = "Role could not be updated, please review the errors below"
55
+ redirect_to edit_role_path(@role)
56
+ rescue ActionController::ParameterMissing => e
57
+ flash[:danger] = "Role could not be updated: ERROR #{e}"
58
+ redirect_to edit_role_path(@role)
59
+ rescue ActiveRecord::ActiveRecordError => e
60
+ flash[:danger] = "The parent you selected leads to an impossible configuration"
61
+ redirect_to edit_role_path(@role)
62
+ end
63
+ end
64
+
65
+ def destroy
66
+ begin
67
+ @role = Role.find params[:id]
68
+ @role.destroy!
69
+
70
+ flash[:success] = "Role #{@role.name} successfully deleted"
71
+
72
+ redirect_to roles_path
73
+ rescue ActiveRecord::DeleteRestrictionError
74
+ flash[:danger] = "Role #{@role.name} could not be deleted because #{@role.user_groups.size} user groups rely on it"
75
+ redirect_to role_path(@role)
76
+ end
77
+ end
78
+
79
+ rescue_from ActiveRecord::RecordNotFound do |e|
80
+ flash[:danger] = "Could not find role."
81
+ redirect_to roles_path
82
+ end
83
+
84
+ private
85
+
86
+ def role_params
87
+ params.require(:role).permit(:name, :parent_id, :description,
88
+ :capability_ids => [])
89
+ end
90
+
91
+ end
92
+ end
@@ -0,0 +1,8 @@
1
+ module Strongbolt
2
+ class SecurityController < ::StrongboltController
3
+ self.model_for_authorization = "Role"
4
+
5
+ def index
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,76 @@
1
+ module Strongbolt
2
+ class UserGroupsController < ::StrongboltController
3
+ def index
4
+ @user_groups = UserGroup.all
5
+ end
6
+
7
+ def show
8
+ @user_group = UserGroup.find params[:id]
9
+ # We select the users not yet in the user group
10
+ @users = Strongbolt.user_class_constant
11
+ .joins("LEFT JOIN strongbolt_user_groups_users sugu ON sugu.user_id = #{Strongbolt.user_class_constant.table_name}.id")
12
+ .joins("LEFT JOIN strongbolt_user_groups sug ON sug.id = sugu.user_group_id")
13
+ .where("sug.id IS NULL OR sug.id != ?", @user_group.id)
14
+ end
15
+
16
+ def create
17
+ begin
18
+ @user_group = UserGroup.create! user_group_params
19
+
20
+ flash[:success] = "Use group was successfully created!"
21
+ redirect_to user_group_path(@user_group)
22
+ rescue ActiveRecord::RecordInvalid => e
23
+ flash[:danger] = "User Group could not be created, please review the errors below"
24
+ redirect_to new_user_group_path
25
+ rescue ActionController::ParameterMissing => e
26
+ flash[:danger] = "User Group could not be created: ERROR #{e}"
27
+ redirect_to new_user_group_path
28
+ end
29
+ end
30
+
31
+ def update
32
+ begin
33
+ @user_group = UserGroup.find params[:id]
34
+ @user_group.update_attributes! user_group_params
35
+
36
+ flash[:success] = "User group was successfully updated!"
37
+ redirect_to user_group_path params[:id]
38
+ rescue ActiveRecord::RecordInvalid => e
39
+ flash[:danger] = "User Group could not be modified, please review the errors below"
40
+ redirect_to edit_user_group_path(params[:id])
41
+ rescue ActionController::ParameterMissing => e
42
+ flash[:danger] = "User Group could not be updated: ERROR #{e}"
43
+ redirect_to edit_user_group_path(params[:id])
44
+ end
45
+ end
46
+
47
+ def destroy
48
+ begin
49
+ @user_group = UserGroup.find params[:id]
50
+ @user_group.destroy!
51
+
52
+ flash[:success] = "User group #{@user_group.name} successfully deleted"
53
+
54
+ redirect_to user_groups_path
55
+ rescue ActiveRecord::DeleteRestrictionError
56
+ flash[:danger] = "User group #{@user_group.name} cannot be deleted because #{@user_group.users.size} users belong to it"
57
+
58
+ redirect_to user_group_path(@user_group)
59
+ end
60
+ end
61
+
62
+ def edit
63
+ @user_group = UserGroup.find params[:id]
64
+ end
65
+
66
+ def new
67
+ @user_group = UserGroup.new
68
+ end
69
+
70
+ private
71
+
72
+ def user_group_params
73
+ params.require(:user_group).permit(:name, :role_ids => [])
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,35 @@
1
+ module Strongbolt
2
+ class UserGroupsUsersController < ::StrongboltController
3
+
4
+ self.model_for_authorization = "UserGroup"
5
+
6
+ def create
7
+ @user_group = UserGroup.find(params[:user_group_id])
8
+ @user = Strongbolt.user_class_constant.find(params[:id])
9
+
10
+ @user_group.users << @user unless @user_group.users.include?(@user)
11
+
12
+ redirect_to request.referrer || user_group_path(@user_group)
13
+ end
14
+
15
+ def destroy
16
+ @user_group = UserGroup.find(params[:user_group_id])
17
+ @user = Strongbolt.user_class_constant.find(params[:id])
18
+
19
+ @user_group.users.delete @user
20
+
21
+ redirect_to request.referrer || user_group_path(@user_group)
22
+ end
23
+
24
+ rescue_from ActiveRecord::RecordNotFound do |e|
25
+ if @user_group.nil?
26
+ flash[:danger] = "User Group ##{params[:user_group_id]} does not exist"
27
+ redirect_to user_groups_path
28
+ else
29
+ flash[:danger] = "User ##{params[:id]} does not exist"
30
+ redirect_to user_group_path(@user_group)
31
+ end
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,2 @@
1
+ class StrongboltController < Strongbolt.parent_controller.constantize
2
+ end
@@ -0,0 +1,13 @@
1
+ <ul class="nav nav-pills nav-justified">
2
+ <li class="<%= current == 'user_groups' ? 'active' : '' %>">
3
+ <%= link_to user_groups_path do %>
4
+ <i class="fa fa-users"></i> User Groups
5
+ <% end %>
6
+ </li>
7
+ <li class="<%= current == 'roles' ? 'active' : '' %>">
8
+ <%= link_to roles_path do %>
9
+ <i class="fa fa-certificate"></i> Roles
10
+ <% end %>
11
+ </li>
12
+ </ul>
13
+ <div class="spacer"></div>
@@ -0,0 +1,53 @@
1
+ <ul class='breadcrumb'>
2
+ <h2 style='text-align:left'>Security: Permissions</h2>
3
+ <li class="active">
4
+ Permissions
5
+ </li>
6
+ </ul>
7
+
8
+ <%= simple_form_for(Capability.new, url: capabilities_path, as: :capability) do |f| %>
9
+ <table class="table table-condensed table-striped">
10
+
11
+ <thead>
12
+ <tr>
13
+ <th>#</th>
14
+ <th>Model</th>
15
+ <th>Action</th>
16
+ <th>Require Ownership?</th>
17
+ <th>Require Tenant Access?</th>
18
+ <th>Roles</th>
19
+ <th></th>
20
+ </tr>
21
+ </thead>
22
+
23
+ <tbody>
24
+ <% @capabilities.ordered.each do |capability| %>
25
+ <tr>
26
+ <td><%= capability.id %></td>
27
+ <td><%= capability.model %></td>
28
+ <td><%= capability.action %></td>
29
+ <td><%= capability.require_ownership ? "Yes" : "No" %></td>
30
+ <td><%= capability.require_tenant_access ? "Yes" : "No" %></td>
31
+ <td><%= link_to "#{capability.roles.size} roles", capability_path(capability) %></td>
32
+ <td align="right">
33
+ <%= link_to capability_path(capability), method: :delete, data: {confirm: "Are you sure?"}, class: 'text-danger' do %>
34
+ <i class="fa fa-trash-o"></i>
35
+ <% end %>
36
+ </td>
37
+ </tr>
38
+ <% end %>
39
+ </tbody>
40
+
41
+ <tfoot>
42
+ <tr>
43
+ <td></td>
44
+ <td><%= f.input_field :model, collection: Capability.models, include_blank: false %></td>
45
+ <td><%= f.input_field :action, collection: Capability::Actions, include_blank: false %></td>
46
+ <td><%= f.input_field :require_ownership, as: :select, include_blank: false %></td>
47
+ <td><%= f.input_field :require_tenant_access, as: :select, include_blank: false %></td>
48
+ <td><%= f.button :submit, "Create Permission", class: "btn btn-primary btn-block" %></td>
49
+ </tr>
50
+ </tfoot>
51
+ </table>
52
+
53
+ <% end %>
@@ -0,0 +1,53 @@
1
+ <ul class='breadcrumb'>
2
+ <h2 style='text-align:left'>Security: Permission <em>#<%= @capability.id %></em></h2>
3
+ <li>
4
+ <%= link_to "Permissions", capabilities_path %>
5
+ </li>
6
+ <li class='active'>
7
+ #<%= @capability.id %>
8
+ </li>
9
+ </ul>
10
+
11
+ <table class="table table-summary">
12
+ <tr>
13
+ <td>Model</td>
14
+ <td><%= @capability.model %></td>
15
+ </tr>
16
+ <tr>
17
+ <td>Action</td>
18
+ <td><%= @capability.action %></td>
19
+ </tr>
20
+ <tr>
21
+ <td>Require Ownership?</td>
22
+ <td><%= @capability.require_ownership ? "Yes" : "No" %></td>
23
+ </tr>
24
+ <tr>
25
+ <td>Require Tenant Access</td>
26
+ <td><%= @capability.require_tenant_access ? "Yes" : "No" %></td>
27
+ </tr>
28
+ <tr>
29
+ <td>Roles</td>
30
+ <td>
31
+ <% if @capability.roles.present? %>
32
+ <% @capability.roles.each do |role| %>
33
+ <div><%= link_to role.name, role_path(role) %></div>
34
+ <% end %>
35
+ <% else %>
36
+ No role linked
37
+ <% end %>
38
+ </td>
39
+ </tr>
40
+ </table>
41
+
42
+
43
+ <div class="pull-right">
44
+ <p>
45
+ <% if @capability.roles.empty? %>
46
+ <%= link_to "Delete", capability_path(@capability), method: :delete, class: "btn btn-danger", data: {confirm: "Are you sure?"} %>
47
+ <% else %>
48
+ <span class="text-danger">
49
+ You cannot delete the capability while roles are still linked to it
50
+ </span>
51
+ <% end %>
52
+ </p>
53
+ </div>
@@ -0,0 +1,47 @@
1
+ <%= simple_form_for(Capability.new, url: role_capabilities_path(@role), as: :capability) do |f| %>
2
+ <table class="table table-striped table-condensed" id="role-capabilities" data-url="<%= role_capabilities_path(@role) %>">
3
+
4
+ <thead>
5
+ <tr>
6
+ <th>Model</th>
7
+ <th>Require Ownership?</th>
8
+ <th>Require Tenant Access?</th>
9
+ <th>Actions</th>
10
+ </tr>
11
+ </thead>
12
+
13
+ <tbody>
14
+ <% @keys.each do |key| %>
15
+
16
+ <tr>
17
+ <td><%= key[:model] %></td>
18
+ <td>
19
+ <%= key[:require_ownership] ? "Yes" : "No" %>
20
+ </td>
21
+ <td>
22
+ <%= key[:require_tenant_access] ? "Yes" : "No" %>
23
+ </td>
24
+ <td>
25
+ <%= render 'capability', key: key, capability: @capabilities[key] || {}, inherited_capability: @inherited_capabilities[key] || {}, path: role_capabilities_path(@role) %>
26
+ </td>
27
+ </tr>
28
+
29
+ <% end %>
30
+
31
+ </tbody>
32
+
33
+ <tfoot>
34
+ <tr>
35
+ <td><%= f.input_field :model, collection: Capability.models, include_blank: false %></td>
36
+ <td><%= f.input_field :require_ownership, as: :select, include_blank: false %></td>
37
+ <td><%= f.input_field :require_tenant_access, as: :select, include_blank: false %></td>
38
+ <td colspan="4">
39
+ <%= f.hidden_field :action, value: "find" %>
40
+ <%= f.button :submit, "Add Permission", class: "btn btn-primary btn-block" %>
41
+ </td>
42
+ </tr>
43
+ </tfoot>
44
+
45
+ </table>
46
+
47
+ <% end %>