authorize_if 0.0.1 → 0.0.2

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +114 -58
  3. data/lib/authorize_if.rb +45 -26
  4. data/lib/authorize_if/errors.rb +19 -0
  5. data/lib/authorize_if/version.rb +1 -1
  6. metadata +7 -85
  7. data/lib/tasks/authorize_if_tasks.rake +0 -4
  8. data/test/dummy/README.rdoc +0 -28
  9. data/test/dummy/Rakefile +0 -6
  10. data/test/dummy/app/assets/javascripts/application.js +0 -13
  11. data/test/dummy/app/assets/stylesheets/application.css +0 -15
  12. data/test/dummy/app/controllers/application_controller.rb +0 -9
  13. data/test/dummy/app/controllers/articles_controller.rb +0 -27
  14. data/test/dummy/app/helpers/application_helper.rb +0 -2
  15. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  16. data/test/dummy/bin/bundle +0 -3
  17. data/test/dummy/bin/rails +0 -4
  18. data/test/dummy/bin/rake +0 -4
  19. data/test/dummy/bin/setup +0 -29
  20. data/test/dummy/config.ru +0 -4
  21. data/test/dummy/config/application.rb +0 -13
  22. data/test/dummy/config/boot.rb +0 -5
  23. data/test/dummy/config/environment.rb +0 -5
  24. data/test/dummy/config/environments/development.rb +0 -35
  25. data/test/dummy/config/environments/production.rb +0 -72
  26. data/test/dummy/config/environments/test.rb +0 -37
  27. data/test/dummy/config/initializers/assets.rb +0 -11
  28. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  29. data/test/dummy/config/initializers/cookies_serializer.rb +0 -3
  30. data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -4
  31. data/test/dummy/config/initializers/inflections.rb +0 -16
  32. data/test/dummy/config/initializers/mime_types.rb +0 -4
  33. data/test/dummy/config/initializers/session_store.rb +0 -3
  34. data/test/dummy/config/initializers/wrap_parameters.rb +0 -9
  35. data/test/dummy/config/locales/en.yml +0 -23
  36. data/test/dummy/config/routes.rb +0 -3
  37. data/test/dummy/config/secrets.yml +0 -22
  38. data/test/dummy/db/test.sqlite3 +0 -0
  39. data/test/dummy/log/test.log +0 -1784
  40. data/test/dummy/public/404.html +0 -67
  41. data/test/dummy/public/422.html +0 -67
  42. data/test/dummy/public/500.html +0 -66
  43. data/test/dummy/public/favicon.ico +0 -0
  44. data/test/integration/authorize_if_integration_test.rb +0 -41
  45. data/test/test_helper.rb +0 -19
  46. data/test/unit/authorize_if_unit_test.rb +0 -113
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fea95712c0006a402eef0bff57366a89a7b6cb67
4
- data.tar.gz: b667cf8c07496f7fa6b1970107e5de1e44b53db2
3
+ metadata.gz: 57156e1bc123cd5c21ac7d8b0103a8eb32fbde03
4
+ data.tar.gz: f13d7d247b7a517f016e1a469f9856f033a2ed4b
5
5
  SHA512:
6
- metadata.gz: 34aff8dfa5ddeeea9ca00539a375c3e97c719b11d86b0367b2bbfdfcbc8d0cd0d58038040ba42f5b108cd4c96fe4e20524779962366e61bae31096840f999d08
7
- data.tar.gz: 761953381f50d9842b22183bbe2582ea680a8650d28848a0dc37bbf2f54eabc0f4c16afa5f58316c700e4e2e3458fe1dcd0aac7d916ca64e82c0a40acac736f4
6
+ metadata.gz: 1990ed7061f41529ab1994cb713605ec0221c2ff7b59b0a9605236feeea26682612490549affd8fd98e208276400eebcb7b3e8a8007f12d3a4e4b246a2fa4936
7
+ data.tar.gz: ccdd44c902ecec0df0b154511ed2074262d6f5954ad9832e1af59eeb64e2ccd393ebdfc357c5eaa969710193094a6178497e228716914e32a24aceb57a53168d
data/README.md CHANGED
@@ -1,33 +1,33 @@
1
- # authorize_if
1
+ # authorize_if [![Gem Version](https://badge.fury.io/rb/authorize_if.svg)](https://badge.fury.io/rb/authorize_if) [![Build Status](https://travis-ci.org/vrybas/authorize_if.svg?branch=master)](https://travis-ci.org/vrybas/authorize_if) [![Code Climate](https://codeclimate.com/github/vrybas/authorize_if/badges/gpa.svg)](https://codeclimate.com/github/vrybas/authorize_if)
2
2
 
