role-authz 0.0.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -13,7 +13,7 @@ require 'merb-core'
13
13
  require 'merb-core/tasks/merb'
14
14
 
15
15
  GEM_NAME = "role-authz"
16
- GEM_VERSION = "0.0.2"
16
+ GEM_VERSION = "1.0.0"
17
17
  AUTHOR = "Jorge Villatoro"
18
18
  EMAIL = "jorge@tomatocannon.com"
19
19
  HOMEPAGE = "http://www.github.com/thelazyfox/role-authz"
@@ -78,5 +78,5 @@ begin
78
78
  end
79
79
  end
80
80
  rescue LoadError
81
- # rspec not installed
81
+ puts "rspec not installed"
82
82
  end
@@ -1,7 +1,7 @@
1
1
  module Authorization
2
2
  @roles = {}
3
3
 
4
- def self.roles_for(operator, target)
4
+ def self.roles_for(operator, target=nil)
5
5
  list = []
6
6
  @roles.each do |name, proc|
7
7
  if proc.call(operator, target)
@@ -12,6 +12,10 @@ module Authorization
12
12
  end
13
13
 
14
14
  def self.add_role(name, &block)
15
- @roles[name] = block
15
+ if block.parameters.count == 2
16
+ @roles[name] = block
17
+ else
18
+ raise InvalidRole
19
+ end
16
20
  end
17
21
  end
@@ -1,7 +1,4 @@
1
- module Authorization
2
- class OpenForRoleStatement < Exception; end
3
- class NoCurrentForRoleStatement < Exception; end
4
-
1
+ module Authorization
5
2
  class ControllerHelper
6
3
  def initialize
7
4
  @working_roles = []
@@ -10,7 +7,7 @@ module Authorization
10
7
 
11
8
  def for_roles(*the_roles)
12
9
  raise OpenForRoleStatement unless @working_roles.empty?
13
- @working_roles += the_roles
10
+ @working_roles = the_roles.clone
14
11
  self
15
12
  end
16
13
  alias_method :for_role, :for_roles
@@ -18,9 +15,7 @@ module Authorization
18
15
  def allow(*the_actions)
19
16
  raise NoCurrentForRoleStatement unless !@working_roles.empty?
20
17
  @working_roles.each do |current_role|
21
- if !@permissions_list.include?(current_role)
22
- @permissions_list[current_role] = []
23
- end
18
+ @permissions_list[current_role] ||= []
24
19
  @permissions_list[current_role] += the_actions
25
20
  end
26
21
  @working_roles.clear
@@ -8,6 +8,7 @@ class Merb::Controller
8
8
  end
9
9
 
10
10
  def self.authorize(klass, &block)
11
+ klass.class_inheritable_accessor :_authorization_proxy
11
12
  klass._authorization_proxy = self
12
13
  self._authorization_target = klass
13
14
  self._authorization ||= Authorization::ControllerHelper.new
@@ -25,8 +26,7 @@ class Merb::Controller
25
26
  end
26
27
 
27
28
  def ensure_authorized
28
- operator = nil
29
- operator = session.user if session.authenticated?
29
+ operator = (session.user if session.authenticated?)
30
30
  roles = Authorization.roles_for(operator, authorization_target)
31
31
  roles.each do |role|
32
32
  actions = self.class._authorization.actions_for(role)
@@ -0,0 +1,5 @@
1
+ module Authorization
2
+ class OpenForRoleStatement < Exception; end
3
+ class NoCurrentForRoleStatement < Exception; end
4
+ class InvalidRole < Exception; end
5
+ end
@@ -1,8 +1,5 @@
1
1
  class Object
2
- class_inheritable_accessor :_authorization_proxy
3
-
4
2
  def self.authorizable!
5
3
  include Authorization::OperatorMixin
6
4
  end
7
-
8
5
  end
@@ -1,18 +1,21 @@
1
1
  module Authorization::OperatorMixin
2
-
3
2
  def authorized?(args = {})
4
3
  @roles ||= Authorization.roles_for(self, args[:target])
5
- if args[:action].nil?
6
- @roles.include?(args[:role])
7
- else
4
+
5
+ if args.key?(:role)
6
+ return @roles.include?(args[:role])
7
+ elsif args.key?(:target) && args.key?(:action)
8
8
  target = args[:target]._authorization_proxy unless args[:target]._authorization_proxy.nil?
9
9
 
10
10
  @roles.each do |role|
