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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d4c1916c358ac2040e5e7af1b5f458694f1d7556
4
- data.tar.gz: 48e86af5958f48b6ce380c3352ab959f9bbcdf54
3
+ metadata.gz: 5fe7375f518e4b28b54badd6031ace79365f8105
4
+ data.tar.gz: 8939b3f2f12e4a4dbb6cb4cf76e288369bbf0e5f
5
5
  SHA512:
6
- metadata.gz: 8ad895fff72a54398cbe5fd46fffdb5484c09f11cbd3a345d5e2519fd6469ec2b3c94f2c837dadbc99582ef59d5f8f9ac70befba74fc4a5af8316d45b5176d83
7
- data.tar.gz: da99f014df61265620e9ae56cdb8af833d852b0e71b0fc6a3bbdd91ecea5b13854ee420138ff817305fa57938238f4087e87b888eae451f0c5a4c567adc1d8c5
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
- Who needs another auth gem? There's a bunch of very good ones out there.
9
- Pundit, cancan, cancancan, Declarative Authorization to name a few very good alternatives.
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
- Unfortunately none of those solutions had built in support for a requirement I had on a project.
12
- My application needed to authorize a user at a given store location.
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
- Suppose I opened a store in Pittsburgh named Joe's Hash Rockets. The word quickly got around that Joe's
15
- hash rockets are the best in town! Business is booming and after some market research I determine that
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
- The problem is that I have some reports that only the store manager should see.
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
- Canner takes this additional layer of authorization in to account.
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
- To do this in other libraries you might find yourself creating roles like
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
- Restart your server
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 model_namePolicy.rb.
75
- i.e UserPolicy, CustomerPolicy, AppPolicy.
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
- The canner_scope method is used to scope the models consistently in your app.
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
- ### can?
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
- You probably recognize this method from Ryan Bates' cancan gem. The idea is the same as well.
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 to your
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
- rescue_from Canner::NotAuthorizedError, with: :user_not_authorized
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
- private
210
+ private
198
211
 
199
- def user_not_authorized(exception)
200
- flash[:error] = exception.message
201
- redirect_to(request.referrer || root_path)
202
- end
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", "~> 3.0"
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
@@ -13,7 +13,7 @@ class Util
13
13
 
14
14
  # ensure given roles are in the form of an array
15
15
  def arrayify(roles)
16
- roles.class == Array ? roles : [roles].flatten
16
+ Array.wrap(roles).flatten
17
17
  end
18
18
 
19
19
  end
@@ -1,3 +1,3 @@
1
1
  module Canner
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
data/lib/canner.rb CHANGED
@@ -1,10 +1,19 @@
1
- # ASSUMES that your permissions policy is in a file with the same name as your model but with Perm.
2
- # i.e UserPerm, CustomerPerm
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
- def self.included(c)
7
- c.helper_method :canner_policy
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 @scope_used
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 @auth_used
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(current_user, current_branch, method_name)
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)
@@ -0,0 +1,3 @@
1
+ Description:
2
+ Generates a base_policy.rb and a stub for the fetch_roles method.
3
+ rails g canner:fetch_roles
@@ -1,6 +1,6 @@
1
1
  module Canner
2
2
  module Generators
3
- class InstallGenerator < ::Rails::Generators::Base
3
+ class FetchRolesGenerator < ::Rails::Generators::Base
4
4
  source_root File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
5
5
 
6
6
  def copy_application_policy
@@ -0,0 +1,8 @@
1
+ class BasePolicy < Canner::Policy
2
+
3
+ # results expected to be an array or strings or symbols that represent the user roles
4
+ def fetch_roles
5
+ @current_user.roles
6
+ end
7
+
8
+ end
@@ -1,8 +1,14 @@
1
1
  Description:
2
- Generates a policy for a model with the given name.
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
- app/policies/user_policy.rb
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
@@ -1,5 +1,5 @@
1
1
  <% module_namespacing do -%>
2
- class <%= class_name %>Policy < BasePolicy
2
+ class <%= class_name %>Policy < <%= parent_class_name %>
3
3
 
4
4
  def canner_scope
5
5
  case @method
@@ -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
@@ -0,0 +1,11 @@
1
+ require 'test_helper'
2
+
3
+ class <%= class_name %>PolicyTest < ActiveSupport::TestCase
4
+
5
+ def can?
6
+ end
7
+
8
+ def canner_scope
9
+ end
10
+
11
+ end
@@ -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
@@ -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.2
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-07-17 00:00:00.000000000 Z
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: '3.0'
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: '3.0'
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
- - ".gitignore"
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/rspec.rb
125
+ - lib/canner/policy.rb
126
126
  - lib/canner/util.rb
127
127
  - lib/canner/version.rb
128
- - lib/generators/canner/install/USAGE
129
- - lib/generators/canner/install/install_generator.rb
130
- - lib/generators/canner/install/templates/base_policy.rb
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
- - spec/Gemfile
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.0
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/Gemfile
165
+ - spec/canner_spec.rb
166
+ - spec/spec_helper.rb
167
+ has_rdoc:
data/lib/canner/rspec.rb DELETED
File without changes
@@ -1,2 +0,0 @@
1
- Description:
2
- Generates the canner base policy. All your policies need to inherit from this policy.
@@ -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
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in canner.gemspec
4
- gemspec