acl_system2 0.2.0 → 0.2.1

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.
@@ -1,5 +1,3 @@
1
- require "#{ File.dirname(__FILE__) }/acl_system2/version"
2
- require "#{ File.dirname(__FILE__) }/acl_system2/caboose/logic_parser"
3
- require "#{ File.dirname(__FILE__) }/acl_system2/caboose/role_handler"
4
- require "#{ File.dirname(__FILE__) }/acl_system2/caboose/access_control"
5
-
1
+ Dir[File.dirname(__FILE__) + '/acl_system2/*.rb'].each do |file|
2
+ require file
3
+ end
@@ -0,0 +1,61 @@
1
+ Dir[File.dirname(__FILE__) + '/access_control/*.rb'].each do |file|
2
+ require file
3
+ end
4
+
5
+ module ACLSystem2
6
+
7
+ module AccessControl
8
+
9
+ def self.included(subject)
10
+ subject.extend(ClassMethods)
11
+ if subject.respond_to? :helper_method
12
+ subject.helper_method(:permit?)
13
+ subject.helper_method(:restrict_to)
14
+ end
15
+ end
16
+
17
+ # return the active access handler, fallback to RoleHandler
18
+ # implement #retrieve_access_handler to return non-default handler
19
+ def access_handler
20
+ if respond_to?(:retrieve_access_handler)
21
+ @handler ||= retrieve_access_handler
22
+ else
23
+ @handler ||= RoleHandler.new
24
+ end
25
+ end
26
+
27
+ # the current access context; will be created if not setup
28
+ # will add current_user and merge any other elements of context
29
+ def access_context(context = {})
30
+ default_access_context.merge(context)
31
+ end
32
+
33
+ def default_access_context
34
+ @default_access_context ||= {}
35
+ @default_access_context[:user] = send(:current_user) if respond_to?(:current_user)
36
+ @default_access_context
37
+ end
38
+
39
+ def default_access_context=(defaults)
40
+ @default_access_context = defaults
41
+ end
42
+
43
+ def permit?(logicstring, context = {})
44
+ access_handler.process(logicstring, access_context(context))
45
+ end
46
+
47
+ # restrict_to "admin | moderator" do
48
+ # link_to "foo"
49
+ # end
50
+ def restrict_to(logicstring, context = {})
51
+ return false if current_user.nil?
52
+ result = ''
53
+ if permit?(logicstring, context)
54
+ result = yield if block_given?
55
+ end
56
+ result
57
+ end
58
+
59
+ end
60
+
61
+ end
@@ -0,0 +1,25 @@
1
+ module ACLSystem2
2
+ module AccessControl
3
+ class AccessSentry
4
+
5
+ def initialize(subject, actions={})
6
+ @actions = actions.inject({}) do |auth, current|
7
+ [current.first].flatten.each { |action| auth[action] = current.last }
8
+ auth
9
+ end
10
+ @subject = subject
11
+ end
12
+
13
+ def allowed?(action)
14
+ if @actions.has_key? action.to_sym
15
+ return @subject.access_handler.process(@actions[action.to_sym].dup, @subject.access_context)
16
+ elsif @actions.has_key? :DEFAULT
17
+ return @subject.access_handler.process(@actions[:DEFAULT].dup, @subject.access_context)
18
+ else
19
+ return true
20
+ end
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,34 @@
1
+ module ACLSystem2
2
+ module AccessControl
3
+ module ClassMethods
4
+ # access_control [:create, :edit] => 'admin & !blacklist',
5
+ # :update => '(admin | moderator) & !blacklist',
6
+ # :list => '(admin | moderator | user) & !blacklist'
7
+ def access_control(actions = {})
8
+ # Add class-wide permission callback to before_filter
9
+ defaults = {}
10
+
11
+ if block_given?
12
+ yield defaults
13
+ default_block_given = true
14
+ end
15
+
16
+ before_filter do |c|
17
+ c.default_access_context = defaults if default_block_given
18
+ @access = AccessSentry.new(c, actions)
19
+
20
+ if @access.allowed?(c.action_name)
21
+ c.send(:permission_granted) if c.respond_to?:permission_granted
22
+ else
23
+ if c.respond_to?(:permission_denied)
24
+ c.send(:permission_denied)
25
+ else
26
+ c.send(:render, :text => "You have insuffient permissions to access #{ c.controller_name }/#{ c.action_name }")
27
+ end
28
+ end
29
+ end
30
+
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,12 @@
1
+ require "#{ File.dirname(__FILE__) }/logic_parser"
2
+
3
+ module ACLSystem2
4
+ class AccessHandler
5
+ include LogicParser
6
+
7
+ def check(key, context)
8
+ false
9
+ end
10
+
11
+ end
12
+ end
@@ -1,4 +1,4 @@
1
- module Caboose
1
+ module ACLSystem2
2
2
 