11
11
  actions = target._authorization.actions_for(role)
12
12
  return true if actions.include?(args[:action]) || actions.include?(:all)
13
13
  end
14
- false
15
14
  end
15
+ false
16
16
  end
17
17
 
18
+ def roles_for(target)
19
+ Authorization.roles_for(self, target)
20
+ end
18
21
  end
@@ -0,0 +1,50 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe "Authorization" do
4
+ before :each do
5
+ Authorization.clear!
6
+ end
7
+
8
+ describe ".add_role(name, &block)" do
9
+ it "accepts valid roles" do
10
+ Authorization.should respond_to(:add_role)
11
+ lambda do
12
+ Authorization.add_role(:foo) do |operator, target|
13
+ if operator == "jorge"
14
+ true
15
+ else
16
+ false
17
+ end
18
+ end
19
+ end.should_not raise_error
20
+ end
21
+
22
+ it "raises InvalidRole exception when the role block is invalid" do
23
+ lambda do
24
+ Authorization.add_role(:foo) {|operator| true}
25
+ end.should raise_error
26
+ end
27
+ end
28
+
29
+ describe ".roles_for(operator, target)" do
30
+ it "returns correct roles for operator, target pairs" do
31
+ Authorization.add_role(:foo) do |operator, target|
32
+ if operator == "foo"
33
+ true
34
+ else
35
+ false
36
+ end
37
+ end
38
+ Authorization.add_role(:bar) do |operator, target|
39
+ if operator == "bar"
40
+ true
41
+ else
42
+ false
43
+ end
44
+ end
45
+
46
+ Authorization.roles_for("foo",nil).should == [:foo]
47
+ Authorization.roles_for("bar",nil).should == [:bar]
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,157 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe "ControllerMixin" do
4
+ before :each do
5
+ Authorization.clear!
6
+ @controller = Class.new Merb::Controller
7
+ end
8
+
9
+ describe ".role(name, &block)" do
10
+ it "defines roles the the specified name and block" do
11
+ lambda do
12
+ @controller.role(:admin) { |operator,target| operator=="admin" }
13
+ @controller.role(:user) { |operator,target| operator=="user" }
14
+ @controller.role(:owner) { |operator,target| operator==target }
15
+ end.should_not raise_error
16
+
17
+ Authorization.roles_for("user").should == [:user]
18
+ Authorization.roles_for("admin").should == [:admin]
19
+ Authorization.roles_for("owner","owner").should == [:owner]
20
+ Authorization.roles_for("user","user").should include(:user, :owner)
21
+ end
22
+
23
+ it "raises an exception when the block does not accept 2 arguments" do
24
+ lambda {@controller.role(:foo) {|operator|}}.should raise_error
25
+ end
26
+ end
27
+
28
+ describe ".authorize(target, &block)" do
29
+ it "can specify self as the target" do
30
+ @controller.should respond_to(:authorize)
31
+ lambda {@controller.authorize(@controller) {}}.should_not raise_error
32
+ end
33
+
34
+ it "can sepcify a resource as a target" do
35
+ @resource = Class.new
36
+
37
+ @controller.should respond_to(:authorize)
38
+ lambda {@controller.authorize(@resource) {}}.should_not raise_error
39
+ @resource.should respond_to(:_authorization_proxy)
40
+ @resource._authorization_proxy.should == @controller
41
+ end
42
+
43
+ it "enforces #ensure_authorized as a before filter" do
44
+ lambda {@controller.authorize(@controller) {}}.should_not raise_error
45
+ @controller._before_filters.flatten.should include(:ensure_authorized)
46
+ end
47
+ end
48
+
49
+ describe "#ensure_authorized" do
50
+ it "raises the Unauthenticated exception when unauthenticated" do
51
+ session = mock("session")
52
+ session.stub!(:authenticated?).and_return(false)
53
+
54
+ controller = @controller.new(nil)
55
+ controller.stub!(:session).and_return(session)
56
+ controller.stub!(:params).and_return({:action => :foo})
57
+ controller.should respond_to(:ensure_authorized)
58
+ lambda do
59
+ controller.ensure_authorized
60
+ end.should raise_exception(Merb::Controller::Unauthenticated)
61
+ end
62
+
63
+ it "raises the Unauthorized exception when no permissions match" do
64
+ session = mock("session");
65
+ session.stub!(:authenticated?).and_return(true)
66
+ session.stub!(:user).and_return("user")
67
+
68
+ controller = @controller.new(nil)
69
+ controller.stub!(:session).and_return(session)
70
+ controller.stub!(:params).and_return({:action => :foo})
71
+ controller.should respond_to(:ensure_authorized)
72
+ lambda do
73
+ controller.ensure_authorized
74
+ end.should raise_exception(::Merb::Controller::Unauthorized)
75
+ end
76
+
77
+ it "raises no exceptions when a permission matches" do
78
+ session = mock("session");
79
+ session.stub!(:authenticated?).and_return(true)
80
+ session.stub!(:user).and_return("user")
81
+
82
+ @controller.role(:user) {|operator,target|operator=="user"}
83
+ @controller.authorize(@controller) do
84
+ for_role(:user).allow(:foo)
85
+ end
86
+
87
+ controller = @controller.new(nil)
88
+ controller.stub!(:session).and_return(session)
89
+ controller.stub!(:params).and_return({:action => :foo})
90
+
91
+ controller.should respond_to(:ensure_authorized)
92
+ lambda {controller.ensure_authorized}.should_not raise_exception
93
+ end
94
+ end
95
+ end
96
+
97
+ describe "ControllerHelper" do
98
+ before :each do
99
+ @authorization = Authorization::ControllerHelper.new
100
+ end
101
+
102
+ describe "#for_roles(*the_roles)" do
103
+ it "selects roles for which to define permissions" do
104
+ @authorization.instance_eval do
105
+ for_roles(:user).allow(:bar)
106
+ end
107
+ @authorization.actions_for(:user).should include(:bar)
108
+ @authorization.actions_for(:foo).should_not include(:bar)
109
+ end
110
+
111
+ it "raises an exception when called directly after #for_roles" do
112
+ lambda do
113
+ @authorization.instance_eval do
114
+ for_roles(:user)
115
+ for_roles(:admin)
116
+ end
117
+ end.should raise_error
118
+ end
119
+
120
+ it "has the alias #for_role" do
121
+ @authorization.should respond_to(:for_role)
122
+ end
123
+ end
124
+
125
+ describe "#allow(*the_actions)" do
126
+ it "sets permissions to be set for the specified roles" do
127
+ @authorization.instance_eval do
128
+ for_roles(:user).allow(:foo)
129
+ for_roles(:admin).allow(:bar)
130
+ end
131
+
132
+ @authorization.actions_for(:user).should include(:foo)
133
+ @authorization.actions_for(:user).should_not include(:bar)
134
+ @authorization.actions_for(:admin).should include(:bar)
135
+ @authorization.actions_for(:admin).should_not include(:foo)
136
+ end
137
+
138
+ it "raises an exception when not called directly after #for_roles" do
139
+ lambda do
140
+ @authorization.instance_eval do
141
+ allow(:foo)
142
+ end
143
+ end.should raise_error
144
+ end
145
+ end
146
+
147
+ describe "#actions_for(role)" do
148
+ it "returns the previously set actions for the specified role" do
149
+ @authorization.instance_eval do
150
+ for_role(:user).allow(:foo)
151
+ end
152
+
153
+ @authorization.should respond_to(:actions_for)
154
+ @authorization.actions_for(:user).should include(:foo)
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,71 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe "OperatorMixin" do
4
+ describe "#authorized?(args)" do
5
+ before do
6
+ Authorization.clear!
7
+ @user = Class.new
8
+ @user.instance_eval {authorizable!}
9
+ @admin = @user.clone
10
+ @controller = Class.new Merb::Controller
11
+ @controller.role(:admin) {|operator,target|operator.kind_of?(@admin)}
12
+ @controller.role(:user) {|operator,target|operator.kind_of?(@user)}
13
+ @controller.role(:owner) {|operator,target|target.respond_to?(:owner)&&target.owner==operator}
14
+ @controller.authorize(@controller) do
15
+ for_role(:admin).allow(:foo)
16
+ for_role(:user).allow(:bar)
17
+ end
18
+
19
+ end
20
+
21
+ it "returns true when the requested role matches" do
22
+ @admin.new.authorized?(:role=>:admin).should be_true
23
+ @user.new.authorized?(:role=>:user).should be_true
24
+ end
25
+
26
+ it "returns false when the requested role does not match" do
27
+ @admin.new.authorized?(:role=>:user).should be_false
28
+ @user.new.authorized?(:role=>:admin).should be_false
29
+ end
30
+
31
+ it "returns false when only an action is specified" do
32
+ @admin.new.authorized?(:action=>:bar).should be_false
33
+ @admin.new.authorized?(:action=>:foo).should be_false
34
+ end
35
+
36
+ it "returns true when the requested target+action matches" do
37
+ user = @user.new
38
+ resource = Class.new
39
+ resource.stub!(:owner).and_return(user)
40
+ @controller.clone.authorize(resource) {for_role(:owner).allow(:foo)}
41
+
42
+ user.authorized?(:target=>resource,:action=>:foo).should be_true
43
+ end
44
+
45
+ it "returns false when the requested target+action does not match" do
46
+ user = @user.new
47
+ resource = Class.new
48
+ resource.stub!(:owner).and_return(user.clone)
49
+ @controller.clone.authorize(resource) {for_role(:owner).allow(:foo)}
50
+
51
+ user.authorized?(:target=>resource,:action=>:foo).should be_false
52
+ end
53
+
54
+ end
55
+
56
+ describe "#roles_for" do
57
+ it "returns the roles for self on the specified target" do
58
+ @user = Class.new
59
+ @user.instance_eval {authorizable!}
60
+ user = @user.new
61
+
62
+ resource = Class.new
63
+ resource.stub!(:owner).and_return(user)
64
+ Authorization.add_role(:user){|operator,target|operator.kind_of?(@user)}
65
+ Authorization.add_role(:owner){|operator,target|target.respond_to?(:owner)&&target.owner==operator}
66
+
67
+ user.roles_for(resource).should include(:owner)
68
+ user.clone.roles_for(resource).should_not include(:owner)
69
+ end
70
+ end
71
+ end
@@ -1,7 +1,14 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
1
+ require File.expand_path('../spec_helper', __FILE__)
2
2
 
