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
@@ -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