canner 0.0.2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +63 -47
- data/canner.gemspec +1 -1
- data/lib/canner/policy.rb +60 -0
- data/lib/canner/util.rb +1 -1
- data/lib/canner/version.rb +1 -1
- data/lib/canner.rb +38 -7
- data/lib/generators/canner/fetch_roles/USAGE +3 -0
- data/lib/generators/canner/{install/install_generator.rb → fetch_roles/fetch_roles_generator.rb} +1 -1
- data/lib/generators/canner/fetch_roles/templates/base_policy.rb +8 -0
- data/lib/generators/canner/policy/USAGE +9 -3
- data/lib/generators/canner/policy/policy_generator.rb +12 -0
- data/lib/generators/canner/policy/templates/policy.rb +1 -1
- data/lib/generators/test_unit/policy_generator.rb +11 -0
- data/lib/generators/test_unit/templates/policy_test.rb +11 -0
- data/spec/canner_spec.rb +151 -0
- data/spec/spec_helper.rb +17 -0
- metadata +33 -28
- data/lib/canner/rspec.rb +0 -0
- data/lib/generators/canner/install/USAGE +0 -2
- data/lib/generators/canner/install/templates/base_policy.rb +0 -52
- data/spec/Gemfile +0 -4
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 5fe7375f518e4b28b54badd6031ace79365f8105
         | 
| 4 | 
            +
              data.tar.gz: 8939b3f2f12e4a4dbb6cb4cf76e288369bbf0e5f
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 62a5ea258681115223f0f122d13246ef36f29eae14b8725831d0e79d1ec81f4a07f91189ba4a44d7465b2639581cc530ea409028bf508dce52e04b2adda0b86a
         | 
| 7 | 
            +
              data.tar.gz: 5ec594066b2daeeff61bdb71f7580dcb71bd6ce427549dbc74a9ae9f48700d9411312d1edb1ce3323321e6ae52307161f1854556f0b19d5d24beac9f20db4df1
         | 
    
        data/README.md
    CHANGED
    
    | @@ -1,35 +1,22 @@ | |
| 1 1 | 
             
            Canner
         | 
| 2 2 | 
             
            ======
         | 
| 3 3 |  | 
| 4 | 
            -
            Canner is an authorization gem heavily modeled after Pundit.
         | 
| 5 | 
            -
            The goal is to take away some of the magic that exists in other auth gems out there and
         | 
| 6 | 
            -
            provide the flexibility needed for your specific app.
         | 
| 4 | 
            +
            Canner is an authorization gem heavily modeled after Pundit.  
         | 
| 7 5 |  | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 6 | 
            +
            Canner's intention is to provide you a framework for authorization that has little to no magic.  
         | 
| 7 | 
            +
            Your canner policies can be as simple or as complicated as your app requires.
         | 
| 10 8 |  | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 9 | 
            +
            Who needs another auth gem?  There's a bunch of very good ones out there.  
         | 
| 10 | 
            +
            Pundit, cancan, cancancan and Declarative Authorization to name a few alternatives.  
         | 
| 13 11 |  | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
            Cleveland is a perfect place to open another store location.
         | 
| 12 | 
            +
            Unfortunately for me, none of those solutions had built in support for a requirement I have on the
         | 
