cancancan 1.17.0 → 3.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/cancancan.gemspec +10 -11
- data/init.rb +2 -0
- data/lib/cancan/ability/actions.rb +93 -0
- data/lib/cancan/ability/rules.rb +96 -0
- data/lib/cancan/ability/strong_parameter_support.rb +41 -0
- data/lib/cancan/ability.rb +87 -198
- data/lib/cancan/class_matcher.rb +30 -0
- data/lib/cancan/conditions_matcher.rb +147 -0
- data/lib/cancan/config.rb +101 -0
- data/lib/cancan/controller_additions.rb +13 -30
- data/lib/cancan/controller_resource.rb +33 -225
- data/lib/cancan/controller_resource_builder.rb +26 -0
- data/lib/cancan/controller_resource_finder.rb +42 -0
- data/lib/cancan/controller_resource_loader.rb +120 -0
- data/lib/cancan/controller_resource_name_finder.rb +23 -0
- data/lib/cancan/controller_resource_sanitizer.rb +32 -0
- data/lib/cancan/exceptions.rb +24 -4
- data/lib/cancan/matchers.rb +12 -1
- data/lib/cancan/model_adapters/abstract_adapter.rb +22 -1
- data/lib/cancan/model_adapters/active_record_4_adapter.rb +25 -44
- data/lib/cancan/model_adapters/active_record_5_adapter.rb +61 -0
- data/lib/cancan/model_adapters/active_record_adapter.rb +157 -83
- data/lib/cancan/model_adapters/conditions_extractor.rb +75 -0
- data/lib/cancan/model_adapters/conditions_normalizer.rb +49 -0
- data/lib/cancan/model_adapters/default_adapter.rb +2 -0
- data/lib/cancan/model_adapters/sti_normalizer.rb +47 -0
- data/lib/cancan/model_adapters/strategies/base.rb +40 -0
- data/lib/cancan/model_adapters/strategies/joined_alias_each_rule_as_exists_subquery.rb +93 -0
- data/lib/cancan/model_adapters/strategies/joined_alias_exists_subquery.rb +31 -0
- data/lib/cancan/model_adapters/strategies/left_join.rb +11 -0
- data/lib/cancan/model_adapters/strategies/subquery.rb +18 -0
- data/lib/cancan/model_additions.rb +6 -2
- data/lib/cancan/parameter_validators.rb +9 -0
- data/lib/cancan/relevant.rb +29 -0
- data/lib/cancan/rule.rb +67 -90
- data/lib/cancan/rules_compressor.rb +23 -0
- data/lib/cancan/sti_detector.rb +12 -0
- data/lib/cancan/unauthorized_message_resolver.rb +24 -0
- data/lib/cancan/version.rb +3 -1
- data/lib/cancan.rb +15 -10
- data/lib/cancancan.rb +2 -0
- data/lib/generators/cancan/ability/ability_generator.rb +3 -1
- data/lib/generators/cancan/ability/templates/ability.rb +9 -9
- metadata +64 -86
- data/.gitignore +0 -15
- data/.rspec +0 -1
- data/.rubocop.yml +0 -39
- data/.rubocop_todo.yml +0 -54
- data/.travis.yml +0 -39
- data/Appraisals +0 -105
- data/CHANGELOG.rdoc +0 -536
- data/CONTRIBUTING.md +0 -23
- data/Gemfile +0 -3
- data/LICENSE +0 -22
- data/README.md +0 -234
- data/Rakefile +0 -13
- data/gemfiles/activerecord_3.2.gemfile +0 -18
- data/gemfiles/activerecord_4.0.gemfile +0 -19
- data/gemfiles/activerecord_4.1.gemfile +0 -19
- data/gemfiles/activerecord_4.2.gemfile +0 -21
- data/gemfiles/activerecord_5.0.gemfile +0 -20
- data/gemfiles/mongoid_2.x.gemfile +0 -18
- data/gemfiles/sequel_3.x.gemfile +0 -18
- data/lib/cancan/inherited_resource.rb +0 -20
- data/lib/cancan/model_adapters/active_record_3_adapter.rb +0 -16
- data/lib/cancan/model_adapters/mongoid_adapter.rb +0 -80
- data/lib/cancan/model_adapters/sequel_adapter.rb +0 -87
- data/spec/README.rdoc +0 -27
- data/spec/cancan/ability_spec.rb +0 -553
- data/spec/cancan/controller_additions_spec.rb +0 -164
- data/spec/cancan/controller_resource_spec.rb +0 -645
- data/spec/cancan/exceptions_spec.rb +0 -58
- data/spec/cancan/inherited_resource_spec.rb +0 -71
- data/spec/cancan/matchers_spec.rb +0 -29
- data/spec/cancan/model_adapters/active_record_4_adapter_spec.rb +0 -160
- data/spec/cancan/model_adapters/active_record_adapter_spec.rb +0 -415
- data/spec/cancan/model_adapters/default_adapter_spec.rb +0 -7
- data/spec/cancan/model_adapters/mongoid_adapter_spec.rb +0 -246
- data/spec/cancan/model_adapters/sequel_adapter_spec.rb +0 -129
- data/spec/cancan/rule_spec.rb +0 -52
- data/spec/matchers.rb +0 -13
- data/spec/spec.opts +0 -2
- data/spec/spec_helper.rb +0 -27
- data/spec/support/ability.rb +0 -6
data/README.md
DELETED
@@ -1,234 +0,0 @@
|
|
1
|
-
# CanCanCan
|
2
|
-
|
3
|
-
[![Gem Version](https://badge.fury.io/rb/cancancan.svg)](http://badge.fury.io/rb/cancancan)
|
4
|
-
[![Travis badge](https://travis-ci.org/CanCanCommunity/cancancan.svg?branch=develop)](https://travis-ci.org/CanCanCommunity/cancancan)
|
5
|
-
[![Code Climate Badge](https://codeclimate.com/github/CanCanCommunity/cancancan.svg)](https://codeclimate.com/github/CanCanCommunity/cancancan)
|
6
|
-
[![Inch CI](http://inch-ci.org/github/CanCanCommunity/cancancan.svg)](http://inch-ci.org/github/CanCanCommunity/cancancan)
|
7
|
-
|
8
|
-
[Wiki](https://github.com/CanCanCommunity/cancancan/wiki) |
|
9
|
-
[RDocs](http://rdoc.info/projects/CanCanCommunity/cancancan) |
|
10
|
-
[Screencast](http://railscasts.com/episodes/192-authorization-with-cancan) |
|
11
|
-
[Gitter](https://gitter.im/CanCanCommunity/cancancan)
|
12
|
-
|
13
|
-
CanCanCan is an authorization library for Ruby 2.0+ and Ruby on Rails 3+ which restricts what resources a given user is allowed to access.
|
14
|
-
|
15
|
-
All permissions are defined in a single location (the `Ability` class) and not duplicated across controllers, views, and database queries.
|
16
|
-
|
17
|
-
|
18
|
-
## Installation
|
19
|
-
|
20
|
-
Add this to your Gemfile:
|
21
|
-
|
22
|
-
gem 'cancancan', '~> 1.10'
|
23
|
-
|
24
|
-
and run the `bundle install` command.
|
25
|
-
|
26
|
-
## Getting Started
|
27
|
-
|
28
|
-
CanCanCan expects a `current_user` method to exist in the controller.
|
29
|
-
First, set up some authentication (such as [Devise](https://github.com/plataformatec/devise) or [Authlogic](https://github.com/binarylogic/authlogic)).
|
30
|
-
See [Changing Defaults](https://github.com/CanCanCommunity/cancancan/wiki/changing-defaults) if you need a different behavior.
|
31
|
-
|
32
|
-
When using [rails-api](https://github.com/rails-api/rails-api), you have to manually include the controller methods for CanCanCan:
|
33
|
-
```ruby
|
34
|
-
class ApplicationController < ActionController::API
|
35
|
-
include CanCan::ControllerAdditions
|
36
|
-
end
|
37
|
-
```
|
38
|
-
|
39
|
-
### 1. Define Abilities
|
40
|
-
|
41
|
-
User permissions are defined in an `Ability` class.
|
42
|
-
|
43
|
-
rails g cancan:ability
|
44
|
-
|
45
|
-
See [Defining Abilities](https://github.com/CanCanCommunity/cancancan/wiki/defining-abilities) for details.
|
46
|
-
|
47
|
-
|
48
|
-
### 2. Check Abilities & Authorization
|
49
|
-
|
50
|
-
The current user's permissions can then be checked using the `can?` and `cannot?` methods in views and controllers.
|
51
|
-
|
52
|
-
```erb
|
53
|
-
<% if can? :update, @article %>
|
54
|
-
<%= link_to "Edit", edit_article_path(@article) %>
|
55
|
-
<% end %>
|
56
|
-
```
|
57
|
-
|
58
|
-
See [Checking Abilities](https://github.com/CanCanCommunity/cancancan/wiki/checking-abilities) for more information
|
59
|
-
|
60
|
-
The `authorize!` method in the controller will raise an exception if the user is not able to perform the given action.
|
61
|
-
|
62
|
-
```ruby
|
63
|
-
def show
|
64
|
-
@article = Article.find(params[:id])
|
65
|
-
authorize! :read, @article
|
66
|
-
end
|
67
|
-
```
|
68
|
-
|
69
|
-
Setting this for every action can be tedious, therefore the `load_and_authorize_resource` method is provided to
|
70
|
-
automatically authorize all actions in a RESTful style resource controller.
|
71
|
-
It will use a before action to load the resource into an instance variable and authorize it for every action.
|
72
|
-
|
73
|
-
```ruby
|
74
|
-
class ArticlesController < ApplicationController
|
75
|
-
load_and_authorize_resource
|
76
|
-
|
77
|
-
def show
|
78
|
-
# @article is already loaded and authorized
|
79
|
-
end
|
80
|
-
end
|
81
|
-
```
|
82
|
-
|
83
|
-
See [Authorizing Controller Actions](https://github.com/CanCanCommunity/cancancan/wiki/authorizing-controller-actions) for more information.
|
84
|
-
|
85
|
-
|
86
|
-
#### Strong Parameters
|
87
|
-
|
88
|
-
When using `strong_parameters` or Rails 4+, you have to sanitize inputs before saving the record, in actions such as `:create` and `:update`.
|
89
|
-
|
90
|
-
For the `:update` action, CanCanCan will load and authorize the resource but *not* change it automatically, so the typical usage would be something like:
|
91
|
-
|
92
|
-
```ruby
|
93
|
-
def update
|
94
|
-
if @article.update_attributes(update_params)
|
95
|
-
# hurray
|
96
|
-
else
|
97
|
-
render :edit
|
98
|
-
end
|
99
|
-
end
|
100
|
-
...
|
101
|
-
|
102
|
-
def update_params
|
103
|
-
params.require(:article).permit(:body)
|
104
|
-
end
|
105
|
-
```
|
106
|
-
|
107
|
-
For the `:create` action, CanCanCan will try to initialize a new instance with sanitized input by seeing if your
|
108
|
-
controller will respond to the following methods (in order):
|
109
|
-
|
110
|
-
1. `create_params`
|
111
|
-
2. `<model_name>_params` such as `article_params` (this is the default convention in rails for naming your param method)
|
112
|
-
3. `resource_params` (a generically named method you could specify in each controller)
|
113
|
-
|
114
|
-
Additionally, `load_and_authorize_resource` can now take a `param_method` option to specify a custom method in the controller to run to sanitize input.
|
115
|
-
|
116
|
-
You can associate the `param_method` option with a symbol corresponding to the name of a method that will get called:
|
117
|
-
|
118
|
-
```ruby
|
119
|
-
class ArticlesController < ApplicationController
|
120
|
-
load_and_authorize_resource param_method: :my_sanitizer
|
121
|
-
|
122
|
-
def create
|
123
|
-
if @article.save
|
124
|
-
# hurray
|
125
|
-
else
|
126
|
-
render :new
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
private
|
131
|
-
|
132
|
-
def my_sanitizer
|
133
|
-
params.require(:article).permit(:name)
|
134
|
-
end
|
135
|
-
end
|
136
|
-
```
|
137
|
-
|
138
|
-
You can also use a string that will be evaluated in the context of the controller using `instance_eval` and needs to contain valid Ruby code.
|
139
|
-
|
140
|
-
load_and_authorize_resource param_method: 'permitted_params.article'
|
141
|
-
|
142
|
-
Finally, it's possible to associate `param_method` with a Proc object which will be called with the controller as the only argument:
|
143
|
-
|
144
|
-
load_and_authorize_resource param_method: Proc.new { |c| c.params.require(:article).permit(:name) }
|
145
|
-
|
146
|
-
See [Strong Parameters](https://github.com/CanCanCommunity/cancancan/wiki/Strong-Parameters) for more information.
|
147
|
-
|
148
|
-
### 3. Handle Unauthorized Access
|
149
|
-
|
150
|
-
If the user authorization fails, a `CanCan::AccessDenied` exception will be raised.
|
151
|
-
You can catch this and modify its behavior in the `ApplicationController`.
|
152
|
-
|
153
|
-
```ruby
|
154
|
-
class ApplicationController < ActionController::Base
|
155
|
-
rescue_from CanCan::AccessDenied do |exception|
|
156
|
-
respond_to do |format|
|
157
|
-
format.json { head :forbidden, content_type: 'text/html' }
|
158
|
-
format.html { redirect_to main_app.root_url, notice: exception.message }
|
159
|
-
format.js { head :forbidden, content_type: 'text/html' }
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
```
|
164
|
-
|
165
|
-
See [Exception Handling](https://github.com/CanCanCommunity/cancancan/wiki/exception-handling) for more information.
|
166
|
-
|
167
|
-
|
168
|
-
### 4. Lock It Down
|
169
|
-
|
170
|
-
If you want to ensure authorization happens on every action in your application, add `check_authorization` to your `ApplicationController`.
|
171
|
-
|
172
|
-
```ruby
|
173
|
-
class ApplicationController < ActionController::Base
|
174
|
-
check_authorization
|
175
|
-
end
|
176
|
-
```
|
177
|
-
|
178
|
-
This will raise an exception if authorization is not performed in an action.
|
179
|
-
If you want to skip this, add `skip_authorization_check` to a controller subclass.
|
180
|
-
See [Ensure Authorization](https://github.com/CanCanCommunity/cancancan/wiki/Ensure-Authorization) for more information.
|
181
|
-
|
182
|
-
|
183
|
-
## Wiki Docs
|
184
|
-
|
185
|
-
* [Upgrading to 1.6](https://github.com/CanCanCommunity/cancancan/wiki/Upgrading-to-1.6)
|
186
|
-
* [Defining Abilities](https://github.com/CanCanCommunity/cancancan/wiki/Defining-Abilities)
|
187
|
-
* [Checking Abilities](https://github.com/CanCanCommunity/cancancan/wiki/Checking-Abilities)
|
188
|
-
* [Authorizing Controller Actions](https://github.com/CanCanCommunity/cancancan/wiki/Authorizing-Controller-Actions)
|
189
|
-
* [Exception Handling](https://github.com/CanCanCommunity/cancancan/wiki/Exception-Handling)
|
190
|
-
* [Changing Defaults](https://github.com/CanCanCommunity/cancancan/wiki/Changing-Defaults)
|
191
|
-
* [See more](https://github.com/CanCanCommunity/cancancan/wiki)
|
192
|
-
|
193
|
-
## Mission
|
194
|
-
|
195
|
-
This repo is a continuation of the dead [CanCan](https://github.com/ryanb/cancan) project.
|
196
|
-
Our mission is to keep CanCan alive and moving forward, with maintenance fixes and new features.
|
197
|
-
Pull Requests are welcome!
|
198
|
-
|
199
|
-
Any help is greatly appreciated, feel free to submit pull-requests or open issues.
|
200
|
-
|
201
|
-
|
202
|
-
## Questions?
|
203
|
-
|
204
|
-
If you have any question or doubt regarding CanCanCan which you cannot find the solution to in the
|
205
|
-
[documentation](https://github.com/CanCanCommunity/cancancan/wiki) or our
|
206
|
-
[mailing list](http://groups.google.com/group/cancancan), please
|
207
|
-
[open a question on Stackoverflow](http://stackoverflow.com/questions/ask?tags=cancancan) with tag
|
208
|
-
[cancancan](http://stackoverflow.com/questions/tagged/cancancan)
|
209
|
-
|
210
|
-
## Bugs?
|
211
|
-
|
212
|
-
If you find a bug please add an [issue on GitHub](https://github.com/CanCanCommunity/cancancan/issues) or fork the project and send a pull request.
|
213
|
-
|
214
|
-
|
215
|
-
## Development
|
216
|
-
|
217
|
-
CanCanCan uses [appraisals](https://github.com/thoughtbot/appraisal) to test the code base against multiple versions
|
218
|
-
of Rails, as well as the different model adapters.
|
219
|
-
|
220
|
-
When first developing, you may need to run `bundle install` and then `appraisal install`, to install the different sets.
|
221
|
-
|
222
|
-
You can then run all appraisal files (like CI does), with `appraisal rake` or just run a specific set `appraisal activerecord_3.0 rake`.
|
223
|
-
|
224
|
-
See the [CONTRIBUTING](https://github.com/CanCanCommunity/cancancan/blob/develop/CONTRIBUTING.md) and
|
225
|
-
[spec/README](https://github.com/CanCanCommunity/cancancan/blob/master/spec/README.rdoc) for more information.
|
226
|
-
|
227
|
-
|
228
|
-
## Special Thanks
|
229
|
-
|
230
|
-
CanCanCan was inspired by [declarative_authorization](https://github.com/stffn/declarative_authorization/) and
|
231
|
-
[aegis](https://github.com/makandra/aegis).
|
232
|
-
|
233
|
-
Also many thanks to the [CanCanCan contributors](https://github.com/CanCanCommunity/cancancan/contributors).
|
234
|
-
See the [CHANGELOG](https://github.com/CanCanCommunity/cancancan/blob/master/CHANGELOG.rdoc) for the full list.
|
data/Rakefile
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'bundler/gem_tasks'
|
2
|
-
require 'rspec/core/rake_task'
|
3
|
-
require 'rubocop/rake_task'
|
4
|
-
|
5
|
-
desc 'Run Rubocop'
|
6
|
-
RuboCop::RakeTask.new
|
7
|
-
|
8
|
-
desc 'Run RSpec'
|
9
|
-
RSpec::Core::RakeTask.new do |t|
|
10
|
-
t.verbose = false
|
11
|
-
end
|
12
|
-
|
13
|
-
task default: [:rubocop, :spec]
|
@@ -1,18 +0,0 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
gem "activerecord", "~> 3.2.0", :require => "active_record"
|
6
|
-
gem "actionpack", "~> 3.2.0", :require => "action_pack"
|
7
|
-
gem "rubocop", "0.48.0"
|
8
|
-
|
9
|
-
platforms :jruby do
|
10
|
-
gem "activerecord-jdbcsqlite3-adapter"
|
11
|
-
gem "jdbc-sqlite3"
|
12
|
-
end
|
13
|
-
|
14
|
-
platforms :ruby, :mswin, :mingw do
|
15
|
-
gem "sqlite3"
|
16
|
-
end
|
17
|
-
|
18
|
-
gemspec :path => "../"
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
gem "activerecord", "~> 4.0.5", :require => "active_record"
|
6
|
-
gem "activesupport", "~> 4.0.5", :require => "active_support/all"
|
7
|
-
gem "actionpack", "~> 4.0.5", :require => "action_pack"
|
8
|
-
gem "rubocop", "0.48.0"
|
9
|
-
|
10
|
-
platforms :jruby do
|
11
|
-
gem "activerecord-jdbcsqlite3-adapter"
|
12
|
-
gem "jdbc-sqlite3"
|
13
|
-
end
|
14
|
-
|
15
|
-
platforms :ruby, :mswin, :mingw do
|
16
|
-
gem "sqlite3"
|
17
|
-
end
|
18
|
-
|
19
|
-
gemspec :path => "../"
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
gem "activerecord", "~> 4.1.1", :require => "active_record"
|
6
|
-
gem "activesupport", "~> 4.1.1", :require => "active_support/all"
|
7
|
-
gem "actionpack", "~> 4.1.1", :require => "action_pack"
|
8
|
-
gem "rubocop", "0.48.0"
|
9
|
-
|
10
|
-
platforms :jruby do
|
11
|
-
gem "activerecord-jdbcsqlite3-adapter"
|
12
|
-
gem "jdbc-sqlite3"
|
13
|
-
end
|
14
|
-
|
15
|
-
platforms :ruby, :mswin, :mingw do
|
16
|
-
gem "sqlite3"
|
17
|
-
end
|
18
|
-
|
19
|
-
gemspec :path => "../"
|
@@ -1,21 +0,0 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
gem "activerecord", "~> 4.2.0", :require => "active_record"
|
6
|
-
gem "activesupport", "~> 4.2.0", :require => "active_support/all"
|
7
|
-
gem "actionpack", "~> 4.2.0", :require => "action_pack"
|
8
|
-
gem "nokogiri", "~> 1.6.8", :require => "nokogiri"
|
9
|
-
gem "rubocop", "0.48.0"
|
10
|
-
|
11
|
-
platforms :jruby do
|
12
|
-
gem "activerecord-jdbcsqlite3-adapter"
|
13
|
-
gem "jdbc-sqlite3"
|
14
|
-
end
|
15
|
-
|
16
|
-
platforms :ruby, :mswin, :mingw do
|
17
|
-
gem "sqlite3"
|
18
|
-
gem "pg"
|
19
|
-
end
|
20
|
-
|
21
|
-
gemspec :path => "../"
|
@@ -1,20 +0,0 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
gem "activerecord", "~> 5.0.0.rc1", :require => "active_record"
|
6
|
-
gem "activesupport", "~> 5.0.0.rc1", :require => "active_support/all"
|
7
|
-
gem "actionpack", "~> 5.0.0.rc1", :require => "action_pack"
|
8
|
-
gem "rubocop", "0.48.0"
|
9
|
-
|
10
|
-
platforms :jruby do
|
11
|
-
gem "activerecord-jdbcsqlite3-adapter"
|
12
|
-
gem "jdbc-sqlite3"
|
13
|
-
end
|
14
|
-
|
15
|
-
platforms :ruby, :mswin, :mingw do
|
16
|
-
gem "sqlite3"
|
17
|
-
gem "pg"
|
18
|
-
end
|
19
|
-
|
20
|
-
gemspec :path => "../"
|
@@ -1,18 +0,0 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
gem "activesupport", "~> 3.0", :require => "active_support/all"
|
6
|
-
gem "actionpack", "~> 3.0", :require => "action_pack"
|
7
|
-
gem "mongoid", "~> 2.0.0"
|
8
|
-
gem "rubocop", "0.48.0"
|
9
|
-
|
10
|
-
platforms :ruby, :mswin, :mingw do
|
11
|
-
gem "bson_ext", "~> 1.1"
|
12
|
-
end
|
13
|
-
|
14
|
-
platforms :jruby do
|
15
|
-
gem "mongo", "~> 1.9.2"
|
16
|
-
end
|
17
|
-
|
18
|
-
gemspec :path => "../"
|
data/gemfiles/sequel_3.x.gemfile
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
gem "sequel", "~> 3.48.0"
|
6
|
-
gem "activesupport", "~> 3.0", :require => "active_support/all"
|
7
|
-
gem "actionpack", "~> 3.0", :require => "action_pack"
|
8
|
-
gem "rubocop", "0.48.0"
|
9
|
-
|
10
|
-
platforms :jruby do
|
11
|
-
gem "jdbc-sqlite3"
|
12
|
-
end
|
13
|
-
|
14
|
-
platforms :ruby, :mswin, :mingw do
|
15
|
-
gem "sqlite3"
|
16
|
-
end
|
17
|
-
|
18
|
-
gemspec :path => "../"
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module CanCan
|
2
|
-
# For use with Inherited Resources
|
3
|
-
class InheritedResource < ControllerResource # :nodoc:
|
4
|
-
def load_resource_instance
|
5
|
-
if parent?
|
6
|
-
@controller.send :association_chain
|
7
|
-
@controller.instance_variable_get("@#{instance_name}")
|
8
|
-
elsif new_actions.include? @params[:action].to_sym
|
9
|
-
resource = @controller.send :build_resource
|
10
|
-
assign_attributes(resource)
|
11
|
-
else
|
12
|
-
@controller.send :resource
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def resource_base
|
17
|
-
@controller.send :end_of_association_chain
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module CanCan
|
2
|
-
module ModelAdapters
|
3
|
-
class ActiveRecord3Adapter < AbstractAdapter
|
4
|
-
include ActiveRecordAdapter
|
5
|
-
def self.for_class?(model_class)
|
6
|
-
model_class <= ActiveRecord::Base
|
7
|
-
end
|
8
|
-
|
9
|
-
private
|
10
|
-
|
11
|
-
def build_relation(*where_conditions)
|
12
|
-
@model_class.where(*where_conditions).includes(joins)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,80 +0,0 @@
|
|
1
|
-
module CanCan
|
2
|
-
module ModelAdapters
|
3
|
-
class MongoidAdapter < AbstractAdapter
|
4
|
-
def self.for_class?(model_class)
|
5
|
-
model_class <= Mongoid::Document
|
6
|
-
end
|
7
|
-
|
8
|
-
def self.override_conditions_hash_matching?(subject, conditions)
|
9
|
-
conditions.any? do |k, _v|
|
10
|
-
key_is_not_symbol = -> { !k.is_a?(Symbol) }
|
11
|
-
subject_value_is_array = lambda do
|
12
|
-
subject.respond_to?(k) && subject.send(k).is_a?(Array)
|
13
|
-
end
|
14
|
-
|
15
|
-
key_is_not_symbol.call || subject_value_is_array.call
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.matches_conditions_hash?(subject, conditions)
|
20
|
-
# To avoid hitting the db, retrieve the raw Mongo selector from
|
21
|
-
# the Mongoid Criteria and use Mongoid::Matchers#matches?
|
22
|
-
subject.matches?(subject.class.where(conditions).selector)
|
23
|
-
end
|
24
|
-
|
25
|
-
def database_records
|
26
|
-
if @rules.empty?
|
27
|
-
@model_class.where(_id: { '$exists' => false, '$type' => 7 }) # return no records in Mongoid
|
28
|
-
elsif @rules.size == 1 && @rules[0].conditions.is_a?(Mongoid::Criteria)
|
29
|
-
@rules[0].conditions
|
30
|
-
else
|
31
|
-
# we only need to process can rules if
|
32
|
-
# there are no rules with empty conditions
|
33
|
-
database_records_from_multiple_rules
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def database_records_from_multiple_rules
|
38
|
-
rules = @rules.reject { |rule| rule.conditions.empty? && rule.base_behavior }
|
39
|
-
process_can_rules = @rules.count == rules.count
|
40
|
-
|
41
|
-
rules.inject(@model_class.all) do |records, rule|
|
42
|
-
if process_can_rules && rule.base_behavior
|
43
|
-
records.or simplify_relations(@model_class, rule.conditions)
|
44
|
-
elsif !rule.base_behavior
|
45
|
-
records.excludes simplify_relations(@model_class, rule.conditions)
|
46
|
-
else
|
47
|
-
records
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
53
|
-
|
54
|
-
# Look for criteria on relations and replace with simple id queries
|
55
|
-
# eg.
|
56
|
-
# {user: {:tags.all => []}} becomes {"user_id" => {"$in" => [__, ..]}}
|
57
|
-
# {user: {:session => {:tags.all => []}}} becomes {"user_id" => {"session_id" => {"$in" => [__, ..]} }}
|
58
|
-
def simplify_relations(model_class, conditions)
|
59
|
-
model_relations = model_class.relations.with_indifferent_access
|
60
|
-
Hash[
|
61
|
-
conditions.map do |k, v|
|
62
|
-
if (relation = model_relations[k])
|
63
|
-
relation_class_name = relation[:class_name].blank? ? k.to_s.classify : relation[:class_name]
|
64
|
-
v = simplify_relations(relation_class_name.constantize, v)
|
65
|
-
relation_ids = relation_class_name.constantize.where(v).distinct(:_id)
|
66
|
-
k = "#{k}_id"
|
67
|
-
v = { '$in' => relation_ids }
|
68
|
-
end
|
69
|
-
[k, v]
|
70
|
-
end
|
71
|
-
]
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# simplest way to add `accessible_by` to all Mongoid Documents
|
78
|
-
module Mongoid::Document::ClassMethods
|
79
|
-
include CanCan::ModelAdditions::ClassMethods
|
80
|
-
end
|
@@ -1,87 +0,0 @@
|
|
1
|
-
module CanCan
|
2
|
-
module ModelAdapters
|
3
|
-
class SequelAdapter < AbstractAdapter
|
4
|
-
def self.for_class?(model_class)
|
5
|
-
model_class <= Sequel::Model
|
6
|
-
end
|
7
|
-
|
8
|
-
def self.find(model_class, id)
|
9
|
-
model_class[id]
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.override_condition_matching?(_subject, _name, value)
|
13
|
-
value.is_a?(Hash)
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.matches_condition?(subject, name, value)
|
17
|
-
obj = subject.send(name)
|
18
|
-
if obj.nil?
|
19
|
-
false
|
20
|
-
else
|
21
|
-
value.each do |k, v|
|
22
|
-
if v.is_a?(Hash)
|
23
|
-
return false unless matches_condition?(obj, k, v)
|
24
|
-
elsif obj.send(k) != v
|
25
|
-
return false
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def database_records
|
32
|
-
if @rules.empty?
|
33
|
-
@model_class.where('1=0')
|
34
|
-
else
|
35
|
-
# only need to process can rules if there are no can rule with empty conditions
|
36
|
-
rules = @rules.reject { |rule| rule.base_behavior && rule.conditions.empty? }
|
37
|
-
rules.reject!(&:base_behavior) if rules.count < @rules.count
|
38
|
-
|
39
|
-
can_condition_added = false
|
40
|
-
rules.reverse.inject(@model_class.dataset) do |records, rule|
|
41
|
-
normalized_conditions = normalize_conditions(rule.conditions)
|
42
|
-
if rule.base_behavior
|
43
|
-
if can_condition_added
|
44
|
-
records.or normalized_conditions
|
45
|
-
else
|
46
|
-
can_condition_added = true
|
47
|
-
records.where normalized_conditions
|
48
|
-
end
|
49
|
-
else
|
50
|
-
records.exclude normalized_conditions
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
private
|
57
|
-
|
58
|
-
def normalize_conditions(conditions, model_class = @model_class)
|
59
|
-
return conditions unless conditions.is_a? Hash
|
60
|
-
conditions.each_with_object({}) do |(name, value), result_hash|
|
61
|
-
if value.is_a? Hash
|
62
|
-
value = value.dup
|
63
|
-
association_class = model_class.association_reflection(name).associated_class
|
64
|
-
nested_resulted = value.each_with_object({}) do |(k, v), nested|
|
65
|
-
if v.is_a?(Hash)
|
66
|
-
value.delete(k)
|
67
|
-
nested_class = association_class.association_reflection(k).associated_class
|
68
|
-
nested[k] = nested_class.where(normalize_conditions(v, association_class))
|
69
|
-
else
|
70
|
-
nested[k] = v
|
71
|
-
end
|
72
|
-
nested
|
73
|
-
end
|
74
|
-
result_hash[name] = association_class.where(nested_resulted)
|
75
|
-
else
|
76
|
-
result_hash[name] = value
|
77
|
-
end
|
78
|
-
result_hash
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
Sequel::Model.class_eval do
|
86
|
-
include CanCan::ModelAdditions
|
87
|
-
end
|
data/spec/README.rdoc
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
= CanCan Specs
|
2
|
-
|
3
|
-
== Running the specs
|
4
|
-
|
5
|
-
To run the specs first run the +bundle+ command to install the necessary gems and the +rake+ command to run the specs.
|
6
|
-
|
7
|
-
bundle
|
8
|
-
|
9
|
-
Then run the appraisal command to install all the necessary test sets:
|
10
|
-
|
11
|
-
appraisal install
|
12
|
-
|
13
|
-
You can then run all test sets:
|
14
|
-
|
15
|
-
appraisal rake
|
16
|
-
|
17
|
-
Or individual ones:
|
18
|
-
|
19
|
-
appraisal activerecord_3.2 rake
|
20
|
-
|
21
|
-
A list of the tests is in the +Appraisal+ file.
|
22
|
-
|
23
|
-
The specs support Ruby 1.8.7+
|
24
|
-
|
25
|
-
== Model Adapters
|
26
|
-
|
27
|
-
The model adapter ENV setting has been removed and replaced with the +Appraisal+ file.
|