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
@@ -4,4 +4,4 @@ module Strongbolt
4
4
 
5
5
  self.abstract_class = true
6
6
  end
7
- end
7
+ end
@@ -21,7 +21,7 @@ module Strongbolt
21
21
  #
22
22
  def unbolted?
23
23
  Grant::Status.grant_disabled? || (defined?(Rails) && defined?(Rails.console)) ||
24
- Strongbolt.current_user.nil?
24
+ Strongbolt.current_user.nil?
25
25
  end
26
26
 
27
27
  #
@@ -39,16 +39,16 @@ module Strongbolt
39
39
  return unless owned?
40
40
 
41
41
  @owner_attribute ||= if self <= Configuration.user_class.constantize
42
- :id
43
- else
44
- owner_association.foreign_key.to_sym
45
- end
42
+ :id
43
+ else
44
+ owner_association.foreign_key.to_sym
45
+ end
46
46
  end
47
47
 
48
48
  #
49
49
  # Authorize as another model
50
50
  #
51
- def authorize_as model_name
51
+ def authorize_as(model_name)
52
52
  @name_for_authorization = model_name
53
53
  end
54
54
 
@@ -66,14 +66,13 @@ module Strongbolt
66
66
  #
67
67
  def owner_association
68
68
  @owner_association ||= reflect_on_all_associations(:belongs_to).select do |assoc|
69
- unless assoc.options.has_key? :polymorphic
70
- assoc.klass <= Configuration.user_class.constantize
71
- else
69
+ if assoc.options.key? :polymorphic
72
70
  false
71
+ else
72
+ assoc.klass <= Configuration.user_class.constantize
73
73
  end
74
74
  end.try(:first)
75
75
  end
76
-
77
76
  end
78
77
 
79
78
  module InstanceMethods
@@ -102,7 +101,6 @@ module Strongbolt
102
101
 
103
102
  # We add the grant to filter everything
104
103
  receiver.class_eval do
105
-
106
104
  #
107
105
  # We use the grant helper method to test authorizations on all methods
108
106
  #
@@ -111,16 +109,17 @@ module Strongbolt
111
109
  # Check the user permission unless no user or rails console
112
110
  # Not using unbolted? here
113
111
  granted = ((defined?(Rails) && defined?(Rails.console)) || user.nil?) ||
114
- user.can?( action, instance )
112
+ user.can?(action, instance)
115
113
 
116
114
  # If not granted, trigger the access denied
117
115
  unless granted
116
+ # rubocop:disable Style/GlobalVars
118
117
  Strongbolt.access_denied user, instance, action, $request.try(:fullpath)
118
+ # rubocop:enable Style/GlobalVars
119
119
  end
120
120
 
121
121
  granted
122
122
  end # End Grant
123
-
124
123
  end
125
124
  end
126
125
  end
@@ -1,32 +1,31 @@
1
1
  module Strongbolt
2
2
  module BoltedController
3
-
4
3
  #
5
4
  # Maps controller actions to CRUD operations
6
5
  #
7
6
  ACTIONS_MAPPING = {
8
- :index => :find,
9
- :show => :find,
10
- :edit => :update,
11
- :update => :update,
12
- :new => :create,
13
- :create => :create,
14
- :destroy => :destroy
15
- }
7
+ index: :find,
8
+ show: :find,
9
+ edit: :update,
10
+ update: :update,
11
+ new: :create,
12
+ create: :create,
13
+ destroy: :destroy
14
+ }.freeze
16
15
 
17
16
  module ClassMethods
18
17
  #
19
18
  # Allows defining a specific model for this controller,
20
19
  # if it cannot be infer from the controller name
21
20
  #
22
- def model_for_authorization= model
21
+ def model_for_authorization=(model)
23
22
  @model_for_authorization = case model
24
- when Class then model
25
- when String then constantize_model(model)
26
- when nil then nil
27
- else
28
- raise ArgumentError, "Model for authorization must be a Class or the name of the Class"
29
- end
23
+ when Class then model
24
+ when String then constantize_model(model)
25
+ when nil then nil
26
+ else
27
+ raise ArgumentError, 'Model for authorization must be a Class or the name of the Class'
28
+ end
30
29
  end
31
30
 
32
31
  #
@@ -40,14 +39,14 @@ module Strongbolt
40
39
  # We cannot just do controller_name.classify as it doesn't keep the modules
41
40
  # We'll also check demoduling one module after the other for case when
