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,14 +1,12 @@
1
1
  module Strongbolt
2
-
3
2
  module Configuration
4
-
5
3
  #
6
4
  # A placeholder class for logger when not defined
7
5
  # Just print what's given
8
6
  #
9
7
  class DefaultLogger
10
- def method_missing method_name, text = nil, &block
11
- puts "[#{method_name}] #{block.present? ? block.call : text}"
8
+ def method_missing(method_name, text = nil, &block)
9
+ puts "[#{method_name}] #{block.present? ? yield : text}"
12
10
  end
13
11
  end
14
12
 
@@ -21,7 +19,9 @@ module Strongbolt
21
19
  #
22
20
  # Returns the constantize version of user class
23
21
  #
24
- def self.user_class_constant() self.user_class.constantize; end
22
+ def self.user_class_constant
23
+ self.user_class.constantize
24
+ end
25
25
 
26
26
  #
27
27
  # Sets the logger used by Strongbolt
@@ -33,20 +33,22 @@ module Strongbolt
33
33
  # Sets the tenants of the application
34
34
  #
35
35
  @@tenants = []
36
- def self.tenants= tenants
36
+ def self.tenants=(tenants)
37
37
  @@tenants = []
38
- [*tenants].each {|t| add_tenant t}
38
+ [*tenants].each { |t| add_tenant t }
39
39
  end
40
40
 
41
41
  #
42
42
  # Returns the tenants
43
43
  #
44
- def self.tenants() @@tenants; end
44
+ def self.tenants
45
+ @@tenants
46
+ end
45
47
 
46
48
  #
47
49
  # Adds a tenant if not in the list
48
50
  #
49
- def self.add_tenant tenant
51
+ def self.add_tenant(tenant)
50
52
  tenant = tenant.constantize if tenant.is_a? String
51
53
  unless @@tenants.any? { |m| m.name == tenant.name }
52
54
  tenant.send :tenant
@@ -54,7 +56,6 @@ module Strongbolt
54
56
  end
55
57
  end
56
58
 
57
-
58
59
  #
59
60
  # Allows to configure what happens when the access is denied,
60
61
  # or call the block that has been given
@@ -62,30 +63,30 @@ module Strongbolt
62
63
  # The block access denied receives as arguments:
63
64
  # user, instance, action, request_path
64
65
  #
65
- def self.access_denied *args, &block
66
+ def self.access_denied(*args, &block)
66
67
  if block.present?
67
68
  @@access_denied_block = block
68
- else
69
- @@access_denied_block.call(*args) if defined?(@@access_denied_block)
69
+ elsif defined?(@@access_denied_block)
70
+ @@access_denied_block.call(*args)
70
71
  end
71
72
  end
72
73
 
73
74
  #
74
75
  # Allows to set Capability Models list
75
76
  #
76
- def self.models= models
77
+ def self.models=(models)
77
78
  Strongbolt::Capability.add_models models
78
79
  end
79
80
 
80
81
  #
81
82
  # Controllers to skip controller authorization check ups
82
83
  #
83
- def self.skip_controller_authorization_for *controllers
84
+ def self.skip_controller_authorization_for(*controllers)
84
85
  ActiveSupport.on_load :action_controller do
85
86
  controllers.each do |controller|
86
87
  begin
87
88
  "#{controller.camelize}Controller".constantize.send :skip_controller_authorization
88
- rescue NameError => e
89
+ rescue NameError
89
90
  raise NameError, "Controller #{controller} doesn't correspond to a valid controller name"
90
91
  end
91
92
  end
@@ -96,7 +97,7 @@ module Strongbolt
96
97
  # Default permissions
97
98
  #
98
99
  @@default_capabilities = []
99
- def self.default_capabilities= list
100
+ def self.default_capabilities=(list)
100
101
  @@default_capabilities = list.inject([]) do |capabilities, hash|
101
102
  capabilities.concat Capability.from_hash(hash)
102
103
  end
@@ -105,7 +106,5 @@ module Strongbolt
105
106
  def self.default_capabilities
106
107
  @@default_capabilities
107
108
  end
108
-
109
109
  end
110
-
111
110
  end
@@ -9,13 +9,13 @@ module Strongbolt
9
9
  # It's not very nice like that but would be too complicated to do like Devise for now...
10
10
  #
11
11
  module UrlHelpers
12
- URLS = %w{role user_group user_group_user role_capability}
12
+ URLS = %w[role user_group user_group_user role_capability].freeze
13
13
 
14
14
  #
15
15
  # Creates the url helpers for the specific url and scope
16
16
  #
