trust 0.6.3 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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/lib/trust/permissions.rb
CHANGED
@@ -23,90 +23,91 @@
|
|
23
23
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
24
|
|
25
25
|
module Trust
|
26
|
+
# = Trust Permissions
|
27
|
+
#
|
28
|
+
# Permissions should be specified in a separate file in you app/model directory. The file could look like this:
|
29
|
+
#
|
30
|
+
# module Permissions
|
31
|
+
# class Default < Trust::Permissions
|
32
|
+
# ...
|
33
|
+
# end
|
34
|
+
# ...
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# The above is the minimum required definitions that must exist in you file. <tt>Default</tt> will be used if no classes
|
38
|
+
# match the permissions requested, so the <tt>Default</tt> class definition is mandatory.
|
39
|
+
#
|
40
|
+
# If you want to separate the permissions into separate files that is ok. Then you shoud place these files in the
|
41
|
+
# /app/model/permissions directory.
|
42
|
+
#
|
43
|
+
# == Defining permisions
|
44
|
+
#
|
45
|
+
# The basic rules is to define classes in the Permissions module that matches your models.
|
46
|
+
# Here are some examples:
|
47
|
+
# * <tt>Project</tt> should have a matching class <tt>Permissions::Project</tt>
|
48
|
+
# * <tt>Account</tt> should have a matching class <tt>Permissions::Account</tt>
|
49
|
+
# * <tt>Account:Credit</tt> may have a matching class <tt>Permissions::Account::Credit</tt>, but if its inheriting from
|
50
|
+
# <tt>Account</tt> and no special handling is necessary, it is not necessary to create the permissions class.
|
51
|
+
#
|
52
|
+
# == Using inheritance
|
53
|
+
#
|
54
|
+
# Inheritance is also fully supported, but should generally follow your own inheritance model
|
55
|
+
#
|
56
|
+
# module Permissions
|
57
|
+
# class Account < Default
|
58
|
+
# role :admin, :accountant do
|
59
|
+
# ...
|
60
|
+
# end
|
61
|
+
# end
|
62
|
+
# class Account::Credit < Account
|
63
|
+
# ...
|
64
|
+
# end
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# == Action aliases
|
68
|
+
#
|
69
|
+
# You can define aliases for actions. You do this by setting the <tt>action_aliases</tt> attribute on Trust::Permissions class
|
70
|
+
# Example:
|
71
|
+
# Trust::Permissions.action_aliases = {
|
72
|
+
# read: [:index, :show],
|
73
|
+
# create: [:create, :new]
|
74
|
+
# }
|
75
|
+
#
|
76
|
+
# Keep in mind that all permissions are expanded upon declaration, so when using the <tt>can?</tt> method you must refer to
|
77
|
+
# the actual action and not the alias. The alias will never give a positive permission.
|
78
|
+
#
|
79
|
+
# == Accessors
|
80
|
+
#
|
81
|
+
# Accessors that can be used when testing permissions:
|
82
|
+
# * <tt>user</tt> - the user currently logged in
|
83
|
+
# * <tt>action</tt> - the action request from the controller such as :edit, or the action tested from helper or
|
84
|
+
# from the object itself when using <tt>ActiveRecord::can?</tt> is being used.
|
85
|
+
# * <tt>subject</tt> - the object that is being tested for permissions. This may be a an existing object, a new object
|
86
|
+
# (such as for +:create+ and +:new+ action), or nil if no object has been instantiated.
|
87
|
+
# * <tt>parent</tt> - the parent object if in a nested route, specified by +belongs_to+ in the controller.
|
88
|
+
# * <tt>klass</tt> - the class of involed in the request. It can be a base class or the real class, depending on
|
89
|
+
# your controller design.
|
90
|
+
#
|
91
|
+
# == Defining your own accessors or instance methods
|
92
|
+
#
|
93
|
+
# You can easily define your own accessors in the classes. These can be helpful when declaring permissions.
|
94
|
+
#
|
95
|
+
# === Example:
|
96
|
+
#
|
97
|
+
# class Account < Trust::Permissions
|
98
|
+
# role :admin, :accountant do
|
99
|
+
# can :update, :unless => :closed?
|
100
|
+
# end
|
101
|
+
# def closed?
|
102
|
+
# subject.closed?
|
103
|
+
# end
|
104
|
+
# end
|
105
|
+
#
|
106
|
+
# In the above example closed is testing on the subject to see if it is closed. The permission is referring to
|
107
|
+
# this method when evaluated.
|
108
|
+
# Keep in mind that you must refer to the +subject+, as you do not access the inctance of the object directly.
|
109
|
+
#
|
26
110
|
class Permissions
|
27
|
-
# = Trust::Permissions
|
28
|
-
# Permissions should be specified in a separate file in you app/model directory. The file could look like this:
|
29
|
-
#
|
30
|
-
# module Permissions
|
31
|
-
# class Default < Trust::Permissions
|
32
|
-
# ...
|
33
|
-
# end
|
34
|
-
# ...
|
35
|
-
# end
|
36
|
-
#
|
37
|
-
# The above is the minimum required definitions that must exist in you file. <tt>Default</tt> will be used if no classes
|
38
|
-
# match the permissions requested, so the <tt>Default</tt> class definition is mandatory.
|
39
|
-
#
|
40
|
-
# If you want to separate the permissions into separate files that is ok. Then you shoud place these files in the
|
41
|
-
# /app/model/permissions directory.
|
42
|
-
#
|
43
|
-
# === Defining permisions
|
44
|
-
#
|
45
|
-
# The basic rules is to define classes in the Permissions module that matches your models.
|
46
|
-
# Here are some examples:
|
47
|
-
# * <tt>Project</tt> should have a matching class <tt>Permissions::Project</tt>
|
48
|
-
# * <tt>Account</tt> should have a matching class <tt>Permissions::Account</tt>
|
49
|
-
# * <tt>Account:Credit</tt> may have a matching class <tt>Permissions::Account::Credit</tt>, but if its inheriting from
|
50
|
-
# <tt>Account</tt> and no special handling is necessary, it is not necessary to create the permissions class.
|
51
|
-
#
|
52
|
-
# === Using inheritance
|
53
|
-
#
|
54
|
-
# Inheritance is also fully supported, but should generally follow your own inheritance model
|
55
|
-
#
|
56
|
-
# module Permissions
|
57
|
-
# class Account < Default
|
58
|
-
# role :admin, :accountant do
|
59
|
-
# ...
|
60
|
-
# end
|
61
|
-
# end
|
62
|
-
# class Account::Credit < Account
|
63
|
-
# ...
|
64
|
-
# end
|
65
|
-
# end
|
66
|
-
#
|
67
|
-
# === Action aliases
|
68
|
-
#
|
69
|
-
# You can define aliases for actions. You do this by setting the <tt>action_aliases</tt> attribute on Trust::Permissions class
|
70
|
-
# Example:
|
71
|
-
# Trust::Permissions.action_aliases = {
|
72
|
-
# read: [:index, :show],
|
73
|
-
# create: [:create, :new]
|
74
|
-
# }
|
75
|
-
#
|
76
|
-
# Keep in mind that all permissions are expanded upon declaration, so when using the <tt>can?</tt> method you must refer to
|
77
|
-
# the actual action and not the alias. The alias will never give a positive permission.
|
78
|
-
#
|
79
|
-
# === Accessors
|
80
|
-
#
|
81
|
-
# Accessors that can be used when testing permissions:
|
82
|
-
# * <tt>user</tt> - the user currently logged in
|
83
|
-
# * <tt>action</tt> - the action request from the controller such as :edit, or the action tested from helper or
|
84
|
-
# from the object itself when using <tt>ActiveRecord::can?</tt> is being used.
|
85
|
-
# * <tt>subject</tt> - the object that is being tested for permissions. This may be a an existing object, a new object
|
86
|
-
# (such as for +:create+ and +:new+ action), or nil if no object has been instantiated.
|
87
|
-
# * <tt>parent</tt> - the parent object if in a nested route, specified by +belongs_to+ in the controller.
|
88
|
-
# * <tt>klass</tt> - the class of involed in the request. It can be a base class or the real class, depending on
|
89
|
-
# your controller design.
|
90
|
-
#
|
91
|
-
# === Defining your own accessors or instance methods
|
92
|
-
#
|
93
|
-
# You can easily define your own accessors in the classes. These can be helpful when declaring permissions.
|
94
|
-
# Example:
|
95
|
-
#
|
96
|
-
# class Account < Trust::Permissions
|
97
|
-
# role :admin, :accountant do
|
98
|
-
# can :update, :unless => :closed?
|
99
|
-
# end
|
100
|
-
# def closed?
|
101
|
-
# subject.closed?
|
102
|
-
# end
|
103
|
-
# end
|
104
|
-
#
|
105
|
-
# In the above example closed is testing on the subject to see if it is closed. The permission is referring to
|
106
|
-
# this method when evaluated.
|
107
|
-
# Keep in mind that you must refer to the +subject+, as you do not access the inctance of the object directly.
|
108
|
-
#
|
109
|
-
|
110
111
|
|
111
112
|
include InheritableAttribute
|
112
113
|
attr_reader :user, :action, :klass, :subject, :parent
|
@@ -121,21 +122,25 @@ module Trust
|
|
121
122
|
}
|
122
123
|
@@can_expressions = 0
|
123
124
|
|
124
|
-
#
|
125
|
+
# Initializes the permission object
|
126
|
+
#
|
125
127
|
# calling the +authorized?+ method on the instance later will test for the authorization.
|
126
|
-
# Parameters:
|
127
|
-
# <tt>user</tt> - user object, must respond to role_symbols
|
128
|
-
# <tt>action</tt> - action, such as :create, :show, etc. Should not be an alias
|
129
|
-
# <tt>klass</tt> - the class of the subject.
|
130
|
-
# <tt>subject</tt> - the subject tested for authorization
|
131
|
-
# <tt>parent</tt> - the parent object, normally declared through belongs_to
|
132
128
|
#
|
133
|
-
#
|
129
|
+
# == Parameters:
|
130
|
+
#
|
131
|
+
# <tt>user</tt> - user object, must respond to role_symbols
|
132
|
+
# <tt>action</tt> - action, such as :create, :show, etc. Should not be an alias
|
133
|
+
# <tt>klass</tt> - the class of the subject.
|
134
|
+
# <tt>subject</tt> - the subject tested for authorization
|
135
|
+
# <tt>parent</tt> - the parent object, normally declared through belongs_to
|
136
|
+
#
|
137
|
+
# See {Trust::Authorization} for more details
|
138
|
+
#
|
134
139
|
def initialize(user, action, klass, subject, parent)
|
135
140
|
@user, @action, @klass, @subject, @parent = user, action, klass, subject, parent
|
136
141
|
end
|
137
142
|
|
138
|
-
#
|
143
|
+
# Returns true if the user is authorized to perform the action
|
139
144
|
def authorized?
|
140
145
|
authorized = nil
|
141
146
|
user && user.role_symbols.each do |role|
|
@@ -175,6 +180,7 @@ module Trust
|
|
175
180
|
|
176
181
|
class << self
|
177
182
|
# Assign permissions to one or more roles.
|
183
|
+
#
|
178
184
|
# You may call role or roles, they are the same function like <tt>role :admin</tt> or <tt>roles :admin, :accountant</tt>
|
179
185
|
#
|
180
186
|
# There are two ways to call role, with or without block. If you want to set multiple permissions with different conditons
|
@@ -198,6 +204,7 @@ module Trust
|
|
198
204
|
# end
|
199
205
|
#
|
200
206
|
# The above permits admin and accountant to read accounts.
|
207
|
+
#
|
201
208
|
def role(*roles, &block)
|
202
209
|
if block_given?
|
203
210
|
if @@can_expressions > 0
|
@@ -226,9 +233,14 @@ module Trust
|
|
226
233
|
alias :roles :role
|
227
234
|
|
228
235
|
# Defines permissions
|
236
|
+
#
|
237
|
+
# === Arguments
|
238
|
+
#
|
229
239
|
# action - can be an alias or an actions of some kind
|
230
240
|
# options - :if/:unless :symbol or proc that will be called to evaluate an expression
|
231
241
|
#
|
242
|
+
# === Example
|
243
|
+
#
|
232
244
|
# module Permissions
|
233
245
|
# class Account < Trust::Permissions
|
234
246
|
# role :admin, :accountant do
|
data/lib/trust/version.rb
CHANGED
data/lib/trust.rb
CHANGED
@@ -28,7 +28,8 @@ module Trust
|
|
28
28
|
autoload :Permissions, 'trust/permissions'
|
29
29
|
autoload :Controller, 'trust/controller'
|
30
30
|
autoload :Authorization, 'trust/authorization'
|
31
|
-
autoload :
|
31
|
+
autoload :ActiveModel, 'trust/active_model'
|
32
|
+
autoload :Actor, 'trust/actor'
|
32
33
|
end
|
33
34
|
require 'trust/controller'
|
34
35
|
class ActionController::Base
|
@@ -36,15 +37,15 @@ class ActionController::Base
|
|
36
37
|
end
|
37
38
|
if defined?(ActiveRecord)
|
38
39
|
class ActiveRecord::Base
|
39
|
-
include Trust::
|
40
|
+
include Trust::ActiveModel
|
40
41
|
end
|
41
42
|
end
|
42
43
|
# always, as it may not exists yet
|
43
44
|
module Mongoid
|
44
45
|
module Document
|
45
|
-
include Trust::
|
46
|
+
include Trust::ActiveModel
|
46
47
|
def Document.included(base)
|
47
|
-
base.send(:extend,Trust::
|
48
|
+
base.send(:extend,Trust::ActiveModel::ClassMethods)
|
48
49
|
end
|
49
50
|
end
|
50
51
|
end
|
@@ -0,0 +1,3 @@
|
|
1
|
+
Connecting to database specified by database.yml
|
2
|
+
MONGODB [DEBUG] Logging level is currently :debug which could negatively impact client-side performance. You should set your logging level no lower than :info in production.
|
3
|
+
MONGODB (23ms) admin['$cmd'].find({:ismaster=>1}).limit(-1)
|