3
3
  Minimalistic authorization library for Ruby on Rails applications. It
4
- defines controller methods `authorize` and `authorize_if`, which accept
5
- authorization rules and raise exception if rule evaluates to `false`.
4
+ defines controller methods `authorize_if` and `authorize`, which accept
5
+ inline or pre-defined authorization rules and raise exception if rule
6
+ evaluates to `false`.
6
7
 
7
- And that's it.
8
+ ## API documentation
8
9
 
9
- ## Installation
10
+ #### Contents:
10
11
 
11
- Add gem to your application's `Gemfile`:
12
+ ##### [`authorize_if`](#authorize_if) - inline authorization
13
+ * [Exception handling](#exception-handling)
14
+ * [Customization of an exception object](#customization-of-an-exception-object)
12
15
 
13
- gem 'authorize_if'
16
+ ##### [`authorize`](#authorize) - authorization using pre-defined authorization rules
17
+ * [Organizing authorization rules](#organizing-authorization-rules)
14
18
 
15
- And then execute:
19
+ ##### [`Installation`](#installation)
16
20
 
17
- $ bundle
21
+ ##### [`Contributing`](#contributing)
18
22
 
19
- Or install it yourself as:
23
+ ##### [`License`](#license)
20
24
 
21
- $ gem install authorize_if
22
-
23
- ## Usage
24
-
25
- #### `authorize_if`
25
+ ## `authorize_if`
26
26
 
27
27
  Accepts any `truthy` or `falsey` Ruby object.
28
28
 
29
29
  ```ruby
30
- class ArticlesController
30
+ class ArticlesController < ActionController::Base
31
31
  def index
32
32
  authorize_if current_user
33
33
  # ...
@@ -37,7 +37,7 @@ class ArticlesController
37
37
  article = Article.find(params[:id])
38
38
 
39
39
  authorize_if article.authored_by?(current_user) ||
40
- article.group.members.include?(current_user)
40
+ article.published?
41
41
  # ...
42
42
  end
43
43
 
@@ -56,11 +56,13 @@ class ArticlesController
56
56
  end
57
57
  ```
58
58
 
59
+ ### Exception handling
60
+
59
61
  It raises `AuthorizeIf::NotAuthorizedError` exception, which you can
60
- rescue right in the controller method
62
+ rescue right in the controller action
61
63
 
62
64
  ```ruby
63
- class ArticlesController
65
+ class ArticlesController < ApplicationController
64
66
  def index
65
67
  authorize_if current_user
66
68
  # ...
@@ -76,38 +78,61 @@ or with `rescue_from` in `ApplicaitonController`:
76
78
 
77
79
  ```ruby
78
80
  class ApplicationController < ActionController::Base
79
- rescue_from "AuthorizeIf::NotAuthorizedError" do |exception|
81
+ rescue_from AuthorizeIf::NotAuthorizedError do |exception|
80
82
  head 403
81
83
  end
82
84
  end
83
85
  ```
84
86
 
85
- You can set custom error message by using configuration block
87
+ ### Customization of an exception object
88
+
89
+ If block is given, `authorize_if` yields the block with an exception
90
+ object. This allows to set custom error message, which is going to be
91
+ used when exception is raised.
92
+
93
+ Also you can use key-value store(plain Ruby hash), `context`, to store
94
+ any data, and access it in the exception handling block.
86
95
 
87
96
  ```ruby
88
- class ArticlesController
97
+ class ArticlesController < ApplicationController
89
98
  def index
90
- authorize_if(current_user) do |config|
91
- config.error_message = "You are not authorized!"
99
+ authorize_if(current_user) do |exception|
100
+ exception.message = "You are not authorized!"
101
+
102
+ exception.context[:request_ip] = "192.168.1.1"
103
+ exception.context[:user_agent] = "Gecko"
92
104
  end
93
105
  # ...
94
106
  end
95
107
  end
108
+ ```
96
109
 
110
+ ```ruby
97
111
  class ApplicationController < ActionController::Base
98
- rescue_from "AuthorizeIf::NotAuthorizedError" do |exception|
99
- render text: exception.message, status: 403
112
+ rescue_from AuthorizeIf::NotAuthorizedError do |exception|
113
+ exception.message
114
+ # => "You are not authorized!"
115
+
116
+ exception.context[:request_ip]
117
+ # => "192.168.1.1"
118
+
119
+ exception.context[:user_agent]
120
+ # => "Gecko"
100
121
  end
101
122
  end
102
123
  ```
103
124
 
104
- #### `authorize`
125
+ ## `authorize`
126
+
127
+ You can define authorization rules for controller actions like this
128
+
129
+ ##### `"authorize_#{action_name}?"`
105
130
 
106
- This method helps to extract authorization rules out of controller. It
107
- expects corresponding authorization rule to exist.
131
+ And then call `authorize`, which is going to find and evaluate
132
+ corresponding authorization rule.
108
133
 
109
134
  ```ruby
110
- class ArticlesController
135
+ class ArticlesController < ActionController::Base
111
136
  def index
112
137
  authorize
113
138
 
@@ -122,32 +147,11 @@ class ArticlesController
122
147
  end
123
148
  ```
124
149
 
125
- You can extract those rules into a module and include them to the
126
- controller.
127
-
128
- ```ruby
129
- module AuthorizationRules
130
- def authorize_index?
131
- current_user.present?
132
- end
133
- end
134
-
135
- class ArticlesController
136
- include AuthorizationRules
137
-
138
- def index
139
- authorize
140
-
141
- # ...
142
- end
143
- end
144
- ```
145
-
146
- `authorize` accepts any parameters and passes them to authorization
150
+ `authorize` accepts any arguments and passes them to authorization
147
151
  rule.
148
152
 
149
153
  ```ruby
150
- class ArticlesController
154
+ class ArticlesController < ActionController::Base
151
155
  def edit
152
156
  article = Article.find(params[:id])
153
157
 
@@ -164,18 +168,24 @@ class ArticlesController
164
168
  end
165
169
  ```
166
170
 
167
- It can also be customized by using configuration block.
171
+ It also accepts customization block, and yields an exception object:
168
172
 
169
173
  ```ruby
170
- class ArticlesController
174
+ class ArticlesController < ActionController::Base
171
175
  def edit
172
176
  article = Article.find(params[:id])
173
177
 
174
- authorize(article) do |config|
175
- config.error_message = "You are not authorized!"
178
+ authorize(article) do |exception|
179
+ exception.message = "You are not authorized!"
180
+ exception.context[:request_ip] = "192.168.1.1"
176
181
  end
177
182
 
178
- # ...
183
+ rescue AuthorizeIf::NotAuthorizedError => e
184
+ e.message
185
+ # => "You are not authorized!"
186
+
187
+ e.context[:request_ip]
188
+ # => "192.168.1.1"
179
189
  end
180
190
 
181
191
  private
@@ -186,6 +196,52 @@ class ArticlesController
186
196
  end
187
197
  ```
188
198
 
199
+ ### Organizing authorization rules
200
+
201
+ You can extract rules into a module and include it to the
202
+ controller.
203
+
204
+ ```ruby
205
+ class ArticlesController < ActionController::Base
206
+ include AuthorizationRules
207
+
208
+ def index
209
+ authorize
210
+
211
+ # ...
212
+ end
213
+ end
214
+ ```
215
+
216
+ ```ruby
217
+ class ArticlesController
218
+ module AuthorizationRules
219
+ def authorize_index?
220
+ current_user.present?
221
+ end
222
+ end
223
+ end
224
+ ```
225
+
226
+ ## Usage outside of controllers
227
+
228
+ Include `AuthorizeIf` module to any class and you'll get `authorize` and
229
+ `authorize_if` methods.
230
+
231
+ ## Installation
232
+
233
+ Add gem to your application's `Gemfile`:
234
+
235
+ gem 'authorize_if'
236
+
237
+ And then execute:
238
+
239
+ $ bundle
240
+
241
+ Or install it manually:
242
+
243
+ $ gem install authorize_if
244
+
189
245
  ## Contributing
190
246
 
191
247
  1. Fork it ( https://github.com/vrybas/authorize_if/fork )
data/lib/authorize_if.rb CHANGED
@@ -1,30 +1,29 @@
1
+ require "authorize_if/version"
2
+ require "authorize_if/errors"
3
+
1
4
  # Provides a set of methods to handle authorization scenarios.
2
5
  # It is included to ActionController::Base on load.
3
6
  #
4
7
  module AuthorizeIf
5
- NotAuthorizedError = Class.new(StandardError)
6
- MissingAuthorizationRuleError = Class.new(StandardError)
7
-
8
- Configuration = Class.new do
9
- attr_accessor :error_message
10
- end
11
-
12
8
  # Evaluates given object as boolean. Returns 'true' if object
13
9
  # evaluates to 'true'. Raises `AuthorizeIf::NotAuthorizedError`
14
10
  # if object evaluates to 'false'.
15
11
  #
16
- # Also accepts block and calls it with `AuthorizeIf::Configuration`
17
- # object as parameter. Behavior can be customized by calling methods
18
- # on configuraiton object.
12
+ # Also accepts block and yields it with `AuthorizeIf::NotAuthorizedError`
13
+ # exception object. Behavior can be customized by calling methods
14
+ # on exception object.
19
15
  #
20
16
  # @param [Object] rule
21
17
  # The authorization rule. Any "truthy" or "falsey" Ruby object.
22
18
  #
23
19
  # @param [Proc] block
24
- # The configuration block. Supported configuration:
25
- # `error_message=()` - custom error message, which will be raised
26
- # along with `AuthorizeIf::NotAuthorizedError`
27
- # exception.
20
+ # The customization block. Supported customization methods:
21
+ # `message=` - error message, which will be raisedalong
22
+ # with `AuthorizeIf::NotAuthorizedError` exception.
23
+ #
24
+ # `context` - a key-value store(plain Ruby hash), which will be
25
+ # passed along with `AuthorizeIf::NotAuthorizedError`
26
+ # exception object, as an object attribute.
28
27
  #
29
28
  # @example
30
29
  # class ArticlesController
@@ -38,16 +37,25 @@ module AuthorizeIf
38
37
  # def edit
39
38
  # @article = Article.find(params[:id])
40
39
  #
41
- # authorize_if @article.authors.include?(current_user) do |config|
42
- # config.error_message = "You are not authorized!"
40
+ # authorize_if @article.authors.include?(current_user) do |exception|
41
+ # exception.message = "You are not authorized!"
42
+ # exception.context[:request_ip] = "192.168.1.1"
43
+ # exception.context[:user_agent] = "Gecko"
43
44
  # end
44
45
  # # => AuthorizeIf::NotAuthorizedError: You are not authorized!
45
46
  #
46
- # ...
47
+ # rescue AuthorizeIf::NotAuthorizedError => e
48
+ # e.message
49
+ # # => "You are not authorized!"
50
+ #
51
+ # e.context[:request_ip]
52
+ # # => "192.168.1.1"
53
+ #
54
+ # e.context[:user_agent]
55
+ # # => "Gecko"
47
56
  # end
48
57
  # end
49
58
  #
50
- #
51
59
  # @return [Boolean]
52
60
  # Returns 'true' if given object evaluates to 'true'.
53
61
  #
@@ -55,10 +63,11 @@ module AuthorizeIf
55
63
  # Raised if given object evaluates to 'false'.
56
64
  #
57
65
  def authorize_if(rule, &block)
58
- config = Configuration.new
59
- block.call(config) if block
66
+ return true if !!rule
60
67
 
61
- !!rule || raise(NotAuthorizedError, config.error_message)
68
+ exception = NotAuthorizedError.exception
69
+ yield(exception) if block
70
+ raise(exception, exception.instance_variable_get(:@message))
62
71
  end
63
72
 
64
73
  # Accepts any arguments and configuration block. Calls corresponding
@@ -72,8 +81,8 @@ module AuthorizeIf
72
81
  # authorization rule.
73
82
  #
74
83
  # @param [Proc] block
75
- # The configuration block. See `#authorize_if` for complete list of
76
- # configuration options.
84
+ # The exception customization block. See `#authorize_if` for complete list of
85
+ # customization methods.
77
86
  #
78
87
  # @example
79
88
  # class ArticlesController
@@ -87,12 +96,22 @@ module AuthorizeIf
87
96
  # def edit
88
97
  # @article = Article.find(params[:id])
89
98
  #
90
- # authorize(@article) do |config|
91
- # config.error_message = "You are not authorized!"
99
+ # authorize(@article) do |exception|
100
+ # exception.message = "You are not authorized!"
101
+ # exception.context[:request_ip] = "192.168.1.1"
102
+ # exception.context[:user_agent] = "Gecko"
92
103
  # end
93
104
  # # => AuthorizeIf::NotAuthorizedError: You are not authorized!
94
105
  #
95
- # ...
106
+ # rescue AuthorizeIf::NotAuthorizedError => e
107
+ # e.message
108
+ # # => "You are not authorized!"
109
+ #
110
+ # e.context[:request_ip]
111
+ # # => "192.168.1.1"
112
+ #
113
+ # e.context[:user_agent]
114
+ # # => "Gecko"
96
115
  # end
97
116
  #
98
117
  # def destroy
@@ -0,0 +1,19 @@
1
+ module AuthorizeIf
2
+ class NotAuthorizedError < StandardError
3
+ attr_reader :context
4
+
5
+ def initialize(*)
6
+ @message = nil
7
+ @context = {}
8
+
9
+ super
10
+ end
11
+
12
+ def message=(msg)
13
+ @message = msg
14
+ end
15
+ end
16
+
17
+ class MissingAuthorizationRuleError < StandardError
18
+ end
19
+ end
@@ -1,3 +1,3 @@
1
1
  module AuthorizeIf
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authorize_if
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Rybas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-02 00:00:00.000000000 Z
11
+ date: 2016-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -25,19 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 4.2.5
27
27
  - !ruby/object:Gem::Dependency
28
- name: m
28
+ name: rspec-rails
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.3.1
33
+ version: '3'
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
- version: 1.3.1
40
+ version: '3'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: byebug
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -63,47 +63,8 @@ files:
63
63
  - README.md
64
64
  - Rakefile
65
65
  - lib/authorize_if.rb
66
+ - lib/authorize_if/errors.rb
66
67
  - lib/authorize_if/version.rb
67
- - lib/tasks/authorize_if_tasks.rake
68
- - test/dummy/README.rdoc
69
- - test/dummy/Rakefile
70
- - test/dummy/app/assets/javascripts/application.js
71
- - test/dummy/app/assets/stylesheets/application.css
72
- - test/dummy/app/controllers/application_controller.rb
73
- - test/dummy/app/controllers/articles_controller.rb
74
- - test/dummy/app/helpers/application_helper.rb
75
- - test/dummy/app/views/layouts/application.html.erb
76
- - test/dummy/bin/bundle
77
- - test/dummy/bin/rails
78
- - test/dummy/bin/rake
79
- - test/dummy/bin/setup
80
- - test/dummy/config.ru
81
- - test/dummy/config/application.rb
82
- - test/dummy/config/boot.rb
83
- - test/dummy/config/environment.rb
84
- - test/dummy/config/environments/development.rb
85
- - test/dummy/config/environments/production.rb
86
- - test/dummy/config/environments/test.rb
87
- - test/dummy/config/initializers/assets.rb
88
- - test/dummy/config/initializers/backtrace_silencers.rb
89
- - test/dummy/config/initializers/cookies_serializer.rb
90
- - test/dummy/config/initializers/filter_parameter_logging.rb
91
- - test/dummy/config/initializers/inflections.rb
92
- - test/dummy/config/initializers/mime_types.rb
93
- - test/dummy/config/initializers/session_store.rb
94
- - test/dummy/config/initializers/wrap_parameters.rb
95
- - test/dummy/config/locales/en.yml
96
- - test/dummy/config/routes.rb
97
- - test/dummy/config/secrets.yml
98
- - test/dummy/db/test.sqlite3
99
- - test/dummy/log/test.log
100
- - test/dummy/public/404.html
101
- - test/dummy/public/422.html
102
- - test/dummy/public/500.html
103
- - test/dummy/public/favicon.ico
104
- - test/integration/authorize_if_integration_test.rb
105
- - test/test_helper.rb
106
- - test/unit/authorize_if_unit_test.rb
107
68
  homepage: https://github.com/vrybas/authorize_if
108
69
  licenses:
109
70
  - MIT
@@ -128,43 +89,4 @@ rubygems_version: 2.5.1
128
89
  signing_key:
129
90
  specification_version: 4
130
91
  summary: Minimalistic authorization library for Ruby on Rails applications.
131
- test_files:
132
- - test/dummy/app/assets/javascripts/application.js
133
- - test/dummy/app/assets/stylesheets/application.css
134
- - test/dummy/app/controllers/application_controller.rb
135
- - test/dummy/app/controllers/articles_controller.rb
136
- - test/dummy/app/helpers/application_helper.rb
137
- - test/dummy/app/views/layouts/application.html.erb
138
- - test/dummy/bin/bundle
139
- - test/dummy/bin/rails
140
- - test/dummy/bin/rake
141
- - test/dummy/bin/setup
142
- - test/dummy/config/application.rb
143
- - test/dummy/config/boot.rb
144
- - test/dummy/config/environment.rb
145
- - test/dummy/config/environments/development.rb
146
- - test/dummy/config/environments/production.rb
147
- - test/dummy/config/environments/test.rb
148
- - test/dummy/config/initializers/assets.rb
149
- - test/dummy/config/initializers/backtrace_silencers.rb
150
- - test/dummy/config/initializers/cookies_serializer.rb
151
- - test/dummy/config/initializers/filter_parameter_logging.rb
152
- - test/dummy/config/initializers/inflections.rb
153
- - test/dummy/config/initializers/mime_types.rb
154
- - test/dummy/config/initializers/session_store.rb
155
- - test/dummy/config/initializers/wrap_parameters.rb
156
- - test/dummy/config/locales/en.yml
157
- - test/dummy/config/routes.rb
158
- - test/dummy/config/secrets.yml
159
- - test/dummy/config.ru
160
- - test/dummy/db/test.sqlite3
161
- - test/dummy/log/test.log
162
- - test/dummy/public/404.html
163
- - test/dummy/public/422.html
164
- - test/dummy/public/500.html
165
- - test/dummy/public/favicon.ico
166
- - test/dummy/Rakefile
167
- - test/dummy/README.rdoc
168
- - test/integration/authorize_if_integration_test.rb
169
- - test/test_helper.rb
170
- - test/unit/authorize_if_unit_test.rb
92
+ test_files: []