42
41
  # the controller and/or the model have different modules
43
- full_name = name.sub("Controller", "").classify
42
+ full_name = name.sub('Controller', '').classify
44
43
  # Split by ::
45
44
  splits = full_name.split('::')
46
45
  # While we still have modules to test
47
46
  while splits.size >= 1
48
47
  begin
49
48
  return constantize_model splits.join('::')
50
- rescue Strongbolt::ModelNotFound => e
49
+ rescue Strongbolt::ModelNotFound
51
50
  ensure
52
51
  # Removes first element
53
52
  splits.shift
@@ -62,10 +61,8 @@ module Strongbolt
62
61
  # No argument given will skip for all actions,
63
62
  # and can be passed only: [] or except: []
64
63
  #
65
- def skip_controller_authorization opts = {}
66
- if Rails::VERSION::MAJOR >= 5
67
- opts = { raise: false }.merge(opts)
68
- end
64
+ def skip_controller_authorization(opts = {})
65
+ opts = { raise: false }.merge(opts) if Rails::VERSION::MAJOR >= 5
69
66
  skip_before_action :check_authorization, opts
70
67
  end
71
68
 
@@ -73,7 +70,7 @@ module Strongbolt
73
70
  # Skip all authorization checking for the controller,
74
71
  # or a subset of actions
75
72
  #
76
- def skip_all_authorization opts = {}
73
+ def skip_all_authorization(opts = {})
77
74
  skip_controller_authorization opts
78
75
  around_action :disable_authorization, opts
79
76
  end
@@ -81,7 +78,7 @@ module Strongbolt
81
78
  #
82
79
  # Sets what CRUD operation match a specific sets of non RESTful actions
83
80
  #
84
- [:find, :update, :create, :destroy].each do |operation|
81
+ %i[find update create destroy].each do |operation|
85
82
  define_method "authorize_as_#{operation}" do |*args|
86
83
  args.each do |action|
87
84
  actions_mapping[action] = operation
@@ -92,7 +89,7 @@ module Strongbolt
92
89
  #
93
90
  # Render without authorization, for better performance
94
91
  #
95
- def render_without_authorization *actions
92
+ def render_without_authorization(*actions)
96
93
  self.actions_without_authorization = [*actions]
97
94
 
98
95
  class_eval do
@@ -100,11 +97,11 @@ module Strongbolt
100
97
  # It needs to be created afterward,
101
98
  # No idea why
102
99
  #
103
- def render *args
100
+ def render(*args)
104
101
  if render_without_authorization?
105
- Strongbolt.without_authorization { _render *args }
102
+ Strongbolt.without_authorization { _render(*args) }
106
103
  else
107
- _render *args
104
+ _render(*args)
108
105
  end
109
106
  end
110
107
  end
@@ -130,24 +127,20 @@ module Strongbolt
130
127
  #
131
128
  # Try to constantize a class
132
129
  #
133
- def constantize_model name
134
- begin
135
- name.constantize
136
- rescue NameError
137
- raise Strongbolt::ModelNotFound, "Model for controller #{controller_name} wasn't found"
138
- end
130
+ def constantize_model(name)
131
+ name.constantize
132
+ rescue NameError
133
+ raise Strongbolt::ModelNotFound, "Model for controller #{controller_name} wasn't found"
139
134
  end
140
-
141
135
  end
142
136
 
143
137
  module InstanceMethods
144
-
145
- def can? *args
146
- Strongbolt.current_user.can? *args
138
+ def can?(*args)
139
+ Strongbolt.current_user.can?(*args)
147
140
  end
148
141
 
149
- def cannot? *args
150
- Strongbolt.current_user.cannot? *args
142
+ def cannot?(*args)
143
+ Strongbolt.current_user.cannot?(*args)
151
144
  end
152
145
 
153
146
  #
@@ -163,11 +156,11 @@ module Strongbolt
163
156
  #
164
157
  # DOESN'T WORK WHEN DEFINED HERE?
165
158
  #
166
- def render *args
159
+ def render(*args)
167
160
  if render_without_authorization?
168
- Strongbolt.without_authorization { _render *args }
161
+ Strongbolt.without_authorization { _render(*args) }
169
162
  else
170
- _render *args
163
+ _render(*args)
171
164
  end
172
165
  end
173
166
 
@@ -183,7 +176,9 @@ module Strongbolt
183
176
  #
184
177
  def set_current_user
185
178
  # To be accessible in the model when not granted
