strongbolt 0.3.12 → 0.3.13

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +56 -0
  3. data/.rubocop_todo.yml +91 -0
  4. data/Gemfile +1 -1
  5. data/Gemfile.lock +18 -2
  6. data/Rakefile +1 -1
  7. data/app/controllers/strongbolt/capabilities_controller.rb +36 -45
  8. data/app/controllers/strongbolt/roles_controller.rb +39 -47
  9. data/app/controllers/strongbolt/security_controller.rb +2 -3
  10. data/app/controllers/strongbolt/user_groups_controller.rb +48 -54
  11. data/app/controllers/strongbolt/user_groups_users_controller.rb +2 -4
  12. data/app/controllers/strongbolt_controller.rb +1 -1
  13. data/circle.yml +13 -0
  14. data/lib/generators/strongbolt/fix_generator.rb +5 -6
  15. data/lib/generators/strongbolt/fix_unique_group_members_generator.rb +2 -3
  16. data/lib/generators/strongbolt/indexes_generator.rb +3 -4
  17. data/lib/generators/strongbolt/install_generator.rb +8 -9
  18. data/lib/generators/strongbolt/templates/fix_unique_group_members.rb +1 -1
  19. data/lib/generators/strongbolt/templates/indexes.rb +1 -1
  20. data/lib/generators/strongbolt/templates/migration.rb +11 -12
  21. data/lib/generators/strongbolt/templates/strongbolt.rb +1 -1
  22. data/lib/generators/strongbolt/views_generator.rb +4 -4
  23. data/lib/strongbolt.rb +51 -54
  24. data/lib/strongbolt/base.rb +1 -1
  25. data/lib/strongbolt/bolted.rb +12 -13
  26. data/lib/strongbolt/bolted_controller.rb +46 -57
  27. data/lib/strongbolt/capabilities_role.rb +5 -5
  28. data/lib/strongbolt/capability.rb +32 -31
  29. data/lib/strongbolt/configuration.rb +18 -19
  30. data/lib/strongbolt/controllers/url_helpers.rb +5 -5
  31. data/lib/strongbolt/engine.rb +9 -9
  32. data/lib/strongbolt/errors.rb +4 -4
  33. data/lib/strongbolt/generators/migration.rb +4 -6
  34. data/lib/strongbolt/helpers.rb +5 -7
  35. data/lib/strongbolt/rails/routes.rb +4 -4
  36. data/lib/strongbolt/role.rb +11 -12
  37. data/lib/strongbolt/roles_user_group.rb +5 -5
  38. data/lib/strongbolt/rspec.rb +2 -2
  39. data/lib/strongbolt/rspec/user.rb +13 -15
  40. data/lib/strongbolt/tenantable.rb +78 -80
  41. data/lib/strongbolt/user_abilities.rb +44 -54
  42. data/lib/strongbolt/user_group.rb +8 -10
  43. data/lib/strongbolt/user_groups_user.rb +6 -6
  44. data/lib/strongbolt/version.rb +1 -1
  45. data/lib/tasks/strongbolt_tasks.rake +4 -4
  46. data/spec/controllers/strongbolt/capabilities_controller_spec.rb +28 -45
  47. data/spec/controllers/strongbolt/roles_controller_spec.rb +39 -72
  48. data/spec/controllers/strongbolt/user_groups_controller_spec.rb +34 -65
  49. data/spec/controllers/strongbolt/user_groups_users_controller_spec.rb +11 -19
  50. data/spec/controllers/without_authorization_controller_spec.rb +5 -5
  51. data/spec/dummy/app/controllers/posts_controller.rb +2 -2
  52. data/spec/dummy/app/controllers/test_controller.rb +1 -1
  53. data/spec/dummy/app/controllers/without_authorization_controller.rb +1 -1
  54. data/spec/dummy/bin/rails +1 -1
  55. data/spec/dummy/config.ru +1 -1
  56. data/spec/dummy/config/application.rb +4 -5
  57. data/spec/dummy/config/initializers/cookies_serializer.rb +1 -1
  58. data/spec/dummy/config/initializers/strongbolt.rb +2 -2
  59. data/spec/dummy/config/routes.rb +1 -3
  60. data/spec/dummy/db/migrate/20150630212236_create_strongbolt_tables.rb +9 -10
  61. data/spec/dummy/db/migrate/20150630212251_create_strongbolt_tables_indexes.rb +2 -2
  62. data/spec/dummy/db/migrate/20160531110509_fix_unique_group_members.rb +1 -1
  63. data/spec/fabricators/capability_fabricator.rb +4 -4
  64. data/spec/fabricators/role_fabricator.rb +3 -3
  65. data/spec/fabricators/user_fabricator.rb +2 -2
  66. data/spec/fabricators/user_group_fabricator.rb +3 -3
  67. data/spec/fixtures/application.rb +6 -3
  68. data/spec/fixtures/controllers.rb +1 -1
  69. data/spec/spec_helper.rb +7 -8
  70. data/spec/strongbolt/bolted_controller_spec.rb +110 -208
  71. data/spec/strongbolt/bolted_spec.rb +26 -40
  72. data/spec/strongbolt/capability_spec.rb +72 -86
  73. data/spec/strongbolt/configuration_spec.rb +33 -46
  74. data/spec/strongbolt/controllers/url_helpers_spec.rb +7 -9
  75. data/spec/strongbolt/helpers_spec.rb +14 -16
  76. data/spec/strongbolt/role_spec.rb +32 -35
  77. data/spec/strongbolt/tenantable_spec.rb +88 -86
  78. data/spec/strongbolt/user_abilities_multiple_tenants_spec.rb +29 -34
  79. data/spec/strongbolt/user_abilities_spec.rb +142 -188
  80. data/spec/strongbolt/user_group_spec.rb +14 -14
  81. data/spec/strongbolt/users_tenant_spec.rb +10 -12
  82. data/spec/strongbolt_spec.rb +53 -73
  83. data/spec/support/controller_macros.rb +1 -3
  84. data/spec/support/db_setup.rb +31 -25
  85. data/spec/support/helpers.rb +12 -12
  86. data/spec/support/transactional_specs.rb +1 -3
  87. data/strongbolt.gemspec +14 -12
  88. metadata +20 -3
