trust 0.6.3 → 0.7.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/README.md +26 -2
- data/lib/trust/active_model.rb +76 -0
- data/lib/trust/{active_record.rb → actor.rb} +25 -35
- data/lib/trust/authorization.rb +38 -13
- data/lib/trust/controller/properties.rb +19 -12
- data/lib/trust/controller/resource.rb +38 -18
- data/lib/trust/controller.rb +26 -14
- data/lib/trust/inheritable_attribute.rb +7 -5
- data/lib/trust/permissions.rb +104 -92
- data/lib/trust/version.rb +1 -1
- data/lib/trust.rb +5 -4
- data/test/dummy/log/development.log +3 -0
- data/test/dummy/log/test.log +12750 -0
- data/test/unit/trust/active_model_test.rb +80 -0
- data/test/unit/trust/{active_record_test.rb → actor_test.rb} +14 -22
- data/test/unit/trust/authorization_test.rb +23 -5
- metadata +12 -7
data/README.md
CHANGED
@@ -141,8 +141,32 @@ can? :edit, @account, @client # is current user allowed to edit the accoun
|
|
141
141
|
#### On ActiveRecord objects you will use permits?
|
142
142
|
|
143
143
|
``` Ruby
|
144
|
-
@customer.permits? :edit
|
145
|
-
Customer.permits? :create, @client
|
144
|
+
@customer.permits? :edit # does the current user have permission to edit the given customer?
|
145
|
+
Customer.permits? :create, @client # does the current user have permission to create customers for client?
|
146
|
+
Customer.permits? :create, @client, :by => @auditor # does the auditor have permission to create customers?
|
147
|
+
Customer.permits? :create, :for => @client, :by => @auditor # same as above
|
148
|
+
```
|
149
|
+
|
150
|
+
#### You can also designate actors in your model so you can test if other people has access to do operations on a subject
|
151
|
+
|
152
|
+
Include the Actor role in the class
|
153
|
+
``` Ruby
|
154
|
+
class Auditor
|
155
|
+
include Trust::Actor
|
156
|
+
...
|
157
|
+
end
|
158
|
+
```
|
159
|
+
|
160
|
+
Now you can test if the auditor has permission to modify customer for client. Three ways of writing it
|
161
|
+
``` Ruby
|
162
|
+
@auditor.can? :update, @customer, @client
|
163
|
+
@auditor.can? :update, @customer, :for => @client
|
164
|
+
@auditor.can? :update, @customer, :parent => @client
|
165
|
+
```
|
166
|
+
|
167
|
+
The above is the same as
|
168
|
+
``` Ruby
|
169
|
+
@customer.permits? :update, @client, :by => @auditor
|
146
170
|
```
|
147
171
|
|
148
172
|
## Instance variables
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# Copyright (c) 2012 Bingo Entreprenøren AS
|
2
|
+
# Copyright (c) 2012 Teknobingo Scandinavia AS
|
3
|
+
# Copyright (c) 2012 Knut I. Stenmark
|
4
|
+
# Copyright (c) 2012 Patrick Hanevold
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
# a copy of this software and associated documentation files (the
|
8
|
+
# "Software"), to deal in the Software without restriction, including
|
9
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
# the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be
|
15
|
+
# included in all copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
21
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
22
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
|
25
|
+
module Trust
|
26
|
+
# = Trust::ActiveModel extension
|
27
|
+
#
|
28
|
+
# Extends ActiveRecord with the +permits?+ and +ensure_permitted!+ method on class and instances
|
29
|
+
# If using Mongoid same features are included there
|
30
|
+
#
|
31
|
+
# Options:
|
32
|
+
#
|
33
|
+
# * +:parent+ - Specifies that the persmision should be tested in the context of a parent
|
34
|
+
# * +:by+ - Specifies an actor to be used instead of the currently logged in user
|
35
|
+
#
|
36
|
+
# ==== Examples
|
37
|
+
#
|
38
|
+
# # If current user is permitted to create customers, create it
|
39
|
+
# if Customer.permits? :create
|
40
|
+
# Customer.create attributes
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# # If current user is permitted to create accounts for the given customer, create it
|
44
|
+
# if Account.permits? :create, @customer
|
45
|
+
# Account.create attributes
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# # If the specified actor is permitted to create accounts for the given customer, create it
|
49
|
+
# if Account.permits? :create, @customer, :by => @actor
|
50
|
+
# Account.create attributes
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# # Raise an exception if user is not permitted to update the given customer, else save it
|
54
|
+
# @customer.ensure_permitted! :update
|
55
|
+
# @customer.save
|
56
|
+
#
|
57
|
+
# # Raise an exception if the specified user is not permitted to update the given customer, else save it
|
58
|
+
# @customer.ensure_permitted! :update, :by => @actor
|
59
|
+
# @customer.save
|
60
|
+
module ActiveModel
|
61
|
+
extend ActiveSupport::Concern
|
62
|
+
|
63
|
+
included do
|
64
|
+
include ClassMethods
|
65
|
+
end
|
66
|
+
|
67
|
+
module ClassMethods
|
68
|
+
def permits?(action, *args)
|
69
|
+
Trust::Authorization.authorized?(action, self, *args)
|
70
|
+
end
|
71
|
+
def ensure_permitted!(action, *args)
|
72
|
+
Trust::Authorization.authorize!(action, self, *args)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -23,43 +23,33 @@
|
|
23
23
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
24
|
|
25
25
|
module Trust
|
26
|
-
|
26
|
+
# = Trust::Actor extension
|
27
|
+
#
|
28
|
+
# Include this module if you want to check if an actor can act upon a specific subject
|
29
|
+
#
|
30
|
+
# ==== Examples
|
31
|
+
#
|
32
|
+
# # If the @actor can create customers, create it
|
33
|
+
# if @actor.can? :create, Customer
|
34
|
+
# Customer.create attributes
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# # If @actor can create accounts for the given customer, create it
|
38
|
+
# if @actor.can? :create, Account, @customer
|
39
|
+
# Account.create attributes
|
40
|
+
# end
|
41
|
+
# # It is also possible to make code more descripting for the same as above
|
42
|
+
# if @actor.can? :create, Account, :parent => @customer # or, ...
|
43
|
+
# if @actor.can? :create, Account, :for => @customer
|
44
|
+
#
|
45
|
+
module Actor
|
27
46
|
extend ActiveSupport::Concern
|
28
|
-
# = Trust::ActiveRecord extension
|
29
|
-
# Extends ActiveRecord with the +permits?+ and +ensure_permitted!+ method on class and instances
|
30
|
-
#
|
31
|
-
# ==== Examples
|
32
|
-
#
|
33
|
-
# # If current user is permitted to create customers, create it
|
34
|
-
# if Customer.permits? :create
|
35
|
-
# Customer.create attributes
|
36
|
-
# end
|
37
|
-
#
|
38
|
-
# # If current user is permitted to create accounts for the given customer, create it
|
39
|
-
# if Account.permits? :create, @customer
|
40
|
-
# Account.create attributes
|
41
|
-
# end
|
42
|
-
#
|
43
|
-
# # If current user is permitted to update the given customer, update it
|
44
|
-
# if @customer.permits? :update
|
45
|
-
# @customer.save
|
46
|
-
# end
|
47
|
-
#
|
48
|
-
# # Raise an exception if user is not permitted to update the given customer, else save it
|
49
|
-
# @customer.ensure_permitted! :update
|
50
|
-
# @customer.save
|
51
47
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
def permits?(action, parent = nil)
|
58
|
-
Trust::Authorization.authorized?(action, self, parent)
|
59
|
-
end
|
60
|
-
def ensure_permitted!(action, parent = nil)
|
61
|
-
Trust::Authorization.authorize!(action, self, parent)
|
62
|
-
end
|
48
|
+
def can?(action, subject, *args)
|
49
|
+
options = args.extract_options!
|
50
|
+
options[:parent] ||= args.first || options.delete(:for)
|
51
|
+
options[:by] = self
|
52
|
+
Trust::Authorization.authorized?(action, subject, options)
|
63
53
|
end
|
64
54
|
end
|
65
55
|
end
|
data/lib/trust/authorization.rb
CHANGED
@@ -23,13 +23,26 @@
|
|
23
23
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
24
|
|
25
25
|
module Trust
|
26
|
+
# = Trust Authorization
|
26
27
|
class Authorization
|
27
28
|
class << self
|
28
|
-
|
29
|
-
#
|
29
|
+
|
30
|
+
# Returns true if user is authorized to perform +action+ on +object+ or +class+.
|
31
|
+
#
|
32
|
+
# Options:
|
33
|
+
#
|
34
|
+
# * +:parent+ - the parent class to associate the subject with, can also be specified after the object
|
35
|
+
# or class. If +parent+ is given, +parent+ may be tested in the implemented Permissions class.
|
36
|
+
# +:parent+ is also aliased to +:for+.
|
37
|
+
#
|
38
|
+
# * +:by+ - Spoecify an actor instead of the user currently logged in
|
39
|
+
#
|
30
40
|
# This method is called by the +can?+ method in Trust::Controller, and is normally
|
31
41
|
# not necessary to call directly.
|
32
|
-
def authorized?(action, object_or_class,
|
42
|
+
def authorized?(action, object_or_class, *args)
|
43
|
+
options = args.extract_options!
|
44
|
+
parent = options[:parent] || options[:for] || args.first
|
45
|
+
actor = options[:by] || user
|
33
46
|
if object_or_class.is_a? Class
|
34
47
|
klass = object_or_class
|
35
48
|
object = nil
|
@@ -40,35 +53,47 @@ module Trust
|
|
40
53
|
# Identify which class to instanciate and then check authorization
|
41
54
|
auth = authorizing_class(klass)
|
42
55
|
# Rails.logger.debug "Trust: Authorizing class for #{klass.name} is #{auth.name}"
|
43
|
-
auth.new(
|
56
|
+
auth.new(actor, action.to_sym, klass, object, parent).authorized?
|
44
57
|
end
|
45
58
|
|
46
59
|
# Tests if user is authorized to perform +action+ on +object+ or +class+, with the
|
47
60
|
# optional parent and raises Trust::AccessDenied exception if not permitted.
|
48
|
-
#
|
49
|
-
#
|
61
|
+
#
|
62
|
+
# Options:
|
63
|
+
#
|
64
|
+
# * +:parent+ - the parent class to associate the subject with, can also be specified after the object
|
65
|
+
# or class. If +parent+ is given, +parent+ may be tested in the implemented Permissions class.
|
66
|
+
# +:parent+ is also aliased to +:for+.
|
67
|
+
#
|
68
|
+
# * +:by+ - Spoecify an actor instead of the user currently logged in
|
69
|
+
#
|
70
|
+
# * +:message+ - The message to be passed onto the AccessDenied exception class
|
71
|
+
#
|
50
72
|
# This method is used by the +access_control+ method in Trust::Controller
|
51
|
-
def authorize!(action, object_or_class,
|
52
|
-
|
73
|
+
def authorize!(action, object_or_class, *args)
|
74
|
+
options = args.extract_options!
|
75
|
+
parent = options[:parent] || options[:for] || args.first
|
76
|
+
message = options[:message]
|
77
|
+
access_denied!(message, action, object_or_class, parent) unless authorized?(action, object_or_class, parent, options)
|
53
78
|
end
|
54
79
|
|
55
|
-
def access_denied!(message = nil, action = nil, subject = nil, parent = nil)
|
80
|
+
def access_denied!(message = nil, action = nil, subject = nil, parent = nil) #:nodoc:
|
56
81
|
raise AccessDenied.new(message, action, subject)
|
57
82
|
end
|
58
83
|
|
59
|
-
#
|
84
|
+
# Returns the current +user+ being used in the authorization process
|
60
85
|
def user
|
61
86
|
Thread.current["current_user"]
|
62
87
|
end
|
63
88
|
|
64
|
-
#
|
65
|
-
#
|
89
|
+
# Sets the current +user+ to be used in the authorization process.
|
90
|
+
# The +user+ is thread safe.
|
66
91
|
def user=(user)
|
67
92
|
Thread.current["current_user"] = user
|
68
93
|
end
|
69
94
|
|
70
95
|
private
|
71
|
-
def authorizing_class(klass)
|
96
|
+
def authorizing_class(klass) #:nodoc:
|
72
97
|
auth = nil
|
73
98
|
klass.ancestors.each do |k|
|
74
99
|
break if k == ::ActiveRecord::Base
|
@@ -24,6 +24,7 @@
|
|
24
24
|
|
25
25
|
module Trust
|
26
26
|
module Controller
|
27
|
+
# = Trust Coontroller Properties
|
27
28
|
class Properties
|
28
29
|
delegate :logger, :to => Rails
|
29
30
|
attr_reader :controller
|
@@ -33,7 +34,7 @@ module Trust
|
|
33
34
|
attr_accessor :member_actions
|
34
35
|
attr_accessor :collection_actions
|
35
36
|
|
36
|
-
def initialize(controller, properties)
|
37
|
+
def initialize(controller, properties) #:nodoc:
|
37
38
|
@controller = controller
|
38
39
|
@model = controller.controller_path
|
39
40
|
if properties
|
@@ -50,16 +51,18 @@ module Trust
|
|
50
51
|
end
|
51
52
|
|
52
53
|
class << self
|
53
|
-
#
|
54
|
-
#
|
54
|
+
# Returns a controller properties object.
|
55
|
+
#
|
56
|
+
# Ensures controller properties are instantiated in a correct manner and that inheritance is supported
|
55
57
|
def instantiate(controller)
|
56
58
|
new(controller, controller.superclass.instance_variable_get(:@properties))
|
57
59
|
end
|
58
60
|
end
|
59
61
|
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
62
|
+
# Returns or sets the model to be used in a controller
|
63
|
+
#
|
64
|
+
# If not set, the controller_path is used.
|
65
|
+
# You can override the model to be accessed in a controller by setting the model.
|
63
66
|
# Note that you should specify the model in plural form.
|
64
67
|
#
|
65
68
|
# ==== Example
|
@@ -81,10 +84,12 @@ module Trust
|
|
81
84
|
end
|
82
85
|
|
83
86
|
# Specify associated resources (nested resources)
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
# belongs_to :
|
87
|
+
#
|
88
|
+
# === Example
|
89
|
+
#
|
90
|
+
# +belongs_to+ :lottery
|
91
|
+
# +belongs_to+ :table, :card_game
|
92
|
+
# +belongs_to+ :card_game, :as => :bridge
|
88
93
|
#
|
89
94
|
def belongs_to(*resources)
|
90
95
|
raise ArgumentError, "You must specify at least one resource after belongs_to" unless resources
|
@@ -99,8 +104,10 @@ module Trust
|
|
99
104
|
@associations.size > 0
|
100
105
|
end
|
101
106
|
|
102
|
-
# actions
|
103
|
-
#
|
107
|
+
# Specify actions to handle
|
108
|
+
#
|
109
|
+
# === Options
|
110
|
+
#
|
104
111
|
# :new => actions # specify new actions - default id :new, :create
|
105
112
|
# :member => actions # specify member actions - default is :show, :edit, :update, :destroy
|
106
113
|
# :collection => actions # specify collection actions - default is :index
|
@@ -61,7 +61,8 @@ module Trust
|
|
61
61
|
end
|
62
62
|
|
63
63
|
# Sets the instance variable
|
64
|
-
#
|
64
|
+
#
|
65
|
+
# Normally set by +load+.
|
65
66
|
# You can access this method from the resource object.
|
66
67
|
#
|
67
68
|
# ==== Example
|
@@ -97,12 +98,14 @@ module Trust
|
|
97
98
|
end
|
98
99
|
|
99
100
|
# Sets the instance variable for collection
|
101
|
+
#
|
100
102
|
# You may want to set this variable in your index action, we do not yet support loading of collections
|
101
103
|
def instances=(instances)
|
102
104
|
@controller.instance_variable_set(:"@#{plural_instance_name}", instances)
|
103
105
|
end
|
104
106
|
|
105
107
|
# Returns either the instances or the instance.
|
108
|
+
#
|
106
109
|
# We have found that this can be useful in some implementation patterns
|
107
110
|
def instantiated
|
108
111
|
instances || instance
|
@@ -113,8 +116,10 @@ module Trust
|
|
113
116
|
info.klass
|
114
117
|
end
|
115
118
|
|
116
|
-
# Loads the resource
|
119
|
+
# Loads the resource
|
120
|
+
#
|
117
121
|
# See Trust::Controller::Properties which controls the behavior of this method.
|
122
|
+
#
|
118
123
|
# It will normally find the instance variable for existing object or initialize them as new.
|
119
124
|
# If using nested resources and +belongs_to+ has been declared in the controller it will use the
|
120
125
|
# parent relation if found.
|
@@ -134,6 +139,7 @@ module Trust
|
|
134
139
|
end
|
135
140
|
|
136
141
|
# Returns the name of the instance for the resource
|
142
|
+
#
|
137
143
|
# ==== Example
|
138
144
|
#
|
139
145
|
# # in AccountsController
|
@@ -143,6 +149,7 @@ module Trust
|
|
143
149
|
end
|
144
150
|
|
145
151
|
# Returns the plural name of the instance for the resource
|
152
|
+
#
|
146
153
|
# ==== Example
|
147
154
|
#
|
148
155
|
# # in AccountsController
|
@@ -152,6 +159,7 @@ module Trust
|
|
152
159
|
end
|
153
160
|
|
154
161
|
# Returns the name of the parent resource
|
162
|
+
#
|
155
163
|
# ==== Example
|
156
164
|
#
|
157
165
|
# # in AccountsController where belongs_to :customer has been declared
|
@@ -171,31 +179,35 @@ module Trust
|
|
171
179
|
end
|
172
180
|
end
|
173
181
|
|
174
|
-
# ResorceInfo
|
182
|
+
# = ResorceInfo
|
183
|
+
#
|
184
|
+
# resolves information about the resource accessed in action controller
|
175
185
|
#
|
176
|
-
# Examples in PeopleController (simple case)
|
177
|
-
#
|
186
|
+
# === Examples in PeopleController (simple case)
|
187
|
+
#
|
178
188
|
# resource.info.klass => Person
|
179
189
|
# resource.info.params => {:person => {...}} # fetches the parameters for the resource
|
180
190
|
# resource.info.name => :person
|
181
191
|
# resource.info.plural_name => :people
|
182
192
|
# resource.info.path => 'people' # this is the controller_path
|
183
193
|
#
|
184
|
-
# Examples in Lottery::AssignmentsController (with name space)
|
185
|
-
#
|
194
|
+
# === Examples in Lottery::AssignmentsController (with name space)
|
195
|
+
#
|
186
196
|
# resource.info.klass => Lottery::Assignment
|
187
197
|
# resource.info.params => {:lottery_assignment => {...}}
|
188
198
|
# resource.info.name => :lottery_assignment
|
189
199
|
# resource.info.plural_name => :lottery_assignments
|
190
200
|
# resource.info.path => 'lottery/assignments' # this is the controller_path
|
191
201
|
#
|
192
|
-
# Examples in ArchiveController (with inheritance)
|
202
|
+
# === Examples in ArchiveController (with inheritance)
|
193
203
|
# Assumptions on routes:
|
204
|
+
#
|
194
205
|
# resources :archives
|
195
206
|
# resources :secret_acrvives, :controller => :archives
|
196
207
|
# resources :public_acrvives, :controller => :archives
|
197
|
-
#
|
198
|
-
# ===
|
208
|
+
#
|
209
|
+
# === Examples below assumes that the route secret_arcives is being accessed at the moment
|
210
|
+
#
|
199
211
|
# resource.info.klass => Archive
|
200
212
|
# resource.info.params => {:secret_archive => {...}}
|
201
213
|
# resource.info.name => :archive
|
@@ -203,27 +215,29 @@ module Trust
|
|
203
215
|
# resource.info.path => 'archive' # this is the controller_path
|
204
216
|
# resource.info.real_class => SecretArchive # Returns the real class which is accessed at the moment
|
205
217
|
#
|
206
|
-
|
207
218
|
class Resource::Info
|
208
219
|
attr_reader :klass, :params, :name, :path, :real_class
|
209
220
|
|
210
|
-
def params
|
221
|
+
def params #:nodoc:
|
211
222
|
@data
|
212
223
|
end
|
213
224
|
|
214
225
|
protected
|
215
|
-
def self.var_name(klass)
|
226
|
+
def self.var_name(klass) #:nodoc:
|
216
227
|
klass.to_s.underscore.tr('/','_').to_sym
|
217
228
|
end
|
218
|
-
def var_name(klass)
|
229
|
+
def var_name(klass) #:nodoc:
|
219
230
|
self.class.var_name(klass)
|
220
231
|
end
|
221
232
|
end
|
222
233
|
|
223
|
-
|
234
|
+
# = Resource::ResorceInfo
|
235
|
+
#
|
236
|
+
# Resolves the resource in subject
|
237
|
+
# (see #ResourceInfo)
|
224
238
|
class Resource::ResourceInfo < Resource::Info
|
225
239
|
|
226
|
-
def initialize(model, params)
|
240
|
+
def initialize(model, params) #:nodoc:
|
227
241
|
@path, params = model, params
|
228
242
|
@klass = model.to_s.classify.constantize
|
229
243
|
@name = model.to_s.singularize.underscore.gsub('/','_').to_sym
|
@@ -234,13 +248,15 @@ module Trust
|
|
234
248
|
@data = params[var_name(ptr)]
|
235
249
|
end
|
236
250
|
|
251
|
+
# Returns the plural name of the resource
|
237
252
|
def plural_name
|
238
253
|
@plural_name ||= path.underscore.tr('/','_').to_sym
|
239
254
|
end
|
240
255
|
|
241
|
-
#
|
256
|
+
# Returns an accessor for association. Tries with full name association first, and if that does not match, tries the demodularized association.
|
257
|
+
#
|
258
|
+
# === Explanation
|
242
259
|
#
|
243
|
-
# Explanation:
|
244
260
|
# Assuming
|
245
261
|
# resource is instance of Lottery::Package #1 (@lottery_package)
|
246
262
|
# association is Lottery::Prizes
|
@@ -258,6 +274,10 @@ module Trust
|
|
258
274
|
end
|
259
275
|
end
|
260
276
|
|
277
|
+
# = Resource::ParentInfo
|
278
|
+
#
|
279
|
+
# Resolves the parent resource in subject
|
280
|
+
# (see #ResourceInfo)
|
261
281
|
class Resource::ParentInfo < Resource::Info
|
262
282
|
attr_reader :object,:as
|
263
283
|
def initialize(resources, params, request)
|
data/lib/trust/controller.rb
CHANGED
@@ -23,6 +23,7 @@
|
|
23
23
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
24
|
|
25
25
|
module Trust
|
26
|
+
# = Trust Controller
|
26
27
|
module Controller
|
27
28
|
autoload :Resource, 'trust/controller/resource'
|
28
29
|
autoload :Properties, 'trust/controller/properties'
|
@@ -49,6 +50,7 @@ module Trust
|
|
49
50
|
delegate :belongs_to, :actions, :model, :to => :properties
|
50
51
|
|
51
52
|
# Enables authorization in controller
|
53
|
+
#
|
52
54
|
# +trustee+ accepts +:off+ or a hash of +callback+ options such as +:except+ and +:only+
|
53
55
|
#
|
54
56
|
# +trustee+ automatically calls the class methods: +set_user+, +load_resource+ and +access_control+
|
@@ -82,8 +84,6 @@ module Trust
|
|
82
84
|
# redirect_to root_url, :alert => exception.message
|
83
85
|
# end
|
84
86
|
# end
|
85
|
-
|
86
|
-
|
87
87
|
def trustee(*args)
|
88
88
|
module_eval do
|
89
89
|
include TrustInstanceMethods
|
@@ -95,15 +95,20 @@ module Trust
|
|
95
95
|
end
|
96
96
|
|
97
97
|
# Enable or disable +before_filter+ callback for setting the current user
|
98
|
-
#
|
98
|
+
#
|
99
|
+
# === Arguments:
|
100
|
+
#
|
99
101
|
# :off - switch callback off
|
100
102
|
# :only - only include these actions
|
101
103
|
# :except - except these actions
|
102
104
|
def set_user(*args)
|
103
105
|
_filter_setting(:set_user, *args)
|
104
106
|
end
|
107
|
+
|
105
108
|
# Enable or disable +before_filter+ callback for setting the loading resource
|
106
|
-
#
|
109
|
+
#
|
110
|
+
# === Arguments:
|
111
|
+
#
|
107
112
|
# :off - switch callback off
|
108
113
|
# :only - only include these actions
|
109
114
|
# :except - except these actions
|
@@ -112,7 +117,9 @@ module Trust
|
|
112
117
|
end
|
113
118
|
# Enable or disable +before_filter+ callback for setting the access control, i.e. verifying permissions
|
114
119
|
# for the logged in user
|
115
|
-
#
|
120
|
+
#
|
121
|
+
# === Arguments:
|
122
|
+
#
|
116
123
|
# :off - switch callback off
|
117
124
|
# :only - only include these actions
|
118
125
|
# :except - except these actions
|
@@ -132,7 +139,7 @@ module Trust
|
|
132
139
|
|
133
140
|
module TrustInstanceMethods
|
134
141
|
# Returns the controller Trust::Controller::Properties.
|
135
|
-
# If no properties are instantiated, it will be instantiated
|
142
|
+
# If no properties are instantiated, it will be instantiated.
|
136
143
|
#
|
137
144
|
# == Delegated methods
|
138
145
|
#
|
@@ -146,8 +153,9 @@ module Trust
|
|
146
153
|
self.class.properties
|
147
154
|
end
|
148
155
|
|
149
|
-
# Sets the current user. It assumes +current_user+ is defined
|
150
|
-
#
|
156
|
+
# Sets the current user. It assumes +current_user+ is defined.
|
157
|
+
#
|
158
|
+
# This method is triggered as a callback on +before_filter+.
|
151
159
|
# You may override this method.
|
152
160
|
#
|
153
161
|
# ==== Example
|
@@ -160,28 +168,32 @@ module Trust
|
|
160
168
|
end
|
161
169
|
|
162
170
|
# Returns the Trust::Controller::Resource resource for the controller.
|
163
|
-
#
|
164
|
-
#
|
171
|
+
#
|
172
|
+
# Available as a helper in views.
|
173
|
+
# See {Trust::Controller::Resource} for relevant methods.
|
165
174
|
def resource
|
166
175
|
@resource ||= Trust::Controller::Resource.new(self, self.class.properties, action_name, params, request)
|
167
176
|
end
|
168
177
|
|
169
178
|
# Loads the resource which basically means loading the instance and eventual parent defined through +belongs_to+
|
179
|
+
#
|
170
180
|
# This method is triggered as a callback on +before_filter+
|
171
|
-
# See Trust::Controller::Resource for more information
|
181
|
+
# See {Trust::Controller::Resource} for more information
|
172
182
|
def load_resource
|
173
183
|
resource.load
|
174
184
|
end
|
175
185
|
|
176
|
-
# Performs the actual access_control
|
186
|
+
# Performs the actual access_control.
|
187
|
+
#
|
177
188
|
# This method is triggered as a callback on +before_filter+
|
178
189
|
def access_control
|
179
190
|
Trust::Authorization.authorize!(action_name, resource.instance || resource.klass, resource.parent)
|
180
191
|
end
|
181
192
|
|
182
|
-
# Tests for current users permissions
|
193
|
+
# Tests for current users permissions.
|
194
|
+
#
|
183
195
|
# If access control is not sufficient in controller, you may use this method.
|
184
|
-
# Also available as a helper in views
|
196
|
+
# Also available as a helper in views.
|
185
197
|
#
|
186
198
|
# ==== Examples
|
187
199
|
# can? :edit # does the current user have permission to edit the current resource?
|
@@ -23,9 +23,10 @@
|
|
23
23
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
24
|
|
25
25
|
module Trust
|
26
|
+
# = Trust InheritableAttribute
|
26
27
|
module InheritableAttribute
|
27
28
|
|
28
|
-
def self.deep_copy value
|
29
|
+
def self.deep_copy( value) #:nodoc:
|
29
30
|
if value.is_a? Hash
|
30
31
|
Hash[*value.map{ |k,v| [self.deep_copy(k),self.deep_copy(v)] }.flatten(1)]
|
31
32
|
elsif value.is_a? Array
|
@@ -40,11 +41,12 @@ module Trust
|
|
40
41
|
extend ActiveSupport::Concern
|
41
42
|
|
42
43
|
module ClassMethods
|
43
|
-
# Creates an inheritable attribute with accessors in the singleton class.
|
44
|
-
#
|
45
|
-
#
|
44
|
+
# Creates an inheritable attribute with accessors in the singleton class.
|
45
|
+
#
|
46
|
+
# Derived classes inherit the attributes. This is especially helpful with arrays or hashes that
|
47
|
+
# are extended in the inheritance chain. Note that you have to initialize the inheritable attribute.
|
46
48
|
#
|
47
|
-
# Example
|
49
|
+
# === Example
|
48
50
|
#
|
49
51
|
# class Cat
|
50
52
|
# inheritable_attr :drinks
|