179
+ # rubocop:disable Style/GlobalVars
186
180
  $request = request
181
+ # rubocop:enable Style/GlobalVars
187
182
  Grant::Status.without_grant do
188
183
  Strongbolt.current_user = send(:current_user) if respond_to?(:current_user)
189
184
  end
@@ -207,7 +202,7 @@ module Strongbolt
207
202
  begin
208
203
  # Current model
209
204
  # begin
210
- obj = self.class.model_for_authorization
205
+ obj = self.class.model_for_authorization
211
206
  # rescue Strongbolt::ModelNotFound
212
207
  # Strongbolt.logger.warn "No class found or defined for controller #{controller_name}"
213
208
  # return
@@ -224,7 +219,7 @@ module Strongbolt
224
219
  raise e
225
220
  end
226
221
  else
227
- Strongbolt.logger.warn "No authorization checking because no current user"
222
+ Strongbolt.logger.warn 'No authorization checking because no current user'
228
223
  end
229
224
  end
230
225
 
@@ -232,17 +227,15 @@ module Strongbolt
232
227
  # Catch Grant::Error and send Strongbolt::Unauthorized instead
233
228
  #
234
229
  def catch_grant_error
235
- begin
236
- yield
237
- rescue Grant::Error => e
238
- raise Strongbolt::Unauthorized, e.to_s
239
- end
230
+ yield
231
+ rescue Grant::Error => e
232
+ raise Strongbolt::Unauthorized, e.to_s
240
233
  end
241
234
 
242
235
  #
243
236
  # Returns the CRUD operations based on the action name
244
237
  #
245
- def crud_operation_of action
238
+ def crud_operation_of(action)
246
239
  operation = self.class.actions_mapping[action.to_sym]
247
240
  # If nothing find, we raise an error
248
241
  if operation.nil?
@@ -257,9 +250,8 @@ module Strongbolt
257
250
  #
258
251
  def disable_authorization
259
252
  Strongbolt.without_authorization { yield }
260
- Strongbolt.logger.warn "Authorization were disabled!"
253
+ Strongbolt.logger.warn 'Authorization were disabled!'
261
254
  end
262
-
263
255
  end
264
256
 
265
257
  def self.included(receiver)
@@ -285,16 +277,13 @@ module Strongbolt
285
277
  if respond_to? :unauthorized
286
278
  unauthorized e
287
279
  else
288
- raise Strongbolt::Unauthorized.new e.to_s
280
+ raise Strongbolt::Unauthorized, e.to_s
289
281
  end
290
282
  end
291
-
292
283
  end # End receiver class eval
293
284
 
294
285
  receiver.extend ClassMethods
295
286
  receiver.send :include, InstanceMethods
296
-
297
287
  end # End self.included
298
-
299
288
  end
300
289
  end
@@ -1,14 +1,14 @@
1
1
  module Strongbolt
2
2
  class CapabilitiesRole < Base
3
- authorize_as "Strongbolt::Role"
3
+ authorize_as 'Strongbolt::Role'
4
4
 
5
5
  belongs_to :role,
6
- :class_name => "Strongbolt::Role",
7
- :inverse_of => :capabilities_roles
6
+ class_name: 'Strongbolt::Role',
7
+ inverse_of: :capabilities_roles
8
8
 
9
9
  belongs_to :capability,
10
- :class_name => "Strongbolt::Capability",
11
- :inverse_of => :capabilities_roles
10
+ class_name: 'Strongbolt::Capability',
11
+ inverse_of: :capabilities_roles
12
12
 
13
13
  validates_presence_of :role, :capability
14
14
  end
@@ -1,25 +1,24 @@
1
1
  module Strongbolt
2
2
  class Capability < Base
3
+ Actions = %w[find create update destroy].freeze
3
4
 
4
- Actions = %w{find create update destroy}
5
-
6
- DEFAULT_MODELS = ["Strongbolt::UserGroup",
7
- "Strongbolt::Role",
8
- "Strongbolt::Capability",
9
- "Strongbolt::UsersTenant"]
5
+ DEFAULT_MODELS = ['Strongbolt::UserGroup',
6
+ 'Strongbolt::Role',
7
+ 'Strongbolt::Capability',
8
+ 'Strongbolt::UsersTenant'].freeze
10
9
 
11
10
  has_many :capabilities_roles,