@@ -1,8 +1,9 @@
1
1
  module Strongbolt
2
2
  module Tenantable
3
3
  module ClassMethods
4
-
5
- def tenant?() (@tenant.present? && @tenant) || Strongbolt.tenants.include?(name); end
4
+ def tenant?
5
+ (@tenant.present? && @tenant) || Strongbolt.tenants.include?(name)
6
+ end
6
7
 
7
8
  private
8
9
 
@@ -12,6 +13,7 @@ module Strongbolt
12
13
  def singular_association_name
13
14
  @singular_association_name ||= self.name.demodulize.underscore.to_sym
14
15
  end
16
+
15
17
  def plural_association_name
16
18
  @plural_association_name ||= self.name.demodulize.underscore.pluralize.to_sym
17
19
  end
@@ -21,21 +23,21 @@ module Strongbolt
21
23
  # It will traverse all the has_many relationships
22
24
  # and add a has_one :tenant if not specified
23
25
  #
24
- def tenant opts = {}
26
+ def tenant(_opts = {})
25
27
  # Stops if already configured
26
28
  return if tenant?
27
29
 
28
- Strongbolt.logger.debug "-------------------------------------------------------------------\n" +
29
- "Configuring tenant #{self.name}\n" +
30
- "-------------------------------------------------------------------\n\n"
30
+ Strongbolt.logger.debug "-------------------------------------------------------------------\n" \
31
+ "Configuring tenant #{self.name}\n" \
32
+ "-------------------------------------------------------------------\n\n"
31
33
  #
32
34
  # We're traversing using BFS the relationships
33
35
  #
34
36
  # Keep track of traversed models and their relationship to the tenant
35
- @models_traversed = {self.name => self}
37
+ @models_traversed = { self.name => self }
36
38
  # File of models/associations to traverse
37
39
  models_to_traverse = reflect_on_all_associations
