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,34 @@
1
+ require "spec_helper"
2
+ require "strongbolt/controllers/url_helpers"
3
+
4
+ module Strongbolt
5
+ module Controllers
6
+ describe UrlHelpers do
7
+
8
+ let(:helpersClass) do
9
+ Class.new do
10
+ def main_app; end
11
+ end
12
+ end
13
+
14
+ before { helpersClass.send :include, UrlHelpers }
15
+
16
+ let(:helpers) { helpersClass.new }
17
+
18
+ subject { helpers }
19
+
20
+ it { should respond_to :new_role_path }
21
+
22
+ describe "edit_role_path" do
23
+ let(:main_app) { double("main_app", :edit_strongbolt_role_path => true) }
24
+
25
+ it "should call new_strongbolt_role_path on the main app" do
26
+ expect(helpers).to receive(:main_app).and_return main_app
27
+ expect(main_app).to receive(:edit_strongbolt_role_path).with 2
28
+ helpers.edit_role_path 2
29
+ end
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,43 @@
1
+ require "spec_helper"
2
+ require "strongbolt/helpers"
3
+
4
+ describe Strongbolt::Helpers do
5
+
6
+ before do
7
+ @user = User.create!
8
+
9
+ define("Helper", Object) do
10
+ include Strongbolt::Helpers
11
+ end
12
+
13
+ Helper.class_exec(@user) do |user|
14
+ define_method :current_user do
15
+ user
16
+ end
17
+ end
18
+ end
19
+
20
+ let(:user) { @user }
21
+ let(:helper) { Helper.new }
22
+
23
+ describe "can?" do
24
+ before do
25
+ expect(user).to receive(:can?).with :find, "me"
26
+ end
27
+
28
+ it "should call the user method" do
29
+ helper.can?(:find) { "me" }
30
+ end
31
+ end
32
+
33
+ describe "cannot?" do
34
+ before do
35
+ expect(user).to receive(:can?).with :find, "me"
36
+ end
37
+
38
+ it "should call the user method" do
39
+ helper.cannot? :find, "me"
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,90 @@
1
+ require "spec_helper"
2
+
3
+ module Strongbolt
4
+
5
+ describe Role do
6
+
7
+ let(:role) { Role.new name: 'Moderator' }
8
+
9
+ subject { role }
10
+
11
+ it { is_expected.to be_valid }
12
+
13
+ it { is_expected.to validate_presence_of :name }
14
+
15
+ it { is_expected.to have_many(:roles_user_groups).class_name("Strongbolt::RolesUserGroup")
16
+ .dependent :restrict_with_exception }
17
+ it { is_expected.to have_many(:user_groups).through :roles_user_groups }
18
+
19
+ it { is_expected.to have_many(:users).through :user_groups }
20
+
21
+ it { is_expected.to have_many(:capabilities_roles).class_name("Strongbolt::CapabilitiesRole")
22
+ .dependent :delete_all }
23
+ it { is_expected.to have_many(:capabilities).through :capabilities_roles }
24
+
25
+ it { is_expected.to belong_to(:parent).class_name("Strongbolt::Role") }
26
+
27
+ describe "inherited capabilities" do
28
+
29
+ before do
30
+ # A family
31
+ grandfather = Role.create! name: "GrandFather"
32
+ father = Role.create! name: "Father", parent: grandfather
33
+ sibling = Role.create! name: "Sibling"
34
+ role.parent = father
35
+ role.save!
36
+ child = Role.create! name: "Child", parent: role
37
+
38
+ # Some capabilities
39
+ begin
40
+ role.capabilities.create! model: "Model", action: "create"
41
+ rescue => e
42
+ puts e.record.capabilities_roles[0].errors.full_messages
43
+ end
44
+ child.capabilities.create! model: "Model", action: "destroy"
45
+ @inherited1 = father.capabilities.create! model: "Model", action: "update"
46
+ @inherited2 = grandfather.capabilities.create! model: "Model", action: "find"
47
+ sibling.capabilities.create! model: "User", action: "find"
48
+ end
49
+
50
+ let(:inherited_capabilities) { role.inherited_capabilities }
51
+
52
+ it "should have 2 inherited_capabilities" do
53
+ expect(inherited_capabilities.size).to eq 2
54
+ end
55
+
56
+ it "should have the right ones" do
57
+ expect(inherited_capabilities).to include @inherited1
58
+ expect(inherited_capabilities).to include @inherited2
59
+ end
60
+
61
+ end
62
+
63
+ describe 'destroy' do |variable|
64
+ before { role.save! }
65
+
66
+ context "when have user groups" do
67
+ before { role.user_groups << UserGroup.create!(name: "User Group") }
68
+
69
+ it "should raise error when destroy" do
70
+ expect do
71
+ role.destroy
72
+ end.to raise_error ActiveRecord::DeleteRestrictionError
73
+ end
74
+ end
75
+
76
+ context "when have children" do
77
+ before { Role.create! name: "Child", parent: role }
78
+
79
+ it "should raise an error when destroy" do
80
+ expect do
81
+ role.destroy
82
+ end.to raise_error ActiveRecord::DeleteRestrictionError
83
+ end
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+
90
+ end
@@ -0,0 +1,281 @@
1
+ require "spec_helper"
2
+
3
+ describe Strongbolt::Tenantable do
4
+
5
+ it "should have been included in ActiveRecord::Base" do
6
+ expect(ActiveRecord::Base.included_modules).to include Strongbolt::Tenantable
7
+ end
8
+
9
+ #
10
+ # When a class is set as tenant
11
+ #
12
+ describe 'tenant?' do
13
+ context "when class is not a tenant" do
14
+ before do
15
+ define_model "OtherModel"
16
+ end
17
+
18
+ it "should return false" do
19
+ expect(OtherModel.tenant?).to eq false
20
+ end
21
+ end
22
+
23
+ context "when class is a tenant" do
24
+ before do
25
+ define_model "OtherModel" do
26
+ send :tenant
27
+ end
28
+ end
29
+ after { Strongbolt.send :tenants=, [] }
30
+
31
+ it "should return true" do
32
+ expect(OtherModel.tenant?).to eq true
33
+ end
34
+ end
35
+ end
36
+
37
+ #
38
+ # Tenant setup
39
+ #
40
+ describe "tenant setup" do
41
+
42
+ #
43
+ # When every association is properly configured
44
+ #
45
+ context "when no configuration error" do
46
+
47
+ #
48
+ # Set up a series of models to test the tenant setup
49
+ #
50
+ before(:all) do
51
+ #
52
+ # Tenant Model
53
+ #
54
+ define_model "TenantModel" do
55
+ self.table_name = "models"
56
+ has_many :child_models, class_name: "ChildModel"
57
+
58
+ belongs_to :parent, class_name: "UnownedModel",
59
+ foreign_key: :parent_id
60
+ end
61
+
62
+ #
63
+ # Direct child to Tenant Model
64
+ #
65
+ define_model "ChildModel" do
66
+ self.table_name = "child_models"
67
+
68
+ belongs_to :tenant_model, foreign_key: :model_id,
69
+ class_name: "TenantModel"
70
+
71
+ has_many :other_child_models, class_name: "OtherChildModel"
72
+ end
73
+
74
+ #
75
+ # 2nd degree child of tenant model
76
+ #
77
+ define_model "OtherChildModel" do
78
+ self.table_name = "child_models"
79
+
80
+ belongs_to :child_model, foreign_key: :model_id,
81
+ class_name: "ChildModel"
82
+ belongs_to :uncle_model, foreign_key: :parent_id,
83
+ class_name: "UncleModel"
84
+ has_one :sibling_model, class_name: "SiblingModel"
85
+ has_one :polymorphic_sibling_model, class_name: "PolymorphicSiblingModel"
86
+
87
+ has_and_belongs_to_many :bottom_models,
88
+ join_table: "model_models",
89
+ class_name: "BottomModel",
90
+ foreign_key: :parent_id,
91
+ association_foreign_key: :child_id
92
+ end
93
+
94
+ #
95
+ # Parent of second degree child
96
+ #
97
+ define_model "UncleModel" do
98
+ self.table_name = "models"
99
+
100
+ has_many :other_child_models, class_name: "OtherChildModel"
101
+ belongs_to :parent, class_name: "UnownedModel",
102
+ foreign_key: :parent_id
103
+ end
104
+
105
+ #
106
+ # Cousin of second degree child
107
+ #
108
+ define_model "SiblingModel" do
109
+ self.table_name = "child_models"
110
+
111
+ belongs_to :other_child_model, foreign_key: :model_id
112
+ end
113
+
114
+ #
115
+ # Cousin of second degree child
116
+ #
117
+ define_model "PolymorphicSiblingModel" do
118
+ self.table_name = "child_models"
119
+
120
+ belongs_to :model, polymorphic: true
121
+ has_one :unowned_model, foreign_key: :model_id
122
+ end
123
+
124
+ #
125
+ # Top level model, parent of Tenant Model
126
+ #
127
+ define_model "UnownedModel" do
128
+ has_many :tenant_models, foreign_key: :parent_id,
129
+ class_name: "TenantModel"
130
+ # has_many :uncle_models, foreign_key: :parent_id
131
+ end
132
+
133
+ #
134
+ # Bottom level model, has and belons to many 2nd degree child
135
+ #
136
+ define_model "BottomModel" do
137
+ self.table_name = "models"
138
+
139
+ has_and_belongs_to_many :other_child_models,
140
+ class_name: "OtherChildModel",
141
+ join_table: "model_models",
142
+ foreign_key: :child_id,
143
+ association_foreign_key: :parent_id
144
+ end
145
+
146
+ TenantModel.send :tenant
147
+ end
148
+
149
+ it "should have added has_one :tenant_model to other child model" do
150
+ expect(OtherChildModel.new).to have_one(:tenant_model).through(:child_model)
151
+ end
152
+
153
+ it "should have added has_many :tenant_models to BottomModel" do
154
+ expect(BottomModel.new).to have_many(:tenant_models).through :other_child_models
155
+ end
156
+
157
+ it "should have created a has_one :tenant_model to SiblingModel" do
158
+ expect(SiblingModel.new).to have_one(:tenant_model).through :other_child_model
159
+ end
160
+
161
+ it "should not have set a :tenant_model on polymorphic association" do
162
+ expect(PolymorphicSiblingModel.new).not_to have_one(:tenant_model)
163
+ end
164
+
165
+ it "should have added has_many :tenant_models to UncleModel" do
166
+ expect(UncleModel.new).not_to have_many(:tenant_models).through :other_child_models
167
+ end
168
+
169
+ %w{ChildModel OtherChildModel BottomModel SiblingModel}.each do |model|
170
+ it "should have added a scope with_tenants to #{model}" do
171
+ expect(model.constantize).to respond_to :with_tenant_models
172
+ end
173
+ end
174
+
175
+ %w{ChildModel OtherChildModel BottomModel SiblingModel}.each do |model|
176
+ it "should have added a scope where_tenants to #{model}" do
177
+ expect(model.constantize).to respond_to :where_tenant_models_among
178
+ end
179
+ end
180
+
181
+ it "creates a has_many users_tenant_models" do
182
+ expect(Strongbolt::Configuration.user_class.constantize.new).to have_many(:users_tenant_models)
183
+ .dependent(:delete_all)
184
+ end
185
+
186
+ it "creates a has_many relationship on the User defined" do
187
+ expect(Strongbolt::Configuration.user_class.constantize.new).to have_many(:tenant_models).through :users_tenant_models
188
+ end
189
+
190
+ it "creates a relationship on the user to get accessible tenants" do
191
+ expect(Strongbolt::Configuration.user_class.constantize.new).to respond_to :accessible_tenant_models
192
+ end
193
+
194
+ it "should have added models to Capability::Models" do
195
+ expect(Strongbolt::Capability.models).to be_present
196
+ expect(Strongbolt::Capability.models.size).to be > 0
197
+ end
198
+
199
+ end
200
+
201
+
202
+ #
203
+ # When an association lacks an inverse (none configured and none found)
204
+ #
205
+
206
+ context "when an association lacks an inverse" do
207
+
208
+ before(:all) do
209
+ #
210
+ # Tenant Model
211
+ #
212
+ define_model "TenantModel" do
213
+ self.table_name = "models"
214
+
215
+ has_many :child_models
216
+ end
217
+
218
+ #
219
+ # Direct child to Tenant Model
220
+ #
221
+ define_model "ChildModel" do
222
+ self.table_name = "child_models"
223
+
224
+ belongs_to :tenant_model, foreign_key: :model_id
225
+
226
+ has_many :other_child_models
227
+ end
228
+
229
+ define_model "OtherChildModel" do
230
+ self.table_name = "child_models"
231
+ end
232
+ end
233
+
234
+ it "should raise an error" do
235
+ expect do
236
+ TenantModel.send :tenant
237
+ end.to raise_error Strongbolt::InverseAssociationNotConfigured
238
+ end
239
+
240
+ end
241
+
242
+ #
243
+ # When a direct association lacks a reference to the tenant
244
+ #
245
+
246
+ context "when an association lacks an inverse" do
247
+
248
+ before(:all) do
249
+ #
250
+ # Tenant Model
251
+ #
252
+ define_model "TenantModel" do
253
+ self.table_name = "models"
254
+
255
+ has_many :child_models
256
+ end
257
+
258
+ #
259
+ # Direct child to Tenant Model
260
+ #
261
+ define_model "ChildModel" do
262
+ self.table_name = "child_models"
263
+ end
264
+ end
265
+
266
+ it "should raise an error" do
267
+ expect do
268
+ TenantModel.send :tenant
269
+ end.to raise_error Strongbolt::DirectAssociationNotConfigured
270
+ end
271
+
272
+ end
273
+
274
+
275
+
276
+ end
277
+
278
+ end
279
+
280
+
281
+