cant_cant_cant 0.1.9 → 0.1.10
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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3c41e2930a4a017599c9e543e4c5e1169889117
|
4
|
+
data.tar.gz: 86763bee8b49529010526fce57b9f679a24a8bfc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 566fcfca7d3f06465cacf466ab1890161d70901a3754d4c61e3d3f924bcd97cf227bb54e3120cd5e69a7801ee2a32a46adc08fb3e414ec0e86307025550cb5b5
|
7
|
+
data.tar.gz: 5c974bc3695058e4b763e9077d10db1b469b5a3613d4475d5fcf9e9e71b90c539ed27be6302fdba0499ec39b1f9087bc184255aaca935d4ef824ff8c04029101
|
data/README.md
CHANGED
@@ -36,7 +36,7 @@ You're done. There is no need to configure more in any of your controllers.
|
|
36
36
|
|
37
37
|
Note that live reloading is not supported yet; it means you'll need to restart your server after modifying your actions/controllers/config to take effect.
|
38
38
|
|
39
|
-
If you need to acquire a list of actions that given roles have access to, just call `CantCantCant.
|
39
|
+
If you need to acquire a list of actions that given roles have access to, just call `CantCantCant.allowed_actions_for(roles)`.
|
40
40
|
|
41
41
|
|
42
42
|
## Configuration
|
data/lib/cant_cant_cant.rb
CHANGED
@@ -1,43 +1,108 @@
|
|
1
1
|
require 'yaml'
|
2
|
+
require 'ostruct'
|
3
|
+
require 'set'
|
4
|
+
require_relative 'concern'
|
2
5
|
|
3
6
|
module CantCantCant
|
4
7
|
PermissionDenied = Class.new(RuntimeError)
|
5
8
|
InvalidConfiguration = Class.new(RuntimeError)
|
9
|
+
UnfilledAction = Class.new(RuntimeError)
|
6
10
|
|
7
11
|
class << self
|
8
|
-
def initialize(config)
|
12
|
+
def initialize(config, &block)
|
9
13
|
@config_file = config
|
10
|
-
@cache = {}
|
11
14
|
|
12
|
-
|
13
|
-
|
15
|
+
@config = OpenStruct.new(
|
16
|
+
injection_mode: :base_controller,
|
17
|
+
base_controller: ActionController::Base,
|
18
|
+
default_policy: :allow,
|
19
|
+
report_unfilled_actions: :ignore,
|
20
|
+
caching: true
|
21
|
+
)
|
22
|
+
@config.instance_eval(&block) if block_given?
|
23
|
+
|
24
|
+
@allow_cache = {}
|
25
|
+
@deny_cache = {}
|
14
26
|
|
15
|
-
def inject_actions
|
16
27
|
validate_config
|
17
28
|
|
18
|
-
|
19
|
-
|
29
|
+
case @config.injection_mode
|
30
|
+
when :base_controller
|
31
|
+
inject_base_controller
|
32
|
+
when :individual
|
33
|
+
inject_individual_actions
|
20
34
|
end
|
21
35
|
end
|
22
36
|
|
23
|
-
def allow?(
|
24
|
-
|
37
|
+
def allow?(action, roles)
|
38
|
+
return true if allowed_actions_for(roles).include? action
|
39
|
+
return false if denied_actions_for(roles).include?(action)
|
40
|
+
|
41
|
+
case @config.report_unfilled_actions
|
42
|
+
# when :ignore, do nothing
|
43
|
+
when :warn
|
44
|
+
warn "Please fill in CantCantCant permission #{action}"
|
45
|
+
when :raise
|
46
|
+
raise UnfilledAction, [action, roles]
|
47
|
+
end
|
48
|
+
|
49
|
+
case @config.default_policy
|
50
|
+
when :allow then true
|
51
|
+
when :deny then false
|
52
|
+
end
|
25
53
|
end
|
26
54
|
|
27
|
-
def
|
55
|
+
def allowed_actions_for(roles)
|
28
56
|
roles = [roles] unless roles.is_a? Array
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
57
|
+
key = roles.sort.join(',')
|
58
|
+
return @allow_cache[key] if @allow_cache[key] && @config.caching
|
59
|
+
|
60
|
+
perms = permission_table
|
61
|
+
.values_at(*roles.map(&:to_s))
|
62
|
+
.select(&:present?)
|
63
|
+
allowed_perms = perms
|
64
|
+
.map { |x| x.select { |_, v| v == 'allow' }.keys }
|
65
|
+
.flatten
|
66
|
+
.uniq
|
67
|
+
@allow_cache[key] = allowed_perms.to_set
|
68
|
+
end
|
69
|
+
|
70
|
+
def all_actions
|
71
|
+
@all_actions = nil unless @config.caching
|
72
|
+
@all_actions ||= permission_table
|
73
|
+
.values
|
74
|
+
.map(&:keys)
|
75
|
+
.flatten
|
76
|
+
.uniq
|
77
|
+
.to_set
|
78
|
+
end
|
79
|
+
|
80
|
+
def denied_actions_for(roles)
|
81
|
+
roles = [roles] unless roles.is_a? Array
|
82
|
+
key = roles.sort.join(',')
|
83
|
+
return @deny_cache[key] if @deny_cache[key] && @config.caching
|
84
|
+
@deny_cache[key] = all_actions - allowed_actions_for(roles)
|
36
85
|
end
|
37
86
|
|
38
87
|
private
|
39
88
|
|
89
|
+
def inject_base_controller
|
90
|
+
base_controller_class = @config.base_controller
|
91
|
+
base_controller_class.before_action CantCantCantAuth
|
92
|
+
end
|
93
|
+
|
94
|
+
def inject_individual_actions
|
95
|
+
controller_actions = all_actions
|
96
|
+
.map { |x| extract_controller(x) }
|
97
|
+
.group_by(&:first)
|
98
|
+
controller_actions.each do |controller, actions|
|
99
|
+
actions = actions.map(&:second)
|
100
|
+
controller.before_action CantCantCantAuth, only: actions
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
40
104
|
def permission_table
|
105
|
+
@permission_table = nil unless @config.caching
|
41
106
|
@permission_table ||= YAML.load_file(@config_file).freeze
|
42
107
|
end
|
43
108
|
|
@@ -51,17 +116,6 @@ module CantCantCant
|
|
51
116
|
[controller_class, action]
|
52
117
|
end
|
53
118
|
|
54
|
-
def inject_action(param)
|
55
|
-
controller_class, action = extract_controller(param)
|
56
|
-
controller_class.class_eval do
|
57
|
-
before_action(only: action) do
|
58
|
-
roles = current_roles
|
59
|
-
next true if CantCantCant.allow?(param, roles)
|
60
|
-
raise PermissionDenied, [param, roles]
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
119
|
def validate_config
|
66
120
|
permission_table.each do |_, perms|
|
67
121
|
perms.each do |param, access|
|
data/lib/concern.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
class CantCantCantAuth
|
2
|
+
def self.before(controller)
|
3
|
+
roles = controller.current_roles
|
4
|
+
params = controller.params
|
5
|
+
action = "#{params[:controller]}\##{params[:action]}"
|
6
|
+
return true if CantCantCant.allow?(action, roles)
|
7
|
+
raise CantCantCant::PermissionDenied, [action, roles]
|
8
|
+
end
|
9
|
+
end
|
@@ -1,6 +1,24 @@
|
|
1
1
|
Rails.application.config.after_initialize do
|
2
|
-
|
3
|
-
CantCantCant.initialize(
|
2
|
+
perm_file = File.join(Rails.root, 'config/cant_cant_cant.yml')
|
3
|
+
CantCantCant.initialize(perm_file) do |c|
|
4
|
+
# - base_controller: Inject validation to the base controller
|
5
|
+
# - individual: Inject validation only to actions specified in config
|
6
|
+
# c.injection_mode = :base_controller
|
7
|
+
|
8
|
+
# This option is ignored unless c.injection_mode == :base_controller
|
9
|
+
# c.base_controller = ActionController::Base
|
10
|
+
|
11
|
+
# Specify what to do for unlisted access
|
12
|
+
# c.default_policy = :allow
|
13
|
+
|
14
|
+
# warn: print a warning for unlisted actions and adopt default_policy
|
15
|
+
# raise: raise an exception for unlisted actions
|
16
|
+
# ignore: ignore validation on unlisted actions and adopt default_policy
|
17
|
+
# c.report_unlisted_actions = :ignore
|
18
|
+
|
19
|
+
# Cache permission or load them from file for every request
|
20
|
+
c.caching = Rails.env.production?
|
21
|
+
end
|
4
22
|
end
|
5
23
|
|
6
24
|
class ActionController::Base
|
@@ -8,6 +26,10 @@ class ActionController::Base
|
|
8
26
|
rescue_from CantCantCant::PermissionDenied do
|
9
27
|
render plain: 'permission denied', status: 403
|
10
28
|
end
|
29
|
+
# Only useful when report_unlisted_actions is set :raise
|
30
|
+
rescue_from CantCantCant::UnfilledAction do
|
31
|
+
render plain: 'action unlisted in cantcantcant permission file'
|
32
|
+
end
|
11
33
|
|
12
34
|
# Write your own method to return the roles for current user
|
13
35
|
def current_roles
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cant_cant_cant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shou Ya
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-03-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -62,6 +62,7 @@ files:
|
|
62
62
|
- README.md
|
63
63
|
- Rakefile
|
64
64
|
- lib/cant_cant_cant.rb
|
65
|
+
- lib/concern.rb
|
65
66
|
- lib/generators/cant_cant_cant/install/install_generator.rb
|
66
67
|
- lib/generators/cant_cant_cant/install/templates/config.yml
|
67
68
|
- lib/generators/cant_cant_cant/install/templates/initializer.rb
|