38
- while models_to_traverse.size > 0
40
+ until models_to_traverse.empty?
39
41
  # BFS search, shiftin first elt of array (older)
40
42
  current_association = models_to_traverse.shift
41
43
  # We don't check has_many :through association,
@@ -46,15 +48,14 @@ module Strongbolt
46
48
  # So unless we've already traversed this model, or that's a through relationship
47
49
  # or a polymorphic association
48
50
  # Also we don't go following belongs_to relationship, it becomes crazy
49
- if should_visit? current_association
50
- # We setup the model using the association given
51
- method = setup_model(current_association)
52
- # We flag the model, storing the name of the method used to link to tenant
53
- @models_traversed[current_association.klass.name] = method
54
- # And add its relationships into the array, at the end, if method not nil
55
- if method.present?
56
- models_to_traverse.concat current_association.klass.reflect_on_all_associations
57
- end
51
+ next unless should_visit? current_association
52
+ # We setup the model using the association given
53
+ method = setup_model(current_association)
54
+ # We flag the model, storing the name of the method used to link to tenant
55
+ @models_traversed[current_association.klass.name] = method
56
+ # And add its relationships into the array, at the end, if method not nil
57
+ if method.present?
58
+ models_to_traverse.concat current_association.klass.reflect_on_all_associations
58
59
  end
59
60
  end
60
61
 
@@ -71,7 +72,7 @@ module Strongbolt
71
72
  # Setup a model and returns the method name in symbol of the
72
73
  # implemented link to the tenant
73
74
  #
74
- def setup_model association
75
+ def setup_model(association)
75
76
  # Source class
76
77
  original_class = association.active_record
77
78
  # Current class
@@ -104,11 +105,10 @@ module Strongbolt
104
105
  # If no inverse, we cannot go further
105
106
  if inverse.nil?
106
107
  raise InverseAssociationNotConfigured, "Assocation #{association.name} on #{association.klass.name} could not be configured correctly as no inverse has been found"
107
- elsif inverse.options.has_key? :polymorphic
108
+ elsif inverse.options.key? :polymorphic
108
109
  return nil
109
110
  end
110
111
 
111
-
112
112
  # Common options
