right_on 0.3.0 → 0.4.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 +5 -5
- data/.hound.yml +2 -0
- data/.rubocop.yml +5 -0
- data/.travis.yml +5 -2
- data/CHANGELOG.md +13 -0
- data/db/migration.rb +6 -6
- data/lib/right_on.rb +8 -1
- data/lib/right_on/ability.rb +9 -0
- data/lib/right_on/by_group.rb +13 -10
- data/lib/right_on/controller_additions.rb +52 -0
- data/lib/right_on/error.rb +3 -0
- data/lib/right_on/permission_denied_response.rb +2 -1
- data/lib/right_on/rails.rb +6 -1
- data/lib/right_on/right.rb +2 -94
- data/lib/right_on/right_allowed.rb +71 -0
- data/lib/right_on/role_model.rb +7 -10
- data/lib/right_on/rule.rb +51 -0
- data/lib/right_on/version.rb +1 -1
- data/right_on.gemspec +4 -2
- data/spec/ability_spec.rb +29 -0
- data/spec/by_group_spec.rb +22 -0
- data/spec/controller_additions_spec.rb +134 -0
- data/spec/{permission_defnied_spec.rb → permission_denied_response_spec.rb} +8 -8
- data/spec/right_allowed_spec.rb +89 -0
- data/spec/right_on_spec.rb +35 -123
- data/spec/role_model_spec.rb +5 -0
- data/spec/rule_spec.rb +81 -0
- data/spec/spec_helper.rb +1 -3
- data/spec/support/bootstrap.rb +19 -9
- data/spec/support/coverage_loader.rb +1 -1
- metadata +54 -13
- data/gemfiles/rails3.gemfile +0 -7
- data/lib/right_on/action_controller_extensions.rb +0 -68
- data/spec/action_controller_extensions_spec.rb +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3ed9eb070b0aac90604d39af448f24eb80f69d1c7b43e70262ff163ebeb9b414
|
4
|
+
data.tar.gz: 5645724ce29fb1167685bb8413b73c487313bd4c285d16ff879043eac3b5dc4b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de53dd0a3448bc3ed57e1621b179a4333c63f976f240f88812e0639c8cd7478ca10efef8cd3df2660ece487e9409f459e14147455d86a89590028c3588c7a8d5
|
7
|
+
data.tar.gz: 0c8836a459c9073b6b38d01efcbc5ca6e533405dc6efde62f462eba10cf8920fe1ba20c29c3703d647a9399cbaedcc68de34f392911c983776e0b0d53676f8c6
|
data/.hound.yml
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 2.3
|
3
|
+
- 2.3
|
4
|
+
- 2.4
|
5
|
+
- 2.5
|
4
6
|
script: "bundle exec rake spec"
|
5
7
|
gemfile:
|
6
|
-
- gemfiles/rails3.gemfile
|
7
8
|
- gemfiles/rails4.gemfile
|
8
9
|
- gemfiles/rails5.gemfile
|
10
|
+
# fix ruby 2.5 issue - https://github.com/travis-ci/travis-ci/issues/9333
|
11
|
+
before_install: gem install bundler
|
9
12
|
notifications:
|
10
13
|
email:
|
11
14
|
- support@travellink.com.au
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,19 @@ This changelog adheres to [Keep a CHANGELOG](http://keepachangelog.com/).
|
|
5
5
|
|
6
6
|
## Unreleased
|
7
7
|
|
8
|
+
## 0.4.0
|
9
|
+
|
10
|
+
### Improved
|
11
|
+
- Improve tests for RightOn::ByGroup
|
12
|
+
- Internal improvement of RightOn::ByGroup
|
13
|
+
- Internal extraction of 'allowed?' feature for failure message
|
14
|
+
- CanCanRight functionality merged into RightOn
|
15
|
+
- Cleanup of CanCanRight/RightOn merge
|
16
|
+
|
17
|
+
### Fixed
|
18
|
+
- [TT-3352] Ensure roles currently in use cannot be deleted
|
19
|
+
- Also dropped rails 3 support due to above
|
20
|
+
|
8
21
|
## 0.3.0
|
9
22
|
|
10
23
|
### Fixed
|
data/db/migration.rb
CHANGED
@@ -1,23 +1,23 @@
|
|
1
1
|
class RightOnMigration < ActiveRecord::Migration
|
2
2
|
def self.change
|
3
3
|
create_table :rights do |t|
|
4
|
-
t.string :name, :controller, :action, :
|
4
|
+
t.string :name, :controller, :action, limit: 150
|
5
5
|
t.timestamps
|
6
6
|
end
|
7
7
|
|
8
8
|
change_table :rights do |t|
|
9
9
|
t.index :action
|
10
10
|
t.index :name
|
11
|
-
t.index [
|
11
|
+
t.index %i[controller action]
|
12
12
|
end
|
13
13
|
|
14
|
-
create_table :rights_roles, :
|
15
|
-
t.integer
|
14
|
+
create_table :rights_roles, id: false do |t|
|
15
|
+
t.integer %i[right_id role_id]
|
16
16
|
end
|
17
17
|
|
18
18
|
change_table :rights_roles do |t|
|
19
|
-
t.index [
|
20
|
-
t.index [
|
19
|
+
t.index %i[right_id role_id]
|
20
|
+
t.index %i[role_id right_id]
|
21
21
|
end
|
22
22
|
|
23
23
|
create_table :roles do |t|
|
data/lib/right_on.rb
CHANGED
data/lib/right_on/by_group.rb
CHANGED
@@ -1,23 +1,24 @@
|
|
1
1
|
module RightOn
|
2
2
|
class ByGroup
|
3
|
+
def self.rights
|
4
|
+
new.by_groups
|
5
|
+
end
|
6
|
+
|
3
7
|
def initialize
|
4
8
|
@rights_by_name = Hash[Right.all.map{|r| [r.name, r]}]
|
5
9
|
end
|
6
10
|
|
7
11
|
def by_groups
|
8
|
-
|
9
|
-
|
10
|
-
|
12
|
+
yaml_rights.each_pair.with_object({}) do |(group, right_names), hash|
|
13
|
+
hash[group] = right_names
|
14
|
+
.flat_map { |right_name| right_name_to_rights(right_name) }
|
15
|
+
end
|
11
16
|
end
|
12
17
|
|
13
18
|
private
|
14
19
|
|
15
|
-
def
|
16
|
-
RightOn
|
17
|
-
right_names
|
18
|
-
.flat_map { |right_name| right_name_to_rights(right_name) }
|
19
|
-
.each { |r| r.group = group }
|
20
|
-
end
|
20
|
+
def yaml_rights
|
21
|
+
YAML.load_file(RightOn.rights_yaml)['rights']
|
21
22
|
end
|
22
23
|
|
23
24
|
def right_name_to_rights(right_name)
|
@@ -41,7 +42,9 @@ module RightOn
|
|
41
42
|
end
|
42
43
|
|
43
44
|
def rights_by_name!(name)
|
44
|
-
@rights_by_name[name] or fail name.inspect
|
45
|
+
@rights_by_name[name] or fail RightOn::RightNotFound, name.inspect
|
45
46
|
end
|
46
47
|
end
|
48
|
+
|
49
|
+
RightNotFound = Class.new(RightOn::Error)
|
47
50
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module RightOn
|
2
|
+
module ControllerAdditions
|
3
|
+
def self.included(base)
|
4
|
+
base.module_eval do
|
5
|
+
class_attribute :rights_from
|
6
|
+
class_attribute :permission_denied_layout
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def authorize_action!
|
13
|
+
controller = (self.rights_from || params[:controller]).to_s
|
14
|
+
action = params[:action].to_s
|
15
|
+
|
16
|
+
return if can_access_controller_action?(controller, action)
|
17
|
+
|
18
|
+
fail CanCan::AccessDenied, "You are not authorized to access this page."
|
19
|
+
end
|
20
|
+
|
21
|
+
def can_access_controller_action?(controller, action)
|
22
|
+
(can?(:access, controller) && !Right.where(ccr_subject: controller + '#' + action).exists?) ||
|
23
|
+
can?(:access, controller + '#' + action)
|
24
|
+
end
|
25
|
+
|
26
|
+
def access_granted?
|
27
|
+
can? :access, [params[:controller], params[:action]].join('#')
|
28
|
+
end
|
29
|
+
|
30
|
+
def rescue_access_denied(exception)
|
31
|
+
@permission_denied_response = RightOn::PermissionDeniedResponse.new(params, controller_action_options)
|
32
|
+
|
33
|
+
respond_to do |format|
|
34
|
+
format.html do
|
35
|
+
render status: :unauthorized,
|
36
|
+
template: 'permission_denied',
|
37
|
+
layout: ( permission_denied_layout || false )
|
38
|
+
end
|
39
|
+
|
40
|
+
format.json do
|
41
|
+
render status: :unauthorized, json: @permission_denied_response.to_json
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def controller_action_options
|
47
|
+
opts = params.slice(:controller, :action)
|
48
|
+
opts[:controller] = rights_from.to_s if rights_from
|
49
|
+
opts
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -4,7 +4,8 @@ module RightOn
|
|
4
4
|
|
5
5
|
def initialize(params, controller_action_options)
|
6
6
|
@params = params
|
7
|
-
|
7
|
+
allower = RightAllowed.new(controller_action_options[:controller], controller_action_options[:action])
|
8
|
+
@right_allowed = RightOn::Right.all.detect { |right| allower.allowed?(right) }
|
8
9
|
@roles_allowed = @right_allowed.roles if @right_allowed
|
9
10
|
@controller_name = @params[:controller] unless @right_allowed
|
10
11
|
end
|
data/lib/right_on/rails.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
require 'right_on/role_model'
|
2
|
+
require 'right_on/ability'
|
3
|
+
require 'right_on/rule'
|
4
|
+
require 'right_on/error'
|
2
5
|
require 'right_on/right'
|
3
6
|
require 'right_on/role'
|
7
|
+
require 'right_on/right_allowed'
|
4
8
|
require 'right_on/by_group'
|
5
|
-
require '
|
9
|
+
require 'cancan/exceptions'
|
10
|
+
require 'right_on/controller_additions'
|
6
11
|
require 'right_on/permission_denied_response'
|
data/lib/right_on/right.rb
CHANGED
@@ -10,70 +10,8 @@ module RightOn
|
|
10
10
|
|
11
11
|
scope :ordered, -> { order :name }
|
12
12
|
|
13
|
-
after_save
|
14
|
-
after_destroy
|
15
|
-
|
16
|
-
attr_accessor :group
|
17
|
-
|
18
|
-
class << self
|
19
|
-
def rights_yaml(file_path)
|
20
|
-
@@rights_yaml = file_path
|
21
|
-
end
|
22
|
-
|
23
|
-
def by_groups
|
24
|
-
RightOn::ByGroup.new.by_groups
|
25
|
-
end
|
26
|
-
|
27
|
-
def yaml_rights
|
28
|
-
YAML::load_file(@@rights_yaml)['rights']
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# Is this right allowed for the given context?
|
33
|
-
#
|
34
|
-
# Context params is an option hash:
|
35
|
-
# :controller => controller name
|
36
|
-
# :action => action name
|
37
|
-
#
|
38
|
-
# The context tells us the state of the request being made.
|
39
|
-
|
40
|
-
def allowed?(context={})
|
41
|
-
return false unless controller == context[:controller]
|
42
|
-
if action
|
43
|
-
action_permitted?(context[:action])
|
44
|
-
else
|
45
|
-
# right without action works if no specific right exists
|
46
|
-
# e.g. can't edit if there's a edit or change right defined
|
47
|
-
# as you must used that specific right
|
48
|
-
specific_rights = Array(APPLICABLE_RIGHTS[context[:action].to_sym]) + [context[:action]]
|
49
|
-
specific_rights.all?{|action| Right["#{context[:controller]}##{action}"].nil?}
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
APPLICABLE_RIGHTS = {
|
54
|
-
:new => [:change],
|
55
|
-
:edit => [:change],
|
56
|
-
:update => [:change],
|
57
|
-
:create => [:change],
|
58
|
-
:destroy => [:change],
|
59
|
-
:index => [:change, :view],
|
60
|
-
:show => [:change, :view]
|
61
|
-
}
|
62
|
-
|
63
|
-
CHANGE_ACTIONS = %w(new edit update create destroy index show)
|
64
|
-
|
65
|
-
VIEW_ACTIONS = %w(index show)
|
66
|
-
|
67
|
-
def action_permitted?(context_action)
|
68
|
-
case action.to_sym
|
69
|
-
when :change
|
70
|
-
CHANGE_ACTIONS.include?(context_action)
|
71
|
-
when :view
|
72
|
-
VIEW_ACTIONS.include?(context_action)
|
73
|
-
else
|
74
|
-
action == context_action
|
75
|
-
end
|
76
|
-
end
|
13
|
+
after_save { RightOn::RightAllowed.clear_cache }
|
14
|
+
after_destroy { RightOn::RightAllowed.clear_cache }
|
77
15
|
|
78
16
|
def sensible_name
|
79
17
|
name.humanize.titleize.gsub(/#/, ' - ')
|
@@ -82,35 +20,5 @@ module RightOn
|
|
82
20
|
def to_s
|
83
21
|
name
|
84
22
|
end
|
85
|
-
|
86
|
-
def self.cache
|
87
|
-
@@cache ||= Rails.cache
|
88
|
-
end
|
89
|
-
|
90
|
-
def self.cache=(cache)
|
91
|
-
@@cache = cache
|
92
|
-
end
|
93
|
-
|
94
|
-
def self.clear_cache
|
95
|
-
cache.delete('Right.all')
|
96
|
-
end
|
97
|
-
|
98
|
-
def clear_cache
|
99
|
-
self.class.clear_cache
|
100
|
-
end
|
101
|
-
|
102
|
-
attr_accessor :rights
|
103
|
-
def self.[](name)
|
104
|
-
@rights = cache.read('Right.all') || calculate_and_write_cache
|
105
|
-
@rights[name]
|
106
|
-
end
|
107
|
-
|
108
|
-
private
|
109
|
-
def self.calculate_and_write_cache
|
110
|
-
right_cache = Hash[Right.all.map{|r|[r.name, r.id]}]
|
111
|
-
cache.write('Right.all', right_cache) or raise RuntimeError, "Could not cache rights"
|
112
|
-
right_cache
|
113
|
-
end
|
114
|
-
|
115
23
|
end
|
116
24
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module RightOn
|
2
|
+
class RightAllowed
|
3
|
+
def initialize(controller, action)
|
4
|
+
@controller = controller
|
5
|
+
@action = action
|
6
|
+
end
|
7
|
+
|
8
|
+
def allowed?(right)
|
9
|
+
return false unless right.controller == @controller
|
10
|
+
if right.action
|
11
|
+
action_permitted?(right.action)
|
12
|
+
else
|
13
|
+
# right without action works if no specific right exists
|
14
|
+
# e.g. can't edit if there's a edit or change right defined
|
15
|
+
# as you must used that specific right
|
16
|
+
specific_rights = Array(APPLICABLE_RIGHTS[@action.to_sym]) + [@action]
|
17
|
+
specific_rights.all?{|action| self.class["#{@controller}##{action}"].nil?}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
APPLICABLE_RIGHTS = {
|
22
|
+
:new => [:change],
|
23
|
+
:edit => [:change],
|
24
|
+
:update => [:change],
|
25
|
+
:create => [:change],
|
26
|
+
:destroy => [:change],
|
27
|
+
:index => [:change, :view],
|
28
|
+
:show => [:change, :view]
|
29
|
+
}
|
30
|
+
|
31
|
+
CHANGE_ACTIONS = %w(new edit update create destroy index show)
|
32
|
+
|
33
|
+
VIEW_ACTIONS = %w(index show)
|
34
|
+
|
35
|
+
def action_permitted?(action)
|
36
|
+
case action.to_sym
|
37
|
+
when :change
|
38
|
+
CHANGE_ACTIONS.include?(@action)
|
39
|
+
when :view
|
40
|
+
VIEW_ACTIONS.include?(@action)
|
41
|
+
else
|
42
|
+
action == @action
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.cache
|
47
|
+
@@cache ||= Rails.cache
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.cache=(cache)
|
51
|
+
@@cache = cache
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.clear_cache
|
55
|
+
cache.delete('Right.all')
|
56
|
+
end
|
57
|
+
|
58
|
+
attr_accessor :rights
|
59
|
+
def self.[](name)
|
60
|
+
@rights = cache.read('Right.all') || calculate_and_write_cache
|
61
|
+
@rights[name]
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
def self.calculate_and_write_cache
|
66
|
+
right_cache = Hash[RightOn::Right.all.map{|r|[r.name, r.id]}]
|
67
|
+
cache.write('Right.all', right_cache) or raise RuntimeError, "Could not cache rights"
|
68
|
+
right_cache
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/right_on/role_model.rb
CHANGED
@@ -1,16 +1,13 @@
|
|
1
1
|
module RightOn
|
2
2
|
module RoleModel
|
3
3
|
def self.included(base)
|
4
|
-
base.module_eval
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
.select('distinct rights.*')
|
12
|
-
.joins(:roles)
|
13
|
-
.where('rights_roles.role_id IN (?)', role_ids)
|
4
|
+
base.module_eval do
|
5
|
+
has_and_belongs_to_many :roles, class_name: 'RightOn::Role'
|
6
|
+
has_many :rights, through: :roles, class_name: 'RightOn::Right'
|
7
|
+
end
|
8
|
+
Role.module_eval do
|
9
|
+
has_and_belongs_to_many base.table_name.to_sym, dependent: :restrict
|
10
|
+
end
|
14
11
|
end
|
15
12
|
|
16
13
|
def has_privileges_of?(other_user)
|