restful_acl 2.1.3 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.textile +19 -18
- data/VERSION +1 -1
- data/lib/restful_acl/base.rb +75 -0
- data/lib/restful_acl/controller.rb +23 -99
- data/lib/restful_acl/errors.rb +6 -0
- data/lib/restful_acl/helper.rb +8 -58
- data/lib/restful_acl/model.rb +42 -40
- data/lib/restful_acl/string.rb +8 -0
- data/lib/restful_acl/url_parser.rb +102 -0
- data/lib/restful_acl.rb +4 -0
- data/rails/init.rb +3 -3
- data/restful_acl.gemspec +12 -3
- data/spec/spec_helper.rb +11 -0
- metadata +10 -4
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg/*
|
data/README.textile
CHANGED
@@ -1,14 +1,20 @@
|
|
1
|
+
h1. Major changes in 3.0 release!
|
2
|
+
|
3
|
+
* RESTful_ACL has been completely refactored for speed and usability.
|
4
|
+
* A full Cucumber test suite has been written (http://github.com/mdarby/restful_acl_app).
|
5
|
+
* The view helpers @creatable@, @deletable@, @updatable@, @readable@ have been replaced by @allowed?@ (see below for more details).
|
6
|
+
|
1
7
|
h2. RESTful_ACL
|
2
8
|
|
3
|
-
|
9
|
+
RESTful_ACL is rails gem that provides a full stack, contextual access control to RESTful resources. Authorization is as simple as true or false.
|
4
10
|
|
5
11
|
h3. What it does
|
6
12
|
|
7
|
-
RESTful_ACL is a
|
13
|
+
RESTful_ACL is a context-based permission engine. It provides full stack access control that is resource context aware. (If a parent is closed, a child is not editable, etc.)
|
8
14
|
|
9
15
|
h3. Requirements
|
10
16
|
|
11
|
-
RESTful_ACL requires the
|
17
|
+
RESTful_ACL requires the notion of a @current_user@. Most authenticaion plugins provide this (AuthLogic, RESTful_Authentication, etc.)
|
12
18
|
|
13
19
|
h3. How to Install
|
14
20
|
|
@@ -18,11 +24,8 @@ Install the RESTful_ACL gem:
|
|
18
24
|
Add the gem to your environment.rb file as thus:
|
19
25
|
<pre>config.gem "restful_acl"</pre>
|
20
26
|
|
21
|
-
RESTful_ACL requires
|
22
|
-
<pre>
|
23
|
-
map.error 'error', :controller => 'some_controller', :action => 'error_action'
|
24
|
-
map.denied 'denied', :controller => 'some_controller', :action => 'denied_action'
|
25
|
-
</pre>
|
27
|
+
RESTful_ACL requires a named route named "denied". Add the following to your routes.rb file:
|
28
|
+
<pre>map.denied 'denied', :controller => 'some_controller', :action => 'denied_action'</pre>
|
26
29
|
|
27
30
|
h3. How to Use
|
28
31
|
|
@@ -71,16 +74,15 @@ RESTful_ACL 2.1+ supports singleton resources. Just pass @:singleton@ to the @lo
|
|
71
74
|
end
|
72
75
|
</pre>
|
73
76
|
|
74
|
-
h4. View
|
77
|
+
h4. View Helper
|
75
78
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
= link_to 'Edit Foo', edit_foo_path(@foo)
|
80
|
-
= link_to 'Create Foo', new_foo_path
|
81
|
-
= link_to 'View Foo', foo_path(@foo)
|
82
|
-
= link_to 'Delete Foo', foo_path(@foo)
|
83
|
-
</pre>
|
79
|
+
RESTful_ACL provides you with a view helper named @allowed?@. Simply pass this method a block containing the URL you'd like to check permission on and it will do the rest.
|
80
|
+
If the @current_user@ is allowed to access the requested link's action, the link will appear; otherwise no link will show.
|
81
|
+
<pre>= allowed?{ link_to ‘Foo Index’, foos_path }
|
82
|
+
= allowed?{ link_to 'Edit Foo', edit_foo_path(@foo) }
|
83
|
+
= allowed?{ link_to 'Create Foo', new_foo_path }
|
84
|
+
= allowed?{ link_to 'View Foo', foo_path(@foo) }
|
85
|
+
= allowed?{ link_to 'Delete Foo', foo_path(@foo), :method => :delete }</pre>
|
84
86
|
|
85
87
|
h3. Huh? Here's an example
|
86
88
|
|
@@ -127,7 +129,6 @@ I normally do something along these lines in RSpec:
|
|
127
129
|
before do
|
128
130
|
@project = mock_model(Project)
|
129
131
|
@author = mock_model(User, :projects => [@project])
|
130
|
-
|
131
132
|
@issue = Issue.factory_girl(:issue, :author => @author, :project => @project)
|
132
133
|
end
|
133
134
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3.0.0
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module RestfulAcl
|
2
|
+
class Base
|
3
|
+
|
4
|
+
attr_accessor :object, :parent, :user, :controller_name, :uri, :action, :object_id
|
5
|
+
|
6
|
+
|
7
|
+
def initialize(options = {})
|
8
|
+
@object_id = options[:object_id]
|
9
|
+
@user = options[:user]
|
10
|
+
@uri = options[:uri]
|
11
|
+
@action = options[:action]
|
12
|
+
@controller_name = options[:controller_name]
|
13
|
+
|
14
|
+
if @object_id.present?
|
15
|
+
load_actors_from_id
|
16
|
+
else
|
17
|
+
load_actors_from_uri
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def load_actors_from_id
|
22
|
+
@object = object_class.find(@object_id)
|
23
|
+
@parent = @object.get_mom if object_class.has_parent?
|
24
|
+
end
|
25
|
+
|
26
|
+
def load_actors_from_uri
|
27
|
+
@parent = load_parent_from_uri if object_class.has_parent?
|
28
|
+
@object = (object_class.is_singleton?) ? load_singleton_object : nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def load_singleton_object
|
32
|
+
@parent.send(object_class.to_s.tableize.singularize.to_sym)
|
33
|
+
end
|
34
|
+
|
35
|
+
def load_parent_from_uri
|
36
|
+
parent_klass = object_class.mom.to_s
|
37
|
+
bits = @uri.split('/')
|
38
|
+
parent_id = bits.at(bits.index(parent_klass.pluralize) + 1)
|
39
|
+
|
40
|
+
parent_klass.classify.constantize.find(parent_id)
|
41
|
+
end
|
42
|
+
|
43
|
+
def object_class
|
44
|
+
@object_class ||= @controller_name.classify.demodulize.constantize
|
45
|
+
end
|
46
|
+
|
47
|
+
def admin?
|
48
|
+
@user.respond_to?("is_admin?") && @user.is_admin?
|
49
|
+
end
|
50
|
+
|
51
|
+
def allowed?
|
52
|
+
return true if admin?
|
53
|
+
|
54
|
+
case @action
|
55
|
+
when "index" then object_class.is_indexable_by(@user, @parent)
|
56
|
+
when "new", "create" then object_class.is_creatable_by(@user, @parent)
|
57
|
+
when "show" then @object.is_readable_by(@user, @parent)
|
58
|
+
when "edit", "update" then @object.is_updatable_by(@user, @parent)
|
59
|
+
when "destroy" then @object.is_deletable_by(@user, @parent)
|
60
|
+
else check_non_restful_route
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def check_non_restful_route
|
65
|
+
if @object.present?
|
66
|
+
@object.is_readable_by(@user, @parent)
|
67
|
+
elsif object_class.present?
|
68
|
+
object_class.is_indexable_by(@user, @parent)
|
69
|
+
else
|
70
|
+
false # If all else fails, deny access
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
@@ -1,114 +1,38 @@
|
|
1
|
-
module
|
1
|
+
module RestfulAcl
|
2
|
+
module Controller
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
module ClassMethods
|
9
|
-
|
10
|
-
attr_accessor :restful_object, :restful_parent, :restful_klass, :restful_user
|
11
|
-
|
12
|
-
def has_permission?
|
13
|
-
return true if administrator?
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
base.send :include, ClassMethods
|
7
|
+
end
|
14
8
|
|
15
|
-
|
9
|
+
module ClassMethods
|
16
10
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
else check_non_restful_route
|
26
|
-
end
|
11
|
+
def has_permission?
|
12
|
+
options = {
|
13
|
+
:controller_name => self.controller_name,
|
14
|
+
:object_id => params[:id],
|
15
|
+
:uri => request.request_uri,
|
16
|
+
:user => current_user,
|
17
|
+
:action => params[:action]
|
18
|
+
}
|
27
19
|
|
28
|
-
|
29
|
-
# Misconfiguration: A RESTful_ACL specific method is missing.
|
30
|
-
raise_error(e)
|
31
|
-
rescue
|
32
|
-
# Failsafe: If any funny business is going on, log and redirect
|
33
|
-
routing_error
|
20
|
+
permission_denied unless RestfulAcl::Base.new(options).allowed?
|
34
21
|
end
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
22
|
|
39
|
-
def load_actors(id)
|
40
|
-
@restful_user = current_user
|
41
23
|
|
42
|
-
|
43
|
-
@restful_klass = self.controller_name.classify.demodulize.constantize
|
24
|
+
private
|
44
25
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
@restful_parent = @restful_object.get_mom if @restful_klass.has_parent?
|
49
|
-
else
|
50
|
-
# No object was requested, so we need to go to the URI to figure out the parent
|
51
|
-
@restful_parent = get_morestful_frorestful_request_uri(@restful_klass) if @restful_klass.has_parent?
|
52
|
-
|
53
|
-
if @restful_klass.is_singleton?
|
54
|
-
@restful_object = @restful_parent.send(@restful_klass.to_s.tableize.singularize.to_sym)
|
55
|
-
else
|
56
|
-
# No object was requested (index, create actions)
|
57
|
-
@restful_object = nil
|
58
|
-
end
|
26
|
+
def permission_denied
|
27
|
+
logger.info("[RESTful_ACL] Permission denied to %s at %s for %s" % [blame, Time.now, request.request_uri])
|
28
|
+
redirect_to denied_url
|
59
29
|
end
|
60
|
-
end
|
61
30
|
|
62
|
-
|
63
|
-
|
64
|
-
@restful_object.is_readable_by(@restful_user, @restful_parent)
|
65
|
-
elsif @restful_klass
|
66
|
-
@restful_klass.is_indexable_by(@restful_user, @restful_parent)
|
67
|
-
else
|
68
|
-
false # If all else fails, deny access
|
31
|
+
def blame
|
32
|
+
(@current_user.present?) ? "User ##{@current_user.id}" : "GUEST"
|
69
33
|
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def get_method_frorestful_error(error)
|
73
|
-
error.message.gsub('`', "'").split("'").at(1)
|
74
|
-
end
|
75
|
-
|
76
|
-
def raise_error(error)
|
77
|
-
method = get_method_frorestful_error(error)
|
78
|
-
message = (is_class_method?(method)) ? "#{@restful_klass}#self.#{method}" : "#{@restful_klass}##{method}"
|
79
|
-
raise NoMethodError, "[RESTful_ACL] #{message}(user, parent = nil) seems to be missing?"
|
80
|
-
end
|
81
34
|
|
82
|
-
|
83
|
-
method =~ /[index|creat]able/
|
84
|
-
end
|
85
|
-
|
86
|
-
def get_morestful_frorestful_request_uri(child_klass)
|
87
|
-
parent_klass = child_klass.mom.to_s
|
88
|
-
bits = request.request_uri.split('/')
|
89
|
-
parent_id = bits.at(bits.index(parent_klass.pluralize) + 1)
|
90
|
-
|
91
|
-
parent_klass.classify.constantize.find(parent_id)
|
92
|
-
end
|
93
|
-
|
94
|
-
def administrator?
|
95
|
-
@restful_user.respond_to?("is_admin?") && @restful_user.is_admin?
|
96
|
-
end
|
97
|
-
|
98
|
-
def blame
|
99
|
-
@restful_user.respond_to?(:login) ? @restful_user.login : @restful_user.username
|
100
|
-
end
|
101
|
-
|
102
|
-
def permission_denied
|
103
|
-
logger.info("[RESTful_ACL] Permission denied to %s at %s for %s" % [(logged_in? ? blame : 'guest'), Time.now, request.request_uri])
|
104
|
-
redirect_to denied_url
|
105
|
-
end
|
106
|
-
|
107
|
-
def routing_error
|
108
|
-
logger.info("[RESTful_ACL] Routing error by %s at %s for %s" % [(logged_in? ? blame : 'guest'), Time.now, request.request_uri])
|
109
|
-
redirect_to error_url
|
110
|
-
end
|
35
|
+
end
|
111
36
|
|
112
37
|
end
|
113
|
-
|
114
38
|
end
|
data/lib/restful_acl/helper.rb
CHANGED
@@ -1,62 +1,12 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
return true if admin_enabled
|
4
|
-
klass.is_indexable_by(current_user, parent_obj)
|
5
|
-
end
|
6
|
-
|
7
|
-
def creatable
|
8
|
-
return true if admin_enabled
|
9
|
-
klass.is_creatable_by(current_user, parent_obj)
|
10
|
-
end
|
11
|
-
alias_method :createable, :creatable
|
12
|
-
|
13
|
-
|
14
|
-
def updatable(object)
|
15
|
-
return true if admin_enabled
|
16
|
-
|
17
|
-
parent = object.get_mom rescue nil
|
18
|
-
object.is_updatable_by(current_user, parent)
|
19
|
-
end
|
20
|
-
alias_method :updateable, :updatable
|
1
|
+
module RestfulAcl
|
2
|
+
module Helper
|
21
3
|
|
4
|
+
def allowed?(&block)
|
5
|
+
options = UrlParser.new(current_user, &block).options_hash
|
6
|
+
access = RestfulAcl::Base.new(options)
|
22
7
|
|
23
|
-
|
24
|
-
return true if admin_enabled
|
25
|
-
|
26
|
-
parent = object.get_mom rescue nil
|
27
|
-
object.is_deletable_by(current_user, parent)
|
28
|
-
end
|
29
|
-
alias_method :deleteable, :deletable
|
30
|
-
|
31
|
-
|
32
|
-
def readable(object)
|
33
|
-
return true if admin_enabled
|
34
|
-
|
35
|
-
parent = object.get_mom rescue nil
|
36
|
-
object.is_readable_by(current_user, parent)
|
37
|
-
end
|
38
|
-
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def klass
|
43
|
-
params[:controller].classify.demodulize.constantize
|
44
|
-
end
|
45
|
-
|
46
|
-
def parent_obj
|
47
|
-
parent_klass.find(parent_id) rescue nil
|
48
|
-
end
|
49
|
-
|
50
|
-
def parent_klass
|
51
|
-
klass.parent.to_s.classify.constantize
|
52
|
-
end
|
53
|
-
|
54
|
-
def parent_id
|
55
|
-
params["#{klass.parent.to_s}_id"]
|
8
|
+
yield if access.allowed?
|
56
9
|
end
|
57
10
|
|
58
|
-
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/restful_acl/model.rb
CHANGED
@@ -1,59 +1,61 @@
|
|
1
|
-
module
|
1
|
+
module RestfulAcl
|
2
|
+
module Model
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
base.send :include, ClassMethods
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
-
|
9
|
+
module ClassMethods
|
10
|
+
attr_accessor :mom, :singleton
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
def logical_parent(model, *options)
|
13
|
+
@mom = model
|
14
|
+
@singleton = options.include?(:singleton)
|
14
15
|
|
15
|
-
|
16
|
-
|
16
|
+
include InstanceMethods
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
def has_parent?
|
20
|
+
@mom.present?
|
21
|
+
end
|
22
|
+
|
23
|
+
def is_singleton?
|
24
|
+
@singleton.present?
|
25
|
+
end
|
21
26
|
|
22
|
-
def is_singleton?
|
23
|
-
@singleton.present?
|
24
27
|
end
|
25
28
|
|
26
|
-
end
|
27
29
|
|
30
|
+
module InstanceMethods
|
28
31
|
|
29
|
-
|
32
|
+
def get_mom
|
33
|
+
parent_klass.find(parent_id) if has_parent?
|
34
|
+
end
|
30
35
|
|
31
|
-
|
32
|
-
parent_klass.find(parent_id) if has_parent?
|
33
|
-
end
|
36
|
+
private
|
34
37
|
|
35
|
-
|
38
|
+
def klass
|
39
|
+
self.class
|
40
|
+
end
|
36
41
|
|
37
|
-
|
38
|
-
|
39
|
-
|
42
|
+
def mom
|
43
|
+
klass.mom
|
44
|
+
end
|
40
45
|
|
41
|
-
|
42
|
-
|
43
|
-
|
46
|
+
def has_parent?
|
47
|
+
!mom.nil?
|
48
|
+
end
|
44
49
|
|
45
|
-
|
46
|
-
|
47
|
-
|
50
|
+
def parent_klass
|
51
|
+
mom.to_s.classify.constantize
|
52
|
+
end
|
48
53
|
|
49
|
-
|
50
|
-
|
51
|
-
|
54
|
+
def parent_id
|
55
|
+
self.instance_eval("#{mom}_id")
|
56
|
+
end
|
52
57
|
|
53
|
-
|
54
|
-
self.instance_eval("#{mom}_id")
|
55
|
-
end
|
58
|
+
end
|
56
59
|
|
57
60
|
end
|
58
|
-
|
59
|
-
end
|
61
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# This class takes a User and block of text containing a URL and deduces the requested action
|
2
|
+
# and any object that that action will be taken upon.
|
3
|
+
#
|
4
|
+
# Author:: Matt Darby (mailto:matt@matt-darby.com)
|
5
|
+
# Copyright:: Copyright(c) 2009 Matt Darby
|
6
|
+
# License:: MIT
|
7
|
+
|
8
|
+
class UrlParser
|
9
|
+
|
10
|
+
TypesOfURLs = [
|
11
|
+
{:name => "parent_with_specific_child", :controller_bit => 3, :object_id_bit => 4, :regex => /\/(\w+)\/(\d+)[\w|-]*\/(\w+)\/(\d+)[\w|-]*$/},
|
12
|
+
{:name => "parent_with_edit_child", :controller_bit => 3, :object_id_bit => 4, :regex => /\/(\w+)\/(\d+)[\w|-]*\/(\w+)\/(\d+)[\w|-]*\/edit$/},
|
13
|
+
{:name => "parent_with_child_index", :controller_bit => 3, :object_id_bit => nil, :regex => /\/(\w+)\/(\d+)[\w|-]*\/(\w+)$/},
|
14
|
+
{:name => "parent_with_new_child", :controller_bit => 3, :object_id_bit => nil, :regex => /\/(\w+)\/(\d+)[\w|-]*\/(\w+)\/new$/},
|
15
|
+
{:name => "edit_singleton_child", :controller_bit => 3, :object_id_bit => nil, :regex => /\/(\w+)\/(\d+)[\w|-]*\/(\w+)\/edit$/},
|
16
|
+
{:name => "new_singleton_child", :controller_bit => 3, :object_id_bit => nil, :regex => /\/(\w+)\/(\d+)[\w|-]*\/(\w+)\/new$/},
|
17
|
+
{:name => "edit_parent", :controller_bit => 1, :object_id_bit => 2, :regex => /\/(\w+)\/edit$/},
|
18
|
+
{:name => "new_parent", :controller_bit => 1, :object_id_bit => nil, :regex => /\/(\w+)\/new$/},
|
19
|
+
{:name => "specific_parent", :controller_bit => 1, :object_id_bit => 2, :regex => /\/(\w+)\/(\d+)[\w|-]*$/},
|
20
|
+
{:name => "parent_index", :controller_bit => 1, :object_id_bit => nil, :regex => /\/(\w+)$/}
|
21
|
+
]
|
22
|
+
|
23
|
+
URL = /href="([\w|\/|-]+)"/
|
24
|
+
AJAXURL = /url:'([\w|\/|-]+)'/
|
25
|
+
NewURL = /\/new$/
|
26
|
+
EditURL = /\/edit$/
|
27
|
+
ObjectURL = /\/(\d+)[\w|-]*$/
|
28
|
+
DestroyURL = /.*m\.setAttribute\('value', 'delete'\).*/
|
29
|
+
|
30
|
+
attr_accessor :text, :user, :url
|
31
|
+
|
32
|
+
# Dynamically define methods based off of TypesOfURLs hash
|
33
|
+
TypesOfURLs.each do |type|
|
34
|
+
define_method(type[:name]) do |url, controller_bit, object_id_bit, regex|
|
35
|
+
data = regex.match(url)
|
36
|
+
controller_name = data[controller_bit]
|
37
|
+
object_id = (object_id_bit.present?) ? data[object_id_bit] : nil
|
38
|
+
action = requested_action(controller_name)
|
39
|
+
|
40
|
+
{
|
41
|
+
:controller_name => controller_name,
|
42
|
+
:object_id => object_id,
|
43
|
+
:action => action,
|
44
|
+
:uri => requested_url,
|
45
|
+
:user => @user
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
def initialize(user, &block)
|
52
|
+
@text = yield
|
53
|
+
@user = user
|
54
|
+
@url = requested_url
|
55
|
+
end
|
56
|
+
|
57
|
+
# Parse a URL and return a hash suitable for usage with RESTful_ACL
|
58
|
+
# * :controller_name => The requested action's controller's name,
|
59
|
+
# * :object_id => The requested ID of the object in question (nil when Index, New, Create actions),
|
60
|
+
# * :action => The requested RESTful action (index, show, etc.),
|
61
|
+
# * :uri => The requested URL,
|
62
|
+
# * :user => The current user (used for context in RESTful_ACL)
|
63
|
+
def options_hash
|
64
|
+
invoke_url_type_method(deduce_url_type)
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
# Call the dynamically created method with arguments from deduced hash
|
71
|
+
def invoke_url_type_method(type)
|
72
|
+
send(type[:name], @url, type[:controller_bit], type[:object_id_bit], type[:regex])
|
73
|
+
end
|
74
|
+
|
75
|
+
# Deduce the requested URL's "type" based on the TypesOfURLs hash
|
76
|
+
def deduce_url_type
|
77
|
+
TypesOfURLs.detect{|type| type[:regex].match(@url)}
|
78
|
+
end
|
79
|
+
|
80
|
+
# Find the requested URL out of the text block received
|
81
|
+
def requested_url
|
82
|
+
link = case @text
|
83
|
+
when URL then URL.match(@text)[1]
|
84
|
+
when AJAXURL then AJAXURL.match(@text)[1]
|
85
|
+
else raise RestfulAcl::UnrecognizedURLError, "'#{@text}' doesn't seem to contain a valid URL?"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Deduce the requested action based on URL type
|
90
|
+
# (or text block as :destroy links are defined via javascript)
|
91
|
+
def requested_action(controller_name)
|
92
|
+
return "destroy" if @text =~ DestroyURL
|
93
|
+
|
94
|
+
case @url
|
95
|
+
when EditURL then "edit"
|
96
|
+
when NewURL then "new"
|
97
|
+
when ObjectURL || controller_name.singular? then "show"
|
98
|
+
else "index"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
data/lib/restful_acl.rb
CHANGED
data/rails/init.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'restful_acl'
|
2
2
|
|
3
|
-
ActionController::Base.send :include,
|
4
|
-
ActionView::Base.send :include,
|
5
|
-
ActiveRecord::Base.send :include,
|
3
|
+
ActionController::Base.send :include, RestfulAcl::Controller
|
4
|
+
ActionView::Base.send :include, RestfulAcl::Helper
|
5
|
+
ActiveRecord::Base.send :include, RestfulAcl::Model
|
6
6
|
|
7
7
|
RAILS_DEFAULT_LOGGER.debug "** [RESTful_ACL] loaded"
|
data/restful_acl.gemspec
CHANGED
@@ -5,28 +5,34 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{restful_acl}
|
8
|
-
s.version = "
|
8
|
+
s.version = "3.0.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Matt Darby"]
|
12
|
-
s.date = %q{2009-11-
|
12
|
+
s.date = %q{2009-11-28}
|
13
13
|
s.description = %q{A Ruby on Rails plugin that provides fine grained access control to RESTful resources.}
|
14
14
|
s.email = %q{matt@matt-darby.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"README.textile"
|
17
17
|
]
|
18
18
|
s.files = [
|
19
|
-
"
|
19
|
+
".gitignore",
|
20
|
+
"MIT-LICENSE",
|
20
21
|
"README.textile",
|
21
22
|
"Rakefile",
|
22
23
|
"VERSION",
|
23
24
|
"init.rb",
|
24
25
|
"lib/restful_acl.rb",
|
26
|
+
"lib/restful_acl/base.rb",
|
25
27
|
"lib/restful_acl/controller.rb",
|
28
|
+
"lib/restful_acl/errors.rb",
|
26
29
|
"lib/restful_acl/helper.rb",
|
27
30
|
"lib/restful_acl/model.rb",
|
31
|
+
"lib/restful_acl/string.rb",
|
32
|
+
"lib/restful_acl/url_parser.rb",
|
28
33
|
"rails/init.rb",
|
29
34
|
"restful_acl.gemspec",
|
35
|
+
"spec/spec_helper.rb",
|
30
36
|
"uninstall.rb"
|
31
37
|
]
|
32
38
|
s.homepage = %q{http://github.com/mdarby/restful_acl}
|
@@ -34,6 +40,9 @@ Gem::Specification.new do |s|
|
|
34
40
|
s.require_paths = ["lib"]
|
35
41
|
s.rubygems_version = %q{1.3.5}
|
36
42
|
s.summary = %q{A Ruby on Rails plugin that provides fine grained access control to RESTful resources.}
|
43
|
+
s.test_files = [
|
44
|
+
"spec/spec_helper.rb"
|
45
|
+
]
|
37
46
|
|
38
47
|
if s.respond_to? :specification_version then
|
39
48
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
require 'restful_acl'
|
4
|
+
require 'spec'
|
5
|
+
require 'spec/autorun'
|
6
|
+
require 'rubygems'
|
7
|
+
require 'activesupport'
|
8
|
+
|
9
|
+
Spec::Runner.configure do |config|
|
10
|
+
|
11
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: restful_acl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Darby
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-28 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -31,17 +31,23 @@ extensions: []
|
|
31
31
|
extra_rdoc_files:
|
32
32
|
- README.textile
|
33
33
|
files:
|
34
|
+
- .gitignore
|
34
35
|
- MIT-LICENSE
|
35
36
|
- README.textile
|
36
37
|
- Rakefile
|
37
38
|
- VERSION
|
38
39
|
- init.rb
|
39
40
|
- lib/restful_acl.rb
|
41
|
+
- lib/restful_acl/base.rb
|
40
42
|
- lib/restful_acl/controller.rb
|
43
|
+
- lib/restful_acl/errors.rb
|
41
44
|
- lib/restful_acl/helper.rb
|
42
45
|
- lib/restful_acl/model.rb
|
46
|
+
- lib/restful_acl/string.rb
|
47
|
+
- lib/restful_acl/url_parser.rb
|
43
48
|
- rails/init.rb
|
44
49
|
- restful_acl.gemspec
|
50
|
+
- spec/spec_helper.rb
|
45
51
|
- uninstall.rb
|
46
52
|
has_rdoc: true
|
47
53
|
homepage: http://github.com/mdarby/restful_acl
|
@@ -71,5 +77,5 @@ rubygems_version: 1.3.5
|
|
71
77
|
signing_key:
|
72
78
|
specification_version: 3
|
73
79
|
summary: A Ruby on Rails plugin that provides fine grained access control to RESTful resources.
|
74
|
-
test_files:
|
75
|
-
|
80
|
+
test_files:
|
81
|
+
- spec/spec_helper.rb
|