113
113
  options = {
114
114
  through: inverse.name,
@@ -145,22 +145,21 @@ module Strongbolt
145
145
  scope "with_#{plur}", -> { includes assoc }
146
146
 
147
147
  scope "where_#{plur}_among", ->(values) do
148
- if values.is_a? Array
149
- # If objects
150
- values = values.map(&:id) if values.first.respond_to? :id
151
- else
152
- # If object
153
- values = values.id if values.respond_to?(:id)
154
- end
155
-
156
- includes(assoc).where(table_name => {id: values})
157
- end
148
+ if values.is_a? Array
149
+ # If objects
150
+ values = values.map(&:id) if values.first.respond_to? :id
151
+ elsif values.respond_to?(:id)
152
+ # If object
153
+ values = values.id
154
+ end
155
+
156
+ includes(assoc).where(table_name => { id: values })
157
+ end
158
158
  end
159
159
 
160
160
  # And return name of association
161
- return assoc
162
- end #/setup_model
163
-
161
+ assoc
162
+ end # /setup_model
164
163
 
165
164
  #
166
165
  # The initial idea of using a polymorphic association on UsersTenant
@@ -196,50 +195,48 @@ module Strongbolt
196
195
  RUBY
197
196
  Strongbolt.const_set users_tenants_subclass_name, users_tenant_subclass
198
197
  end
199
- end #/create_users_tenant_subclass
198
+ end # /create_users_tenant_subclass
200
199
 
201
200
  #
202
201
  # Setups the has_many thru association on the User class
203
202
  #
204
203
  def setup_association_on_user
205
- begin
206
- user_class = Configuration.user_class.constantize
207
-
208
- # Setup the association
209
- # The first one should never be there before
210
- user_class.has_many :"users_#{plural_association_name}",
211
- :class_name => "Strongbolt::#{users_tenants_subclass_name}",
212
- :inverse_of => :user,
213
- :dependent => :delete_all,
214
- :foreign_key => :user_id
215
-
216
- # This one may have been overriden by the developer
217
- unless user_class.respond_to? plural_association_name
218
- user_class.has_many plural_association_name,
219
- :source => :"#{singular_association_name}",
220
- :class_name => self.name,
221
- :through => :"users_#{plural_association_name}"
222
- end
204
+ user_class = Configuration.user_class.constantize
205
+
206
+ # Setup the association
207
+ # The first one should never be there before
208
+ user_class.has_many :"users_#{plural_association_name}",
209
+ class_name: "Strongbolt::#{users_tenants_subclass_name}",
210
+ inverse_of: :user,
211
+ dependent: :delete_all,
212
+ foreign_key: :user_id
213
+
214
+ # This one may have been overriden by the developer
215
+ unless user_class.respond_to? plural_association_name
216
+ user_class.has_many plural_association_name,
217
+ source: :"#{singular_association_name}",
218
+ class_name: self.name,
219
+ through: :"users_#{plural_association_name}"
220
+ end
223
221
 
224
- # Setup a quick method to get accessible clients directly
225
- unless user_class.respond_to? "accessible_#{plural_association_name}"
226
- user_class.class_exec(self, plural_association_name) do |klass, plur|
227
- define_method "accessible_#{plur}" do
228
- # If can find ALL the tenants
229
- if can? :find, klass, :any, true
230
- # Then it can access all of them
231
- klass.all
232
- else
233
- # Otherwise, only the ones he manages
234
- send plur
235
- end
222
+ # Setup a quick method to get accessible clients directly
223
+ unless user_class.respond_to? "accessible_#{plural_association_name}"
224
+ user_class.class_exec(self, plural_association_name) do |klass, plur|
225
+ define_method "accessible_#{plur}" do
226
+ # If can find ALL the tenants
227
+ if can? :find, klass, :any, true
228
+ # Then it can access all of them
229
+ klass.all
230
+ else
231
+ # Otherwise, only the ones he manages
232
+ send plur
236
233
  end
237
234
  end
238
235
  end
239
- rescue NameError => e
240
- Strongbolt.logger.error "User #{Configuration.user_class} could not have his association to tenant #{name} created"
241
236
  end
242
- end #/setup_association_on_user
237
+ rescue NameError
238
+ Strongbolt.logger.error "User #{Configuration.user_class} could not have his association to tenant #{name} created"
239
+ end # /setup_association_on_user
243
240
 
244
241
  #
245
242
  # returns the name of the subclass of Strongbolt::UsersTenant, containing
@@ -251,13 +248,13 @@ module Strongbolt
251
248
  # The module name is left in the name, so that we won't have any collisions
252
249
  # with the same class names in different modules.
253
250
  "Users#{self.name.gsub('::', '')}"
254
- end #/users_tenants_subclass_name
251
+ end # /users_tenants_subclass_name
255
252
 
256
253
  #
257
254
  # Returns the inverse of specified association, using what's given
258
255
  # as inverse_of or trying to guess it
259
256
  #
260
- def inverse_of association
257
+ def inverse_of(association)
261
258
  # If specified in association configuration
262
259
  return association.inverse_of if association.has_inverse?
263
260
 
@@ -266,15 +263,17 @@ module Strongbolt
266
263
  # Else we need to find it, using the class as reference
267
264
  association.klass.reflect_on_all_associations.each do |assoc|
268
265
  # If the association is polymorphic
269
- if assoc.options.has_key? :polymorphic
266
+ if assoc.options.key? :polymorphic
267
+ if association.options && association.options[:as] == assoc.name
268
+ return assoc
269
+ end
270
270
  polymorphic_associations << assoc
271
-
272
271
  # If same class than the original source of the association
273
272
  elsif assoc.klass == association.active_record
274
273
 
275
- Strongbolt.logger.debug "Selected inverse of #{association.name} between #{association.active_record} " +
276
- "and #{association.klass} is #{assoc.name}.\n " +
277
- "If not, please configure manually the inverse of #{association.name}\n"
274
+ Strongbolt.logger.debug "Selected inverse of #{association.name} between #{association.active_record} " \
275
+ "and #{association.klass} is #{assoc.name}.\n " \
276
+ "If not, please configure manually the inverse of #{association.name}\n"
278
277
 
279
278
  return assoc
280
279
  end
@@ -284,7 +283,7 @@ module Strongbolt
284
283
  return polymorphic_associations.first
285
284
  end
286
285
 
287
- return nil
286
+ nil
288
287
  end
289
288
 
290
289
  #
@@ -296,13 +295,12 @@ module Strongbolt
296
295
  # and not HasManyThrough, unless it's AR v >= 4.1.0 && < 4.2.0 where
297
296
  # they define a HasManyAndBelongsTo as a HasManyThrough in the reflections
298
297
  #
299
- def should_visit? association
300
- ! (association.is_a?(ActiveRecord::Reflection::ThroughReflection) ||
298
+ def should_visit?(association)
299
+ !(association.is_a?(ActiveRecord::Reflection::ThroughReflection) ||
301
300
  association.macro == :belongs_to ||
302
- (@models_traversed.has_key?(association.klass.name) &&
303
- @models_traversed[association.klass.name].present?) )
301
+ (@models_traversed.key?(association.klass.name) &&
302
+ @models_traversed[association.klass.name].present?))
304
303
  end
305
-
306
304
  end
307
305
 
308
306
  module InstanceMethods
@@ -1,7 +1,6 @@
1
1
  module Strongbolt
2
2
  module UserAbilities
3
3
  module ClassMethods
4
-
5
4
  end
6
5
 
7
6
  module InstanceMethods
@@ -12,16 +11,16 @@ module Strongbolt
12
11
  #----------------------------------------------------------#
13
12
  def capabilities
14
13
  @capabilities_cache ||= Strongbolt::Capability.unscoped.joins(:roles)
15
- .joins('INNER JOIN strongbolt_roles as children_roles ON strongbolt_roles.lft <= children_roles.lft AND children_roles.rgt <= strongbolt_roles.rgt')
16
- .joins('INNER JOIN strongbolt_roles_user_groups rug ON rug.role_id = children_roles.id')
17
- .joins('INNER JOIN strongbolt_user_groups_users ugu ON ugu.user_group_id = rug.user_group_id')
18
- .where('ugu.user_id = ?', self.id).distinct.to_a.concat(Strongbolt.default_capabilities)
14
+ .joins('INNER JOIN strongbolt_roles as children_roles ON strongbolt_roles.lft <= children_roles.lft AND children_roles.rgt <= strongbolt_roles.rgt')
15
+ .joins('INNER JOIN strongbolt_roles_user_groups rug ON rug.role_id = children_roles.id')
16
+ .joins('INNER JOIN strongbolt_user_groups_users ugu ON ugu.user_group_id = rug.user_group_id')
17
+ .where('ugu.user_id = ?', self.id).distinct.to_a.concat(Strongbolt.default_capabilities)
19
18
  end
20
19
 
21
20
  #
22
21
  # Adds a managed tenant to the user
23
22
  #
24
- def add_tenant tenant
23
+ def add_tenant(tenant)
25
24
  sing_tenant_name = tenant.class.name.demodulize.underscore
26
25
  send("users_#{sing_tenant_name.pluralize}").create! sing_tenant_name => tenant
27
26
  # users_tenants.create! tenant: tenant
@@ -31,17 +30,16 @@ module Strongbolt
31
30
  # Main method for user, used to check whether the user
32
31
  # is authorized to perform a certain action on an instance/class
33
32
  #
34
- def can? action, instance, attrs = :any, all_instance = false
33
+ def can?(action, instance, attrs = :any, all_instance = false)
35
34
  without_grant do
36
-
37
35
  # Get the actual instance if we were given AR
38
36
  instance = instance.try(:first) if instance.is_a?(ActiveRecord::Relation)
39
37
  return false if instance.nil?
40
38
 
41
39
  # We require this to be an *existing* user, that the action and attribute be symbols
42
40
  # and that the instance is a class or a String
43
- raise ArgumentError, "Action must be a symbol and instance must be Class, String, Symbol or AR" unless self.id.present? && action.is_a?(Symbol) &&
44
- (instance.is_a?(ActiveRecord::Base) || instance.is_a?(Class) || instance.is_a?(String)) && attrs.is_a?(Symbol)
41
+ raise ArgumentError, 'Action must be a symbol and instance must be Class, String, Symbol or AR' unless self.id.present? && action.is_a?(Symbol) &&
42
+ (instance.is_a?(ActiveRecord::Base) || instance.is_a?(Class) || instance.is_a?(String)) && attrs.is_a?(Symbol)
45
43
 
46
44
  # Pre-populate all the capabilities into a results cache for quick lookup. Permissions for all "non-owned" objects are
47
45
  # immediately available; additional lookups are required for owned objects (e.g. User, CheckoutBag, etc.).
@@ -58,35 +56,33 @@ module Strongbolt
58
56
  model_name = model.send(:name_for_authorization)
59
57
  else
60
58
  model = nil # We could do model_name.constantize, but there's a big cost to doing this
61
- # if we don't need it, so just defer until we determine there's an actual need
59
+ # if we don't need it, so just defer until we determine there's an actual need
62
60
  model_name = instance
63
61
  end
64
62
 
65
63
  # Look up the various possible valid entries in the cache that would allow us to see this
66
64
  return capability_in_cache?(action, instance, model_name, attrs, all_instance)
67
-
68
- end #end w/o grant
65
+ end # end w/o grant
69
66
  end
70
67
 
71
68
  #
72
69
  # Convenient method
73
70
  #
74
- def cannot? *args
75
- !can? *args
71
+ def cannot?(*args)
72
+ !can?(*args)
76
73
  end
77
74
 
78
75
  #
79
76
  # Checks if the user owns the instance given
80
77
  #
81
- def owns? instance
78
+ def owns?(instance)
82
79
  raise ArgumentError unless instance.is_a?(Object) && !instance.is_a?(Class)
83
80
  # If the user id is set, does this (a) user id match the user_id field of the instance
84
81
  # or (b) if this is a User instance, does the user id match the instance id?
85
82
  key = instance.is_a?(User) ? :id : :user_id
86
- return !id.nil? && instance.try(key) == id
83
+ !id.nil? && instance.try(key) == id
87
84
  end
88
85
 
89
-
90
86
  private
91
87
 
92
88
  #
@@ -99,14 +95,13 @@ module Strongbolt
99
95
  @model_ancestor_cache ||= {}
100
96
 
101
97
  # User can find itself by default
102
- @results_cache["findUserany-any"] = true
98
+ @results_cache['findUserany-any'] = true
103
99
  @results_cache["findUserany-#{id}"] = true
104
100
 
105
101
  #
106
102
  # Store every capability fetched
107
103
  #
108
104
  capabilities.each do |capability|
109
-
110
105
  k = "#{capability.action}#{capability.model}"
111
106
  attr_k = capability.attr || 'all'
112
107
 
@@ -137,14 +132,11 @@ module Strongbolt
137
132
  end
138
133
  end # End each capability
139
134
 
140
- Strongbolt.logger.info "Populated capabilities in #{(Time.now - beginning)*1000}ms"
135
+ Strongbolt.logger.info "Populated capabilities in #{(Time.now - beginning) * 1000}ms"
141
136
 
142
137
  @results_cache
143
138
  end # End Populate capabilities Cache
144
139
 
145
-
146
-
147
-
148
140
  #----------------------------------------------------------#
149
141
  # #
150
142
  # Checks if the user can perform 'action' on 'instance' #
@@ -154,20 +146,20 @@ module Strongbolt
154
146
  def capability_in_cache?(action, instance, model_name, attrs = :any, all_instance = false)
155
147
  action_model = "#{action}#{model_name}"
156
148
 
157
- Strongbolt.logger.warn "User has no results cache" if @results_cache.empty?
149
+ Strongbolt.logger.warn 'User has no results cache' if @results_cache.empty?
158
150
  Strongbolt.logger.debug { "Authorizing user to perform #{action} on #{instance.inspect}" }
159
151
 
160
152
  # we don't know or care about tenants or if this is a new record
161
153
  if instance.is_a?(ActiveRecord::Base) && !instance.new_record?
162
154
  # First, check if we have a hash/cache hit for User being able to do this action to every instance of the model/class
163
- return true if @results_cache["#{action_model}all-all"] #Access to all attributes on ENTIRE class?
164
- return true if @results_cache["#{action_model}#{attrs}-all"] #Access to this specific attribute on ENTIRE class?
155
+ return true if @results_cache["#{action_model}all-all"] # Access to all attributes on ENTIRE class?
156
+ return true if @results_cache["#{action_model}#{attrs}-all"] # Access to this specific attribute on ENTIRE class?
165
157
 
166
158
  # If we're checking on a specific instance of the class, not the general model,
167
159
  # append the id to the key
168
160
  id = instance.try(:id)
169
161
  return true if @results_cache["#{action_model}all-#{id}"] # Access to all this instance's attributes?
170
- return true if @results_cache["#{action_model}#{attrs}-#{id}"] #Access to this instance's attribute?
162
+ return true if @results_cache["#{action_model}#{attrs}-#{id}"] # Access to this instance's attribute?
171
163
 
172
164
  # Checking ownership and tenant access
173
165
  # Block access for non tenanted instance
@@ -187,30 +179,30 @@ module Strongbolt
187
179
  end
188
180
 
189
181
  # Finally we check for tenanted instances
190
- @results_cache["#{action_model}all-#{id}"] = @results_cache["#{action_model}all-tenanted"] && valid_tenants #Access to all attributes on tenanted class?
191
- @results_cache["#{action_model}#{attrs}-#{id}"] = @results_cache["#{action_model}#{attrs}-tenanted"] && valid_tenants #Access to this specific attribute on tenanted class?
182
+ @results_cache["#{action_model}all-#{id}"] = @results_cache["#{action_model}all-tenanted"] && valid_tenants # Access to all attributes on tenanted class?
183
+ @results_cache["#{action_model}#{attrs}-#{id}"] = @results_cache["#{action_model}#{attrs}-tenanted"] && valid_tenants # Access to this specific attribute on tenanted class?
192
184
  return true if @results_cache["#{action_model}all-#{id}"] || @results_cache["#{action_model}#{attrs}-#{id}"]
193
185
  elsif instance.is_a?(ActiveRecord::Base) && instance.new_record?
194
- return true if @results_cache["#{action_model}all-all"] #Access to all attributes on ENTIRE class?
195
- return true if @results_cache["#{action_model}#{attrs}-all"] #Access to this specific attribute on ENTIRE class?
186
+ return true if @results_cache["#{action_model}all-all"] # Access to all attributes on ENTIRE class?
187
+ return true if @results_cache["#{action_model}#{attrs}-all"] # Access to this specific attribute on ENTIRE class?
196
188
  # Checking if the instance is from valid tenants (if necessary)
197
189
  valid_tenants = has_access_to_tenants?(instance)
198
- return true if @results_cache["#{action_model}all-tenanted"] && valid_tenants #Access to all attributes on tenanted class?
199
- return true if @results_cache["#{action_model}#{attrs}-tenanted"] && valid_tenants #Access to this specific attribute on tenanted class?
190
+ return true if @results_cache["#{action_model}all-tenanted"] && valid_tenants # Access to all attributes on tenanted class?
191
+ return true if @results_cache["#{action_model}#{attrs}-tenanted"] && valid_tenants # Access to this specific attribute on tenanted class?
200
192
 
201
193
  # Finally, in the case where it's a non tenanted model (it still need to have valid_tenants == true)
202
194
  return true if @results_cache["#{action_model}all-any"] && valid_tenants
203
195
  return true if @results_cache["#{action_model}#{attrs}-any"] && valid_tenants
204
196
  else
205
197
  # First, check if we have a hash/cache hit for User being able to do this action to every instance of the model/class
206
- return true if @results_cache["#{action_model}all-all"] #Access to all attributes on ENTIRE class?
207
- return true if @results_cache["#{action_model}#{attrs}-all"] #Access to this specific attribute on ENTIRE class?
208
- return true if @results_cache["#{action_model}all-any"] && ! all_instance #Access to all attributes on at least once instance?
209
- return true if @results_cache["#{action_model}#{attrs}-any"] && ! all_instance #Access to this specific attribute on at least once instance?
198
+ return true if @results_cache["#{action_model}all-all"] # Access to all attributes on ENTIRE class?
199
+ return true if @results_cache["#{action_model}#{attrs}-all"] # Access to this specific attribute on ENTIRE class?
200
+ return true if @results_cache["#{action_model}all-any"] && !all_instance # Access to all attributes on at least once instance?
201
+ return true if @results_cache["#{action_model}#{attrs}-any"] && !all_instance # Access to this specific attribute on at least once instance?
210
202
  end
211
- #logger.info "Cache miss for checking access to #{key}"
203
+ # logger.info "Cache miss for checking access to #{key}"
212
204
 
213
- return false
205
+ false
214
206
  end
215
207
 
216
208
  #
@@ -218,7 +210,7 @@ module Strongbolt
218
210
  #
219
211
  # returns true even if instance has no relationship to any tenant
220
212
  #
221
- def has_access_to_tenants? instance, tenants = nil
213
+ def has_access_to_tenants?(instance, tenants = nil)
222
214
  # If no tenants list given, we take all
223
215
  tenants ||= Strongbolt.tenants
224
216
  # Populate the cache if needed
@@ -232,11 +224,11 @@ module Strongbolt
232
224
  if instance.class == tenant
233
225
  tenant_ids = [instance.id]
234
226
  elsif instance.respond_to?(tenant.send(:singular_association_name))
235
- if instance.send(tenant.send(:singular_association_name)).present?
236
- tenant_ids = [instance.send(tenant.send(:singular_association_name)).id]
237
- else
238
- tenant_ids = []
239
- end
227
+ tenant_ids = if instance.send(tenant.send(:singular_association_name)).present?
228
+ [instance.send(tenant.send(:singular_association_name)).id]
229
+ else
230
+ []
231
+ end
240
232
  elsif instance.respond_to?(tenant.send(:plural_association_name))
241
233
  tenant_ids = instance.send("#{tenant.send(:singular_association_name)}_ids")
242
234
  else
@@ -249,7 +241,7 @@ module Strongbolt
249
241
  tenant_ids = []
250
242
  end
251
243
  found_any_tenant_relationship = true unless tenant_ids.empty?
252
- has_access_to_current_tenant = (tenant_ids.size > 0 && (@tenants_cache[tenant.name] & tenant_ids).present?)
244
+ has_access_to_current_tenant = (!tenant_ids.empty? && (@tenants_cache[tenant.name] & tenant_ids).present?)
253
245
  result || has_access_to_current_tenant
254
246
  end
255
247
  has_access_to_any_tenant || !found_any_tenant_relationship
@@ -270,8 +262,6 @@ module Strongbolt
270
262
  Strongbolt.logger.debug "#{@tenants_cache[tenant.name].size} #{tenant.name}"
271
263
  end
272
264
  end
273
-
274
-
275
265
  end # End InstanceMethods
276
266
 
277
267
  def self.included(receiver)
@@ -280,11 +270,11 @@ module Strongbolt
280
270
 
281
271
  receiver.class_eval do
282
272
  has_many :user_groups_users,
283
- :class_name => "Strongbolt::UserGroupsUser",
284
- :dependent => :delete_all,
285
- :inverse_of => :user,
286
- :foreign_key => :user_id
287
- has_many :user_groups, :through => :user_groups_users
273
+ class_name: 'Strongbolt::UserGroupsUser',
274
+ dependent: :delete_all,
275
+ inverse_of: :user,
276
+ foreign_key: :user_id
277
+ has_many :user_groups, through: :user_groups_users
288
278
 
289
279
  has_many :roles, through: :user_groups
290
280
  end