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/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)
|