authorize_if 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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: []