declarative_authorization 0.5.2 → 0.5.3
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/CHANGELOG +10 -0
 - data/README.rdoc +12 -7
 - data/app/views/authorization_usages/index.html.erb +1 -1
 - data/lib/declarative_authorization/authorization.rb +18 -9
 - data/lib/declarative_authorization/development_support/analyzer.rb +1 -1
 - data/lib/declarative_authorization/development_support/change_analyzer.rb +1 -1
 - data/lib/declarative_authorization/helper.rb +8 -0
 - data/lib/declarative_authorization/in_controller.rb +44 -12
 - data/lib/declarative_authorization/in_model.rb +49 -22
 - data/lib/declarative_authorization/maintenance.rb +3 -6
 - data/lib/declarative_authorization/reader.rb +6 -6
 - data/test/authorization_test.rb +19 -0
 - data/test/controller_test.rb +1 -1
 - data/test/helper_test.rb +78 -3
 - data/test/model_test.rb +28 -0
 - data/test/schema.sql +2 -1
 - data/test/test_helper.rb +5 -3
 - metadata +3 -3
 
    
        data/CHANGELOG
    CHANGED
    
    | 
         @@ -1,3 +1,13 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ** RELEASE 0.5.3 (May 25, 2011)
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            * Bugfixes and documentation cleanup
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            * Rails 3.1.rc1 compatibility [sb]
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            * Added has_any_role?, has_any_role_with_hierarchy? [t.pickett66]
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            * Allow changing the default role [dbloete]
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
       1 
11 
     | 
    
         
             
            ** RELEASE 0.5.2 (Dec 31, 2010) **
         
     | 
| 
       2 
12 
     | 
    
         | 
| 
       3 
13 
     | 
    
         
             
            * Bugfixes and documentation updates
         
     | 
    
        data/README.rdoc
    CHANGED
    
    | 
         @@ -192,13 +192,13 @@ See also Authorization::AuthorizationHelper. 
     | 
|
| 
       192 
192 
     | 
    
         | 
| 
       193 
193 
     | 
    
         
             
            == Models
         
     | 
| 
       194 
194 
     | 
    
         | 
| 
       195 
     | 
    
         
            -
            There are two  
     | 
| 
      
 195 
     | 
    
         
            +
            There are two distinct features for model security built into this plugin:
         
     | 
| 
       196 
196 
     | 
    
         
             
            authorizing CRUD operations on objects as well as query rewriting to limit
         
     | 
| 
       197 
197 
     | 
    
         
             
            results according to certain privileges.
         
     | 
| 
       198 
198 
     | 
    
         | 
| 
       199 
199 
     | 
    
         
             
            See also Authorization::AuthorizationInModel.
         
     | 
| 
       200 
200 
     | 
    
         | 
| 
       201 
     | 
    
         
            -
            === Model security for CRUD  
     | 
| 
      
 201 
     | 
    
         
            +
            === Model security for CRUD operations
         
     | 
| 
       202 
202 
     | 
    
         
             
            To activate model security, all it takes is an explicit enabling for each
         
     | 
| 
       203 
203 
     | 
    
         
             
            model that model security should be enforced on, i.e.
         
     | 
| 
       204 
204 
     | 
    
         | 
| 
         @@ -215,7 +215,7 @@ happened if an operation is denied, the filters throw 
     | 
|
| 
       215 
215 
     | 
    
         
             
            Authorization::NotAuthorized exceptions.
         
     | 
| 
       216 
216 
     | 
    
         | 
| 
       217 
217 
     | 
    
         
             
            As access control on read are costly, with possibly lots of objects being
         
     | 
| 
       218 
     | 
    
         
            -
            loaded at a time in one query, checks on read need to be  
     | 
| 
      
 218 
     | 
    
         
            +
            loaded at a time in one query, checks on read need to be activated explicitly by
         
     | 
| 
       219 
219 
     | 
    
         
             
            adding the :include_read option.
         
     | 
| 
       220 
220 
     | 
    
         | 
| 
       221 
221 
     | 
    
         
             
            === Query rewriting through named scopes
         
     | 
| 
         @@ -256,6 +256,11 @@ public pages, :+guest+ can be used to allow access for users that are not 
     | 
|
| 
       256 
256 
     | 
    
         
             
            logged in.  All other roles are application defined and need to be associated
         
     | 
| 
       257 
257 
     | 
    
         
             
            with users by the application.
         
     | 
| 
       258 
258 
     | 
    
         | 
| 
      
 259 
     | 
    
         
            +
            If you need to change the default role, you can do so by adding an initializer
         
     | 
| 
      
 260 
     | 
    
         
            +
            that contains the following statement:
         
     | 
| 
      
 261 
     | 
    
         
            +
             
     | 
| 
      
 262 
     | 
    
         
            +
                Authorization.default_role = :anonymous
         
     | 
| 
      
 263 
     | 
    
         
            +
             
     | 
| 
       259 
264 
     | 
    
         
             
            Privileges, such as :create, may be put into hierarchies to simplify
         
     | 
| 
       260 
265 
     | 
    
         
             
            maintenance.  So the example above has the same meaning as
         
     | 
| 
       261 
266 
     | 
    
         | 
| 
         @@ -512,12 +517,12 @@ sbartsch at tzi.org 
     | 
|
| 
       512 
517 
     | 
    
         | 
| 
       513 
518 
     | 
    
         
             
            Thanks to John Joseph Bachir, Eike Carls, Dennis Blöte, Kai Chen, Erik Dahlstrand,
         
     | 
| 
       514 
519 
     | 
    
         
             
            Jeroen van Dijk, Alexander Dobriakov, Sebastian Dyck, Ari Epstein, Jeremy Friesen,
         
     | 
| 
       515 
     | 
    
         
            -
            Tim Harper, hollownest, Daniel Kristensen, Brad Langhorst, Brian Langenfeld,
         
     | 
| 
       516 
     | 
    
         
            -
            Georg Ledermann, Geoff Longman, Olly Lylo, Mark Mansour, Thomas Maurer, Sharagoz,
         
     | 
| 
       517 
     | 
    
         
            -
            TJ Singleton, Mike Vincent
         
     | 
| 
      
 520 
     | 
    
         
            +
            Tim Harper, hollownest, Daniel Kristensen, Jeremy Kleindl, Brad Langhorst, Brian Langenfeld,
         
     | 
| 
      
 521 
     | 
    
         
            +
            Georg Ledermann, Geoff Longman, Olly Lylo, Mark Mansour, Thomas Maurer, Tyler Pickett, Sharagoz,
         
     | 
| 
      
 522 
     | 
    
         
            +
            TJ Singleton, Mike Vincent, Joel Westerberg
         
     | 
| 
       518 
523 
     | 
    
         | 
| 
       519 
524 
     | 
    
         | 
| 
       520 
     | 
    
         
            -
            =  
     | 
| 
      
 525 
     | 
    
         
            +
            = License
         
     | 
| 
       521 
526 
     | 
    
         | 
| 
       522 
527 
     | 
    
         
             
            Copyright (c) 2008 Steffen Bartsch, TZI, Universität Bremen, Germany
         
     | 
| 
       523 
528 
     | 
    
         
             
            released under the MIT license
         
     | 
| 
         @@ -17,7 +17,7 @@ 
     | 
|
| 
       17 
17 
     | 
    
         
             
              <% @auth_usages_by_controller.keys.sort {|c1, c2| c1.name <=> c2.name}.each do |controller| %>
         
     | 
| 
       18 
18 
     | 
    
         
             
                <% default_context = controller.controller_name.to_sym rescue nil %>
         
     | 
| 
       19 
19 
     | 
    
         
             
                <tr>
         
     | 
| 
       20 
     | 
    
         
            -
                  <th colspan="3"><%= h controller. 
     | 
| 
      
 20 
     | 
    
         
            +
                  <th colspan="3"><%= h controller.name.underscore.sub(/_controller\Z/, '') %></th>
         
     | 
| 
       21 
21 
     | 
    
         
             
                </tr>
         
     | 
| 
       22 
22 
     | 
    
         
             
                <% @auth_usages_by_controller[controller].keys.sort {|c1, c2| c1.to_s <=> c2.to_s}.each do |action| %>
         
     | 
| 
       23 
23 
     | 
    
         
             
                  <% auth_info = @auth_usages_by_controller[controller][action] %>
         
     | 