12
- :class_name => "Strongbolt::CapabilitiesRole",
13
- :dependent => :restrict_with_exception,
14
- :inverse_of => :capability
11
+ class_name: 'Strongbolt::CapabilitiesRole',
12
+ dependent: :restrict_with_exception,
13
+ inverse_of: :capability
15
14
 
16
- has_many :roles, :through => :capabilities_roles
15
+ has_many :roles, through: :capabilities_roles
17
16
 
18
17
  has_many :users, through: :roles
19
18
 
20
19
  validates :model, :action, presence: true
21
20
  validates :action, inclusion: Actions,
22
- uniqueness: {scope: [:model, :require_ownership, :require_tenant_access]}
21
+ uniqueness: { scope: %i[model require_ownership require_tenant_access] }
23
22
  validate :model_exists?
24
23
 
25
24
  before_validation :set_default
@@ -28,10 +27,15 @@ module Strongbolt
28
27
  #
29
28
  # List all the models to be used in capabilities
30
29
  #
31
- def self.models() @models ||= DEFAULT_MODELS; end
32
- def self.models=(models) @models = models; end
30
+ def self.models
31
+ @models ||= DEFAULT_MODELS
32
+ end
33
+
34
+ class << self
35
+ attr_writer :models
36
+ end
33
37
 
34
- def self.add_models models
38
+ def self.add_models(models)
35
39
  @models ||= DEFAULT_MODELS
36
40
  @models |= [*models]
37
41
  @models.sort!
@@ -39,9 +43,9 @@ module Strongbolt
39
43
 
40
44
  scope :ordered, -> {
41
45
  select("#{self.table_name}.*")
42
- .select("CASE WHEN action = 'find' THEN 0 " +
43
- "WHEN action = 'create' THEN 1 " +
44
- "WHEN action = 'update' THEN 2 " +
46
+ .select("CASE WHEN action = 'find' THEN 0 " \
47
+ "WHEN action = 'create' THEN 1 " \
48
+ "WHEN action = 'update' THEN 2 " \
45
49
  "WHEN action = 'destroy' THEN 3 END AS action_id")
46
50
  .order(:model, :require_ownership, :require_tenant_access, 'action_id')
47
51
  }
@@ -54,9 +58,9 @@ module Strongbolt
54
58
  table = []
55
59
  all.ordered.each do |capability|
56
60
  if table.last.nil? ||
57
- ! (table.last[:model] == capability.model &&
58
- table.last[:require_ownership] == capability.require_ownership &&
59
- table.last[:require_tenant_access] == capability.require_tenant_access)
61
+ !(table.last[:model] == capability.model &&
62
+ table.last[:require_ownership] == capability.require_ownership &&
63
+ table.last[:require_tenant_access] == capability.require_tenant_access)
60
64
 
61
65
  table << {
62
66
  model: capability.model,
@@ -98,11 +102,8 @@ module Strongbolt
98
102
  hash[key][capability.action.to_sym] = true
99
103
  end
100
104
  hash
101
- end
102
-
105
+ end #
103
106
 
104
-
105
- #
106
107
  # Create a set capabilities from a hash
107
108
  # which has:
108
109
  # {
@@ -114,20 +115,20 @@ module Strongbolt
114
115
  # Actions can be either one operation, an array of operations,
115
116
  # or :all meaning all operations
116
117
  #
117
- def self.from_hash hash
118
+ def self.from_hash(hash)
118
119
  hash.symbolize_keys!
119
120
  actions_from_list(hash[:actions]).map do |action|
120
- new :model => hash[:model],
121
- :require_ownership => hash[:require_ownership],
122
- :require_tenant_access => hash[:require_tenant_access],
123
- :action => action
121
+ new model: hash[:model],
122
+ require_ownership: hash[:require_ownership],
123
+ require_tenant_access: hash[:require_tenant_access],
124
+ action: action
124
125
  end
125
126
  end
126
127
 
127
128
  #
128
129
  # Virtual setter of actions
129
130
  #
130
- def self.actions_from_list actions
131
+ def self.actions_from_list(actions)
131
132
  # Transform actions array
132
133
  if actions.respond_to?(:to_sym) && actions.to_sym == :all
133
134
  Actions # All actions
@@ -145,7 +146,7 @@ module Strongbolt
145
146
  if model.present?
146
147
  begin
147
148
  model.constantize
148
- rescue NameError => e
149
+ rescue NameError
149
150
  errors.add :model, "#{model} is not a valid model"
150
151
  end
151
152
  end