right_on 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/.travis.yml +14 -0
- data/Gemfile +7 -0
- data/LICENSE +21 -0
- data/README.md +60 -0
- data/Rakefile +12 -0
- data/db/migration.rb +34 -0
- data/db/rights_roles.yml +16 -0
- data/gemfiles/rails3.gemfile +7 -0
- data/gemfiles/rails4.gemfile +6 -0
- data/lib/right_on/action_controller_extensions.rb +68 -0
- data/lib/right_on/generators/USAGE +8 -0
- data/lib/right_on/generators/right_migration_generator.rb +59 -0
- data/lib/right_on/generators/templates/right_migration.rb +32 -0
- data/lib/right_on/permission_denied_response.rb +43 -0
- data/lib/right_on/rails.rb +5 -0
- data/lib/right_on/railtie.rb +12 -0
- data/lib/right_on/restricted_by_right.rb +56 -0
- data/lib/right_on/right.rb +171 -0
- data/lib/right_on/rights_manager.rb +140 -0
- data/lib/right_on/role.rb +16 -0
- data/lib/right_on/role_model.rb +33 -0
- data/lib/right_on/tasks/rights_roles.rake +12 -0
- data/lib/right_on/tasks/seeds_rights.rake +28 -0
- data/lib/right_on/version.rb +3 -0
- data/lib/right_on.rb +12 -0
- data/right_on.gemspec +33 -0
- data/spec/action_controller_extensions_spec.rb +34 -0
- data/spec/right_on_spec.rb +206 -0
- data/spec/role_model_spec.rb +45 -0
- data/spec/schema.rb +44 -0
- data/spec/spec_helper.rb +42 -0
- data/spec/support/bootstrap.rb +15 -0
- data/spec/support/coverage_loader.rb +26 -0
- data/views/_edit_rights.html.haml +15 -0
- data/views/_rights_roles_matrix.html.haml +24 -0
- metadata +268 -0
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'input_reader'
|
2
|
+
require 'rails/generators'
|
3
|
+
|
4
|
+
# Extra require so generator can be used in rake task
|
5
|
+
require 'right_on/generators/right_migration_generator'
|
6
|
+
|
7
|
+
module RightOn
|
8
|
+
class RightsManager
|
9
|
+
class << self
|
10
|
+
|
11
|
+
def controllers
|
12
|
+
controllers_path = File.join("#{Rails.root}",'app','controllers')
|
13
|
+
controllers_suffix = '_controller.rb'
|
14
|
+
controllers_files = File.join(controllers_path, '**', '*' + controllers_suffix)
|
15
|
+
Dir[controllers_files].map do |f|
|
16
|
+
[File.dirname(f)[(controllers_path.length + 1)..-1],
|
17
|
+
File.basename(f,controllers_suffix)].compact.join('/')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def missing_rights
|
23
|
+
rights = Right.all.map(&:controller)
|
24
|
+
controllers.reject { |c| rights.include?(c) }
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def add_right(options = {})
|
29
|
+
options = parse_right_options(options)
|
30
|
+
add_and_run_right_migration(options)
|
31
|
+
add_right_fixture(options)
|
32
|
+
puts "Added right #{options[:name]}"
|
33
|
+
add_right if options[:unattended].blank? && InputReader.get_boolean(:prompt => "Add another right?(Y/N)")
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def add_right_record(options = {})
|
38
|
+
unless Right.find_by_name(options[:name])
|
39
|
+
Right.create(options.slice(:controller, :action, :name, :roles))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
# Converts options from {:key => 'value', :key2 => 'value2', :blank => ''}
|
45
|
+
# to "--key=value --key2=value2" (Notice how blank is not included)
|
46
|
+
def build_unix_options(options = {})
|
47
|
+
options.select{|k,v| v.present?}.map do |key, value|
|
48
|
+
"--#{key}=#{value}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
def add_right_migration(options = {})
|
54
|
+
migration_options = options.slice(:controller, :action, :right)
|
55
|
+
puts options.inspect
|
56
|
+
puts "#{options[:name]} #{build_unix_options(migration_options)}"
|
57
|
+
migration_file = Rails::Generators.invoke("right_on:right_migration",
|
58
|
+
[options[:name]] + build_unix_options(migration_options)
|
59
|
+
)
|
60
|
+
raise "Could not generate migration" unless migration_file.present?
|
61
|
+
migration_file.first
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
def add_and_run_right_migration(options = {})
|
66
|
+
migration_file = add_right_migration(options)
|
67
|
+
ENV['VERSION'] = File.basename(migration_file).split('_').first
|
68
|
+
Rake::Task['db:migrate:up'].invoke
|
69
|
+
ENV.delete 'VERSION'
|
70
|
+
true
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
def add_right_fixture(options = {})
|
75
|
+
right_roles_yaml_path = File.join("#{Rails.root}",'db','fixtures','rights_roles.yml')
|
76
|
+
right_roles = YAML::load_file(right_roles_yaml_path)
|
77
|
+
|
78
|
+
group = options[:group].presence || options[:controller]
|
79
|
+
|
80
|
+
right_roles['rights'][group] ||= []
|
81
|
+
right_roles['rights'][group].delete(options[:controller])
|
82
|
+
|
83
|
+
right = right_roles['rights'][group].find do |right|
|
84
|
+
right.is_a?(Hash) && right.keys.include?(options[:controller])
|
85
|
+
end
|
86
|
+
|
87
|
+
if options[:action].present?
|
88
|
+
right ||= (right_roles['rights'][group] << {}).last
|
89
|
+
right[options[:controller]] ||= []
|
90
|
+
right[options[:controller]] << options[:action] unless right[options[:controller]].include?(options[:action])
|
91
|
+
elsif !right
|
92
|
+
right_roles['rights'][group] << options[:controller]
|
93
|
+
end
|
94
|
+
|
95
|
+
options[:bootstrap_roles].each do |role_title|
|
96
|
+
(right_roles['roles'][role_title] || []) << [options[:controller].presence,options[:action].presence].compact.join("#")
|
97
|
+
end
|
98
|
+
|
99
|
+
File.open(right_roles_yaml_path, "w") do |f|
|
100
|
+
f.write(right_roles.to_yaml)
|
101
|
+
end
|
102
|
+
|
103
|
+
true
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def parse_right_options(options = {})
|
110
|
+
parsed_options = {}
|
111
|
+
|
112
|
+
parsed_options[:controller] = options[:controller].presence ||
|
113
|
+
InputReader.select_item(missing_rights, :prompt => "Right:", :allow_blank => true) ||
|
114
|
+
InputReader.get_string(:allow_blank => false, :prompt => "Controller:")
|
115
|
+
|
116
|
+
parsed_options[:action] = options[:action].presence ||
|
117
|
+
InputReader.get_string(:allow_blank => true, :prompt => "Action:")
|
118
|
+
|
119
|
+
parsed_options[:name] = options[:name].presence ||
|
120
|
+
InputReader.get_string(:allow_blank => true, :prompt => "Name:") ||
|
121
|
+
[parsed_options[:controller].presence, parsed_options[:action].presence].compact.join('#')
|
122
|
+
|
123
|
+
parsed_options[:group] = options[:group].presence ||
|
124
|
+
InputReader.get_string(:allow_blank => true, :prompt => "Group:")
|
125
|
+
|
126
|
+
parsed_options[:right] = options[:right].presence ||
|
127
|
+
InputReader.select_item(Right.all, :selection_attribute => :name, :allow_blank => true, :prompt => "Assign new right to anyone with right:").name
|
128
|
+
|
129
|
+
right_roles_yaml_path = File.join("#{Rails.root}",'db','fixtures','rights_roles.yml')
|
130
|
+
right_roles = YAML::load_file(right_roles_yaml_path)
|
131
|
+
bootstrap_roles = right_roles['roles'].keys
|
132
|
+
parsed_options[:bootstrap_roles] = options[:bootstrap_role].presence ||
|
133
|
+
InputReader.select_items(bootstrap_roles, :allow_blank => true, :prompt => "Assign to which bootstrap roles:")
|
134
|
+
|
135
|
+
parsed_options
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module RightOn
|
2
|
+
class Role < ActiveRecord::Base
|
3
|
+
|
4
|
+
has_and_belongs_to_many :rights, :class_name => 'RightOn::Right'
|
5
|
+
|
6
|
+
validates_presence_of :title
|
7
|
+
validates_uniqueness_of :title
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
self.title.try(:titleize)
|
11
|
+
end
|
12
|
+
|
13
|
+
alias_method :name, :to_s
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module RightOn
|
2
|
+
module RoleModel
|
3
|
+
def self.included(base)
|
4
|
+
base.module_eval 'has_and_belongs_to_many :roles, :class_name => "RightOn::Role"'
|
5
|
+
Role.module_eval "has_and_belongs_to_many :#{base.table_name}"
|
6
|
+
end
|
7
|
+
|
8
|
+
def roles_allowed_to_assign
|
9
|
+
Role.accessible_to(self)
|
10
|
+
end
|
11
|
+
|
12
|
+
def rights
|
13
|
+
@rights ||=
|
14
|
+
Right
|
15
|
+
.select('distinct rights.*')
|
16
|
+
.joins(:roles)
|
17
|
+
.where('rights_roles.role_id IN (?)', role_ids)
|
18
|
+
end
|
19
|
+
|
20
|
+
def has_access_to?(client_type)
|
21
|
+
has_right?(client_type.right)
|
22
|
+
end
|
23
|
+
|
24
|
+
def has_right?(right_or_string)
|
25
|
+
right = right_or_string.is_a?(Right) ? right_or_string : Right.find_by_name(right_or_string)
|
26
|
+
rights.include?(right)
|
27
|
+
end
|
28
|
+
|
29
|
+
def has_privileges_of?(other_user)
|
30
|
+
(other_user.rights - rights).empty?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
namespace :rights do
|
2
|
+
desc "Check for controllers without rights"
|
3
|
+
task :check => :environment do
|
4
|
+
puts "Missing rights for controllers:"
|
5
|
+
puts RightOn::RightsManager.missing_rights
|
6
|
+
end
|
7
|
+
|
8
|
+
desc "Add rights for missing controllers"
|
9
|
+
task :add, [:controller, :action] => :environment do |t, args|
|
10
|
+
RightOn::RightsManager.add_right(args)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
namespace "db" do
|
2
|
+
namespace "seed" do
|
3
|
+
desc "Seed initial rights to each role"
|
4
|
+
task :rights => :environment do
|
5
|
+
load "#{Rails.root}/db/fixtures/rights_roles.rb"
|
6
|
+
end
|
7
|
+
|
8
|
+
namespace "rights" do
|
9
|
+
desc "Remove existing rights data and reinitiate it with seeds."
|
10
|
+
task :redo => :environment do
|
11
|
+
message = []
|
12
|
+
message << "This rake task will delete all existing rights and reload Roles with the default rights"
|
13
|
+
message << "Every roles will lose their existing rights unless specified in db/fixtures/rights_roles.yml"
|
14
|
+
|
15
|
+
RakeUserInterface.confirmation_required(message) do
|
16
|
+
RightOn::Right.transaction do
|
17
|
+
if RightOn::Right.count > 0
|
18
|
+
puts "Removing existing Right data..."
|
19
|
+
RightOn::Right.destroy_all
|
20
|
+
end
|
21
|
+
|
22
|
+
Rake::Task["db:seed:rights"].invoke
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/right_on.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
module RightOn
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
require 'dependent_restrict'
|
5
|
+
require 'right_on/restricted_by_right'
|
6
|
+
ActiveRecord::Base.send(:include, RestrictedByRight)
|
7
|
+
|
8
|
+
require 'rails'
|
9
|
+
require 'right_on/railtie'
|
10
|
+
require 'right_on/rights_manager'
|
11
|
+
end
|
12
|
+
|
data/right_on.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'right_on/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'right_on'
|
8
|
+
spec.version = RightOn::VERSION
|
9
|
+
spec.authors = ["Michael Noack", "Alessandro Berardi"]
|
10
|
+
spec.email = 'development@travellink.com.au'
|
11
|
+
spec.description = "This helps systems manage rights and roles on a controller/action basis."
|
12
|
+
spec.summary = "Set of extensions to core rails to give rights and roles."
|
13
|
+
spec.homepage = 'http://github.com/sealink/right_on'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency('activerecord', [">= 3.2.0", "< 5.0.0"])
|
22
|
+
spec.add_dependency('activesupport', [">= 3.2.0", "< 5.0.0"])
|
23
|
+
spec.add_dependency('dependent_restrict', [">= 0.2.1"])
|
24
|
+
spec.add_dependency('input_reader', ["~> 0.0"])
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
26
|
+
spec.add_development_dependency 'rake'
|
27
|
+
spec.add_development_dependency 'rspec'
|
28
|
+
spec.add_development_dependency 'simplecov'
|
29
|
+
spec.add_development_dependency 'simplecov-rcov'
|
30
|
+
spec.add_development_dependency 'coveralls'
|
31
|
+
spec.add_development_dependency 'sqlite3'
|
32
|
+
spec.add_development_dependency 'travis'
|
33
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'action_controller'
|
4
|
+
class AdminController < ActionController::Base
|
5
|
+
include RightOn::ActionControllerExtensions
|
6
|
+
def current_user
|
7
|
+
Thread.current[:user]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe AdminController do
|
12
|
+
let(:basic_user) { User.where(name: 'basic').first }
|
13
|
+
let(:admin_user) { User.where(name: 'admin').first }
|
14
|
+
|
15
|
+
before do
|
16
|
+
Bootstrap.reset_database
|
17
|
+
controller.params = {controller: 'admin', action: 'index'}
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:controller) { AdminController.new }
|
21
|
+
context 'basic user' do
|
22
|
+
before { Thread.current[:user] = basic_user }
|
23
|
+
it 'should not allow access' do
|
24
|
+
expect(controller.access_allowed?).to be false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'admin user' do
|
29
|
+
before { Thread.current[:user] = admin_user }
|
30
|
+
it 'should allow access' do
|
31
|
+
expect(controller.access_allowed?).to be true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,206 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe User do
|
4
|
+
let(:basic_user) { User.where(name: 'basic').first }
|
5
|
+
let(:admin_user) { User.where(name: 'admin').first }
|
6
|
+
|
7
|
+
before do
|
8
|
+
Bootstrap.reset_database
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should compare privileges' do
|
12
|
+
expect(admin_user.has_privileges_of?(basic_user)).to eq true
|
13
|
+
expect(basic_user.has_privileges_of?(admin_user)).to eq false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe RightOn::Right do
|
18
|
+
before do
|
19
|
+
RightOn::Right.delete_all
|
20
|
+
Model.delete_all
|
21
|
+
|
22
|
+
@model = Model.create!(:name => 'Test')
|
23
|
+
|
24
|
+
@users = RightOn::Right.create!(:name => 'users', :controller => 'users')
|
25
|
+
@other = RightOn::Right.create!(:name => 'models', :controller => 'models')
|
26
|
+
@index = RightOn::Right.create!(:name => 'models#index', :controller => 'models', :action => 'index')
|
27
|
+
@change = RightOn::Right.create!(:name => 'models#change', :controller => 'models', :action => 'change')
|
28
|
+
@view = RightOn::Right.create!(:name => 'models#view', :controller => 'models', :action => 'view')
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should display nicely with sensible_name and to_s' do
|
32
|
+
expect(@model.right.to_s).to eq 'Model: Test'
|
33
|
+
expect(@other.to_s).to eq 'models'
|
34
|
+
expect(@index.to_s).to eq 'models#index'
|
35
|
+
|
36
|
+
expect(@model.right.sensible_name).to eq 'Model: Test'
|
37
|
+
expect(@other.sensible_name).to eq 'Models'
|
38
|
+
expect(@index.sensible_name).to eq 'Models - Index'
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should create right for restricted right' do
|
42
|
+
right = @model.right
|
43
|
+
expect(right).to_not be_nil
|
44
|
+
expect(right.name).to eq 'Model: Test'
|
45
|
+
expect{right.destroy}.to raise_error(ActiveRecord::DetailedDeleteRestrictionError)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should identify correct groups' do
|
49
|
+
rights = RightOn::Right.regular_rights_with_group.sort_by{|r| r.name} # Sort for ruby 1.9 compatibility
|
50
|
+
expect(rights.map(&:name)).to eq %w(models models#change models#index models#view users)
|
51
|
+
expect(rights.map(&:group)).to eq %w(general general general general admin)
|
52
|
+
|
53
|
+
expect(RightOn::Right.by_groups).to eq(
|
54
|
+
'general' => [@other, @index, @view, @change],
|
55
|
+
'admin' => [@users],
|
56
|
+
'other' => [@model.right]
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should determine if it is allowed based on context' do
|
61
|
+
index_action = {:controller => 'models', :action => 'index'}
|
62
|
+
edit_action = {:controller => 'models', :action => 'edit'}
|
63
|
+
hello_action = {:controller => 'models', :action => 'hello'}
|
64
|
+
|
65
|
+
expect(@model.right.allowed?(index_action)).to eq false
|
66
|
+
|
67
|
+
expect(@users.allowed?(:controller => 'users', :action => 'index')).to eq true
|
68
|
+
expect(@users.allowed?(:controller => 'users', :action => 'edit' )).to eq true
|
69
|
+
expect(@users.allowed?(:controller => 'users', :action => 'hello')).to eq true
|
70
|
+
|
71
|
+
expect(@other.allowed?(index_action)).to eq false # as specific action exists
|
72
|
+
expect(@other.allowed?(edit_action )).to eq false # as specific action exists
|
73
|
+
expect(@other.allowed?(hello_action)).to eq true # as hello isn't defined
|
74
|
+
|
75
|
+
expect(@index.allowed?(index_action)).to eq true
|
76
|
+
expect(@index.allowed?(edit_action )).to eq false
|
77
|
+
expect(@index.allowed?(hello_action)).to eq false
|
78
|
+
|
79
|
+
expect(@view.allowed?(index_action)).to eq true
|
80
|
+
expect(@view.allowed?(edit_action )).to eq false
|
81
|
+
expect(@view.allowed?(hello_action)).to eq false
|
82
|
+
|
83
|
+
expect(@change.allowed?(index_action)).to eq true
|
84
|
+
expect(@change.allowed?(edit_action )).to eq true
|
85
|
+
expect(@change.allowed?(hello_action)).to eq false
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe RightOn::Right, "when created" do
|
90
|
+
it "should validate presence of name" do
|
91
|
+
subject.valid?
|
92
|
+
expect(subject.errors[:name]).to_not be_blank
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe RightOn::Right, "with a name and controller" do
|
97
|
+
before do
|
98
|
+
@new_right = RightOn::Right.new(:name => "tickets", :controller => "tickets")
|
99
|
+
@new_right.save!
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should create a new right" do
|
103
|
+
expect(@new_right.name).to eq "tickets"
|
104
|
+
expect(@new_right.controller).to eq "tickets"
|
105
|
+
expect(@new_right.save).to eq true
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
describe RightOn::Right, "with a name, controller and action" do
|
111
|
+
before do
|
112
|
+
@new_right = RightOn::Right.new(:name => "tickets@destroy", :controller => "tickets", :action => "destroy")
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should create a new right" do
|
116
|
+
expect(@new_right.name).to eq "tickets@destroy"
|
117
|
+
expect(@new_right.controller).to eq "tickets"
|
118
|
+
expect(@new_right.action).to eq "destroy"
|
119
|
+
expect(@new_right.save).to eq true
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe RightOn::Right, "with only a name" do
|
124
|
+
before do
|
125
|
+
@new_right = RightOn::Right.new(:name => "tickets2")
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should create a new right" do
|
129
|
+
expect(@new_right.save).to eq true
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe RightOn::Right, "with the same name" do
|
134
|
+
before do
|
135
|
+
@old_right = RightOn::Right.new(:name => "tickets3", :controller => "tickets")
|
136
|
+
@old_right.save!
|
137
|
+
@new_right = RightOn::Right.new(:name => "tickets3", :controller => "tickets")
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should not create a new right" do
|
141
|
+
expect(@new_right.save).to eq false
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe RightOn::Role, "can have many rights" do
|
146
|
+
let(:role1) { RightOn::Role.new(:title => 'role 1') }
|
147
|
+
|
148
|
+
specify { expect(role1.to_s).to eq 'Role 1' }
|
149
|
+
|
150
|
+
context 'when assigned rights' do
|
151
|
+
let(:right1) { RightOn::Right.create!(:name => 'right 1') }
|
152
|
+
let(:right2) { RightOn::Right.create!(:name => 'right 2') }
|
153
|
+
|
154
|
+
before do
|
155
|
+
role1.save!
|
156
|
+
role1.rights = [right1, right2]
|
157
|
+
end
|
158
|
+
|
159
|
+
after do
|
160
|
+
role1.destroy
|
161
|
+
right1.destroy
|
162
|
+
right2.destroy
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should have and belong to many" do
|
166
|
+
expect(role1.rights.size).to eq 2
|
167
|
+
expect(right1.roles.size).to eq 1
|
168
|
+
expect(right2.roles.size).to eq 1
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe 'when checking accessibility to a controller' do
|
174
|
+
|
175
|
+
let(:test_controller_right) { RightOn::Right.new(name: 'test', controller: 'test') }
|
176
|
+
let(:user) { double(rights: [test_controller_right]) }
|
177
|
+
let(:controller) { 'test' }
|
178
|
+
let(:action) { 'index' }
|
179
|
+
let(:params) { {controller: 'test', action: 'index'} }
|
180
|
+
|
181
|
+
before do
|
182
|
+
stub_const 'TestController', double(current_user: user, params: params)
|
183
|
+
TestController.extend RightOn::ActionControllerExtensions
|
184
|
+
allow(TestController).to receive(:rights_from).and_return(nil)
|
185
|
+
end
|
186
|
+
|
187
|
+
specify { expect(TestController.access_allowed?(controller)).to be_truthy }
|
188
|
+
specify { expect(TestController.access_allowed?('other')).to be_falsey }
|
189
|
+
specify { expect(TestController.access_allowed_to_controller?(controller)).to be_truthy }
|
190
|
+
specify { expect(TestController.access_allowed_to_controller?('other')).to be_falsey }
|
191
|
+
|
192
|
+
describe 'when inheriting rights' do
|
193
|
+
let(:controller) { 'test_inherited' }
|
194
|
+
|
195
|
+
before do
|
196
|
+
stub_const 'TestInheritedController', double(current_user: user, params: params)
|
197
|
+
TestInheritedController.extend RightOn::ActionControllerExtensions
|
198
|
+
allow(TestInheritedController).to receive(:rights_from).and_return(:test)
|
199
|
+
end
|
200
|
+
|
201
|
+
specify { expect(TestInheritedController.access_allowed?(controller)).to be_falsey }
|
202
|
+
specify { expect(TestInheritedController.access_allowed?('other')).to be_falsey }
|
203
|
+
specify { expect(TestInheritedController.access_allowed_to_controller?(controller)).to be_truthy }
|
204
|
+
specify { expect(TestInheritedController.access_allowed_to_controller?('other')).to be_falsey }
|
205
|
+
end
|
206
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RightOn::RoleModel do
|
4
|
+
let(:admin_role) { RightOn::Role.create!(title: 'admin') }
|
5
|
+
let(:product_right) { RightOn::Right.create!(name: 'Products', controller: 'products') }
|
6
|
+
|
7
|
+
before do
|
8
|
+
RightOn::Role.delete_all
|
9
|
+
RightOn::Right.delete_all
|
10
|
+
admin_role.rights << product_right
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:basic_user) { User.create! }
|
14
|
+
let(:admin) { User.create!(roles: [admin_role]) }
|
15
|
+
|
16
|
+
it 'basic user should have no access' do
|
17
|
+
expect(basic_user.rights).to be_empty
|
18
|
+
expect(basic_user.has_right?('Products')).to be false
|
19
|
+
expect(basic_user.has_right?(product_right)).to be false
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'admin user should have full access' do
|
23
|
+
expect(admin.rights.size).to eq 1
|
24
|
+
expect(admin.has_right?('Products')).to be true
|
25
|
+
expect(admin.has_right?(product_right)).to be true
|
26
|
+
end
|
27
|
+
|
28
|
+
it '#has_privileges_of?' do
|
29
|
+
expect(admin.has_privileges_of?(basic_user)).to be true
|
30
|
+
expect(basic_user.has_privileges_of?(admin)).to be false
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'when associating rights of other objects' do
|
34
|
+
let(:model1) { Model.create! }
|
35
|
+
|
36
|
+
before do
|
37
|
+
admin_role.rights << model1.right
|
38
|
+
end
|
39
|
+
|
40
|
+
it '#has_access_to?' do
|
41
|
+
expect(admin.has_access_to?(model1)).to be true
|
42
|
+
expect(basic_user.has_access_to?(model1)).to be false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/spec/schema.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
ActiveRecord::Schema.define(:version => 1) do
|
2
|
+
create_table :rights do |t|
|
3
|
+
t.string :name, :controller, :action, :limit => 150
|
4
|
+
t.timestamps null: true
|
5
|
+
end
|
6
|
+
|
7
|
+
change_table :rights do |t|
|
8
|
+
t.index :action
|
9
|
+
t.index [:controller, :action]
|
10
|
+
t.index :name
|
11
|
+
end
|
12
|
+
|
13
|
+
create_table :rights_roles, :id => false do |t|
|
14
|
+
t.integer :right_id, :role_id
|
15
|
+
end
|
16
|
+
|
17
|
+
change_table :rights_roles do |t|
|
18
|
+
t.index [:right_id, :role_id]
|
19
|
+
t.index [:role_id, :right_id]
|
20
|
+
end
|
21
|
+
|
22
|
+
create_table :roles do |t|
|
23
|
+
t.string :title
|
24
|
+
t.text :description
|
25
|
+
t.integer :right_id
|
26
|
+
t.timestamps null: true
|
27
|
+
end
|
28
|
+
|
29
|
+
add_index :roles, :right_id
|
30
|
+
|
31
|
+
create_table :models do |t|
|
32
|
+
t.string :name
|
33
|
+
t.integer :right_id
|
34
|
+
end
|
35
|
+
|
36
|
+
create_table :users do |t|
|
37
|
+
t.string :name
|
38
|
+
end
|
39
|
+
|
40
|
+
create_table :roles_users do |t|
|
41
|
+
t.integer :role_id, :user_id
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper.rb"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'bundler/setup'
|
10
|
+
Bundler.require :default, :test
|
11
|
+
|
12
|
+
require 'support/bootstrap'
|
13
|
+
require 'support/coverage_loader'
|
14
|
+
|
15
|
+
require 'right_on'
|
16
|
+
require 'right_on/rails'
|
17
|
+
|
18
|
+
RSpec.configure do |config|
|
19
|
+
config.run_all_when_everything_filtered = true
|
20
|
+
config.filter_run :focus
|
21
|
+
config.before :all do
|
22
|
+
RightOn::Right.cache = ActiveSupport::Cache::MemoryStore.new
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
DB_FILE = 'tmp/test_db'
|
27
|
+
FileUtils.mkdir_p File.dirname(DB_FILE)
|
28
|
+
FileUtils.rm_f DB_FILE
|
29
|
+
|
30
|
+
ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => DB_FILE
|
31
|
+
|
32
|
+
load('spec/schema.rb')
|
33
|
+
|
34
|
+
RightOn::Right.rights_yaml 'db/rights_roles.yml'
|
35
|
+
|
36
|
+
class Model < ActiveRecord::Base
|
37
|
+
restricted_by_right
|
38
|
+
end
|
39
|
+
|
40
|
+
class User < ActiveRecord::Base
|
41
|
+
include RightOn::RoleModel
|
42
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Bootstrap
|
2
|
+
def self.reset_database
|
3
|
+
RightOn::Right.delete_all
|
4
|
+
RightOn::Role.delete_all
|
5
|
+
User.delete_all
|
6
|
+
|
7
|
+
basic_right = RightOn::Right.create!(:name => 'basic', :controller => 'basic')
|
8
|
+
admin_right = RightOn::Right.create!(:name => 'admin', :controller => 'admin')
|
9
|
+
basic_role = RightOn::Role.create!(:title => 'Basic', :rights => [basic_right])
|
10
|
+
admin_role = RightOn::Role.create!(:title => 'Admin', :rights => [admin_right])
|
11
|
+
|
12
|
+
User.create!(name: 'basic', roles: [basic_role])
|
13
|
+
User.create!(name: 'admin', roles: [basic_role, admin_role])
|
14
|
+
end
|
15
|
+
end
|