17
- def self.create_url_helper url, scope=nil
18
- [:path, :url].each do |path_or_url|
17
+ def self.create_url_helper(url, scope = nil)
18
+ %i[path url].each do |path_or_url|
19
19
  class_eval <<-URL_HELPERS
20
20
  def #{scope.present? ? "#{scope}_" : ''}#{url}_#{path_or_url} *args
21
21
  send(:main_app).send("#{scope.present? ? "#{scope}_" : ''}strongbolt_#{url}_#{path_or_url}", *args)
@@ -30,8 +30,8 @@ module Strongbolt
30
30
  URLS.each do |url|
31
31
  create_url_helper url
32
32
  create_url_helper url.pluralize
33
- [:new, :edit].each { |scope| create_url_helper url, scope }
33
+ %i[new edit].each { |scope| create_url_helper url, scope }
34
34
  end
35
35
  end
36
36
  end
37
- end
37
+ end
@@ -1,25 +1,25 @@
1
- require "strongbolt/rails/routes"
1
+ require 'strongbolt/rails/routes'
2
2
 
3
- require "strongbolt/helpers"
4
- require "strongbolt/controllers/url_helpers"
3
+ require 'strongbolt/helpers'
4
+ require 'strongbolt/controllers/url_helpers'
5
5
 
6
6
  module Strongbolt
7
7
  class Engine < ::Rails::Engine
8
-
9
8
  initializer 'strongbolt.assets.precompile' do |app|
10
- %w(javascripts).each do |sub|
9
+ next if Rails.application.config.try(:api_only)
10
+ %w[javascripts].each do |sub|
11
11
  app.config.assets.paths << root.join('app', 'assets', sub).to_s
12
12
  end
13
13
  end
14
14
 
15
- initializer "strongbolt.helpers" do
15
+ initializer 'strongbolt.helpers' do
16
16
  ActionView::Base.send :include, Strongbolt::Helpers
17
17
  end
18
18
 
19
19
  #
20
20
  # Session Store should be accessible anytime
21
21
  #
22
- initializer "strongbolt.session" do
22
+ initializer 'strongbolt.session' do
23
23
  if defined? ActiveRecord::SessionStore::Session
24
24
  ActiveRecord::SessionStore::Session.grant(:find, :create, :update, :destroy) { true }
25
25
  end
@@ -28,7 +28,7 @@ module Strongbolt
28
28
  #
29
29
  # Avoids authorization checking in the middleware
30
30
  #
31
- initializer "strongbolt.devise_integration" do
31
+ initializer 'strongbolt.devise_integration' do
32
32
  if defined?(Warden) && defined?(Warden::SessionSerializer)
33
33
  Warden::SessionSerializer.perform_without_authorization :store, :fetch, :delete
34
34
  end
@@ -37,7 +37,7 @@ module Strongbolt
37
37
  #
38
38
  # Initialize our custom url helpers
39
39
  #
40
- initializer "strongbolt.url_helpers" do
40
+ initializer 'strongbolt.url_helpers' do
41
41
  Strongbolt.include_helpers Strongbolt::Controllers
42
42
  end
43
43
  end
@@ -19,13 +19,13 @@ module Strongbolt
19
19
  if @message
20
20
  @message
21
21
  else
22
- user_str = user == nil ? 'Anonymous' : "#{user.try(:class).try(:name)}:#{user.try :id}"
23
- model_str = model.is_a?(Class) ? "#{model.try :name}" : "#{model.try(:class).try(:name)}:#{model.try :id}"
22
+ user_str = user.nil? ? 'Anonymous' : "#{user.try(:class).try(:name)}:#{user.try :id}"
23
+ model_str = model.is_a?(Class) ? (model.try :name).to_s : "#{model.try(:class).try(:name)}:#{model.try :id}"
24
24
  "#{action} permission not granted to #{user_str} for resource #{model_str}"
25
25
  end
26
26
  end
27
27
  end
28
-
28
+
29
29
  ModelNotFound = Class.new StrongboltError
30
30
  ActionNotConfigured = Class.new StrongboltError
31
31
 
@@ -35,4 +35,4 @@ module Strongbolt
35
35
  TenantError = Class.new StrongboltError
36
36
  InverseAssociationNotConfigured = Class.new TenantError
37
37
  DirectAssociationNotConfigured = Class.new TenantError
38
- end
38
+ end
@@ -3,7 +3,7 @@ require 'rails/generators/active_record'
3
3
  module Strongbolt
4
4
  module Generators
5
5
  module Migration
6
- def self.included receiver
6
+ def self.included(receiver)
7
7
  receiver.send :include, Rails::Generators::Migration
8
8
  receiver.send :include, InstanceMethods
9
9
  receiver.extend ClassMethods
@@ -17,14 +17,12 @@ module Strongbolt
17
17
  next_migration_number = current_migration_number(dirname) + 1
18
18
  ActiveRecord::Migration.next_migration_number(next_migration_number)
19
19
  end
20
-
21
20
  end
22
21
 
23
22
  module InstanceMethods
24
-
25
23
  def copy_migration(source, target)
26
- if self.class.migration_exists?("db/migrate", "#{target}")
27
- say_status "skipped", "Migration #{target}.rb already exists"
24
+ if self.class.migration_exists?('db/migrate', target.to_s)
25
+ say_status 'skipped', "Migration #{target}.rb already exists"
28
26
  else
29
27
  migration_template "#{source}.rb", "db/migrate/#{target}.rb"
30
28
  end
@@ -32,4 +30,4 @@ module Strongbolt
32
30
  end
33
31
  end
34
32
  end
35
- end
33
+ end
@@ -1,18 +1,16 @@
1
1
  module Strongbolt
2
2
  module Helpers
3
- def can? *args, &block
3
+ def can?(*args, &block)
4
4
  # Block can be used when testing an instance
5
5
  Strongbolt.without_authorization do
6
- if block.present?
7
- args.insert 1, block.call
8
- end
6
+ args.insert 1, yield if block.present?
9
7
 
10
- return current_user.can? *args
8
+ return current_user.can?(*args)
11
9
  end
12
10
  end
13
11
 
14
- def cannot? *args, &block
15
- ! can? *args, &block
12
+ def cannot?(*args, &block)
13
+ !can?(*args, &block)
16
14
  end
17
15
  end
18
16
  end
@@ -4,17 +4,17 @@ module ActionDispatch::Routing
4
4
  #
5
5
  class Mapper
6
6
  def strongbolt
7
- scope :module => :strongbolt do
7
+ scope module: :strongbolt do
8
8
  resources :user_groups do
9
- resources :user_groups_users, as: :users, path: 'users', only: [:create, :destroy]
9
+ resources :user_groups_users, as: :users, path: 'users', only: %i[create destroy]
10
10
  end
11
11
 
12
12
  resources :roles do
13
- resources :capabilities, only: [:create, :destroy] do
13
+ resources :capabilities, only: %i[create destroy] do
14
14
  delete :destroy, on: :collection
15
15
  end
16
16
  end
17
17
  end
18
18
  end
19
19
  end
20
- end
20
+ end
@@ -1,23 +1,22 @@
1
1
  module Strongbolt
2
2
  class Role < Base
3
-
4
3
  acts_as_nested_set
5
4
 
6
5
  validates :name, presence: true
7
6
 
8
7
  has_many :roles_user_groups,
9
- :class_name => "Strongbolt::RolesUserGroup",
10
- :dependent => :restrict_with_exception,
11
- :inverse_of => :role
12
- has_many :user_groups, :through => :roles_user_groups
8
+ class_name: 'Strongbolt::RolesUserGroup',
9
+ dependent: :restrict_with_exception,
10
+ inverse_of: :role
11
+ has_many :user_groups, through: :roles_user_groups
13
12
 
14
13
  has_many :users, through: :user_groups
15
14
 
16
15
  has_many :capabilities_roles,
17
- :class_name => "Strongbolt::CapabilitiesRole",
18
- :dependent => :delete_all,
19
- :inverse_of => :role
20
- has_many :capabilities, :through => :capabilities_roles
16
+ class_name: 'Strongbolt::CapabilitiesRole',
17
+ dependent: :delete_all,
18
+ inverse_of: :role
19
+ has_many :capabilities, through: :capabilities_roles
21
20
 
22
21
  before_destroy :should_not_have_children
23
22
 
@@ -29,15 +28,15 @@ module Strongbolt
29
28
  #
30
29
  def inherited_capabilities
31
30
  Strongbolt::Capability.joins(:roles)
32
- .where("strongbolt_roles.lft < :lft AND strongbolt_roles.rgt > :rgt", lft: lft, rgt: rgt)
33
- .distinct
31
+ .where('strongbolt_roles.lft < :lft AND strongbolt_roles.rgt > :rgt', lft: lft, rgt: rgt)
32
+ .distinct
34
33
  end
35
34
 
36
35
  private
37
36
 
38
37
  def should_not_have_children
39
38
  if children.count > 0
40
- raise ActiveRecord::DeleteRestrictionError.new :children
39
+ raise ActiveRecord::DeleteRestrictionError, :children
41
40
  end
42
41
  end
43
42
  end
@@ -1,14 +1,14 @@
1
1
  module Strongbolt
2
2
  class RolesUserGroup < Base
3
- authorize_as "Strongbolt::UserGroup"
3
+ authorize_as 'Strongbolt::UserGroup'
4
4
 
5
5
  belongs_to :user_group,
6
- :class_name => "Strongbolt::UserGroup",
7
- :inverse_of => :roles_user_groups
6
+ class_name: 'Strongbolt::UserGroup',
7
+ inverse_of: :roles_user_groups
8
8
 
9
9
  belongs_to :role,
10
- :class_name => "Strongbolt::Role",
11
- :inverse_of => :roles_user_groups
10
+ class_name: 'Strongbolt::Role',
11
+ inverse_of: :roles_user_groups
12
12
 
13
13
  validates_presence_of :user_group, :role
14
14
  end
@@ -19,11 +19,11 @@ if defined?(RSpec)
19
19
  end
20
20
 
21
21
  config.around(:each) do |example|
22
- Strongbolt.without_authorization &example
22
+ Strongbolt.without_authorization(&example)
23
23
  # Clear all the User authorizations that could have been defined
24
24
  User.clear_authorizations
25
25
  # Removes the user from current_user to avoid leaks
26
26
  Strongbolt.current_user = nil
27
27
  end
28
28
  end
29
- end
29
+ end
@@ -7,12 +7,11 @@ Strongbolt.user_class_constant.class_eval do
7
7
  # Best to use a class context and use class instance variables
8
8
  #
9
9
  class << self
10
-
11
10
  def authorizations
12
11
  @authorizations ||= {}
13
12
  end
14
13
 
15
- def set_authorization_for user, authorized, *args
14
+ def set_authorization_for(user, authorized, *args)
16
15
  return if user.new_record?
17
16
 
18
17
  self.authorizations[user.id] ||= {}
@@ -23,22 +22,22 @@ Strongbolt.user_class_constant.class_eval do
23
22
  @authorizations = {}
24
23
  end
25
24
 
26
- def authorized? user, *args
25
+ def authorized?(user, *args)
27
26
  # Cannot do if user not saved
28
27
  return false if user.new_record?
29
28
  key = key_for(*args)
30
29
  if self.authorizations[user.id].present? && self.authorizations[user.id][key].present?
31
30
  return self.authorizations[user.id][key]
32
31
  else
33
- user._can? *args
32
+ user._can?(*args)
34
33
  end
35
34
  end
36
35
 
37
- def key_for *args
36
+ def key_for(*args)
38
37
  action = args[0]
39
38
  instance = args[1]
40
39
  attrs = args[2] || :any
41
- all_instances = (args[3] || false) ? "all" : "tenanted"
40
+ all_instances = args[3] || false ? 'all' : 'tenanted'
42
41
  if instance.is_a?(ActiveRecord::Base)
43
42
  model = instance.class.name
44
43
  if instance.new_record?
@@ -51,21 +50,20 @@ Strongbolt.user_class_constant.class_eval do
51
50
  "#{action}-#{model}-#{attrs}-#{all_instances}"
52
51
  end
53
52
  end
54
-
55
53
  end
56
54
 
57
55
  #
58
56
  # 2 methods to setup mocking and stubs
59
57
  #
60
58
  def init
61
- if RSpec::Mocks::Version::STRING >= "3.0"
62
- require "rspec/mocks/standalone"
59
+ if RSpec::Mocks::Version::STRING >= '3.0'
60
+ require 'rspec/mocks/standalone'
63
61
  else
64
- RSpec::Mocks::setup(self) unless self.respond_to? :allow
62
+ RSpec::Mocks.setup(self) unless self.respond_to? :allow
65
63
  end
66
64
  end
67
65
 
68
- def setup_stub authorized, arguments
66
+ def setup_stub(authorized, arguments)
69
67
  init
70
68
  # Set the authorizations on a class level
71
69
  self.class.set_authorization_for self, authorized, *arguments
@@ -76,15 +74,15 @@ Strongbolt.user_class_constant.class_eval do
76
74
  #
77
75
  alias_method :_can?, :can?
78
76
 
79
- def can? *args
77
+ def can?(*args)
80
78
  self.class.authorized? self, *args
81
79
  end
82
80
 
83
- def can! *args
81
+ def can!(*args)
84
82
  setup_stub true, args
85
83
  end
86
84
 
87
- def cannot! *args
85
+ def cannot!(*args)
88
86
  setup_stub false, args
89
87
  end
90
- end
88
+ end