critic 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 119a637d018051dfe1517011f155c2d78155ccdc
4
- data.tar.gz: eb1a100714ade7c9d2b8e15f1bd99b023fe07a1c
3
+ metadata.gz: '0119b15b73b4b634a8094d17b84a57d1a184a4ac'
4
+ data.tar.gz: 695b82b9e3aef373a73b23fa865e67ed4cd0e896
5
5
  SHA512:
6
- metadata.gz: 0a0e3a0ec214a2a081a3b3725e2271f9bd5e975195f3663c7015600f2647d406a60ffa4c0363bd60e6071a63077a5fbd9cbaec9365102dad49ba98711f267901
7
- data.tar.gz: ea2def4856cc138ed661bc309cf48c64ab5820e111e9f60a5f5e89581610c60a7aa04d2a4786f438548f7e83df297587a3075abd085c45ad0829689b1e00bc12
6
+ metadata.gz: e006d30bcdfced9e3eb957cc8ddb80418b894213eab82f3b8f0f520282eaf47e3c76b6120ff23da6ad153886476bf7b12b1833aba6f1924e42f9b9925b13d7ed
7
+ data.tar.gz: 7f8256287c97d17118eb0f33665602d63364657fd6b9dbe0fac96bd9cb6ad2221e0ede3a68bb50c7c488dc35b7c2b69c8ccddff8138c2edc7b80a5e2b07379ce
data/.gitignore CHANGED
@@ -9,3 +9,4 @@
9
9
  /tmp/
10
10
  spec/examples.txt
11
11
  *.gem
12
+ gemfiles/
data/.travis.yml CHANGED
@@ -4,8 +4,14 @@ cache:
4
4
  - bundler
5
5
  rvm:
6
6
  - 2.3.0
7
- script:
7
+ before_script:
8
+ - bundle install
9
+ script:
8
10
  - bundle exec rake rubocop
9
11
  - bundle exec rake spec
10
12
  notifications:
11
13
  email: false
