strongbolt 0.3.12 → 0.3.13

Sign up to get free protection for your applications and to get access to all the features.
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