role-authz 0.0.2 → 1.0.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/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"