3
- describe "role-authz" do
4
- it "should do nothing" do
5
- true.should == true
3
+ describe "ObjectMixin" do
4
+ describe ".authorizable!" do
5
+ it "includes OperatorMixin" do
6
+ class Foo
7
+ authorizable!
8
+ end
9
+
10
+ Foo.ancestors.should include(::Authorization::OperatorMixin)
11
+ end
6
12
  end
7
- end
13
+ end
14
+
data/spec/spec_helper.rb CHANGED
@@ -1 +1,11 @@
1
- $:.push File.join(File.dirname(__FILE__), '..', 'lib')
1
+ # Loads up Merb and the Plugin
2
+ require 'merb-core'
3
+ require 'spec'
4
+ require File.expand_path("../../lib/role-authz", __FILE__)
5
+
6
+ # Simple helper to clear out the auth role list
7
+ module Authorization
8
+ def self.clear!
9
+ @roles.clear
10
+ end
11
+ end
metadata CHANGED
@@ -3,10 +3,10 @@ name: role-authz
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
+ - 1
6
7
  - 0
7
8
  - 0
8
- - 2
9
- version: 0.0.2
9
+ version: 1.0.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jorge Villatoro
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-08-12 00:00:00 -05:00
17
+ date: 2011-02-11 00:00:00 -06:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -50,9 +50,13 @@ files:
50
50
  - lib/role-authz/authorization/authorization.rb
51
51
  - lib/role-authz/authorization/controller_helper.rb
52
52
  - lib/role-authz/authorization/controller_mixin.rb
53
+ - lib/role-authz/authorization/exceptions.rb
53
54
  - lib/role-authz/authorization/object_mixin.rb
54
55
  - lib/role-authz/authorization/operator_mixin.rb
55
56
  - lib/role-authz.rb
57
+ - spec/authorization_spec.rb
58
+ - spec/controller_spec.rb
59
+ - spec/operator_spec.rb
56
60
  - spec/role-authz_spec.rb
57
61
  - spec/spec_helper.rb
58
62
  has_rdoc: true
@@ -69,7 +73,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
69
73
  requirements:
70
74
  - - ">="
71
75
  - !ruby/object:Gem::Version
72
- hash: -4311421285429235749
76
+ hash: 1726181753105293631
73
77
  segments:
74
78
  - 0
75
79
  version: "0"
@@ -78,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
82
  requirements:
79
83
  - - ">="
80
84
  - !ruby/object:Gem::Version
81
- hash: -4311421285429235749
85
+ hash: 1726181753105293631
82
86
  segments:
83
87
  - 0
84
88
  version: "0"