rolypoly 0.0.5 → 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.
- data/README.md +26 -1
- data/lib/rolypoly/controller_role_dsl.rb +23 -2
- data/lib/rolypoly/role_gatekeeper.rb +30 -9
- data/lib/rolypoly/version.rb +1 -1
- data/spec/lib/rolypoly/controller_role_dsl_spec.rb +10 -2
- metadata +4 -4
data/README.md
CHANGED
@@ -23,7 +23,7 @@ $> bundle
|
|
23
23
|
|
24
24
|
```ruby
|
25
25
|
class ApplicationController < ActionController::Base
|
26
|
-
def
|
26
|
+
def current_user_roles
|
27
27
|
current_user.roles
|
28
28
|
end
|
29
29
|
|
@@ -57,6 +57,7 @@ class UsersController < ApplicationController
|
|
57
57
|
|
58
58
|
# Make action public
|
59
59
|
restrict(:landing).to_none
|
60
|
+
# OR
|
60
61
|
publicize :landing
|
61
62
|
|
62
63
|
def landing
|
@@ -66,6 +67,30 @@ class UsersController < ApplicationController
|
|
66
67
|
# Give up and make all public
|
67
68
|
all_public
|
68
69
|
end
|
70
|
+
|
71
|
+
# Want some more complex role handling?
|
72
|
+
class ProfilesController < ApplicationController
|
73
|
+
allow(:admin).to_access(:index)
|
74
|
+
allow(:owner).to_access(:edit)
|
75
|
+
publicize(:show)
|
76
|
+
|
77
|
+
def index
|
78
|
+
current_roles # => [#<SomeCustomRoleObject to_role_string: "admin", filters: [...]>]
|
79
|
+
end
|
80
|
+
|
81
|
+
def edit # Raises permission error before entering this
|
82
|
+
current_roles # => []
|
83
|
+
end
|
84
|
+
|
85
|
+
def show
|
86
|
+
current_roles # => []
|
87
|
+
end
|
88
|
+
|
89
|
+
def current_user_roles
|
90
|
+
current_user.roles # => [#<SomeCustomRoleObject to_role_string: "admin", filters: [...]>, #<SomeCustomRoleObject to_role_string: "scorekeeper", filters: [...]>]
|
91
|
+
end
|
92
|
+
private :current_user_roles
|
93
|
+
end
|
69
94
|
```
|
70
95
|
|
71
96
|
## Contributing
|
@@ -14,8 +14,8 @@ module Rolypoly
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
unless sub.method_defined? :
|
18
|
-
define_method(:
|
17
|
+
unless sub.method_defined? :current_user_roles
|
18
|
+
define_method(:current_user_roles) { [] }
|
19
19
|
end
|
20
20
|
sub.send :extend, ClassMethods
|
21
21
|
sub.class_eval do # Sometimes get Stack Too Deep errors if in ClassMethods
|
@@ -34,6 +34,27 @@ module Rolypoly
|
|
34
34
|
raise Rolypoly::FailedRoleCheckError
|
35
35
|
end
|
36
36
|
|
37
|
+
def current_roles
|
38
|
+
return [] if rolypoly_gatekeepers.empty?
|
39
|
+
current_gatekeepers.reduce([]) { |array, gatekeeper|
|
40
|
+
if gatekeeper.role? current_user_roles
|
41
|
+
array += Array(gatekeeper.allowed_roles(current_user_roles, action_name))
|
42
|
+
end
|
43
|
+
array
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
def public?
|
48
|
+
return true if rolypoly_gatekeepers.empty?
|
49
|
+
current_gatekeepers.any &:public?
|
50
|
+
end
|
51
|
+
|
52
|
+
def current_gatekeepers
|
53
|
+
rolypoly_gatekeepers.select { |gatekeeper|
|
54
|
+
gatekeeper.action? action_name
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
37
58
|
def rolypoly_role_access?
|
38
59
|
rolypoly_gatekeepers.empty? ||
|
39
60
|
rolypoly_gatekeepers.any? { |gatekeeper|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'set'
|
2
2
|
module Rolypoly
|
3
3
|
class RoleGatekeeper
|
4
|
+
attr_reader :roles
|
4
5
|
def initialize(roles, actions)
|
5
6
|
self.roles = Set.new Array(roles).map(&:to_s)
|
6
7
|
self.actions = Set.new Array(actions).map(&:to_s)
|
@@ -35,28 +36,48 @@ module Rolypoly
|
|
35
36
|
role?(current_roles)
|
36
37
|
end
|
37
38
|
|
39
|
+
def allowed_roles(current_roles, action)
|
40
|
+
return [] if public? || !action?(action)
|
41
|
+
match_roles(current_roles)
|
42
|
+
end
|
43
|
+
|
38
44
|
def all_public
|
39
45
|
self.public = true
|
40
46
|
self.all_actions = true
|
41
47
|
end
|
42
48
|
|
43
|
-
protected # self.attr= gets mad
|
44
|
-
attr_accessor :roles
|
45
|
-
attr_accessor :actions
|
46
|
-
attr_accessor :all_actions
|
47
|
-
attr_accessor :public
|
48
|
-
|
49
49
|
def role?(check_roles)
|
50
|
-
check_roles = Set.new
|
50
|
+
check_roles = Set.new sanitize_role_input(check_roles)
|
51
51
|
public? || !(check_roles & roles).empty?
|
52
52
|
end
|
53
|
-
private :role?
|
54
53
|
|
55
54
|
def action?(check_actions)
|
56
55
|
check_actions = Set.new Array(check_actions).map(&:to_s)
|
57
56
|
all_actions? || !(check_actions & actions).empty?
|
58
57
|
end
|
59
|
-
|
58
|
+
|
59
|
+
protected # self.attr= gets mad
|
60
|
+
attr_writer :roles
|
61
|
+
attr_accessor :actions
|
62
|
+
attr_accessor :all_actions
|
63
|
+
attr_accessor :public
|
64
|
+
|
65
|
+
def match_roles(check_roles)
|
66
|
+
check_roles.reduce([]) { |array, role_object|
|
67
|
+
array << role_object if roles.include?(sanitize_role_object(role_object))
|
68
|
+
array
|
69
|
+
}
|
70
|
+
end
|
71
|
+
private :match_roles
|
72
|
+
|
73
|
+
def sanitize_role_input(role_objects)
|
74
|
+
Array(role_objects).map { |r| sanitize_role_object(r) }
|
75
|
+
end
|
76
|
+
private :sanitize_role_input
|
77
|
+
|
78
|
+
def sanitize_role_object(role_object)
|
79
|
+
role_object.respond_to?(:to_role_string) ? role_object.to_role_string : role_object.to_s
|
80
|
+
end
|
60
81
|
|
61
82
|
def can_set_with_to?
|
62
83
|
roles.empty?
|
data/lib/rolypoly/version.rb
CHANGED
@@ -1,4 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
class RoleObject < Struct.new :name
|
3
|
+
def to_s
|
4
|
+
name.to_s
|
5
|
+
end
|
6
|
+
end
|
2
7
|
module Rolypoly
|
3
8
|
describe ControllerRoleDSL do
|
4
9
|
let(:example_controller) do
|
@@ -14,11 +19,11 @@ module Rolypoly
|
|
14
19
|
describe "setting up with DSL" do
|
15
20
|
describe "from allow side" do
|
16
21
|
let(:controller_instance) { subject.new }
|
17
|
-
let(:
|
22
|
+
let(:current_user_roles) { [RoleObject.new(:admin), RoleObject.new(:scorekeeper)] }
|
18
23
|
before do
|
19
24
|
subject.allow(:admin).to_access(:index)
|
20
25
|
subject.publicize(:landing)
|
21
|
-
controller_instance.stub
|
26
|
+
controller_instance.stub current_user_roles: current_user_roles, action_name: action_name
|
22
27
|
end
|
23
28
|
|
24
29
|
describe "#index" do
|
@@ -27,6 +32,9 @@ module Rolypoly
|
|
27
32
|
expect { controller_instance.rolypoly_check_role_access! }
|
28
33
|
.not_to raise_error
|
29
34
|
end
|
35
|
+
it "can get current_roles from controller" do
|
36
|
+
controller_instance.current_roles.should == [RoleObject.new(:admin)]
|
37
|
+
end
|
30
38
|
end
|
31
39
|
|
32
40
|
describe "#show" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rolypoly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-10-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -97,7 +97,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
97
97
|
version: '0'
|
98
98
|
segments:
|
99
99
|
- 0
|
100
|
-
hash:
|
100
|
+
hash: -3998777984339591811
|
101
101
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
102
|
none: false
|
103
103
|
requirements:
|
@@ -106,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
106
106
|
version: '0'
|
107
107
|
segments:
|
108
108
|
- 0
|
109
|
-
hash:
|
109
|
+
hash: -3998777984339591811
|
110
110
|
requirements: []
|
111
111
|
rubyforge_project:
|
112
112
|
rubygems_version: 1.8.25
|