| 13 | 
            +
            project [Kennel Captain](http://www.kennelcaptain.com)  
         | 
| 17 14 |  | 
| 18 | 
            -
             | 
| 19 | 
            -
            In any of the above listed gems if you have a manager role you could see all the reports regardless
         | 
| 20 | 
            -
            of the store location aka store branch.
         | 
| 15 | 
            +
            We need to authorize a user at a given store location, and that's a feature canner will support.
         | 
| 21 16 |  | 
| 22 | 
            -
             | 
| 23 | 
            -
            Instead of saying:
         | 
| 24 | 
            -
            Can the currently signed in user access this particular report.
         | 
| 25 | 
            -
            Canner can say:
         | 
| 26 | 
            -
            Can the currently signed in user access this particular report for this particular branch.
         | 
| 17 | 
            +
            For details see the wiki page [Authorize with Branches ( Store Locations )](https://github.com/jacklin10/canner/wiki/Authorize-with-Branches)
         | 
| 27 18 |  | 
| 28 | 
            -
             | 
| 29 | 
            -
            pittsburgh_manager and cleveland_manager.  Or maybe writing some monkey patches to hack in what you need.
         | 
| 30 | 
            -
             | 
| 31 | 
            -
            Canner is designed to give you an outline of what you'll need for your app's auth needs and leaves
         | 
| 32 | 
            -
            the level of complexity needed up to the requirements of your particular application.
         | 
| 19 | 
            +
            Also note that canner works fine if you don't need this particular feature, its just there if you do.
         | 
| 33 20 |  | 
| 34 21 | 
             
            ## Installation
         | 
| 35 22 |  | 
| @@ -46,14 +33,6 @@ Then run | |
| 46 33 | 
             
            bundle install
         | 
| 47 34 | 
             
            ```
         | 
| 48 35 |  | 
| 49 | 
            -
            After the gem is installed you'll need to run the install generator:
         | 
| 50 | 
            -
             | 
| 51 | 
            -
            ``` ruby
         | 
| 52 | 
            -
            rails g canner:install
         | 
| 53 | 
            -
            ```
         | 
| 54 | 
            -
             | 
| 55 | 
            -
            This will create a policies directory and create the base_policy.rb
         | 
| 56 | 
            -
             | 
| 57 36 | 
             
            Now include canner in your application_controller.rb
         | 
| 58 37 |  | 
| 59 38 | 
             
            ``` ruby
         | 
| @@ -66,13 +45,24 @@ You'll then need to create a Policy class for the models you'd like to authorize | |
| 66 45 | 
             
            rails g canner:policy user
         | 
| 67 46 | 
             
            ```
         | 
| 68 47 |  | 
| 69 | 
            -
             | 
| 48 | 
            +
            If your app gets roles from a user in a way other than @current_user.roles then you'll
         | 
| 49 | 
            +
            need to override the fetch_roles policy method.
         | 
| 50 | 
            +
             | 
| 51 | 
            +
            ```ruby
         | 
| 52 | 
            +
            rails g canner:fetch_roles
         | 
| 53 | 
            +
            ```
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            More details are available in the wiki: 
         | 
| 56 | 
            +
            [Overriding the Fetching of Roles](https://github.com/jacklin10/canner/wiki/Feed-Roles)
         | 
| 70 57 |  | 
| 71 58 | 
             
            ## Policies
         | 
| 72 59 |  | 
| 73 60 | 
             
            As mentioned Canner is strongly influenced by Pundit and is also based on Policy objects.
         | 
| 74 | 
            -
            Your policy objects should be named using the pattern | 
| 75 | 
            -
             | 
| 61 | 
            +
            Your policy objects should be named using the following pattern:   
         | 
| 62 | 
            +
            UserPolicy, CustomerPolicy, AppPolicy.
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            Use the generator to save you some time: 
         | 
| 65 | 
            +
            ``` rails g canner:policy <model name> ```
         | 
| 76 66 |  | 
| 77 67 | 
             
            Your policy models need to implement 2 methods:
         | 
| 78 68 | 
             
            ``` ruby
         | 
| @@ -85,7 +75,9 @@ end | |
| 85 75 |  | 
| 86 76 | 
             
            ### canner_scope
         | 
| 87 77 |  | 
| 88 | 
            -
             | 
| 78 | 
            +
            You'll want to implement this method for each of your model policies that extend from base_policy.rb.
         | 
| 79 | 
            +
             | 
| 80 | 
            +
            The canner_scope method is used to scope the authorized models consistently in your app.
         | 
| 89 81 |  | 
| 90 82 | 
             
            For example in my app the Customers controller uses the canner_scope to
         | 
| 91 83 | 
             
            ensure only Users from the current_company are displayed.
         | 
| @@ -129,9 +121,12 @@ class CustomerPolicy < BasePolicy | |
| 129 121 | 
             
            end
         | 
| 130 122 | 
             
            ```
         | 
| 131 123 |  | 
| 132 | 
            -
             | 
| 124 | 
            +
            Now you don't really need to think about the auth logic when fetching a list of customers.
         | 
| 125 | 
            +
            Just make sure you use the policy and you'll only show the users what is intended.
         | 
| 133 126 |  | 
| 134 | 
            -
             | 
| 127 | 
            +
            Also if your policy changes at some point its a one place fix.
         | 
| 128 | 
            +
             | 
| 129 | 
            +
            ### can?
         | 
| 135 130 |  | 
| 136 131 | 
             
            You use the can method to determine if the current_user is able to access an action or resource.
         | 
| 137 132 |  | 
| @@ -148,10 +143,9 @@ when :something_random | |
| 148 143 | 
             
            else
         | 
| 149 144 | 
             
              false
         | 
| 150 145 | 
             
            end
         | 
| 151 | 
            -
             | 
| 152 | 
            -
            # Then in controller do:
         | 
| 153 | 
            -
            can?(:something_random, :customer)
         | 
| 154 146 | 
             
            ```
         | 
| 147 | 
            +
            # Then in controller do:
         | 
| 148 | 
            +
            ```can?(:something_random, :customer)```
         | 
| 155 149 |  | 
| 156 150 | 
             
            In english the can method is saying:
         | 
| 157 151 |  | 
| @@ -160,12 +154,22 @@ use the CustomerPolicy's can? method to do the checking. | |
| 160 154 |  | 
| 161 155 | 
             
            `can?(:something_random, :user)` would use the ... you guessed it UserPolicy's can? method.
         | 
| 162 156 |  | 
| 157 | 
            +
            If you want to deny access by default across all model policies you could do something as simple as:
         | 
| 158 | 
            +
             | 
| 159 | 
            +
            ``` ruby
         | 
| 160 | 
            +
            def can?
         | 
| 161 | 
            +
              false
         | 
| 162 | 
            +
            end
         | 
| 163 | 
            +
            ```
         | 
| 164 | 
            +
             | 
| 165 | 
            +
            in your base_policy's `can?` method
         | 
| 166 | 
            +
             | 
| 163 167 | 
             
            ### Force the Use of Policies
         | 
| 164 168 |  | 
| 165 169 | 
             
            Also like Pundit you can force your app to use policies.
         | 
| 166 170 | 
             
            I recommend you do this so you don't forget to wrap authorization about some of your resources.
         | 
| 167 171 |  | 
| 168 | 
            -
            To make sure your controller actions are using the can? method add this  | 
| 172 | 
            +
            To make sure your controller actions are using the can? method add this near the top of your
         | 
| 169 173 | 
             
            application_controller.rb
         | 
| 170 174 |  | 
| 171 175 | 
             
            ``` ruby
         | 
| @@ -180,6 +184,15 @@ after_action :ensure_scope, only: :index | |
| 180 184 | 
             
            Note the use of only here.  You usually won't need the canner_scope on anything except
         | 
| 181 185 | 
             
            for the index to be strictly enforced.
         | 
| 182 186 |  | 
| 187 | 
            +
            If you would like to skip for a particular controller just add
         | 
| 188 | 
            +
            ``` ruby
         | 
| 189 | 
            +
            skip_filter :ensure_scope
         | 
| 190 | 
            +
            ```
         | 
| 191 | 
            +
            And / Or
         | 
| 192 | 
            +
            ``` ruby
         | 
| 193 | 
            +
            skip_filter :ensure_auth
         | 
| 194 | 
            +
            ```
         | 
| 195 | 
            +
             | 
| 183 196 | 
             
            ### Handle Canner Authorization Failures
         | 
| 184 197 |  | 
| 185 198 | 
             
            When a user does stumble onto something they don't have access to you'll want to politely
         | 
| @@ -188,18 +201,18 @@ tell them about it and direct the app flow as you see fit. | |
| 188 201 | 
             
            To accomplish this in your application_controller.rb add
         | 
| 189 202 |  | 
| 190 203 | 
             
            ``` ruby
         | 
| 191 | 
            -
             | 
| 204 | 
            +
            rescue_from Canner::NotAuthorizedError, with: :user_not_authorized
         | 
| 192 205 | 
             
            ```
         | 
| 193 206 |  | 
| 194 207 | 
             
            You can name your method whatever you want.  Mine is user_not_authorized and looks like this:
         | 
| 195 208 |  | 
| 196 209 | 
             
            ``` ruby
         | 
| 197 | 
            -
             | 
| 210 | 
            +
            private
         | 
| 198 211 |  | 
| 199 | 
            -
             | 
| 200 | 
            -
             | 
| 201 | 
            -
             | 
| 202 | 
            -
             | 
| 212 | 
            +
            def user_not_authorized(exception)
         | 
| 213 | 
            +
              flash[:error] = exception.message
         | 
| 214 | 
            +
              redirect_to(request.referrer || root_path)
         | 
| 215 | 
            +
            end
         | 
| 203 216 | 
             
            ```
         | 
| 204 217 |  | 
| 205 218 | 
             
            ### Using can? in views
         | 
| @@ -228,4 +241,7 @@ would only be able to see the create customer link if they had an admin role. | |
| 228 241 | 
             
              end
         | 
| 229 242 | 
             
            ```
         | 
| 230 243 |  | 
| 244 | 
            +
            ## Testing
         | 
| 231 245 |  | 
| 246 | 
            +
            See the wiki for some testing tips
         | 
| 247 | 
            +
            [Testing](https://github.com/jacklin10/canner/wiki/Testing)
         | 
    
        data/canner.gemspec
    CHANGED
    
    | @@ -20,7 +20,7 @@ Gem::Specification.new do |gem| | |
| 20 20 | 
             
              gem.add_dependency "activesupport"
         | 
| 21 21 | 
             
              gem.add_development_dependency "activemodel"
         | 
| 22 22 | 
             
              gem.add_development_dependency "bundler", "~> 1.3"
         | 
| 23 | 
            -
              gem.add_development_dependency "rspec", "~>  | 
| 23 | 
            +
              gem.add_development_dependency "rspec", "~> 2.1"
         | 
| 24 24 | 
             
              gem.add_development_dependency "pry"
         | 
| 25 25 | 
             
              gem.add_development_dependency "rake"
         | 
| 26 26 | 
             
              gem.add_development_dependency "yard"
         | 
| @@ -0,0 +1,60 @@ | |
| 1 | 
            +
            module Canner
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              class Policy
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def initialize(current_user, method, current_branch=nil)
         | 
| 6 | 
            +
                  @current_user = current_user
         | 
| 7 | 
            +
                  @current_branch = current_branch
         | 
| 8 | 
            +
                  @method = method.to_sym
         | 
| 9 | 
            +
                  @roles = fetch_roles
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                # if you handle your roles differently you'll need to override.
         | 
| 13 | 
            +
                # use: rails g canner:fetch_roles
         | 
| 14 | 
            +
                # expects an array or strings or symbols that represent the user roles
         | 
| 15 | 
            +
                def fetch_roles
         | 
| 16 | 
            +
                  @current_user.roles
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                # implement in your policy class to auto scope in an action
         | 
| 20 | 
            +
                def canner_scope
         | 
| 21 | 
            +
                  raise ArgumentError.new("NOT IMPLEMENTED")
         | 
| 22 | 
            +
                  # ex:
         | 
| 23 | 
            +
                  # case @method
         | 
| 24 | 
            +
                  # when :index
         | 
| 25 | 
            +
                  #   User.by_branch(@current_branch)
         | 
| 26 | 
            +
                  # else
         | 
| 27 | 
            +
                  #   User.none
         | 
| 28 | 
            +
                  # end
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                # implment in your policy class.
         | 
| 32 | 
            +
                # return true when the user can access the action or resource and false when they can't
         | 
| 33 | 
            +
                def can?
         | 
| 34 | 
            +
                  raise ArgumentError.new("NOT IMPLEMENTED")
         | 
| 35 | 
            +
                  # ex:
         | 
| 36 | 
            +
                  # case @method
         | 
| 37 | 
            +
                  # when :index, :show
         | 
| 38 | 
            +
                  #   has_role?(:admin)
         | 
| 39 | 
            +
                  # else
         | 
| 40 | 
            +
                  #   false
         | 
| 41 | 
            +
                  # end
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                protected
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                def is_method?(methods)
         | 
| 47 | 
            +
                  prepare(methods).include?(@method)
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                def has_role?(roles)
         | 
| 51 | 
            +
                  begin
         | 
| 52 | 
            +
                    @roles.any?{|r| Util.prepare(roles).include?(r.to_sym) }
         | 
| 53 | 
            +
                  rescue Exception => e
         | 
| 54 | 
            +
                    raise ArgumentError.new "Canner: Problem fetching user roles. If current_user.roles isn't how you do it see wiki for overriding fetch_roles."
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
              end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
            end
         | 
    
        data/lib/canner/util.rb
    CHANGED
    
    
    
        data/lib/canner/version.rb
    CHANGED
    
    
    
        data/lib/canner.rb
    CHANGED
    
    | @@ -1,10 +1,19 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 1 | 
            +
            require 'active_support/core_ext/string'
         | 
| 2 | 
            +
            require "active_support/concern"
         | 
| 3 | 
            +
            require 'canner/policy'
         | 
| 4 | 
            +
            require 'canner/util'
         | 
| 5 | 
            +
             | 
| 3 6 | 
             
            module Canner
         | 
| 4 7 |  | 
| 8 | 
            +
              extend ActiveSupport::Concern
         | 
| 9 | 
            +
             | 
| 5 10 | 
             
              # so you don't have to have a helper method in the app_controller
         | 
| 6 | 
            -
               | 
| 7 | 
            -
                 | 
| 11 | 
            +
              included do
         | 
| 12 | 
            +
                if respond_to?(:helper_method)
         | 
| 13 | 
            +
                  helper_method :canner_policy
         | 
| 14 | 
            +
                  helper_method :canner_user
         | 
| 15 | 
            +
                  helper_method :canner_branch
         | 
| 16 | 
            +
                end
         | 
| 8 17 | 
             
              end
         | 
| 9 18 |  | 
| 10 19 | 
             
              class NotAuthorizedError < StandardError
         | 
| @@ -14,12 +23,21 @@ module Canner | |
| 14 23 | 
             
              class AuthNotUsedError < StandardError; end
         | 
| 15 24 | 
             
              class ScopeNotUsedError < StandardError; end
         | 
| 16 25 |  | 
| 26 | 
            +
              def auth_used
         | 
| 27 | 
            +
                @auth_used ||= false
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              def scope_used
         | 
| 31 | 
            +
                @scope_used ||= false
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
             | 
| 17 34 | 
             
              # method_name - The controller action method that you are concerned with access
         | 
| 18 35 | 
             
              # target_model - Name of the object you are limiting access to. ( :user, :pet, :customer )
         | 
| 19 36 | 
             
              # target_obj   - The instance obj for what you want to test.  ( does user 1 have access to company 1?)
         | 
| 20 37 | 
             
              def instance_can?(method_name, target_model, target_obj)
         | 
| 21 38 | 
             
                policy = canner_policy(method_name, target_model)
         | 
| 22 39 | 
             
                raise NotAuthorizedError.new("You do not have access to this #{target_model.capitalize}") unless policy.instance_can?(target_obj)
         | 
| 40 | 
            +
                true
         | 
| 23 41 | 
             
              end
         | 
| 24 42 |  | 
| 25 43 | 
             
              # method_name - The controller action method that you are concerned with access
         | 
| @@ -27,6 +45,7 @@ module Canner | |
| 27 45 | 
             
              def can?(method_name, target_model)
         | 
| 28 46 | 
             
                @auth_used = true
         | 
| 29 47 | 
             
                raise NotAuthorizedError.new("You are not authorized to perform this action.") unless canner_policy(method_name, target_model).can?
         | 
| 48 | 
            +
                true
         | 
| 30 49 | 
             
              end
         | 
| 31 50 |  | 
| 32 51 | 
             
              # method_name - The controller action method that you are concerned with access
         | 
| @@ -36,20 +55,32 @@ module Canner | |
| 36 55 | 
             
                canner_policy(method_name, target_model).canner_scope
         | 
| 37 56 | 
             
              end
         | 
| 38 57 |  | 
| 58 | 
            +
              # override this if your method for getting the current user isn't called current_user.
         | 
| 59 | 
            +
              def canner_user
         | 
| 60 | 
            +
                current_user
         | 
| 61 | 
            +
              end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
              # override this if your method for getting the current branch isn't called current_branch.
         | 
| 64 | 
            +
              def canner_branch
         | 
| 65 | 
            +
                current_branch
         | 
| 66 | 
            +
              end
         | 
| 67 | 
            +
             | 
| 39 68 | 
             
              protected
         | 
| 40 69 |  | 
| 41 70 | 
             
              def ensure_scope
         | 
| 42 71 | 
             
                return if devise_controller? rescue false
         | 
| 43 | 
            -
                raise ScopeNotUsedError.new("Must use a canner_scope or exclude this action from the after_action") unless  | 
| 72 | 
            +
                raise ScopeNotUsedError.new("Must use a canner_scope or exclude this action from the after_action") unless scope_used
         | 
| 73 | 
            +
                true
         | 
| 44 74 | 
             
              end
         | 
| 45 75 |  | 
| 46 76 | 
             
              def ensure_auth
         | 
| 47 77 | 
             
                return if devise_controller? rescue false
         | 
| 48 | 
            -
                raise AuthNotUsedError.new("Must use can? method or exclude this action from the after_action") unless  | 
| 78 | 
            +
                raise AuthNotUsedError.new("Must use can? method or exclude this action from the after_action") unless auth_used
         | 
| 79 | 
            +
                true
         | 
| 49 80 | 
             
              end
         | 
| 50 81 |  | 
| 51 82 | 
             
              def canner_policy(method_name, target_model)
         | 
| 52 | 
            -
                derive_class_name(target_model).constantize.new( | 
| 83 | 
            +
                derive_class_name(target_model).constantize.new(canner_user, method_name, canner_branch)
         | 
| 53 84 | 
             
              end
         | 
| 54 85 |  | 
| 55 86 | 
             
              def derive_class_name(target_model)
         | 
| @@ -1,8 +1,14 @@ | |
| 1 1 | 
             
            Description:
         | 
| 2 | 
            -
             | 
| 2 | 
            +
              Generates a policy for a model with the given name.
         | 
| 3 3 |  | 
| 4 | 
            -
            Example:
         | 
| 4 | 
            +
              Example:
         | 
| 5 5 | 
             
                rails generate canner:policy user
         | 
| 6 6 |  | 
| 7 7 | 
             
                This will create:
         | 
| 8 | 
            -
             | 
| 8 | 
            +
                  app/policies/user_policy.rb
         | 
| 9 | 
            +
              
         | 
| 10 | 
            +
              Note: 
         | 
| 11 | 
            +
                If you have overridden fetch_roles, or created a base policy of your own you'll want to pass
         | 
| 12 | 
            +
                the parent option and specify your parent.
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                rails generate canner:policy user --parent BasePolicy
         | 
| @@ -2,12 +2,24 @@ module Canner | |
| 2 2 | 
             
              module Generators
         | 
| 3 3 | 
             
                class PolicyGenerator < ::Rails::Generators::NamedBase
         | 
| 4 4 | 
             
                  source_root File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
         | 
| 5 | 
            +
                  check_class_collision suffix: "Policy"
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                  class_option :parent, type: :string, desc: "The parent class for the generated policy"
         | 
| 5 8 |  | 
| 6 9 | 
             
                  def create_policy
         | 
| 7 10 | 
             
                    template 'policy.rb', File.join('app/policies', class_path, "#{file_name}_policy.rb")
         | 
| 8 11 | 
             
                  end
         | 
| 9 12 |  | 
| 10 13 | 
             
                  hook_for :test_framework
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  private
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  def parent_class_name
         | 
| 18 | 
            +
                    options.fetch("parent") do
         | 
| 19 | 
            +
                      Canner::Policy
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
             | 
| 11 23 | 
             
                end
         | 
| 12 24 | 
             
              end
         | 
| 13 25 | 
             
            end
         | 
| @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            module TestUnit
         | 
| 2 | 
            +
              module Generators
         | 
| 3 | 
            +
                class PolicyGenerator < ::Rails::Generators::NamedBase
         | 
| 4 | 
            +
                  source_root File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  def create_policy_test
         | 
| 7 | 
            +
                    template 'policy_test.rb', File.join('test/policies', class_path, "#{file_name}_policy_test.rb")
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
            end
         | 
    
        data/spec/canner_spec.rb
    ADDED
    
    | @@ -0,0 +1,151 @@ | |
| 1 | 
            +
            require "spec_helper"
         | 
| 2 | 
            +
            require "canner"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class Sample
         | 
| 5 | 
            +
            end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            class SamplePolicy
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              def initialize(current_user, method, current_branch)
         | 
| 10 | 
            +
                @current_user = current_user
         | 
| 11 | 
            +
                @current_branch = current_branch
         | 
| 12 | 
            +
                @method = method.to_sym
         | 
| 13 | 
            +
                @roles = fetch_roles
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              def fetch_roles
         | 
| 17 | 
            +
                # ['admin']
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              def canner_scope
         | 
| 21 | 
            +
                # [Sample.new]
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            class AppController
         | 
| 27 | 
            +
              include Canner
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              attr_reader :current_user, :current_branch, :params
         | 
| 30 | 
            +
            end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            describe Canner do
         | 
| 33 | 
            +
              let(:user) { double }
         | 
| 34 | 
            +
              let(:branch) { double }
         | 
| 35 | 
            +
              let(:app_controller) { AppController.new }
         | 
| 36 | 
            +
              let(:sample_policy) {SamplePolicy.new(user, 'index', branch) }
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              describe "instance_can?" do
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                it "should call the policy's instance_can method" do
         | 
| 41 | 
            +
                  expect(app_controller).to receive(:canner_policy).and_return(sample_policy)
         | 
| 42 | 
            +
                  expect(sample_policy).to receive(:instance_can?).and_return true
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  app_controller.instance_can?('test', 'sample', Sample.new)
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                it "should raise a NotAuthorizedError if the policy's instance_can? returns false" do
         | 
| 48 | 
            +
                  expect(app_controller).to receive(:canner_policy).and_return(sample_policy)
         | 
| 49 | 
            +
                  expect(sample_policy).to receive(:instance_can?).and_return false
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  expect { app_controller.instance_can?('test', 'sample', Sample.new) }.to raise_error(Canner::NotAuthorizedError)
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                it "should return true if the policy allows access to the instance" do
         | 
| 55 | 
            +
                  expect(app_controller).to receive(:canner_policy).and_return(sample_policy)
         | 
| 56 | 
            +
                  expect(sample_policy).to receive(:instance_can?).and_return true
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  app_controller.instance_can?('test', 'sample', Sample.new).should be_truthy
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
              end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
              describe "can?" do
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                it "should call the policy's can? method" do
         | 
| 66 | 
            +
                  expect(app_controller).to receive(:canner_policy).and_return(sample_policy)
         | 
| 67 | 
            +
                  expect(sample_policy).to receive(:can?).and_return true
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                  app_controller.can?('test', 'sample')
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                it "should raise a NotAuthorized error if the policy's can? returns false" do
         | 
| 73 | 
            +
                  expect(app_controller).to receive(:canner_policy).and_return(sample_policy)
         | 
| 74 | 
            +
                  expect(sample_policy).to receive(:can?).and_return false
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                  expect { app_controller.can?('test', 'sample') }.to raise_error(Canner::NotAuthorizedError)
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                it "should return true if the policy's can? permits access" do
         | 
| 80 | 
            +
                  expect(app_controller).to receive(:canner_policy).and_return(sample_policy)
         | 
| 81 | 
            +
                  expect(sample_policy).to receive(:can?).and_return true
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                  expect(app_controller.can?('test', 'sample')).to eq true
         | 
| 84 | 
            +
                end
         | 
| 85 | 
            +
             | 
| 86 | 
            +
              end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
              describe "canner_scope" do
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                it "should call the policy's canner_scope" do
         | 
| 91 | 
            +
                  expect(app_controller).to receive(:canner_policy).and_return(sample_policy)
         | 
| 92 | 
            +
                  expect(sample_policy).to receive(:canner_scope)
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                  app_controller.canner_scope('test', 'sample')
         | 
| 95 | 
            +
                end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
              end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
              describe "ensure_scope" do
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                it "should not raise an error if canner_scope was called" do
         | 
| 102 | 
            +
                  expect(app_controller).to receive(:canner_policy).and_return(sample_policy)
         | 
| 103 | 
            +
                  expect(sample_policy).to receive(:canner_scope).and_return(true)
         | 
| 104 | 
            +
                  app_controller.canner_scope('test', 'sample')
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                  expect(app_controller.send(:ensure_scope)).to be_truthy
         | 
| 107 | 
            +
                end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                it "should raise error if canner_scope was not called" do
         | 
| 110 | 
            +
                  expect { app_controller.send(:ensure_scope) }.to raise_error(Canner::ScopeNotUsedError)
         | 
| 111 | 
            +
                end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
              end
         | 
| 114 | 
            +
             | 
| 115 | 
            +
              describe "ensure_auth" do
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                it "should not raise an error if can? was called" do
         | 
| 118 | 
            +
                  expect(app_controller).to receive(:canner_policy).and_return(sample_policy)
         | 
| 119 | 
            +
                  expect(sample_policy).to receive(:can?).and_return(true)
         | 
| 120 | 
            +
                  app_controller.can?('test', 'sample')
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                  expect(app_controller.send(:ensure_auth)).to be_truthy
         | 
| 123 | 
            +
                end
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                it "should raise error if can? was not called" do
         | 
| 126 | 
            +
                  expect { app_controller.send(:ensure_auth) }.to raise_error(Canner::AuthNotUsedError)
         | 
| 127 | 
            +
                end
         | 
| 128 | 
            +
             | 
| 129 | 
            +
              end
         | 
| 130 | 
            +
             | 
| 131 | 
            +
              describe "canner_policy" do
         | 
| 132 | 
            +
             | 
| 133 | 
            +
                it "should instantiate the proper policy class" do
         | 
| 134 | 
            +
                  expect(app_controller).to receive(:canner_user).and_return user
         | 
| 135 | 
            +
                  expect(app_controller).to receive(:canner_branch).and_return branch
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                  expect(app_controller.send(:canner_policy, 'test', 'sample')).to be_a SamplePolicy
         | 
| 138 | 
            +
                end
         | 
| 139 | 
            +
             | 
| 140 | 
            +
              end
         | 
| 141 | 
            +
             | 
| 142 | 
            +
              describe "derive_class_name" do
         | 
| 143 | 
            +
             | 
| 144 | 
            +
                it "should return the proper policy class name from the model" do
         | 
| 145 | 
            +
                  expect(app_controller.send(:derive_class_name, 'sample')).to eq "SamplePolicy"
         | 
| 146 | 
            +
                  expect(app_controller.send(:derive_class_name, 'samples')).to eq "SamplePolicy"
         | 
| 147 | 
            +
                end
         | 
| 148 | 
            +
             | 
| 149 | 
            +
              end
         | 
| 150 | 
            +
             | 
| 151 | 
            +
            end
         | 
    
        data/spec/spec_helper.rb
    ADDED
    
    | @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            # This file was generated by the `rspec --init` command. Conventionally, all
         | 
| 2 | 
            +
            # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
         | 
| 3 | 
            +
            # Require this file using `require "spec_helper"` to ensure that it is only
         | 
| 4 | 
            +
            # loaded once.
         | 
| 5 | 
            +
            #
         | 
| 6 | 
            +
            # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
         | 
| 7 | 
            +
            RSpec.configure do |config|
         | 
| 8 | 
            +
              config.treat_symbols_as_metadata_keys_with_true_values = true
         | 
| 9 | 
            +
              config.run_all_when_everything_filtered = true
         | 
| 10 | 
            +
              config.filter_run :focus
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              # Run specs in random order to surface order dependencies. If you find an
         | 
| 13 | 
            +
              # order dependency and want to debug it, you can fix the order by providing
         | 
| 14 | 
            +
              # the seed, which is printed after each run.
         | 
| 15 | 
            +
              #     --seed 1234
         | 
| 16 | 
            +
              config.order = 'random'
         | 
| 17 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,111 +1,111 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: canner
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0 | 
| 4 | 
            +
              version: 0.1.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Joe Acklin
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2014- | 
| 11 | 
            +
            date: 2014-08-29 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: activesupport
         | 
| 15 15 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 16 | 
             
                requirements:
         | 
| 17 | 
            -
                - -  | 
| 17 | 
            +
                - - '>='
         | 
| 18 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 19 | 
             
                    version: '0'
         | 
| 20 20 | 
             
              type: :runtime
         | 
| 21 21 | 
             
              prerelease: false
         | 
| 22 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 23 | 
             
                requirements:
         | 
| 24 | 
            -
                - -  | 
| 24 | 
            +
                - - '>='
         | 
| 25 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 26 | 
             
                    version: '0'
         | 
| 27 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 28 | 
             
              name: activemodel
         | 
| 29 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 30 | 
             
                requirements:
         | 
| 31 | 
            -
                - -  | 
| 31 | 
            +
                - - '>='
         | 
| 32 32 | 
             
                  - !ruby/object:Gem::Version
         | 
| 33 33 | 
             
                    version: '0'
         | 
| 34 34 | 
             
              type: :development
         | 
| 35 35 | 
             
              prerelease: false
         | 
| 36 36 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 37 | 
             
                requirements:
         | 
| 38 | 
            -
                - -  | 
| 38 | 
            +
                - - '>='
         | 
| 39 39 | 
             
                  - !ruby/object:Gem::Version
         | 
| 40 40 | 
             
                    version: '0'
         | 
| 41 41 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 42 42 | 
             
              name: bundler
         | 
| 43 43 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 44 | 
             
                requirements:
         | 
| 45 | 
            -
                - -  | 
| 45 | 
            +
                - - ~>
         | 
| 46 46 | 
             
                  - !ruby/object:Gem::Version
         | 
| 47 47 | 
             
                    version: '1.3'
         | 
| 48 48 | 
             
              type: :development
         | 
| 49 49 | 
             
              prerelease: false
         | 
| 50 50 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 51 | 
             
                requirements:
         | 
| 52 | 
            -
                - -  | 
| 52 | 
            +
                - - ~>
         | 
| 53 53 | 
             
                  - !ruby/object:Gem::Version
         | 
| 54 54 | 
             
                    version: '1.3'
         | 
| 55 55 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 56 56 | 
             
              name: rspec
         | 
| 57 57 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 58 | 
             
                requirements:
         | 
| 59 | 
            -
                - -  | 
| 59 | 
            +
                - - ~>
         | 
| 60 60 | 
             
                  - !ruby/object:Gem::Version
         | 
| 61 | 
            -
                    version: ' | 
| 61 | 
            +
                    version: '2.1'
         | 
| 62 62 | 
             
              type: :development
         | 
| 63 63 | 
             
              prerelease: false
         | 
| 64 64 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 65 65 | 
             
                requirements:
         | 
| 66 | 
            -
                - -  | 
| 66 | 
            +
                - - ~>
         | 
| 67 67 | 
             
                  - !ruby/object:Gem::Version
         | 
| 68 | 
            -
                    version: ' | 
| 68 | 
            +
                    version: '2.1'
         | 
| 69 69 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 70 70 | 
             
              name: pry
         | 
| 71 71 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 72 72 | 
             
                requirements:
         | 
| 73 | 
            -
                - -  | 
| 73 | 
            +
                - - '>='
         | 
| 74 74 | 
             
                  - !ruby/object:Gem::Version
         | 
| 75 75 | 
             
                    version: '0'
         | 
| 76 76 | 
             
              type: :development
         | 
| 77 77 | 
             
              prerelease: false
         | 
| 78 78 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 79 79 | 
             
                requirements:
         | 
| 80 | 
            -
                - -  | 
| 80 | 
            +
                - - '>='
         | 
| 81 81 | 
             
                  - !ruby/object:Gem::Version
         | 
| 82 82 | 
             
                    version: '0'
         | 
| 83 83 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 84 84 | 
             
              name: rake
         | 
| 85 85 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 86 86 | 
             
                requirements:
         | 
| 87 | 
            -
                - -  | 
| 87 | 
            +
                - - '>='
         | 
| 88 88 | 
             
                  - !ruby/object:Gem::Version
         | 
| 89 89 | 
             
                    version: '0'
         | 
| 90 90 | 
             
              type: :development
         | 
| 91 91 | 
             
              prerelease: false
         | 
| 92 92 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 93 93 | 
             
                requirements:
         | 
| 94 | 
            -
                - -  | 
| 94 | 
            +
                - - '>='
         | 
| 95 95 | 
             
                  - !ruby/object:Gem::Version
         | 
| 96 96 | 
             
                    version: '0'
         | 
| 97 97 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 98 98 | 
             
              name: yard
         | 
| 99 99 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 100 100 | 
             
                requirements:
         | 
| 101 | 
            -
                - -  | 
| 101 | 
            +
                - - '>='
         | 
| 102 102 | 
             
                  - !ruby/object:Gem::Version
         | 
| 103 103 | 
             
                    version: '0'
         | 
| 104 104 | 
             
              type: :development
         | 
| 105 105 | 
             
              prerelease: false
         | 
| 106 106 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 107 107 | 
             
                requirements:
         | 
| 108 | 
            -
                - -  | 
| 108 | 
            +
                - - '>='
         | 
| 109 109 | 
             
                  - !ruby/object:Gem::Version
         | 
| 110 110 | 
             
                    version: '0'
         | 
| 111 111 | 
             
            description: No magic authorization for Rails
         | 
| @@ -115,25 +115,28 @@ executables: [] | |
| 115 115 | 
             
            extensions: []
         | 
| 116 116 | 
             
            extra_rdoc_files: []
         | 
| 117 117 | 
             
            files:
         | 
| 118 | 
            -
            -  | 
| 118 | 
            +
            - .gitignore
         | 
| 119 119 | 
             
            - Gemfile
         | 
| 120 120 | 
             
            - LICENSE
         | 
| 121 121 | 
             
            - README.md
         | 
| 122 122 | 
             
            - Rakefile
         | 
| 123 123 | 
             
            - canner.gemspec
         | 
| 124 124 | 
             
            - lib/canner.rb
         | 
| 125 | 
            -
            - lib/canner/ | 
| 125 | 
            +
            - lib/canner/policy.rb
         | 
| 126 126 | 
             
            - lib/canner/util.rb
         | 
| 127 127 | 
             
            - lib/canner/version.rb
         | 
| 128 | 
            -
            - lib/generators/canner/ | 
| 129 | 
            -
            - lib/generators/canner/ | 
| 130 | 
            -
            - lib/generators/canner/ | 
| 128 | 
            +
            - lib/generators/canner/fetch_roles/USAGE
         | 
| 129 | 
            +
            - lib/generators/canner/fetch_roles/fetch_roles_generator.rb
         | 
| 130 | 
            +
            - lib/generators/canner/fetch_roles/templates/base_policy.rb
         | 
| 131 131 | 
             
            - lib/generators/canner/policy/USAGE
         | 
| 132 132 | 
             
            - lib/generators/canner/policy/policy_generator.rb
         | 
| 133 133 | 
             
            - lib/generators/canner/policy/templates/policy.rb
         | 
| 134 134 | 
             
            - lib/generators/rspec/policy_generator.rb
         | 
| 135 135 | 
             
            - lib/generators/rspec/templates/policy_spec.rb
         | 
| 136 | 
            -
            -  | 
| 136 | 
            +
            - lib/generators/test_unit/policy_generator.rb
         | 
| 137 | 
            +
            - lib/generators/test_unit/templates/policy_test.rb
         | 
| 138 | 
            +
            - spec/canner_spec.rb
         | 
| 139 | 
            +
            - spec/spec_helper.rb
         | 
| 137 140 | 
             
            homepage: https://github.com/jacklin10/canner
         | 
| 138 141 | 
             
            licenses:
         | 
| 139 142 | 
             
            - MIT
         | 
| @@ -144,19 +147,21 @@ require_paths: | |
| 144 147 | 
             
            - lib
         | 
| 145 148 | 
             
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 146 149 | 
             
              requirements:
         | 
| 147 | 
            -
              - -  | 
| 150 | 
            +
              - - '>='
         | 
| 148 151 | 
             
                - !ruby/object:Gem::Version
         | 
| 149 152 | 
             
                  version: '0'
         | 
| 150 153 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 151 154 | 
             
              requirements:
         | 
| 152 | 
            -
              - -  | 
| 155 | 
            +
              - - '>='
         | 
| 153 156 | 
             
                - !ruby/object:Gem::Version
         | 
| 154 157 | 
             
                  version: '0'
         | 
| 155 158 | 
             
            requirements: []
         | 
| 156 159 | 
             
            rubyforge_project: 
         | 
| 157 | 
            -
            rubygems_version: 2.4. | 
| 160 | 
            +
            rubygems_version: 2.4.1
         | 
| 158 161 | 
             
            signing_key: 
         | 
| 159 162 | 
             
            specification_version: 4
         | 
| 160 163 | 
             
            summary: Rails Auth
         | 
| 161 164 | 
             
            test_files:
         | 
| 162 | 
            -
            - spec/ | 
| 165 | 
            +
            - spec/canner_spec.rb
         | 
| 166 | 
            +
            - spec/spec_helper.rb
         | 
| 167 | 
            +
            has_rdoc: 
         | 
    
        data/lib/canner/rspec.rb
    DELETED
    
    | 
            File without changes
         | 
| @@ -1,52 +0,0 @@ | |
| 1 | 
            -
            class BasePolicy
         | 
| 2 | 
            -
             | 
| 3 | 
            -
              def initialize(current_user, current_branch, method)
         | 
| 4 | 
            -
                @current_user = current_user
         | 
| 5 | 
            -
                @current_branch = current_branch
         | 
| 6 | 
            -
                @method = method.to_sym
         | 
| 7 | 
            -
                @roles = fetch_roles
         | 
| 8 | 
            -
              end
         | 
| 9 | 
            -
             | 
| 10 | 
            -
              # implement this in your policy class
         | 
| 11 | 
            -
              # expects an array or strings or symbols that represent the user roles
         | 
| 12 | 
            -
              def fetch_roles
         | 
| 13 | 
            -
                raise ArgumentError.new("YOU NEED TO IMPLEMENT")
         | 
| 14 | 
            -
                # ex. User.roles
         | 
| 15 | 
            -
              end
         | 
| 16 | 
            -
             | 
| 17 | 
            -
              # implement in your policy class to auto scope in an action
         | 
| 18 | 
            -
              def canner_scope
         | 
| 19 | 
            -
                raise ArgumentError.new("NOT IMPLEMENTED")
         | 
| 20 | 
            -
                # ex:
         | 
| 21 | 
            -
                # case @method
         | 
| 22 | 
            -
                # when :index
         | 
| 23 | 
            -
                #   User.by_branch(@current_branch)
         | 
| 24 | 
            -
                # else
         | 
| 25 | 
            -
                #   User.none
         | 
| 26 | 
            -
                # end
         | 
| 27 | 
            -
              end
         | 
| 28 | 
            -
             | 
| 29 | 
            -
              # implment in your policy class.
         | 
| 30 | 
            -
              # return true when the user can access the action or resource and false when they can't
         | 
| 31 | 
            -
              def can?
         | 
| 32 | 
            -
                raise ArgumentError.new("NOT IMPLEMENTED")
         | 
| 33 | 
            -
                # ex:
         | 
| 34 | 
            -
                # case @method
         | 
| 35 | 
            -
                # when :index, :show
         | 
| 36 | 
            -
                #   has_role?(:admin)
         | 
| 37 | 
            -
                # else
         | 
| 38 | 
            -
                #   false
         | 
| 39 | 
            -
                # end
         | 
| 40 | 
            -
              end
         | 
| 41 | 
            -
             | 
| 42 | 
            -
              protected
         | 
| 43 | 
            -
             | 
| 44 | 
            -
              def is_method?(methods)
         | 
| 45 | 
            -
                prepare(methods).include?(@method)
         | 
| 46 | 
            -
              end
         | 
| 47 | 
            -
             | 
| 48 | 
            -
              def has_role?(roles)
         | 
| 49 | 
            -
                @roles.any?{|r| prepare(roles).include?(r.to_sym) }
         | 
| 50 | 
            -
              end
         | 
| 51 | 
            -
             | 
| 52 | 
            -
            end
         | 
    
        data/spec/Gemfile
    DELETED