14
+ gemfile:
15
+ - gemfiles/activesupport_5.gemfile
16
+ - gemfiles/activesupport_4.gemfile
17
+ - gemfiles/activesupport_3.gemfile
data/Appraisals ADDED
@@ -0,0 +1,11 @@
1
+ appraise "activesupport-5" do
2
+ gem "activesupport", '~> 5.0'
3
+ end
4
+
5
+ appraise "activesupport-4" do
6
+ gem "activesupport", '~> 4.2'
7
+ end
8
+
9
+ appraise "activesupport-3" do
10
+ gem "activesupport", '~> 3.2'
11
+ end
data/CHANGELOG.md ADDED
@@ -0,0 +1,22 @@
1
+ # Change Log
2
+
3
+ ## [Unreleased](https://github.com/lanej/critic/tree/HEAD)
4
+
5
+ [Full Changelog](https://github.com/lanej/critic/compare/v0.2.0...HEAD)
6
+
7
+ **Merged pull requests:**
8
+
9
+ - chore: loosen activesupport requirement and test versions [\#3](https://github.com/lanej/critic/pull/3) ([lanej](https://github.com/lanej))
10
+ - add MIT license [\#2](https://github.com/lanej/critic/pull/2) ([thommahoney](https://github.com/thommahoney))
11
+
12
+ ## [v0.2.0](https://github.com/lanej/critic/tree/v0.2.0) (2016-06-22)
13
+ [Full Changelog](https://github.com/lanej/critic/compare/v0.1.1...v0.2.0)
14
+
15
+ **Merged pull requests:**
16
+
17
+ - add callbacks to `Critic::Policy\#authorize` [\#1](https://github.com/lanej/critic/pull/1) ([lanej](https://github.com/lanej))
18
+
19
+ ## [v0.1.1](https://github.com/lanej/critic/tree/v0.1.1) (2016-06-07)
20
+
21
+
22
+ \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
data/Gemfile CHANGED
@@ -5,7 +5,8 @@ source 'https://rubygems.org'
5
5
  gemspec
6
6
 
7
7
  gem 'activesupport', '~> 3.2.22', require: false
8
- gem 'rubocop', '~> 0.40', require: false
8
+ gem 'appraisal', '~> 2.1'
9
+ gem 'rubocop', '~> 0.46.0', require: false
9
10
 
10
11
  group :test do
11
12
  gem 'pry-nav'
data/LICENSE.txt ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2016 Joshua Lane
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -46,7 +46,7 @@ The most basic actions return `true` or `false` to indicate the authorization st
46
46
  class PostPolicy
47
47
  include Critic::Policy
48
48
 
49
- def update
49
+ def update?
50
50
  !resource.locked
51
51
  end
52
52
  end
@@ -60,15 +60,15 @@ Verify authorization using `#authorize`.
60
60
  Post = Struct.new(:locked)
61
61
  User = Struct.new
62
62
 
63
- PostPolicy.authorize(:update, User.new, Post.new(false)).granted? #=> true
64
- PostPolicy.authorize(:update, User.new, Post.new(true)).granted? #=> false
63
+ PostPolicy.authorize(:update?, User.new, Post.new(false)).granted? #=> true
64
+ PostPolicy.authorize(:update?, User.new, Post.new(true)).granted? #=> false
65
65
  ```
66
66
 
67
67
  #### Scopes
68
68
 
69
69
  Scopes treat `resource` as a starting point and return a restricted set of associated resources. Policies can have any number of scopes. The default scope is `#index`.
70
70
 
71
- ```
71
+ ```ruby
72
72
  # app/policies/post_policy.rb
73
73
  class PostPolicy
74
74
  include Critic::Policy
@@ -79,6 +79,40 @@ class PostPolicy
79
79
  end
80
80
  ```
81
81
 
82
+ #### Convention
83
+
84
+ It can be a useful convention to add a `?` suffix to your action methods. This allows a clear separation between actions and scopes. All other methods should be `protected`, similar to Rails controller.
85
+
86
+ ```ruby
87
+ # app/policies/post_policy.rb
88
+ class PostPolicy
89
+ include Critic::Policy
90
+
91
+ # default scope
92
+ def index
93
+ Post.where(published: true)
94
+ end
95
+
96
+ # custom scope
97
+ def author_index
98
+ Post.where(author_id: subject.id)
99
+ end
100
+
101
+ # action
102
+ def show?
103
+ (post.draft? && authored_post?) || post.published?
104
+ end
105
+
106
+ protected
107
+
108
+ alias post resource
109
+
110
+ def authored_post?
111
+ subject == post.author
112
+ end
113
+ end
114
+ ```
115
+
82
116
  ### Controller
83
117
 
84
118
  Controllers are the primary consumer of policies. Controllers ask the policy if an authenticated subject is authorized to perform a specific action on a specific resource.
@@ -127,8 +161,12 @@ class PostController < Sinatra::Base
127
161
  post.to_json
128
162
  end
129
163
  end
164
+
165
+
130
166
  ```
131
167
 
168
+ #### Custom subject
169
+
132
170
  By default, the policy's subject is referenced by `current_user`. Override `critic` to customize.
133
171
 
134
172
  ```ruby
@@ -144,9 +182,43 @@ class ApplicationController < ActionController::Base
144
182
  end
145
183
  ```
146
184
 
185
+ #### Custom policy
186
+
187
+ The default policy for a resource is referenced by the resoure class name. For instance, Critic will look for a `PostPolicy` for a `Post.new` object. You can set a custom policy for the entire controller by overriding the `policy` method.
188
+
189
+ ```ruby
190
+ # app/controllers/post_controller.rb
191
+ class PostController < ActionController::Base
192
+ include Critic::Controller
193
+
194
+ protected
195
+
196
+ def policy(_resource)
197
+ V2::PostPolicy
198
+ end
199
+ end
200
+ ```
201
+
202
+ You can also provide a specific policy when calling `authorize`
203
+
204
+ ```ruby
205
+ # app/controllers/post_controller.rb
206
+ class PostController < ActionController::Base
207
+ include Critic::Controller
208
+
209
+ def show
210
+ post = Post.find(params[:id])
211
+ authorize post, policy: V2::PostPolicy
212
+
213
+ render json: post
214
+ end
215
+ end
216
+ ```
217
+
147
218
 
148
219
  #### Testing
149
220
 
221
+ `bundle exec rake spec`
150
222
 
151
223
  ## Development
152
224
 
@@ -157,4 +229,3 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
157
229
  ## Contributing
158
230
 
159
231
  Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/critic.
160
-
data/critic.gemspec CHANGED
@@ -18,10 +18,11 @@ Gem::Specification.new do |spec|
18
18
  spec.bindir = 'bin'
19
19
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ['lib']
21
+ spec.license = 'MIT'
21
22
 
22
23
  spec.add_development_dependency 'bundler', '~> 1.10'
23
24
  spec.add_development_dependency 'rake', '~> 10.0'
24
- spec.add_development_dependency 'rspec'
25
+ spec.add_development_dependency 'rspec', '~> 3.4'
25
26
 
26
- spec.add_dependency 'activesupport', '> 3.0', '< 5.0'
27
+ spec.add_dependency 'activesupport', '> 3.0', '< 6.0'
27
28
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ # Represents an authorization result for a policy and action
2
3
  class Critic::Authorization
3
4
  attr_reader :policy, :action
4
5
  attr_accessor :messages, :granted, :result, :metadata
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ # Custom error class for authorization failures
2
3
  class Critic::AuthorizationDenied < Critic::Error
3
4
  DEFAULT_MESSAGE = 'Authorization denied'
4
5
 
@@ -58,10 +58,10 @@ module Critic::Callbacks
58
58
 
59
59
  def _normalize_callback_option(options, from, to) # :nodoc:
60
60
  from = options[from]
61
- if from
62
- from = Array(from).map { |o| "authorization.action.to_s == '#{o}'" }
63
- options[to] = Array(options[to]).unshift(from).join(' || ')
64
- end
61
+ return unless from
62
+
63
+ from = Array(from).map { |o| "authorization.action.to_s == '#{o}'" }
64
+ options[to] = Array(options[to]).unshift(from).join(' || ')
65
65
  end
66
66
 
67
67
  # Skip before, after, and around action callbacks matching any of the names.
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ # Sugar for accessing the authorization interface
2
3
  module Critic::Controller
3
4
  extend ActiveSupport::Concern
4
5
 
@@ -33,10 +34,10 @@ module Critic::Controller
33
34
  authorize(scope, authorization_action, *args, policy: policy, **options)
34
35
  end
35
36
 
36
- protected
37
-
38
37
  attr_reader :authorization
39
38
 
39
+ protected
40
+
40
41
  def authorization_failed!
41
42
  raise Critic::AuthorizationDenied, authorization
42
43
  end
data/lib/critic/policy.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ # Represents the authorization policy interface
2
3
  module Critic::Policy
3
4
  extend ActiveSupport::Concern
4
5
 
@@ -39,21 +40,12 @@ module Critic::Policy
39
40
  end
40
41
  end
41
42
 
42
- attr_reader :subject, :resource, :errors
43
- attr_accessor :authorization
44
-
45
- delegate :messages, :metadata, to: :authorization
46
-
47
43
  def initialize(subject, resource)
48
44
  @subject = subject
49
45
  @resource = resource
50
46
  @errors = []
51
47
  end
52
48
 
53
- def failure_message(action)
54
- "#{subject} is not authorized to #{action} #{resource}"
55
- end
56
-
57
49
  def authorize(action, *args)
58
50
  self.authorization = Critic::Authorization.new(self, action)
59
51
 
@@ -62,8 +54,8 @@ module Critic::Policy
62
54
  authorization.result = result if authorization.result.nil?
63
55
 
64
56
  case authorization.result
65
- when Critic::Authorization
66
- # user has accessed authorization directly
57
+ # when Critic::Authorization
58
+ # # user has accessed authorization directly
67
59
  when String
68
60
  authorization.granted = false
69
61
  authorization.messages << result
@@ -77,8 +69,18 @@ module Critic::Policy
77
69
  authorization
78
70
  end
79
71
 
72
+ attr_accessor :authorization
73
+
80
74
  protected
81
75
 
76
+ attr_reader :subject, :resource, :errors
77
+
78
+ delegate :messages, :metadata, to: :authorization
79
+
80
+ def failure_message(action)
81
+ "#{subject} is not authorized to #{action} #{resource}"
82
+ end
83
+
82
84
  def halt(*response)
83
85
  throw :halt, *response
84
86
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Critic
3
- VERSION = '0.2.0'
3
+ VERSION = '0.2.1'
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: critic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Lane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-22 00:00:00.000000000 Z
11
+ date: 2016-12-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -42,16 +42,16 @@ dependencies:
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '3.4'
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
- version: '0'
54
+ version: '3.4'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: activesupport
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -61,7 +61,7 @@ dependencies:
61
61
  version: '3.0'
62
62
  - - "<"
63
63
  - !ruby/object:Gem::Version
64
- version: '5.0'
64
+ version: '6.0'
65
65
  type: :runtime
66
66
  prerelease: false
67
67
  version_requirements: !ruby/object:Gem::Requirement
@@ -71,7 +71,7 @@ dependencies:
71
71
  version: '3.0'
72
72
  - - "<"
73
73
  - !ruby/object:Gem::Version
74
- version: '5.0'
74
+ version: '6.0'
75
75
  description: Resource authorization via PORO
76
76
  email:
77
77
  - me@joshualane.com
@@ -85,7 +85,10 @@ files:
85
85
  - ".rspec"
86
86
  - ".rubocop.yml"
87
87
  - ".travis.yml"
88
+ - Appraisals
89
+ - CHANGELOG.md
88
90
  - Gemfile
91
+ - LICENSE.txt
89
92
  - README.md
90
93
  - Rakefile
91
94
  - bin/console
@@ -99,7 +102,8 @@ files:
99
102
  - lib/critic/policy.rb
100
103
  - lib/critic/version.rb
101
104
  homepage: http://lanej.io/critic
102
- licenses: []
105
+ licenses:
106
+ - MIT
103
107
  metadata: {}
104
108
  post_install_message:
105
109
  rdoc_options: []
@@ -117,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
121
  version: '0'
118
122
  requirements: []
119
123
  rubyforge_project:
120
- rubygems_version: 2.5.1
124
+ rubygems_version: 2.5.2
121
125
  signing_key:
122
126
  specification_version: 4
123
127
  summary: Resource authorization