3
3
  module LogicParser
4
4
  # This module holds our recursive descent parser that take a logic string
@@ -45,4 +45,4 @@ module Caboose
45
45
 
46
46
  end # LogicParser
47
47
 
48
- end
48
+ end
@@ -1,20 +1,13 @@
1
- module Caboose
2
-
3
- class AccessHandler
4
- include LogicParser
1
+ require "#{ File.dirname(__FILE__) }/access_handler"
2
+
3
+ module ACLSystem2
5
4
 
6
- def check(key, context)
7
- false
8
- end
9
-
10
- end
11
-
12
5
  class RoleHandler < AccessHandler
13
6
 
14
7
  def check(key, context)
15
8
  context[:user].roles.map{ |role| role.title.downcase}.include? key.downcase
16
9
  end
17
10
 
18
- end # End RoleHandler
11
+ end
19
12
 
20
- end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module ACLSystem2
2
- VERSION = "0.2.0"
2
+ VERSION = '0.2.1'
3
3
  end
@@ -1,5 +1,5 @@
1
1
  require "#{ File.dirname(__FILE__) }/../lib/acl_system2"
2
2
 
3
- ActionController::Base.send :include, Caboose
4
- ActionController::Base.send :include, Caboose::AccessControl
3
+ ActionController::Base.send :include, ACLSystem2
4
+ ActionController::Base.send :include, ACLSystem2::AccessControl
5
5
 
@@ -1,90 +1,10 @@
1
- require 'test/unit'
2
1
  require File.dirname(__FILE__) + '/test_helper'
3
- require 'ostruct'
4
2
 
5
- # mock objects
6
-
7
- class User
8
-
9
- attr_accessor :name
10
-
11
- def name
12
- @name ||= 'anon'
13
- @name
14
- end
15
-
16
- def roles
17
- [OpenStruct.new(:title => 'admin'), OpenStruct.new(:title => 'user')]
18
- end
19
-
20
- end
21
-
22
- class ControllerProxy
23
-
24
- attr_accessor :action_name
25
-
26
- class << self
27
-
28
- attr_reader :before_block
29
-
30
- def before_filter(&block)
31
- @before_block = block if block_given?
32
- end
33
-
34
- end
35
-
36
- def before_action
37
- self.class.before_block.call(self)
38
- end
39
-
40
- include Caboose::AccessControl
41
-
42
- access_control([:create, :edit] => 'admin & !blacklist',
43
- :update => '(admin | moderator) & !blacklist',
44
- :list => '(admin | moderator | user) & !blacklist',
45
- :private => 'vip') do |context|
46
- context[:variable] = 'value'
47
- context[:login_time] = Time.new
48
- end
49
-
50
- def permission_granted
51
- true
52
- end
53
-
54
- def permission_denied
55
- false
56
- end
57
-
58
- def current_user
59
- User.new
60
- end
61
-
62
- end
63
-
64
- class FabOnlyHandler < Caboose::AccessHandler
65
-
66
- def check(key, context)
67
- (context[:user].name.downcase == 'fabien' and context[:user].roles.map{ |role| role.title.downcase}.include?(key))
68
- end
69
-
70
- end
71
-
72
- class ControllerProxyWithFabHandler < ControllerProxy
73
-
74
- def retrieve_access_handler
75
- FabOnlyHandler.new
76
- end
77
-
78
- end
79
-
80
-
81
- # tests
82
3
  class AccessControlTest < Test::Unit::TestCase
