restful_acl 3.0.3 → 3.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +160 -0
- data/VERSION +1 -1
- data/lib/restful_acl.rb +2 -1
- data/lib/restful_acl/helper.rb +2 -0
- data/restful_acl.gemspec +4 -4
- metadata +4 -4
- data/README.textile +0 -162
data/README.markdown
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
RESTful_ACL
|
2
|
+
===========
|
3
|
+
RESTful_ACL is a full-stack context-based permission engine. It provides access control that is contextually aware. (If a parent is closed, a child is not editable, etc.) Permission is as simple as true or false.
|
4
|
+
|
5
|
+
Requirements
|
6
|
+
------------
|
7
|
+
RESTful_ACL requires the notion of a `current_user`. Most authenticaion plugins provide this (AuthLogic, RESTful_Authentication, etc.)
|
8
|
+
|
9
|
+
How to Install
|
10
|
+
--------------
|
11
|
+
Install the RESTful_ACL gem:
|
12
|
+
<pre><code>sudo gem install restful_acl -s http://gemcutter.org</code></pre>
|
13
|
+
|
14
|
+
Add the gem to your environment.rb file as thus:
|
15
|
+
<pre><code>config.gem "restful_acl"</code></pre>
|
16
|
+
|
17
|
+
RESTful_ACL requires a named route named "denied". Add the following to your routes.rb file:
|
18
|
+
<pre><code>map.denied 'denied', :controller => 'some_controller', :action => 'denied_action'</code></pre>
|
19
|
+
|
20
|
+
Controllers
|
21
|
+
-----------
|
22
|
+
Add `before_filter :has_permission?` into any controller that you'd like to restrict access to (or `application_controller.rb` for your entire app).
|
23
|
+
|
24
|
+
Models
|
25
|
+
------
|
26
|
+
Define the following five methods in the model of every resource you'd like to restrict access to. The five methods can contain anything you'd like so long as they return a boolean true or false. This allows you to define your User's roles any way you wish.
|
27
|
+
|
28
|
+
<pre><code>class Issue < ActiveRecord::Base
|
29
|
+
|
30
|
+
# This method checks permissions for the :index action
|
31
|
+
def self.is_indexable_by(user, parent = nil)
|
32
|
+
end
|
33
|
+
|
34
|
+
# This method checks permissions for the :create and :new action
|
35
|
+
def self.is_creatable_by(user, parent = nil)
|
36
|
+
end
|
37
|
+
|
38
|
+
# This method checks permissions for the :show action
|
39
|
+
def is_readable_by(user, parent = nil)
|
40
|
+
end
|
41
|
+
|
42
|
+
# This method checks permissions for the :update and :edit action
|
43
|
+
def is_updatable_by(user, parent = nil)
|
44
|
+
end
|
45
|
+
|
46
|
+
# This method checks permissions for the :destroy action
|
47
|
+
def is_deletable_by(user, parent = nil)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
</code></pre>
|
52
|
+
|
53
|
+
Parent / Child resources
|
54
|
+
------------------------
|
55
|
+
|
56
|
+
Sometimes actions should only be allowable on a resource if some "parent" resource allows them. Contextual permissions FTW.
|
57
|
+
|
58
|
+
Link your "child" resource with its "parent" resource by using the `logical_parent` macro and you'll have access to the "parent" resource in your child's RESTful_ACL methods.
|
59
|
+
|
60
|
+
<pre><code>class Child < ActiveRecord::Base
|
61
|
+
logical_parent :parent
|
62
|
+
...
|
63
|
+
end
|
64
|
+
</code></pre>
|
65
|
+
|
66
|
+
If the "child" resource is a singleton, just pass `:singleton` to the `logical_parent` macro:
|
67
|
+
|
68
|
+
<pre><code>class Car < ActiveRecord::Base
|
69
|
+
logical_parent :owner, :singleton
|
70
|
+
...
|
71
|
+
end
|
72
|
+
</code></pre>
|
73
|
+
|
74
|
+
View Helper
|
75
|
+
-----------
|
76
|
+
|
77
|
+
RESTful_ACL adds a view helper called `allowed?`. Simply pass this method a block containing the URL you'd like to check permission on and it will do the rest.
|
78
|
+
The link will appear if the `current_user` is allowed to access the passed-in link's action.
|
79
|
+
|
80
|
+
<pre><code>= allowed?{ link_to ‘Foo Index’, foos_path }
|
81
|
+
= allowed?{ link_to 'Edit Foo', edit_foo_path(@foo) }
|
82
|
+
= allowed?{ link_to 'Create Foo', new_foo_path }
|
83
|
+
= allowed?{ link_to 'View Foo', foo_path(@foo) }
|
84
|
+
= allowed?{ link_to 'Delete Foo', foo_path(@foo), :method => :delete }
|
85
|
+
</code></pre>
|
86
|
+
|
87
|
+
|
88
|
+
Huh? Here's an example
|
89
|
+
----------------------
|
90
|
+
Let's say that you have two resources: `Project` and `Issue`. A Project has many Issues, an Issue belongs to a Project. I'd like to make sure that the current user is a member of the Project before they can create a new Issue in that Project:
|
91
|
+
|
92
|
+
<pre><code>class Issue < ActiveRecord::Base
|
93
|
+
logical_parent :project
|
94
|
+
|
95
|
+
belongs_to :author
|
96
|
+
belongs_to :project
|
97
|
+
|
98
|
+
def self.is_indexable_by(user, parent = nil)
|
99
|
+
user.projects.include?(parent)
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.is_creatable_by(user, parent = nil)
|
103
|
+
user.projects.include?(parent)
|
104
|
+
end
|
105
|
+
|
106
|
+
def is_updatable_by(user, parent = nil)
|
107
|
+
user == author && parent.is_active?
|
108
|
+
end
|
109
|
+
|
110
|
+
def is_deletable_by(user, parent = nil)
|
111
|
+
user == author
|
112
|
+
end
|
113
|
+
|
114
|
+
def is_readable_by(user, parent = nil)
|
115
|
+
user.projects.include?(parent)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
</code></pre>
|
119
|
+
|
120
|
+
If you still have questions, please checkout the [test app](http://github.com/mdarby/restful_acl_app)
|
121
|
+
|
122
|
+
Admins RULE!
|
123
|
+
------------
|
124
|
+
RESTful_ACL grants global access to all actions to site administrators. To enable this, make sure that your User model defines an `is_admin?` method *and/or* an `is_admin` attribute. If the `current_user.is_admin?` returns true, access will be granted automatically.
|
125
|
+
|
126
|
+
How to Test
|
127
|
+
-----------
|
128
|
+
I normally do something along these lines in RSpec:
|
129
|
+
|
130
|
+
<pre><code>describe "Issue" do
|
131
|
+
before do
|
132
|
+
@project = mock_model(:project)
|
133
|
+
@author = mock_model(:user, :projects => [@project])
|
134
|
+
@issue = Factory(:issue, :author => @author, :project => @project)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should be modifiable by the author when the Project is active" do
|
138
|
+
@project.stub!(:is_active? => true)
|
139
|
+
@issue.is_updatable_by(@author, @project).should be_true
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should be deletable by the author" do
|
143
|
+
@issue.is_deletable_by(@author, @project).should be_true
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should be readable by those assigned to the Project" do
|
147
|
+
Issue.is_readable_by(@author, @project).should be_true
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should be creatable by those assigned to the Project" do
|
151
|
+
Issue.is_creatable_by(@author, @project).should be_true
|
152
|
+
end
|
153
|
+
end
|
154
|
+
</code></pre>
|
155
|
+
|
156
|
+
About the Author
|
157
|
+
----------------
|
158
|
+
My name is [Matt Darby.](http://blog.matt-darby.com) I’m an IT Manager and pro-web-dev at for [Dynamix Engineering](http://dynamix-ltd.com) and hold a Master’s Degree in Computer Science from [Franklin University](http://www.franklin.edu) in sunny [Columbus, OH.](http://en.wikipedia.org/wiki/Columbus,_Ohio)
|
159
|
+
|
160
|
+
Feel free to check out my [site](http://matt-darby.com) or [recommend me](http://www.workingwithrails.com/person/10908-matt-darby)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.0.
|
1
|
+
3.0.4
|
data/lib/restful_acl.rb
CHANGED
data/lib/restful_acl/helper.rb
CHANGED
data/restful_acl.gemspec
CHANGED
@@ -5,20 +5,20 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{restful_acl}
|
8
|
-
s.version = "3.0.
|
8
|
+
s.version = "3.0.4"
|
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{
|
12
|
+
s.date = %q{2010-01-24}
|
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
|
-
"README.
|
16
|
+
"README.markdown"
|
17
17
|
]
|
18
18
|
s.files = [
|
19
19
|
".gitignore",
|
20
20
|
"MIT-LICENSE",
|
21
|
-
"README.
|
21
|
+
"README.markdown",
|
22
22
|
"Rakefile",
|
23
23
|
"VERSION",
|
24
24
|
"init.rb",
|
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: 3.0.
|
4
|
+
version: 3.0.4
|
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:
|
12
|
+
date: 2010-01-24 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -29,11 +29,11 @@ executables: []
|
|
29
29
|
extensions: []
|
30
30
|
|
31
31
|
extra_rdoc_files:
|
32
|
-
- README.
|
32
|
+
- README.markdown
|
33
33
|
files:
|
34
34
|
- .gitignore
|
35
35
|
- MIT-LICENSE
|
36
|
-
- README.
|
36
|
+
- README.markdown
|
37
37
|
- Rakefile
|
38
38
|
- VERSION
|
39
39
|
- init.rb
|
data/README.textile
DELETED
@@ -1,162 +0,0 @@
|
|
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
|
-
|
7
|
-
h2. RESTful_ACL
|
8
|
-
|
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.
|
10
|
-
|
11
|
-
h3. What it does
|
12
|
-
|
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.)
|
14
|
-
|
15
|
-
h3. Requirements
|
16
|
-
|
17
|
-
RESTful_ACL requires the notion of a @current_user@. Most authenticaion plugins provide this (AuthLogic, RESTful_Authentication, etc.)
|
18
|
-
|
19
|
-
h3. How to Install
|
20
|
-
|
21
|
-
Install the RESTful_ACL gem:
|
22
|
-
<pre>sudo gem install restful_acl -s http://gemcutter.org</pre>
|
23
|
-
|
24
|
-
Add the gem to your environment.rb file as thus:
|
25
|
-
<pre>config.gem "restful_acl"</pre>
|
26
|
-
|
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>
|
29
|
-
|
30
|
-
h3. How to Use
|
31
|
-
|
32
|
-
h4. Controllers
|
33
|
-
|
34
|
-
Add @before_filter :has_permission?@ into any controller that you'd like to restrict access to (or application_controller.rb for your entire app).
|
35
|
-
|
36
|
-
h4. Models
|
37
|
-
|
38
|
-
Define a parent resource (if one exists) by using the @logical_parent@ method, and define the following five methods in the model of every resource you'd like to restrict access to. The five methods can contain anything you'd like so long as they return a boolean true or false. This allows you to define your User's roles any way you wish.
|
39
|
-
|
40
|
-
<pre>
|
41
|
-
class Issue < ActiveRecord::Base
|
42
|
-
logical_parent :some_model_name
|
43
|
-
|
44
|
-
# This method checks permissions for the :index action
|
45
|
-
def self.is_indexable_by(user, parent = nil)
|
46
|
-
end
|
47
|
-
|
48
|
-
# This method checks permissions for the :create and :new action
|
49
|
-
def self.is_creatable_by(user, parent = nil)
|
50
|
-
end
|
51
|
-
|
52
|
-
# This method checks permissions for the :show action
|
53
|
-
def is_readable_by(user, parent = nil)
|
54
|
-
end
|
55
|
-
|
56
|
-
# This method checks permissions for the :update and :edit action
|
57
|
-
def is_updatable_by(user, parent = nil)
|
58
|
-
end
|
59
|
-
|
60
|
-
# This method checks permissions for the :destroy action
|
61
|
-
def is_deletable_by(user, parent = nil)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
</pre>
|
65
|
-
|
66
|
-
h4. Singleton Resources
|
67
|
-
|
68
|
-
RESTful_ACL 2.1+ supports singleton resources. Just pass @:singleton@ to the @logical_parent@
|
69
|
-
|
70
|
-
<pre>
|
71
|
-
class Car < ActiveRecord::Base
|
72
|
-
logical_parent :owner, :singleton
|
73
|
-
...
|
74
|
-
end
|
75
|
-
</pre>
|
76
|
-
|
77
|
-
h4. View Helper
|
78
|
-
|
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>
|
86
|
-
|
87
|
-
h3. Huh? Here's an example
|
88
|
-
|
89
|
-
Let's say that you have two resources: Project and Issue. A Project has many Issues, an Issue belongs to a Project. I'd like to make sure that the current user is a member of the Project before they can create a new Issue in that Project:
|
90
|
-
|
91
|
-
<pre>
|
92
|
-
class Issue < ActiveRecord::Base
|
93
|
-
logical_parent :project
|
94
|
-
|
95
|
-
belongs_to :author
|
96
|
-
belongs_to :project
|
97
|
-
|
98
|
-
def self.is_indexable_by(user, parent = nil)
|
99
|
-
user.projects.include?(parent)
|
100
|
-
end
|
101
|
-
|
102
|
-
def self.is_creatable_by(user, parent = nil)
|
103
|
-
user.projects.include?(parent)
|
104
|
-
end
|
105
|
-
|
106
|
-
def is_updatable_by(user, parent = nil)
|
107
|
-
user == author && parent.is_active?
|
108
|
-
end
|
109
|
-
|
110
|
-
def is_deletable_by(user, parent = nil)
|
111
|
-
user == author
|
112
|
-
end
|
113
|
-
|
114
|
-
def is_readable_by(user, parent = nil)
|
115
|
-
user.projects.include?(parent)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
</pre>
|
119
|
-
|
120
|
-
h3. Admins RULE!
|
121
|
-
|
122
|
-
RESTful_ACL grants global access to all actions to site administrators. To enable this, make sure that your User model defines an @is_admin?@ method *and/or* an @is_admin@ attribute. If the @current_user.is_admin?@ returns true, access will be granted automatically.
|
123
|
-
|
124
|
-
h3. How to Test
|
125
|
-
|
126
|
-
I normally do something along these lines in RSpec:
|
127
|
-
<pre>
|
128
|
-
describe "Issue" do
|
129
|
-
before do
|
130
|
-
@project = mock_model(Project)
|
131
|
-
@author = mock_model(User, :projects => [@project])
|
132
|
-
@issue = Issue.factory_girl(:issue, :author => @author, :project => @project)
|
133
|
-
end
|
134
|
-
|
135
|
-
it "should be modifiable by the author when the Project is active" do
|
136
|
-
@project.stub!(:is_active? => true)
|
137
|
-
@issue.is_updatable_by(@author, @project).should be_true
|
138
|
-
end
|
139
|
-
|
140
|
-
it "should be deletable by the author" do
|
141
|
-
@issue.is_deletable_by(@author, @project).should be_true
|
142
|
-
end
|
143
|
-
|
144
|
-
it "should be readable by those assigned to the Project" do
|
145
|
-
Issue.is_readable_by(@author, @project).should be_true
|
146
|
-
end
|
147
|
-
|
148
|
-
it "should be creatable by those assigned to the Project" do
|
149
|
-
Issue.is_creatable_by(@author, @project).should be_true
|
150
|
-
end
|
151
|
-
end
|
152
|
-
</pre>
|
153
|
-
|
154
|
-
h3. Help
|
155
|
-
|
156
|
-
Add a ticket to "RESTful_ACL's Lighthouse Account":http://mdarby.lighthouseapp.com/projects/28698-restful_acl/overview
|
157
|
-
|
158
|
-
h3. About the Author
|
159
|
-
|
160
|
-
My name is "Matt Darby.":http://blog.matt-darby.com I’m an IT Manager and pro-web-dev at for "Dynamix Engineering":http://dynamix-ltd.com and hold a Master’s Degree in Computer Science from "Franklin University":http://www.franklin.edu in sunny "Columbus, OH.":http://en.wikipedia.org/wiki/Columbus,_Ohio
|
161
|
-
|
162
|
-
Feel free to check out my "site":http://matt-darby.com or "recommend me":http://www.workingwithrails.com/person/10908-matt-darby
|