| 
         @@ -9,7 +9,7 @@ module Authorization 
     | 
|
| 
       9 
9 
     | 
    
         
             
              # NotAuthorized is raised if the current user is not allowed to perform
         
     | 
| 
       10 
10 
     | 
    
         
             
              # the given operation possibly on a specific object.
         
     | 
| 
       11 
11 
     | 
    
         
             
              class NotAuthorized < AuthorizationError ; end
         
     | 
| 
       12 
     | 
    
         
            -
              # AttributeAuthorizationError is more specific than NotAuthorized,  
     | 
| 
      
 12 
     | 
    
         
            +
              # AttributeAuthorizationError is more specific than NotAuthorized, signaling
         
     | 
| 
       13 
13 
     | 
    
         
             
              # that the access was denied on the grounds of attribute conditions.
         
     | 
| 
       14 
14 
     | 
    
         
             
              class AttributeAuthorizationError < NotAuthorized ; end
         
     | 
| 
       15 
15 
     | 
    
         
             
              # AuthorizationUsageError is used whenever a situation is encountered
         
     | 
| 
         @@ -25,7 +25,7 @@ module Authorization 
     | 
|
| 
       25 
25 
     | 
    
         
             
              # Controller-independent method for retrieving the current user.
         
     | 
| 
       26 
26 
     | 
    
         
             
              # Needed for model security where the current controller is not available.
         
     | 
| 
       27 
27 
     | 
    
         
             
              def self.current_user
         
     | 
| 
       28 
     | 
    
         
            -
                Thread.current["current_user"] ||  
     | 
| 
      
 28 
     | 
    
         
            +
                Thread.current["current_user"] || AnonymousUser.new
         
     | 
| 
       29 
29 
     | 
    
         
             
              end
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
       31 
31 
     | 
    
         
             
              # Controller-independent method for setting the current user.
         
     | 
| 
         @@ -52,6 +52,15 @@ module Authorization 
     | 
|
| 
       52 
52 
     | 
    
         
             
                @@dot_path = path
         
     | 
| 
       53 
53 
     | 
    
         
             
              end
         
     | 
| 
       54 
54 
     | 
    
         | 
| 
      
 55 
     | 
    
         
            +
              @@default_role = :guest
         
     | 
| 
      
 56 
     | 
    
         
            +
              def self.default_role
         
     | 
| 
      
 57 
     | 
    
         
            +
                @@default_role
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              def self.default_role= (role)
         
     | 
| 
      
 61 
     | 
    
         
            +
                @@default_role = role.to_sym
         
     | 
| 
      
 62 
     | 
    
         
            +
              end
         
     | 
| 
      
 63 
     | 
    
         
            +
              
         
     | 
| 
       55 
64 
     | 
    
         
             
              # Authorization::Engine implements the reference monitor.  It may be used
         
     | 
| 
       56 
65 
     | 
    
         
             
              # for querying the permission and retrieving obligations under which
         
     | 
| 
       57 
66 
     | 
    
         
             
              # a certain privilege is granted for the current user.
         
     | 
| 
         @@ -113,7 +122,7 @@ module Authorization 
     | 
|
| 
       113 
122 
     | 
    
         
             
                #   The context part of the privilege.
         
     | 
| 
       114 
123 
     | 
    
         
             
                #   Defaults either to the tableized +class_name+ of the given :+object+, if given.
         
     | 
| 
       115 
124 
     | 
    
         
             
                #   That is, :+users+ for :+object+ of type User.  
         
     | 
| 
       116 
     | 
    
         
            -
                #   Raises AuthorizationUsageError if context is missing and not to be  
     | 
| 
      
 125 
     | 
    
         
            +
                #   Raises AuthorizationUsageError if context is missing and not to be inferred.
         
     | 
| 
       117 
126 
     | 
    
         
             
                # [:+object+] An context object to test attribute checks against.
         
     | 
| 
       118 
127 
     | 
    
         
             
                # [:+skip_attribute_test+]
         
     | 
| 
       119 
128 
     | 
    
         
             
                #   Skips those attribute checks in the 
         
     | 
| 
         @@ -232,8 +241,8 @@ module Authorization 
     | 
|
| 
       232 
241 
     | 
    
         
             
                  raise AuthorizationUsageError, "User object doesn't respond to roles (#{user.inspect})" \
         
     | 
| 
       233 
242 
     | 
    
         
             
                    if !user.respond_to?(:role_symbols) and !user.respond_to?(:roles)
         
     | 
| 
       234 
243 
     | 
    
         | 
| 
       235 
     | 
    
         
            -
                   
     | 