83
4
 
84
-
85
5
  def test_first
86
6
  context = { :user => User.new }
87
- @handler = Caboose::RoleHandler.new
7
+ @handler = ACLSystem2::RoleHandler.new
88
8
  assert @handler.process("(admin | moderator) & !blacklist", context)
89
9
  assert @handler.process("(user | moderator) & !blacklist", context)
90
10
  assert @handler.process("(user | moderator | user) & !blacklist", context)
@@ -159,4 +79,4 @@ class AccessControlTest < Test::Unit::TestCase
159
79
  assert controller.access_context.include?(:login_time)
160
80
  end
161
81
 
162
- end
82
+ end
@@ -0,0 +1,5 @@
1
+ require 'ostruct'
2
+
3
+ Dir[File.dirname(__FILE__) + '/mocks/*.rb'].each do |file|
4
+ require file
5
+ end
@@ -0,0 +1,43 @@
1
+ require "#{ File.dirname(__FILE__) }/user"
2
+
3
+ class ControllerProxy
4
+
5
+ attr_accessor :action_name
6
+
7
+ class << self
8
+
9
+ attr_reader :before_block
10
+
11
+ def before_filter(&block)
12
+ @before_block = block if block_given?
13
+ end
14
+
15
+ end
16
+
17
+ def before_action
18
+ self.class.before_block.call(self)
19
+ end
20
+
21
+ include ACLSystem2::AccessControl
22
+
23
+ access_control([:create, :edit] => 'admin & !blacklist',
24
+ :update => '(admin | moderator) & !blacklist',
25
+ :list => '(admin | moderator | user) & !blacklist',
26
+ :private => 'vip') do |context|
27
+ context[:variable] = 'value'
28
+ context[:login_time] = Time.new
29
+ end
30
+
31
+ def permission_granted
32
+ true
33
+ end
34
+
35
+ def permission_denied
36
+ false
37
+ end
38
+
39
+ def current_user
40
+ User.new
41
+ end
42
+
43
+ end
@@ -0,0 +1,10 @@
1
+ require "#{ File.dirname(__FILE__) }/controller_proxy"
2
+ require "#{ File.dirname(__FILE__) }/fab_only_handler"
3
+
4
+ class ControllerProxyWithFabHandler < ControllerProxy
5
+
6
+ def retrieve_access_handler
7
+ FabOnlyHandler.new
8
+ end
9
+
10
+ end
@@ -0,0 +1,8 @@
1
+ class FabOnlyHandler < ACLSystem2::AccessHandler
2
+
3
+ def check(key, context)
4
+ (context[:user].name.downcase == 'fabien' && context[:user].roles.map{ |role| role.title.downcase }.include?(key))
5
+ end
6
+
7
+ end
8
+
@@ -0,0 +1,13 @@
1
+ class User
2
+
3
+ attr_accessor :name
4
+
5
+ def name
6
+ @name ||= 'anon'
7
+ end
8
+
9
+ def roles
10
+ [OpenStruct.new(:title => 'admin'), OpenStruct.new(:title => 'user')]
11
+ end
12
+
13
+ end
@@ -1,3 +1,4 @@
1
+ require 'test/unit'
1
2
  require 'turn'
2
3
 
3
4
  Turn.config do |c|
@@ -5,4 +6,4 @@ Turn.config do |c|
5
6
  end
6
7
 
7
8
  require "#{ File.dirname(__FILE__) }/../lib/acl_system2"
8
-
9
+ require "#{ File.dirname(__FILE__) }/mocks"
metadata CHANGED
@@ -1,76 +1,74 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: acl_system2
3
- version: !ruby/object:Gem::Version
4
- hash: 23
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 2
9
- - 0
10
- version: 0.2.0
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Ezra Zygmuntowicz
14
9
  - Fabien Franzen
15
10
  - Gareth Rees
16
11
  autorequire:
17
12
  bindir: bin
18
13
  cert_chain: []
19
-
20
- date: 2013-01-29 00:00:00 Z
21
- dependencies:
22
- - !ruby/object:Gem::Dependency
14
+ date: 2013-03-06 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
23
17
  name: minitest
