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 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