| 
       236 
     | 
    
         
            -
                      "role_symbols to your User model.") if defined?( 
     | 
| 
      
 244 
     | 
    
         
            +
                  Rails.logger.info("The use of user.roles is deprecated.  Please add a method " +
         
     | 
| 
      
 245 
     | 
    
         
            +
                      "role_symbols to your User model.") if defined?(Rails) and Rails.respond_to?(:logger) and !user.respond_to?(:role_symbols)
         
     | 
| 
       237 
246 
     | 
    
         | 
| 
       238 
247 
     | 
    
         
             
                  roles = user.respond_to?(:role_symbols) ? user.role_symbols : user.roles
         
     | 
| 
       239 
248 
     | 
    
         | 
| 
         @@ -241,7 +250,7 @@ module Authorization 
     | 
|
| 
       241 
250 
     | 
    
         
             
                    "doesn't return an Array of Symbols (#{roles.inspect})" \
         
     | 
| 
       242 
251 
     | 
    
         
             
                        if !roles.is_a?(Array) or (!roles.empty? and !roles[0].is_a?(Symbol))
         
     | 
| 
       243 
252 
     | 
    
         | 
| 
       244 
     | 
    
         
            -
                  (roles.empty? ? [ 
     | 
| 
      
 253 
     | 
    
         
            +
                  (roles.empty? ? [Authorization.default_role] : roles)
         
     | 
| 
       245 
254 
     | 
    
         
             
                end
         
     | 
| 
       246 
255 
     | 
    
         | 
| 
       247 
256 
     | 
    
         
             
                # Returns the role symbols and inherritted role symbols for the given user
         
     | 
| 
         @@ -685,10 +694,10 @@ module Authorization 
     | 
|
| 
       685 
694 
     | 
    
         
             
                end
         
     | 
| 
       686 
695 
     | 
    
         
             
              end
         
     | 
| 
       687 
696 
     | 
    
         | 
| 
       688 
     | 
    
         
            -
              # Represents a pseudo-user to facilitate  
     | 
| 
       689 
     | 
    
         
            -
              class  
     | 
| 
      
 697 
     | 
    
         
            +
              # Represents a pseudo-user to facilitate anonymous users in applications
         
     | 
| 
      
 698 
     | 
    
         
            +
              class AnonymousUser
         
     | 
| 
       690 
699 
     | 
    
         
             
                attr_reader :role_symbols
         
     | 
| 
       691 
     | 
    
         
            -
                def initialize (roles = [ 
     | 
| 
      
 700 
     | 
    
         
            +
                def initialize (roles = [Authorization.default_role])
         
     | 
| 
       692 
701 
     | 
    
         
             
                  @role_symbols = roles
         
     | 
| 
       693 
702 
     | 
    
         
             
                end
         
     | 
| 
       694 
703 
     | 
    
         
             
              end
         
     | 
| 
         @@ -32,7 +32,7 @@ module Authorization 
     | 
|
| 
       32 
32 
     | 
    
         | 
| 
       33 
33 
     | 
    
         
             
                    # * strategy for removing: [remove privilege, add privilege to different role]
         
     | 
| 
       34 
34 
     | 
    
         
             
                    @seen_states = Set.new
         
     | 
| 
       35 
     | 
    
         
            -
                    # *  
     | 
| 
      
 35 
     | 
    
         
            +
                    # * heuristic: change of failed tests;  small number of policy items
         
     | 
| 
       36 
36 
     | 
    
         
             
                    strategy = case [change_action, type]
         
     | 
| 
       37 
37 
     | 
    
         
             
                               when [:remove, :permission]
         
     | 
| 
       38 
38 
     | 
    
         
             
                                 [:remove_role_from_user, :remove_privilege, :add_privilege,
         
     | 
| 
         @@ -56,5 +56,13 @@ module Authorization 
     | 
|
| 
       56 
56 
     | 
    
         
             
                def has_role_with_hierarchy?(*roles, &block)
         
     | 
| 
       57 
57 
     | 
    
         
             
                  controller.has_role_with_hierarchy?(*roles, &block)
         
     | 
| 
       58 
58 
     | 
    
         
             
                end
         
     | 
| 
      
 59 
     | 
    
         
            +
                
         
     | 
| 
      
 60 
     | 
    
         
            +
                def has_any_role?(*roles,&block)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  controller.has_any_role?(*roles,&block)
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
                
         
     | 
| 
      
 64 
     | 
    
         
            +
                def has_any_role_with_hierarchy?(*roles, &block)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  controller.has_any_role_with_hierarchy?(*roles, &block)
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
       59 
67 
     | 
    
         
             
              end
         
     | 
| 
       60 
68 
     | 
    
         
             
            end
         
     | 
| 
         @@ -12,13 +12,13 @@ module Authorization 
     | 
|
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
                DEFAULT_DENY = false
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
                # If attribute_check is set for filter_access_to,  
     | 
| 
      
 15 
     | 
    
         
            +
                # If attribute_check is set for filter_access_to, decl_auth_context will try to
         
     | 
| 
       16 
16 
     | 
    
         
             
                # load the appropriate object from the current controller's model with
         
     | 
| 
       17 
17 
     | 
    
         
             
                # the id from params[:id].  If that fails, a 404 Not Found is often the
         
     | 
| 
       18 
18 
     | 
    
         
             
                # right way to handle the error.  If you have additional measures in place
         
     | 
| 
       19 
19 
     | 
    
         
             
                # that restricts the find scope, handling this error as a permission denied
         
     | 
| 
       20 
20 
     | 
    
         
             
                # might be a better way.  Set failed_auto_loading_is_not_found to false
         
     | 
| 
       21 
     | 
    
         
            -
                # for the latter  
     | 
| 
      
 21 
     | 
    
         
            +
                # for the latter behavior.
         
     | 
| 
       22 
22 
     | 
    
         
             
                @@failed_auto_loading_is_not_found = true
         
     | 
| 
       23 
23 
     | 
    
         
             
                def self.failed_auto_loading_is_not_found?
         
     | 
| 
       24 
24 
     | 
    
         
             
                  @@failed_auto_loading_is_not_found
         
     | 
| 
         @@ -52,7 +52,7 @@ module Authorization 
     | 
|
| 
       52 
52 
     | 
    
         
             
                  context = object = nil
         
     | 
| 
       53 
53 
     | 
    
         
             
                  if object_or_sym.nil?
         
     | 
| 
       54 
54 
     | 
    
         
             
                    context = self.class.decl_auth_context
         
     | 
| 
       55 
     | 
    
         
            -
                  elsif object_or_sym.is_a?(Symbol)
         
     | 
| 
      
 55 
     | 
    
         
            +
                  elsif !object_or_sym.respond_to?(:proxy_reflection) and object_or_sym.is_a?(Symbol)
         
     | 
| 
       56 
56 
     | 
    
         
             
                    context = object_or_sym
         
     | 
| 
       57 
57 
     | 
    
         
             
                  else
         
     | 
| 
       58 
58 
     | 
    
         
             
                    object = object_or_sym
         
     | 
| 
         @@ -86,6 +86,17 @@ module Authorization 
     | 
|
| 
       86 
86 
     | 
    
         
             
                  result
         
     | 
| 
       87 
87 
     | 
    
         
             
                end
         
     | 
| 
       88 
88 
     | 
    
         | 
| 
      
 89 
     | 
    
         
            +
                # Intended to be used where you want to allow users with any single listed role to view 
         
     | 
| 
      
 90 
     | 
    
         
            +
                # the content in question
         
     | 
| 
      
 91 
     | 
    
         
            +
                def has_any_role?(*roles,&block)
         
     | 
| 
      
 92 
     | 
    
         
            +
                  user_roles = authorization_engine.roles_for(current_user)
         
     | 
| 
      
 93 
     | 
    
         
            +
                  result = roles.any? do |role|
         
     | 
| 
      
 94 
     | 
    
         
            +
                    user_roles.include?(role)
         
     | 
| 
      
 95 
     | 
    
         
            +
                  end
         
     | 
| 
      
 96 
     | 
    
         
            +
                  yield if result and block_given?
         
     | 
| 
      
 97 
     | 
    
         
            +
                  result
         
     | 
| 
      
 98 
     | 
    
         
            +
                end
         
     | 
| 
      
 99 
     | 
    
         
            +
                
         
     | 
| 
       89 
100 
     | 
    
         
             
                # As has_role? except checks all roles included in the role hierarchy
         
     | 
| 
       90 
101 
     | 
    
         
             
                def has_role_with_hierarchy?(*roles, &block)
         
     | 
| 
       91 
102 
     | 
    
         
             
                  user_roles = authorization_engine.roles_with_hierarchy_for(current_user)
         
     | 
| 
         @@ -96,6 +107,15 @@ module Authorization 
     | 
|
| 
       96 
107 
     | 
    
         
             
                  result
         
     | 
| 
       97 
108 
     | 
    
         
             
                end
         
     | 
| 
       98 
109 
     | 
    
         | 
| 
      
 110 
     | 
    
         
            +
                # As has_any_role? except checks all roles included in the role hierarchy
         
     | 
| 
      
 111 
     | 
    
         
            +
                def has_any_role_with_hierarchy?(*roles, &block)
         
     | 
| 
      
 112 
     | 
    
         
            +
                  user_roles = authorization_engine.roles_with_hierarchy_for(current_user)
         
     | 
| 
      
 113 
     | 
    
         
            +
                  result = roles.any? do |role|
         
     | 
| 
      
 114 
     | 
    
         
            +
                    user_roles.include?(role)
         
     | 
| 
      
 115 
     | 
    
         
            +
                  end
         
     | 
| 
      
 116 
     | 
    
         
            +
                  yield if result and block_given?
         
     | 
| 
      
 117 
     | 
    
         
            +
                  result
         
     | 
| 
      
 118 
     | 
    
         
            +
                end
         
     | 
| 
       99 
119 
     | 
    
         | 
| 
       100 
120 
     | 
    
         
             
                protected
         
     | 
| 
       101 
121 
     | 
    
         
             
                def filter_access_filter # :nodoc:
         
     | 
| 
         @@ -194,7 +214,7 @@ module Authorization 
     | 
|
| 
       194 
214 
     | 
    
         
             
                  #     end
         
     | 
| 
       195 
215 
     | 
    
         
             
                  #   end
         
     | 
| 
       196 
216 
     | 
    
         
             
                  # 
         
     | 
| 
       197 
     | 
    
         
            -
                  # By default, required privileges are  
     | 
| 
      
 217 
     | 
    
         
            +
                  # By default, required privileges are inferred from the action name and
         
     | 
| 
       198 
218 
     | 
    
         
             
                  # the controller name.  Thus, in UserController :+edit+ requires
         
     | 
| 
       199 
219 
     | 
    
         
             
                  # :+edit+ +users+.  To specify required privilege, use the option :+require+
         
     | 
| 
       200 
220 
     | 
    
         
             
                  #   filter_access_to :new, :create, :require => :create, :context => :users
         
     | 
| 
         @@ -256,7 +276,7 @@ module Authorization 
     | 
|
| 
       256 
276 
     | 
    
         
             
                  #   to load the object.  Both should return the loaded object.
         
     | 
| 
       257 
277 
     | 
    
         
             
                  #   If a Proc object is given, e.g. by way of
         
     | 
| 
       258 
278 
     | 
    
         
             
                  #   +lambda+, it is called in the instance of the controller.  
         
     | 
| 
       259 
     | 
    
         
            -
                  #   Example demonstrating the default  
     | 
| 
      
 279 
     | 
    
         
            +
                  #   Example demonstrating the default behavior:
         
     | 
| 
       260 
280 
     | 
    
         
             
                  #     filter_access_to :show, :attribute_check => true,
         
     | 
| 
       261 
281 
     | 
    
         
             
                  #                      :load_method => lambda { User.find(params[:id]) }
         
     | 
| 
       262 
282 
     | 
    
         
             
                  # 
         
     | 
| 
         @@ -337,7 +357,7 @@ module Authorization 
     | 
|
| 
       337 
357 
     | 
    
         
             
                  #
         
     | 
| 
       338 
358 
     | 
    
         
             
                  # In many cases, the default seven CRUD actions are not sufficient.  As in
         
     | 
| 
       339 
359 
     | 
    
         
             
                  # the resource definition for routing you may thus give additional member,
         
     | 
| 
       340 
     | 
    
         
            -
                  # new and collection methods.  The options allow you to specify the
         
     | 
| 
      
 360 
     | 
    
         
            +
                  # new and collection methods.  The +options+ allow you to specify the
         
     | 
| 
       341 
361 
     | 
    
         
             
                  # required privileges for each action by providing a hash or an array of
         
     | 
| 
       342 
362 
     | 
    
         
             
                  # pairs.  By default, for each action the action name is taken as privilege
         
     | 
| 
       343 
363 
     | 
    
         
             
                  # (action search in the example below requires the privilege :index
         
     | 
| 
         @@ -348,7 +368,19 @@ module Authorization 
     | 
|
| 
       348 
368 
     | 
    
         
             
                  #         :additional_member => {:mark_as_key_company => :update}
         
     | 
| 
       349 
369 
     | 
    
         
             
                  #   end
         
     | 
| 
       350 
370 
     | 
    
         
             
                  # The +additional_+* options add to the respective CRUD actions,
         
     | 
| 
       351 
     | 
    
         
            -
                  # the other options  
     | 
| 
      
 371 
     | 
    
         
            +
                  # the other options (:+member+, :+collection+, :+new+) replace their
         
     | 
| 
      
 372 
     | 
    
         
            +
                  # respective CRUD actions.
         
     | 
| 
      
 373 
     | 
    
         
            +
                  #    filter_resource_access :member => { :toggle_open => :update }
         
     | 
| 
      
 374 
     | 
    
         
            +
                  # Would declare :toggle_open as the only member action in the controller and
         
     | 
| 
      
 375 
     | 
    
         
            +
                  # require that permission :update is granted for the current user.
         
     | 
| 
      
 376 
     | 
    
         
            +
                  #    filter_resource_access :additional_member => { :toggle_open => :update }
         
     | 
| 
      
 377 
     | 
    
         
            +
                  # Would add a member action :+toggle_open+ to the default members, such as :+show+.
         
     | 
| 
      
 378 
     | 
    
         
            +
                  #
         
     | 
| 
      
 379 
     | 
    
         
            +
                  # If :+collection+ is an array of method names filter_resource_access will 
         
     | 
| 
      
 380 
     | 
    
         
            +
                  # associate a permission with the method that is the same as the method 
         
     | 
| 
      
 381 
     | 
    
         
            +
                  # name and no attribute checks will be performed unless 
         
     | 
| 
      
 382 
     | 
    
         
            +
                  #   :attribute_check => true
         
     | 
| 
      
 383 
     | 
    
         
            +
                  # is added in the options.
         
     | 
| 
       352 
384 
     | 
    
         
             
                  # 
         
     | 
| 
       353 
385 
     | 
    
         
             
                  # You can override the default object loading by implementing any of the
         
     | 
| 
       354 
386 
     | 
    
         
             
                  # following instance methods on the controller.  Examples are given for the
         
     | 
| 
         @@ -390,7 +422,7 @@ module Authorization 
     | 
|
| 
       390 
422 
     | 
    
         
             
                  #   +nested_in+, attribute check is deactivated for these actions.  By
         
     | 
| 
       391 
423 
     | 
    
         
             
                  #   default, collection is set to :+index+.
         
     | 
| 
       392 
424 
     | 
    
         
             
                  # [:+additional_collection+]
         
     | 
| 
       393 
     | 
    
         
            -
                  #   Allows to add additional  
     | 
| 
      
 425 
     | 
    
         
            +
                  #   Allows to add additional collection actions to the default resource +collection+
         
     | 
| 
       394 
426 
     | 
    
         
             
                  #   actions.
         
     | 
| 
       395 
427 
     | 
    
         
             
                  # [:+new+]
         
     | 
| 
       396 
428 
     | 
    
         
             
                  #   +new+ methods are actions such as +new+ and +create+, which don't
         
     | 
| 
         @@ -422,7 +454,7 @@ module Authorization 
     | 
|
| 
       422 
454 
     | 
    
         
             
                  #   +additional_member+ or rather the default member actions (:+show+, :+edit+,
         
     | 
| 
       423 
455 
     | 
    
         
             
                  #   :+update+, :+destroy+).
         
     | 
| 
       424 
456 
     | 
    
         
             
                  # [:+no_attribute_check+]
         
     | 
| 
       425 
     | 
    
         
            -
                  #   Allows to set actions for which no attribute check should be  
     | 
| 
      
 457 
     | 
    
         
            +
                  #   Allows to set actions for which no attribute check should be performed.
         
     | 
| 
       426 
458 
     | 
    
         
             
                  #   See filter_access_to on details.  By default, with no +nested_in+,
         
     | 
| 
       427 
459 
     | 
    
         
             
                  #   +no_attribute_check+ is set to all collections.  If +nested_in+ is given
         
     | 
| 
       428 
460 
     | 
    
         
             
                  #   +no_attribute_check+ is empty by default.
         
     | 
| 
         @@ -443,8 +475,8 @@ module Authorization 
     | 
|
| 
       443 
475 
     | 
    
         
             
                      :nested_in  => nil,
         
     | 
| 
       444 
476 
     | 
    
         
             
                    }.merge(options)
         
     | 
| 
       445 
477 
     | 
    
         | 
| 
       446 
     | 
    
         
            -
                    new_actions = actions_from_option(options[:new]).merge(
         
     | 
| 
       447 
     | 
    
         
            -
                        actions_from_option(options[:additional_new]))
         
     | 
| 
      
 478 
     | 
    
         
            +
                    new_actions = actions_from_option( options[:new] ).merge(
         
     | 
| 
      
 479 
     | 
    
         
            +
                        actions_from_option(options[:additional_new]) )
         
     | 
| 
       448 
480 
     | 
    
         
             
                    members = actions_from_option(options[:member]).merge(
         
     | 
| 
       449 
481 
     | 
    
         
             
                        actions_from_option(options[:additional_member]))
         
     | 
| 
       450 
482 
     | 
    
         
             
                    collections = actions_from_option(options[:collection]).merge(
         
     | 
| 
         @@ -609,7 +641,7 @@ module Authorization 
     | 
|
| 
       609 
641 
     | 
    
         
             
                    unless object
         
     | 
| 
       610 
642 
     | 
    
         
             
                      begin
         
     | 
| 
       611 
643 
     | 
    
         
             
                        object = load_object_model.find(contr.params[:id])
         
     | 
| 
       612 
     | 
    
         
            -
                      rescue  
     | 
| 
      
 644 
     | 
    
         
            +
                      rescue => e
         
     | 
| 
       613 
645 
     | 
    
         
             
                        contr.logger.debug("filter_access_to tried to find " +
         
     | 
| 
       614 
646 
     | 
    
         
             
                            "#{load_object_model} from params[:id] " +
         
     | 
| 
       615 
647 
     | 
    
         
             
                            "(#{contr.params[:id].inspect}), because attribute_check is enabled " +
         
     | 
| 
         @@ -34,29 +34,31 @@ module Authorization 
     | 
|
| 
       34 
34 
     | 
    
         
             
                def self.included(base) # :nodoc:
         
     | 
| 
       35 
35 
     | 
    
         
             
                  #base.extend(ClassMethods)
         
     | 
| 
       36 
36 
     | 
    
         
             
                  base.module_eval do
         
     | 
| 
       37 
     | 
    
         
            -
                     
     | 
| 
       38 
     | 
    
         
            -
                       
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
                            options[:context]
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
                            parent_scope.proxy_reflection 
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
                            parent_scope.decl_auth_context
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
                             
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
                      user = options[:user] || Authorization.current_user
         
     | 
| 
      
 37 
     | 
    
         
            +
                    if Rails.version < "3.1"
         
     | 
| 
      
 38 
     | 
    
         
            +
                      scopes[:with_permissions_to] = lambda do |parent_scope, *args|
         
     | 
| 
      
 39 
     | 
    
         
            +
                        options = args.last.is_a?(Hash) ? args.pop : {}
         
     | 
| 
      
 40 
     | 
    
         
            +
                        privilege = (args[0] || :read).to_sym
         
     | 
| 
      
 41 
     | 
    
         
            +
                        privileges = [privilege]
         
     | 
| 
      
 42 
     | 
    
         
            +
                        context =
         
     | 
| 
      
 43 
     | 
    
         
            +
                            if options[:context]
         
     | 
| 
      
 44 
     | 
    
         
            +
                              options[:context]
         
     | 
| 
      
 45 
     | 
    
         
            +
                            elsif parent_scope.respond_to?(:proxy_reflection)
         
     | 
| 
      
 46 
     | 
    
         
            +
                              parent_scope.proxy_reflection.klass.name.tableize.to_sym
         
     | 
| 
      
 47 
     | 
    
         
            +
                            elsif parent_scope.respond_to?(:decl_auth_context)
         
     | 
| 
      
 48 
     | 
    
         
            +
                              parent_scope.decl_auth_context
         
     | 
| 
      
 49 
     | 
    
         
            +
                            else
         
     | 
| 
      
 50 
     | 
    
         
            +
                              parent_scope.name.tableize.to_sym
         
     | 
| 
      
 51 
     | 
    
         
            +
                            end
         
     | 
| 
       53 
52 
     | 
    
         | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
      
 53 
     | 
    
         
            +
                        user = options[:user] || Authorization.current_user
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                        engine = options[:engine] || Authorization::Engine.instance
         
     | 
| 
      
 56 
     | 
    
         
            +
                        engine.permit!(privileges, :user => user, :skip_attribute_test => true,
         
     | 
| 
      
 57 
     | 
    
         
            +
                                       :context => context)
         
     | 
| 
       57 
58 
     | 
    
         | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
      
 59 
     | 
    
         
            +
                        obligation_scope_for( privileges, :user => user,
         
     | 
| 
      
 60 
     | 
    
         
            +
                            :context => context, :engine => engine, :model => parent_scope)
         
     | 
| 
      
 61 
     | 
    
         
            +
                      end
         
     | 
| 
       60 
62 
     | 
    
         
             
                    end
         
     | 
| 
       61 
63 
     | 
    
         | 
| 
       62 
64 
     | 
    
         
             
                    # Builds and returns a scope with joins and conditions satisfying all obligations.
         
     | 
| 
         @@ -96,7 +98,32 @@ module Authorization 
     | 
|
| 
       96 
98 
     | 
    
         
             
                    #   current user.
         
     | 
| 
       97 
99 
     | 
    
         
             
                    #
         
     | 
| 
       98 
100 
     | 
    
         
             
                    def self.with_permissions_to (*args)
         
     | 
| 
       99 
     | 
    
         
            -
                       
     | 
| 
      
 101 
     | 
    
         
            +
                      if Rails.version < "3.1"
         
     | 
| 
      
 102 
     | 
    
         
            +
                        scopes[:with_permissions_to].call(self, *args)
         
     | 
| 
      
 103 
     | 
    
         
            +
                      else
         
     | 
| 
      
 104 
     | 
    
         
            +
                        options = args.last.is_a?(Hash) ? args.pop : {}
         
     | 
| 
      
 105 
     | 
    
         
            +
                        privilege = (args[0] || :read).to_sym
         
     | 
| 
      
 106 
     | 
    
         
            +
                        privileges = [privilege]
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                        parent_scope = scoped
         
     | 
| 
      
 109 
     | 
    
         
            +
                        context =
         
     | 
| 
      
 110 
     | 
    
         
            +
                            if options[:context]
         
     | 
| 
      
 111 
     | 
    
         
            +
                              options[:context]
         
     | 
| 
      
 112 
     | 
    
         
            +
                            elsif parent_scope.klass.respond_to?(:decl_auth_context)
         
     | 
| 
      
 113 
     | 
    
         
            +
                              parent_scope.klass.decl_auth_context
         
     | 
| 
      
 114 
     | 
    
         
            +
                            else
         
     | 
| 
      
 115 
     | 
    
         
            +
                              parent_scope.klass.name.tableize.to_sym
         
     | 
| 
      
 116 
     | 
    
         
            +
                            end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                        user = options[:user] || Authorization.current_user
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
                        engine = options[:engine] || Authorization::Engine.instance
         
     | 
| 
      
 121 
     | 
    
         
            +
                        engine.permit!(privileges, :user => user, :skip_attribute_test => true,
         
     | 
| 
      
 122 
     | 
    
         
            +
                                       :context => context)
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
                        obligation_scope_for( privileges, :user => user,
         
     | 
| 
      
 125 
     | 
    
         
            +
                            :context => context, :engine => engine, :model => parent_scope.klass)
         
     | 
| 
      
 126 
     | 
    
         
            +
                      end
         
     | 
| 
       100 
127 
     | 
    
         
             
                    end
         
     | 
| 
       101 
128 
     | 
    
         | 
| 
       102 
129 
     | 
    
         
             
                    # Activates model security for the current model.  Then, CRUD operations
         
     | 
| 
         @@ -55,17 +55,14 @@ module Authorization 
     | 
|
| 
       55 
55 
     | 
    
         
             
                  def self.usages_by_controller
         
     | 
| 
       56 
56 
     | 
    
         
             
                    # load each application controller
         
     | 
| 
       57 
57 
     | 
    
         
             
                    begin
         
     | 
| 
       58 
     | 
    
         
            -
                      Dir. 
     | 
| 
       59 
     | 
    
         
            -
                         
     | 
| 
       60 
     | 
    
         
            -
                          require File.join(::Rails.root, %w{app controllers}, entry)
         
     | 
| 
       61 
     | 
    
         
            -
                        end
         
     | 
| 
      
 58 
     | 
    
         
            +
                      Dir.glob(File.join(::Rails.root, 'app', 'controllers', '**', '*_controller\.rb')) do |entry|
         
     | 
| 
      
 59 
     | 
    
         
            +
                        require entry
         
     | 
| 
       62 
60 
     | 
    
         
             
                      end
         
     | 
| 
       63 
61 
     | 
    
         
             
                    rescue Errno::ENOENT
         
     | 
| 
       64 
62 
     | 
    
         
             
                    end
         
     | 
| 
       65 
63 
     | 
    
         
             
                    controllers = []
         
     | 
| 
       66 
64 
     | 
    
         
             
                    ObjectSpace.each_object(Class) do |obj|
         
     | 
| 
       67 
     | 
    
         
            -
                      controllers << obj if obj.ancestors.include?(ActionController::Base) and
         
     | 
| 
       68 
     | 
    
         
            -
                                            !%w{ActionController::Base ApplicationController}.include?(obj.name)
         
     | 
| 
      
 65 
     | 
    
         
            +
                      controllers << obj if obj.ancestors.include?(ActionController::Base) and obj != ActionController::Base and obj.name.demodulize != 'ApplicationController'
         
     | 
| 
       69 
66 
     | 
    
         
             
                    end
         
     | 
| 
       70 
67 
     | 
    
         | 
| 
       71 
68 
     | 
    
         
             
                    controllers.inject({}) do |memo, controller|
         
     | 
| 
         @@ -6,7 +6,7 @@ module Authorization 
     | 
|
| 
       6 
6 
     | 
    
         
             
              # Parses an authorization configuration file in the authorization DSL and
         
     | 
| 
       7 
7 
     | 
    
         
             
              # constructs a data model of its contents.
         
     | 
| 
       8 
8 
     | 
    
         
             
              # 
         
     | 
| 
       9 
     | 
    
         
            -
              # For examples and the  
     | 
| 
      
 9 
     | 
    
         
            +
              # For examples and the modeled data model, see the 
         
     | 
| 
       10 
10 
     | 
    
         
             
              # README[link:files/README_rdoc.html].
         
     | 
| 
       11 
11 
     | 
    
         
             
              #
         
     | 
| 
       12 
12 
     | 
    
         
             
              # Also, see role definition methods
         
     | 
| 
         @@ -381,12 +381,12 @@ module Authorization 
     | 
|
| 
       381 
381 
     | 
    
         
             
                  #
         
     | 
| 
       382 
382 
     | 
    
         
             
                  #   role :branch_manager
         
     | 
| 
       383 
383 
     | 
    
         
             
                  #     has_permission_on :branches, :to => :manage do
         
     | 
| 
       384 
     | 
    
         
            -
                  #       if_attribute :employees =>  
     | 
| 
      
 384 
     | 
    
         
            +
                  #       if_attribute :employees => contains { user }
         
     | 
| 
       385 
385 
     | 
    
         
             
                  #     end
         
     | 
| 
       386 
386 
     | 
    
         
             
                  #     has_permission_on :employees, :to => :read do
         
     | 
| 
       387 
387 
     | 
    
         
             
                  #       if_permitted_to :read, :branch
         
     | 
| 
       388 
388 
     | 
    
         
             
                  #       # instead of
         
     | 
| 
       389 
     | 
    
         
            -
                  #       # if_attribute :branch => { :employees =>  
     | 
| 
      
 389 
     | 
    
         
            +
                  #       # if_attribute :branch => { :employees => contains { user } }
         
     | 
| 
       390 
390 
     | 
    
         
             
                  #     end
         
     | 
| 
       391 
391 
     | 
    
         
             
                  #   end
         
     | 
| 
       392 
392 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -404,19 +404,19 @@ module Authorization 
     | 
|
| 
       404 
404 
     | 
    
         
             
                  # To check permissions based on the current object, the attribute has to
         
     | 
| 
       405 
405 
     | 
    
         
             
                  # be left out:
         
     | 
| 
       406 
406 
     | 
    
         
             
                  #   has_permission_on :branches, :to => :manage do
         
     | 
| 
       407 
     | 
    
         
            -
                  #     if_attribute :employees =>  
     | 
| 
      
 407 
     | 
    
         
            +
                  #     if_attribute :employees => contains { user }
         
     | 
| 
       408 
408 
     | 
    
         
             
                  #   end
         
     | 
| 
       409 
409 
     | 
    
         
             
                  #   has_permission_on :branches, :to => :paint_green do
         
     | 
| 
       410 
410 
     | 
    
         
             
                  #     if_permitted_to :update
         
     | 
| 
       411 
411 
     | 
    
         
             
                  #   end
         
     | 
| 
       412 
     | 
    
         
            -
                  # Normally, one would merge those rules into one.   
     | 
| 
      
 412 
     | 
    
         
            +
                  # Normally, one would merge those rules into one.  Dividing makes sense
         
     | 
| 
       413 
413 
     | 
    
         
             
                  # if additional if_attribute are used in the second rule or those rules
         
     | 
| 
       414 
414 
     | 
    
         
             
                  # are applied to different roles.
         
     | 
| 
       415 
415 
     | 
    
         
             
                  #
         
     | 
| 
       416 
416 
     | 
    
         
             
                  # Options:
         
     | 
| 
       417 
417 
     | 
    
         
             
                  # [:+context+]
         
     | 
| 
       418 
418 
     | 
    
         
             
                  #   When using with_permissions_to, the target context of the if_permitted_to
         
     | 
| 
       419 
     | 
    
         
            -
                  #   statement is  
     | 
| 
      
 419 
     | 
    
         
            +
                  #   statement is inferred from the last reflections target class.  Still,
         
     | 
| 
       420 
420 
     | 
    
         
             
                  #   you may override this algorithm by setting the context explicitly.
         
     | 
| 
       421 
421 
     | 
    
         
             
                  #     if_permitted_to :read, :home_branch, :context => :branches
         
     | 
| 
       422 
422 
     | 
    
         
             
                  #     if_permitted_to :read, :branch => :main_company, :context => :companies
         
     | 
    
        data/test/authorization_test.rb
    CHANGED
    
    | 
         @@ -316,6 +316,25 @@ class AuthorizationTest < Test::Unit::TestCase 
     | 
|
| 
       316 
316 
     | 
    
         
             
                assert !engine.permit?(:test, :context => :permissions_2)
         
     | 
| 
       317 
317 
     | 
    
         
             
              end
         
     | 
| 
       318 
318 
     | 
    
         | 
| 
      
 319 
     | 
    
         
            +
              def test_default_role
         
     | 
| 
      
 320 
     | 
    
         
            +
                previous_default_role = Authorization.default_role
         
     | 
| 
      
 321 
     | 
    
         
            +
                Authorization.default_role = :anonymous
         
     | 
| 
      
 322 
     | 
    
         
            +
                reader = Authorization::Reader::DSLReader.new
         
     | 
| 
      
 323 
     | 
    
         
            +
                reader.parse %{
         
     | 
| 
      
 324 
     | 
    
         
            +
                  authorization do
         
     | 
| 
      
 325 
     | 
    
         
            +
                    role :anonymous do
         
     | 
| 
      
 326 
     | 
    
         
            +
                      has_permission_on :permissions, :to => :test
         
     | 
| 
      
 327 
     | 
    
         
            +
                    end
         
     | 
| 
      
 328 
     | 
    
         
            +
                  end
         
     | 
| 
      
 329 
     | 
    
         
            +
                }
         
     | 
| 
      
 330 
     | 
    
         
            +
                engine = Authorization::Engine.new(reader)
         
     | 
| 
      
 331 
     | 
    
         
            +
                assert engine.permit?(:test, :context => :permissions)
         
     | 
| 
      
 332 
     | 
    
         
            +
                assert !engine.permit?(:test, :context => :permissions, 
         
     | 
| 
      
 333 
     | 
    
         
            +
                  :user => MockUser.new(:guest))
         
     | 
| 
      
 334 
     | 
    
         
            +
                # reset the default role, so that it does not mess up other tests
         
     | 
| 
      
 335 
     | 
    
         
            +
                Authorization.default_role = previous_default_role
         
     | 
| 
      
 336 
     | 
    
         
            +
              end
         
     | 
| 
      
 337 
     | 
    
         
            +
              
         
     | 
| 
       319 
338 
     | 
    
         
             
              def test_invalid_user_model
         
     | 
| 
       320 
339 
     | 
    
         
             
                reader = Authorization::Reader::DSLReader.new
         
     | 
| 
       321 
340 
     | 
    
         
             
                reader.parse %{
         
     | 
    
        data/test/controller_test.rb
    CHANGED
    
    | 
         @@ -262,7 +262,7 @@ class LoadObjectControllerTest < ActionController::TestCase 
     | 
|
| 
       262 
262 
     | 
    
         
             
                  end
         
     | 
| 
       263 
263 
     | 
    
         
             
                }
         
     | 
| 
       264 
264 
     | 
    
         | 
| 
       265 
     | 
    
         
            -
                assert_raise  
     | 
| 
      
 265 
     | 
    
         
            +
                assert_raise StandardError, "No id param supplied" do
         
     | 
| 
       266 
266 
     | 
    
         
             
                  request!(MockUser.new(:test_role), "show", reader)
         
     | 
| 
       267 
267 
     | 
    
         
             
                end
         
     | 
| 
       268 
268 
     | 
    
         | 
    
        data/test/helper_test.rb
    CHANGED
    
    | 
         @@ -113,7 +113,42 @@ class HelperTest < ActionController::TestCase 
     | 
|
| 
       113 
113 
     | 
    
         
             
                end
         
     | 
| 
       114 
114 
     | 
    
         
             
                assert !block_evaled
         
     | 
| 
       115 
115 
     | 
    
         
             
              end
         
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
      
 116 
     | 
    
         
            +
              
         
     | 
| 
      
 117 
     | 
    
         
            +
              def test_has_any_role
         
     | 
| 
      
 118 
     | 
    
         
            +
                reader = Authorization::Reader::DSLReader.new
         
     | 
| 
      
 119 
     | 
    
         
            +
                reader.parse %{
         
     | 
| 
      
 120 
     | 
    
         
            +
                  authorization do
         
     | 
| 
      
 121 
     | 
    
         
            +
                    role :test_role do
         
     | 
| 
      
 122 
     | 
    
         
            +
                      has_permission_on :mocks, :to => :show
         
     | 
| 
      
 123 
     | 
    
         
            +
                    end
         
     | 
| 
      
 124 
     | 
    
         
            +
                  end
         
     | 
| 
      
 125 
     | 
    
         
            +
                }
         
     | 
| 
      
 126 
     | 
    
         
            +
                user = MockUser.new(:test_role)
         
     | 
| 
      
 127 
     | 
    
         
            +
                request!(user, :action, reader)
         
     | 
| 
      
 128 
     | 
    
         
            +
                
         
     | 
| 
      
 129 
     | 
    
         
            +
                assert has_any_role?(:test_role)
         
     | 
| 
      
 130 
     | 
    
         
            +
                assert !has_any_role?(:test_role2)
         
     | 
| 
      
 131 
     | 
    
         
            +
                assert has_any_role?(:test_role, :test_role2)
         
     | 
| 
      
 132 
     | 
    
         
            +
                
         
     | 
| 
      
 133 
     | 
    
         
            +
                block_evaled = false
         
     | 
| 
      
 134 
     | 
    
         
            +
                has_any_role?(:test_role) do
         
     | 
| 
      
 135 
     | 
    
         
            +
                  block_evaled = true
         
     | 
| 
      
 136 
     | 
    
         
            +
                end
         
     | 
| 
      
 137 
     | 
    
         
            +
                assert block_evaled
         
     | 
| 
      
 138 
     | 
    
         
            +
                
         
     | 
| 
      
 139 
     | 
    
         
            +
                block_evaled = false
         
     | 
| 
      
 140 
     | 
    
         
            +
                has_any_role?(:test_role2) do
         
     | 
| 
      
 141 
     | 
    
         
            +
                  block_evaled = true
         
     | 
| 
      
 142 
     | 
    
         
            +
                end
         
     | 
| 
      
 143 
     | 
    
         
            +
                assert !block_evaled
         
     | 
| 
      
 144 
     | 
    
         
            +
                
         
     | 
| 
      
 145 
     | 
    
         
            +
                block_evaled = false
         
     | 
| 
      
 146 
     | 
    
         
            +
                has_any_role?(:test_role,:test_role2) do
         
     | 
| 
      
 147 
     | 
    
         
            +
                  block_evaled = true
         
     | 
| 
      
 148 
     | 
    
         
            +
                end
         
     | 
| 
      
 149 
     | 
    
         
            +
                assert block_evaled
         
     | 
| 
      
 150 
     | 
    
         
            +
              end
         
     | 
| 
      
 151 
     | 
    
         
            +
              
         
     | 
| 
       117 
152 
     | 
    
         
             
              def test_has_role_with_guest_user
         
     | 
| 
       118 
153 
     | 
    
         
             
                reader = Authorization::Reader::DSLReader.new
         
     | 
| 
       119 
154 
     | 
    
         
             
                reader.parse %{
         
     | 
| 
         @@ -165,8 +200,48 @@ class HelperTest < ActionController::TestCase 
     | 
|
| 
       165 
200 
     | 
    
         
             
                  block_evaled = true
         
     | 
| 
       166 
201 
     | 
    
         
             
                end
         
     | 
| 
       167 
202 
     | 
    
         
             
                assert !block_evaled
         
     | 
| 
       168 
     | 
    
         
            -
             
     | 
| 
       169 
203 
     | 
    
         
             
              end
         
     | 
| 
       170 
204 
     | 
    
         | 
| 
       171 
     | 
    
         
            -
              
         
     | 
| 
      
 205 
     | 
    
         
            +
              def test_has_any_role_with_hierarchy
         
     | 
| 
      
 206 
     | 
    
         
            +
                reader = Authorization::Reader::DSLReader.new
         
     | 
| 
      
 207 
     | 
    
         
            +
                reader.parse %{
         
     | 
| 
      
 208 
     | 
    
         
            +
                  authorization do
         
     | 
| 
      
 209 
     | 
    
         
            +
                    role :test_role do
         
     | 
| 
      
 210 
     | 
    
         
            +
                      has_permission_on :mocks, :to => :show
         
     | 
| 
      
 211 
     | 
    
         
            +
                    end
         
     | 
| 
      
 212 
     | 
    
         
            +
                    role :other_role do
         
     | 
| 
      
 213 
     | 
    
         
            +
                      has_permission_on :another_mocks, :to => :show
         
     | 
| 
      
 214 
     | 
    
         
            +
                    end
         
     | 
| 
      
 215 
     | 
    
         
            +
             
     | 
| 
      
 216 
     | 
    
         
            +
                    role :root do
         
     | 
| 
      
 217 
     | 
    
         
            +
                      includes :test_role
         
     | 
| 
      
 218 
     | 
    
         
            +
                    end
         
     | 
| 
      
 219 
     | 
    
         
            +
                  end
         
     | 
| 
      
 220 
     | 
    
         
            +
                }    
         
     | 
| 
      
 221 
     | 
    
         
            +
                
         
     | 
| 
      
 222 
     | 
    
         
            +
                user = MockUser.new(:root)
         
     | 
| 
      
 223 
     | 
    
         
            +
                request!(user, :action, reader)
         
     | 
| 
      
 224 
     | 
    
         
            +
                
         
     | 
| 
      
 225 
     | 
    
         
            +
                assert has_any_role_with_hierarchy?(:test_role)
         
     | 
| 
      
 226 
     | 
    
         
            +
                assert !has_any_role_with_hierarchy?(:other_role)
         
     | 
| 
      
 227 
     | 
    
         
            +
                assert has_any_role_with_hierarchy?(:test_role,:other_role)
         
     | 
| 
      
 228 
     | 
    
         
            +
             
     | 
| 
      
 229 
     | 
    
         
            +
                block_evaled = false
         
     | 
| 
      
 230 
     | 
    
         
            +
                has_any_role_with_hierarchy?(:test_role) do
         
     | 
| 
      
 231 
     | 
    
         
            +
                  block_evaled = true
         
     | 
| 
      
 232 
     | 
    
         
            +
                end
         
     | 
| 
      
 233 
     | 
    
         
            +
                assert block_evaled
         
     | 
| 
      
 234 
     | 
    
         
            +
                
         
     | 
| 
      
 235 
     | 
    
         
            +
                block_evaled = false
         
     | 
| 
      
 236 
     | 
    
         
            +
                has_any_role_with_hierarchy?(:test_role2) do
         
     | 
| 
      
 237 
     | 
    
         
            +
                  block_evaled = true
         
     | 
| 
      
 238 
     | 
    
         
            +
                end
         
     | 
| 
      
 239 
     | 
    
         
            +
                assert !block_evaled
         
     | 
| 
      
 240 
     | 
    
         
            +
                
         
     | 
| 
      
 241 
     | 
    
         
            +
                block_evaled = false
         
     | 
| 
      
 242 
     | 
    
         
            +
                has_any_role_with_hierarchy?(:test_role,:test_role2) do
         
     | 
| 
      
 243 
     | 
    
         
            +
                  block_evaled = true
         
     | 
| 
      
 244 
     | 
    
         
            +
                end
         
     | 
| 
      
 245 
     | 
    
         
            +
                assert block_evaled
         
     | 
| 
      
 246 
     | 
    
         
            +
              end
         
     | 
| 
       172 
247 
     | 
    
         
             
            end
         
     | 
    
        data/test/model_test.rb
    CHANGED
    
    | 
         @@ -71,6 +71,7 @@ class TestAttr < ActiveRecord::Base 
     | 
|
| 
       71 
71 
     | 
    
         
             
              belongs_to :branch
         
     | 
| 
       72 
72 
     | 
    
         
             
              belongs_to :company
         
     | 
| 
       73 
73 
     | 
    
         
             
              has_many :test_attr_throughs
         
     | 
| 
      
 74 
     | 
    
         
            +
              has_many :test_model_security_model_with_finds
         
     | 
| 
       74 
75 
     | 
    
         
             
              attr_reader :role_symbols
         
     | 
| 
       75 
76 
     | 
    
         
             
              def initialize (*args)
         
     | 
| 
       76 
77 
     | 
    
         
             
                @role_symbols = []
         
     | 
| 
         @@ -89,6 +90,7 @@ end 
     | 
|
| 
       89 
90 
     | 
    
         
             
            class TestModelSecurityModelWithFind < ActiveRecord::Base
         
     | 
| 
       90 
91 
     | 
    
         
             
              set_table_name "test_model_security_models"
         
     | 
| 
       91 
92 
     | 
    
         
             
              has_many :test_attrs
         
     | 
| 
      
 93 
     | 
    
         
            +
              belongs_to :test_attr
         
     | 
| 
       92 
94 
     | 
    
         
             
              using_access_control :include_read => true, 
         
     | 
| 
       93 
95 
     | 
    
         
             
                :context => :test_model_security_models
         
     | 
| 
       94 
96 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1591,6 +1593,32 @@ class ModelTest < Test::Unit::TestCase 
     | 
|
| 
       1591 
1593 
     | 
    
         
             
                end
         
     | 
| 
       1592 
1594 
     | 
    
         
             
              end
         
     | 
| 
       1593 
1595 
     | 
    
         | 
| 
      
 1596 
     | 
    
         
            +
              def test_model_security_with_read_restrictions_and_exists
         
     | 
| 
      
 1597 
     | 
    
         
            +
                reader = Authorization::Reader::DSLReader.new
         
     | 
| 
      
 1598 
     | 
    
         
            +
                reader.parse %{
         
     | 
| 
      
 1599 
     | 
    
         
            +
                  authorization do
         
     | 
| 
      
 1600 
     | 
    
         
            +
                    role :test_role do
         
     | 
| 
      
 1601 
     | 
    
         
            +
                      has_permission_on :test_model_security_models do
         
     | 
| 
      
 1602 
     | 
    
         
            +
                        to :read, :create, :update, :delete
         
     | 
| 
      
 1603 
     | 
    
         
            +
                        if_attribute :test_attr => is { user.test_attr }
         
     | 
| 
      
 1604 
     | 
    
         
            +
                      end
         
     | 
| 
      
 1605 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1606 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1607 
     | 
    
         
            +
                }
         
     | 
| 
      
 1608 
     | 
    
         
            +
                Authorization::Engine.instance(reader)
         
     | 
| 
      
 1609 
     | 
    
         
            +
             
     | 
| 
      
 1610 
     | 
    
         
            +
                test_attr = TestAttr.create
         
     | 
| 
      
 1611 
     | 
    
         
            +
                Authorization.current_user = MockUser.new(:test_role, :test_attr => test_attr)
         
     | 
| 
      
 1612 
     | 
    
         
            +
                object_with_find = TestModelSecurityModelWithFind.create :test_attr => test_attr
         
     | 
| 
      
 1613 
     | 
    
         
            +
                assert_nothing_raised do
         
     | 
| 
      
 1614 
     | 
    
         
            +
                  object_with_find.class.find(object_with_find.id)
         
     | 
| 
      
 1615 
     | 
    
         
            +
                end
         
     | 
| 
      
 1616 
     | 
    
         
            +
                assert_equal 1, test_attr.test_model_security_model_with_finds.length
         
     | 
| 
      
 1617 
     | 
    
         
            +
                
         
     | 
| 
      
 1618 
     | 
    
         
            +
                # Raises error since AR does not populate the object
         
     | 
| 
      
 1619 
     | 
    
         
            +
                #assert test_attr.test_model_security_model_with_finds.exists?(object_with_find)
         
     | 
| 
      
 1620 
     | 
    
         
            +
              end
         
     | 
| 
      
 1621 
     | 
    
         
            +
             
     | 
| 
       1594 
1622 
     | 
    
         
             
              def test_model_security_delete_unallowed
         
     | 
| 
       1595 
1623 
     | 
    
         
             
                reader = Authorization::Reader::DSLReader.new
         
     | 
| 
       1596 
1624 
     | 
    
         
             
                reader.parse %{
         
     | 
    
        data/test/schema.sql
    CHANGED
    
    | 
         @@ -28,7 +28,8 @@ CREATE TABLE 'test_attr_throughs' ( 
     | 
|
| 
       28 
28 
     | 
    
         
             
            CREATE TABLE 'test_model_security_models' (
         
     | 
| 
       29 
29 
     | 
    
         
             
              'id' INTEGER PRIMARY KEY NOT NULL, 
         
     | 
| 
       30 
30 
     | 
    
         
             
              'attr' integer default 1, 
         
     | 
| 
       31 
     | 
    
         
            -
              'attr_2' integer default 1
         
     | 
| 
      
 31 
     | 
    
         
            +
              'attr_2' integer default 1,
         
     | 
| 
      
 32 
     | 
    
         
            +
              'test_attr_id' integer
         
     | 
| 
       32 
33 
     | 
    
         
             
            );
         
     | 
| 
       33 
34 
     | 
    
         | 
| 
       34 
35 
     | 
    
         
             
            CREATE TABLE 'n_way_join_items' (
         
     | 
    
        data/test/test_helper.rb
    CHANGED
    
    | 
         @@ -62,7 +62,7 @@ class MockDataObject 
     | 
|
| 
       62 
62 
     | 
    
         
             
              end
         
     | 
| 
       63 
63 
     | 
    
         | 
| 
       64 
64 
     | 
    
         
             
              def self.find(*args)
         
     | 
| 
       65 
     | 
    
         
            -
                raise "Couldn't find #{self.name} with id #{args[0].inspect}" unless args[0]
         
     | 
| 
      
 65 
     | 
    
         
            +
                raise StandardError, "Couldn't find #{self.name} with id #{args[0].inspect}" unless args[0]
         
     | 
| 
       66 
66 
     | 
    
         
             
                new :id => args[0]
         
     | 
| 
       67 
67 
     | 
    
         
             
              end
         
     | 
| 
       68 
68 
     | 
    
         
             
            end
         
     | 
| 
         @@ -118,7 +118,8 @@ if Rails.version < "3" 
     | 
|
| 
       118 
118 
     | 
    
         
             
                map.connect ':controller/:action/:id'
         
     | 
| 
       119 
119 
     | 
    
         
             
              end
         
     | 
| 
       120 
120 
     | 
    
         
             
            else
         
     | 
| 
       121 
     | 
    
         
            -
              Rails::Application.routes.draw do
         
     | 
| 
      
 121 
     | 
    
         
            +
              #Rails::Application.routes.draw do
         
     | 
| 
      
 122 
     | 
    
         
            +
              Rails.application.routes.draw do
         
     | 
| 
       122 
123 
     | 
    
         
             
                match '/name/spaced_things(/:action)' => 'name/spaced_things'
         
     | 
| 
       123 
124 
     | 
    
         
             
                match '/deep/name_spaced/things(/:action)' => 'deep/name_spaced/things'
         
     | 
| 
       124 
125 
     | 
    
         
             
                match '/:controller(/:action(/:id))'
         
     | 
| 
         @@ -146,7 +147,8 @@ class Test::Unit::TestCase 
     | 
|
| 
       146 
147 
     | 
    
         | 
| 
       147 
148 
     | 
    
         
             
              unless Rails.version < "3"
         
     | 
| 
       148 
149 
     | 
    
         
             
                def setup
         
     | 
| 
       149 
     | 
    
         
            -
                   
     | 
| 
      
 150 
     | 
    
         
            +
                  #@routes = Rails::Application.routes
         
     | 
| 
      
 151 
     | 
    
         
            +
                  @routes = Rails.application.routes
         
     | 
| 
       150 
152 
     | 
    
         
             
                end
         
     | 
| 
       151 
153 
     | 
    
         
             
              end
         
     | 
| 
       152 
154 
     | 
    
         
             
            end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version 
     | 
|
| 
       5 
5 
     | 
    
         
             
              segments: 
         
     | 
| 
       6 
6 
     | 
    
         
             
              - 0
         
     | 
| 
       7 
7 
     | 
    
         
             
              - 5
         
     | 
| 
       8 
     | 
    
         
            -
              -  
     | 
| 
       9 
     | 
    
         
            -
              version: 0.5. 
     | 
| 
      
 8 
     | 
    
         
            +
              - 3
         
     | 
| 
      
 9 
     | 
    
         
            +
              version: 0.5.3
         
     | 
| 
       10 
10 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       11 
11 
     | 
    
         
             
            authors: 
         
     | 
| 
       12 
12 
     | 
    
         
             
            - Steffen Bartsch
         
     | 
| 
         @@ -14,7 +14,7 @@ autorequire: 
     | 
|
| 
       14 
14 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       15 
15 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
            date:  
     | 
| 
      
 17 
     | 
    
         
            +
            date: 2011-05-25 00:00:00 +02:00
         
     | 
| 
       18 
18 
     | 
    
         
             
            default_executable: 
         
     | 
| 
       19 
19 
     | 
    
         
             
            dependencies: []
         
     | 
| 
       20 
20 
     | 
    
         |