24
- prerelease: false
25
- requirement: &id001 !ruby/object:Gem::Requirement
18
+ requirement: !ruby/object:Gem::Requirement
26
19
  none: false
27
- requirements:
28
- - - ">="
29
- - !ruby/object:Gem::Version
30
- hash: 3
31
- segments:
32
- - 0
33
- version: "0"
20
+ requirements:
21
+ - - ! '>='
22
+ - !ruby/object:Gem::Version
23
+ version: '0'
34
24
  type: :development
35
- version_requirements: *id001
36
- - !ruby/object:Gem::Dependency
37
- name: turn
38
25
  prerelease: false
39
- requirement: &id002 !ruby/object:Gem::Requirement
26
+ version_requirements: !ruby/object:Gem::Requirement
40
27
  none: false
41
- requirements:
42
- - - ">="
43
- - !ruby/object:Gem::Version
44
- hash: 3
45
- segments:
46
- - 0
47
- version: "0"
28
+ requirements:
29
+ - - ! '>='
30
+ - !ruby/object:Gem::Version
31
+ version: '0'
32
+ - !ruby/object:Gem::Dependency
33
+ name: turn
34
+ requirement: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
48
40
  type: :development
49
- version_requirements: *id002
50
- - !ruby/object:Gem::Dependency
51
- name: rake
52
41
  prerelease: false
53
- requirement: &id003 !ruby/object:Gem::Requirement
42
+ version_requirements: !ruby/object:Gem::Requirement
54
43
  none: false
55
- requirements:
56
- - - ">="
57
- - !ruby/object:Gem::Version
58
- hash: 3
59
- segments:
60
- - 0
61
- version: "0"
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ - !ruby/object:Gem::Dependency
49
+ name: rake
50
+ requirement: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
62
56
  type: :development
63
- version_requirements: *id003
64
- description: An access control gem for Rails. A flexible declarative way of protecting your various controller actions using roles.
65
- email:
57
+ prerelease: false
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ description: An access control gem for Rails. A flexible declarative way of protecting
65
+ your various controller actions using roles.
66
+ email:
66
67
  - gareth@garethrees.co.uk
67
68
  executables: []
68
-
69
69
  extensions: []
70
-
71
70
  extra_rdoc_files: []
72
-
73
- files:
71
+ files:
74
72
  - .gitignore
75
73
  - Gemfile
76
74
  - LICENSE.txt
@@ -78,46 +76,50 @@ files:
78
76
  - Rakefile
79
77
  - acl_system2.gemspec
80
78
  - lib/acl_system2.rb
81
- - lib/acl_system2/caboose/access_control.rb
82
- - lib/acl_system2/caboose/logic_parser.rb
83
- - lib/acl_system2/caboose/role_handler.rb
79
+ - lib/acl_system2/access_control.rb
80
+ - lib/acl_system2/access_control/access_sentry.rb
81
+ - lib/acl_system2/access_control/class_methods.rb
82
+ - lib/acl_system2/access_handler.rb
83
+ - lib/acl_system2/logic_parser.rb
84
+ - lib/acl_system2/role_handler.rb
84
85
  - lib/acl_system2/version.rb
85
86
  - rails/init.rb
86
87
  - test/access_control_test.rb
88
+ - test/mocks.rb
89
+ - test/mocks/controller_proxy.rb
90
+ - test/mocks/controller_proxy_with_fab_handler.rb
91
+ - test/mocks/fab_only_handler.rb
92
+ - test/mocks/user.rb
87
93
  - test/test_helper.rb
88
94
  homepage: https://github.com/boxuk/acl_system2
89
95
  licenses: []
90
-
91
96
  post_install_message:
92
97
  rdoc_options: []
93
-
94
- require_paths:
98
+ require_paths:
95
99
  - lib
96
- required_ruby_version: !ruby/object:Gem::Requirement
100
+ required_ruby_version: !ruby/object:Gem::Requirement
97
101
  none: false
98
- requirements:
99
- - - ">="
100
- - !ruby/object:Gem::Version
101
- hash: 3
102
- segments:
103
- - 0
104
- version: "0"
105
- required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
107
  none: false
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- hash: 3
111
- segments:
112
- - 0
113
- version: "0"
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
114
112
  requirements: []
