lib/trust/permissions.rb in trust-0.6.3 vs lib/trust/permissions.rb in trust-0.7.0
- old
+ new
@@ -21,95 +21,96 @@
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
module Trust
+ # = Trust Permissions
+ #
+ # Permissions should be specified in a separate file in you app/model directory. The file could look like this:
+ #
+ # module Permissions
+ # class Default < Trust::Permissions
+ # ...
+ # end
+ # ...
+ # end
+ #
+ # The above is the minimum required definitions that must exist in you file. <tt>Default</tt> will be used if no classes
+ # match the permissions requested, so the <tt>Default</tt> class definition is mandatory.
+ #
+ # If you want to separate the permissions into separate files that is ok. Then you shoud place these files in the
+ # /app/model/permissions directory.
+ #
+ # == Defining permisions
+ #
+ # The basic rules is to define classes in the Permissions module that matches your models.
+ # Here are some examples:
+ # * <tt>Project</tt> should have a matching class <tt>Permissions::Project</tt>
+ # * <tt>Account</tt> should have a matching class <tt>Permissions::Account</tt>
+ # * <tt>Account:Credit</tt> may have a matching class <tt>Permissions::Account::Credit</tt>, but if its inheriting from
+ # <tt>Account</tt> and no special handling is necessary, it is not necessary to create the permissions class.
+ #
+ # == Using inheritance
+ #
+ # Inheritance is also fully supported, but should generally follow your own inheritance model
+ #
+ # module Permissions
+ # class Account < Default
+ # role :admin, :accountant do
+ # ...
+ # end
+ # end
+ # class Account::Credit < Account
+ # ...
+ # end
+ # end
+ #
+ # == Action aliases
+ #
+ # You can define aliases for actions. You do this by setting the <tt>action_aliases</tt> attribute on Trust::Permissions class
+ # Example:
+ # Trust::Permissions.action_aliases = {
+ # read: [:index, :show],
+ # create: [:create, :new]
+ # }
+ #
+ # Keep in mind that all permissions are expanded upon declaration, so when using the <tt>can?</tt> method you must refer to
+ # the actual action and not the alias. The alias will never give a positive permission.
+ #
+ # == Accessors
+ #
+ # Accessors that can be used when testing permissions:
+ # * <tt>user</tt> - the user currently logged in
+ # * <tt>action</tt> - the action request from the controller such as :edit, or the action tested from helper or
+ # from the object itself when using <tt>ActiveRecord::can?</tt> is being used.
+ # * <tt>subject</tt> - the object that is being tested for permissions. This may be a an existing object, a new object
+ # (such as for +:create+ and +:new+ action), or nil if no object has been instantiated.
+ # * <tt>parent</tt> - the parent object if in a nested route, specified by +belongs_to+ in the controller.
+ # * <tt>klass</tt> - the class of involed in the request. It can be a base class or the real class, depending on
+ # your controller design.
+ #
+ # == Defining your own accessors or instance methods
+ #
+ # You can easily define your own accessors in the classes. These can be helpful when declaring permissions.
+ #
+ # === Example:
+ #
+ # class Account < Trust::Permissions
+ # role :admin, :accountant do
+ # can :update, :unless => :closed?
+ # end
+ # def closed?
+ # subject.closed?
+ # end
+ # end
+ #
+ # In the above example closed is testing on the subject to see if it is closed. The permission is referring to
+ # this method when evaluated.
+ # Keep in mind that you must refer to the +subject+, as you do not access the inctance of the object directly.
+ #
class Permissions
- # = Trust::Permissions
- # Permissions should be specified in a separate file in you app/model directory. The file could look like this:
- #
- # module Permissions
- # class Default < Trust::Permissions
- # ...
- # end
- # ...
- # end
- #
- # The above is the minimum required definitions that must exist in you file. <tt>Default</tt> will be used if no classes
- # match the permissions requested, so the <tt>Default</tt> class definition is mandatory.
- #
- # If you want to separate the permissions into separate files that is ok. Then you shoud place these files in the
- # /app/model/permissions directory.
- #
- # === Defining permisions
- #
- # The basic rules is to define classes in the Permissions module that matches your models.
- # Here are some examples:
- # * <tt>Project</tt> should have a matching class <tt>Permissions::Project</tt>
- # * <tt>Account</tt> should have a matching class <tt>Permissions::Account</tt>
- # * <tt>Account:Credit</tt> may have a matching class <tt>Permissions::Account::Credit</tt>, but if its inheriting from
- # <tt>Account</tt> and no special handling is necessary, it is not necessary to create the permissions class.
- #
- # === Using inheritance
- #
- # Inheritance is also fully supported, but should generally follow your own inheritance model
- #
- # module Permissions
- # class Account < Default
- # role :admin, :accountant do
- # ...
- # end
- # end
- # class Account::Credit < Account
- # ...
- # end
- # end
- #
- # === Action aliases
- #
- # You can define aliases for actions. You do this by setting the <tt>action_aliases</tt> attribute on Trust::Permissions class
- # Example:
- # Trust::Permissions.action_aliases = {
- # read: [:index, :show],
- # create: [:create, :new]
- # }
- #
- # Keep in mind that all permissions are expanded upon declaration, so when using the <tt>can?</tt> method you must refer to
- # the actual action and not the alias. The alias will never give a positive permission.
- #
- # === Accessors
- #
- # Accessors that can be used when testing permissions:
- # * <tt>user</tt> - the user currently logged in
- # * <tt>action</tt> - the action request from the controller such as :edit, or the action tested from helper or
- # from the object itself when using <tt>ActiveRecord::can?</tt> is being used.
- # * <tt>subject</tt> - the object that is being tested for permissions. This may be a an existing object, a new object
- # (such as for +:create+ and +:new+ action), or nil if no object has been instantiated.
- # * <tt>parent</tt> - the parent object if in a nested route, specified by +belongs_to+ in the controller.
- # * <tt>klass</tt> - the class of involed in the request. It can be a base class or the real class, depending on
- # your controller design.
- #
- # === Defining your own accessors or instance methods
- #
- # You can easily define your own accessors in the classes. These can be helpful when declaring permissions.
- # Example:
- #
- # class Account < Trust::Permissions
- # role :admin, :accountant do
- # can :update, :unless => :closed?
- # end
- # def closed?
- # subject.closed?
- # end
- # end
- #
- # In the above example closed is testing on the subject to see if it is closed. The permission is referring to
- # this method when evaluated.
- # Keep in mind that you must refer to the +subject+, as you do not access the inctance of the object directly.
- #
-
include InheritableAttribute
attr_reader :user, :action, :klass, :subject, :parent
inheritable_attr :permissions
class_attribute :action_aliases, :instance_writer => false, :instance_reader => false
self.permissions = {}
@@ -119,25 +120,29 @@
update: [:update, :edit],
manage: [:index, :show, :create, :new, :update, :edit, :destroy]
}
@@can_expressions = 0
- # initializes the permission object
+ # Initializes the permission object
+ #
# calling the +authorized?+ method on the instance later will test for the authorization.
- # Parameters:
- # <tt>user</tt> - user object, must respond to role_symbols
- # <tt>action</tt> - action, such as :create, :show, etc. Should not be an alias
- # <tt>klass</tt> - the class of the subject.
- # <tt>subject</tt> - the subject tested for authorization
- # <tt>parent</tt> - the parent object, normally declared through belongs_to
#
- # See Trust::Authorization for more details
+ # == Parameters:
+ #
+ # <tt>user</tt> - user object, must respond to role_symbols
+ # <tt>action</tt> - action, such as :create, :show, etc. Should not be an alias
+ # <tt>klass</tt> - the class of the subject.
+ # <tt>subject</tt> - the subject tested for authorization
+ # <tt>parent</tt> - the parent object, normally declared through belongs_to
+ #
+ # See {Trust::Authorization} for more details
+ #
def initialize(user, action, klass, subject, parent)
@user, @action, @klass, @subject, @parent = user, action, klass, subject, parent
end
- # returns true if the user is authorized to perform the action
+ # Returns true if the user is authorized to perform the action
def authorized?
authorized = nil
user && user.role_symbols.each do |role|
(permissions[role] || {}).each do |act, opt|
if act == action
@@ -173,10 +178,11 @@
end.all?
end
class << self
# Assign permissions to one or more roles.
+ #
# You may call role or roles, they are the same function like <tt>role :admin</tt> or <tt>roles :admin, :accountant</tt>
#
# There are two ways to call role, with or without block. If you want to set multiple permissions with different conditons
# then you should use a block.
#
@@ -196,10 +202,11 @@
# end
# end
# end
#
# The above permits admin and accountant to read accounts.
+ #
def role(*roles, &block)
if block_given?
if @@can_expressions > 0
@@can_expressions = 0
raise RoleAssigmnentMissing
@@ -224,11 +231,16 @@
end
end
alias :roles :role
# Defines permissions
+ #
+ # === Arguments
+ #
# action - can be an alias or an actions of some kind
# options - :if/:unless :symbol or proc that will be called to evaluate an expression
+ #
+ # === Example
#
# module Permissions
# class Account < Trust::Permissions
# role :admin, :accountant do
# can :read