rolypoly 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -23,7 +23,7 @@ $> bundle
23
23
 
24
24
  ```ruby
25
25
  class ApplicationController < ActionController::Base
26
- def current_roles
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? :current_roles
18
- define_method(:current_roles) { [] }
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 Array(check_roles).map(&:to_s)
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
- private :action?
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?
@@ -1,3 +1,3 @@
1
1
  module Rolypoly
2
- VERSION = "0.0.5"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -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(:current_roles) { [:admin] }
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 current_roles: current_roles, action_name: action_name
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.5
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-09-25 00:00:00.000000000 Z
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: 1102617344684518140
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: 1102617344684518140
109
+ hash: -3998777984339591811
110
110
  requirements: []
111
111
  rubyforge_project:
112
112
  rubygems_version: 1.8.25