115
-
116
113
  rubyforge_project:
117
114
  rubygems_version: 1.8.23
118
115
  signing_key:
119
116
  specification_version: 3
120
117
  summary: An access control gem for Rails
121
- test_files:
118
+ test_files:
122
119
  - test/access_control_test.rb
120
+ - test/mocks.rb
121
+ - test/mocks/controller_proxy.rb
122
+ - test/mocks/controller_proxy_with_fab_handler.rb
123
+ - test/mocks/fab_only_handler.rb
124
+ - test/mocks/user.rb
123
125
  - test/test_helper.rb
@@ -1,112 +0,0 @@
1
-
2
- module Caboose
3
-
4
- module AccessControl
5
-
6
- def self.included(subject)
7
- subject.extend(ClassMethods)
8
- if subject.respond_to? :helper_method
9
- subject.helper_method(:permit?)
10
- subject.helper_method(:restrict_to)
11
- end
12
- end
13
-
14
- module ClassMethods
15
- # access_control [:create, :edit] => 'admin & !blacklist',
16
- # :update => '(admin | moderator) & !blacklist',
17
- # :list => '(admin | moderator | user) & !blacklist'
18
- def access_control(actions={})
19
- # Add class-wide permission callback to before_filter
20
- defaults = {}
21
- if block_given?
22
- yield defaults
23
- default_block_given = true
24
- end
25
- before_filter do |c|
26
- c.default_access_context = defaults if default_block_given
27
- @access = AccessSentry.new(c, actions)
28
- if @access.allowed?(c.action_name)
29
- c.send(:permission_granted) if c.respond_to?:permission_granted
30
- else
31
- if c.respond_to?:permission_denied
32
- c.send(:permission_denied)
33
- else
34
- c.send(:render, :text => "You have insuffient permissions to access #{c.controller_name}/#{c.action_name}")
35
- end
36
- end
37
- end
38
- end
39
- end # ClassMethods
40
-
41
- # return the active access handler, fallback to RoleHandler
42
- # implement #retrieve_access_handler to return non-default handler
43
- def access_handler
44
- if respond_to?(:retrieve_access_handler)
45
- @handler ||= retrieve_access_handler
46
- else
47
- @handler ||= RoleHandler.new
48
- end
49
- end
50
-
51
- # the current access context; will be created if not setup
52
- # will add current_user and merge any other elements of context
53
- def access_context(context = {})
54
- default_access_context.merge(context)
55
- end
56
-
57
- def default_access_context
58
- @default_access_context ||= {}
59
- @default_access_context[:user] = send(:current_user) if respond_to?(:current_user)
60
- @default_access_context
61
- end
62
-
63
- def default_access_context=(defaults)
64
- @default_access_context = defaults
65
- end
66
-
67
- def permit?(logicstring, context = {})
68
- access_handler.process(logicstring, access_context(context))
69
- end
70
-
71
- # restrict_to "admin | moderator" do
72
- # link_to "foo"
73
- # end
74
- def restrict_to(logicstring, context = {})
75
- return false if current_user.nil?
76
- result = ''
77
- if permit?(logicstring, context)
78
- result = yield if block_given?
79
- end
80
- result
81
- end
82
-
83
- class AccessSentry
84
-
85
- def initialize(subject, actions={})
86
- @actions = actions.inject({}) do |auth, current|
87
- [current.first].flatten.each { |action| auth[action] = current.last }
88
- auth
89
- end
90
- @subject = subject
91
- end
92
-
93
- def allowed?(action)
94
- if @actions.has_key? action.to_sym
95
- return @subject.access_handler.process(@actions[action.to_sym].dup, @subject.access_context)
96
- elsif @actions.has_key? :DEFAULT
97
- return @subject.access_handler.process(@actions[:DEFAULT].dup, @subject.access_context)
98
- else
99
- return true
100
- end
101
- end
102
-
103
- end # AccessSentry
104
-
105
- end # AccessControl
106
-
107
- end # Caboose
108
-
109
-
110
-
111
-
112
-