authorize_if 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +200 -0
  4. data/Rakefile +34 -0
  5. data/lib/authorize_if.rb +138 -0
  6. data/lib/authorize_if/version.rb +3 -0
  7. data/lib/tasks/authorize_if_tasks.rake +4 -0
  8. data/test/dummy/README.rdoc +28 -0
  9. data/test/dummy/Rakefile +6 -0
  10. data/test/dummy/app/assets/javascripts/application.js +13 -0
  11. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  12. data/test/dummy/app/controllers/application_controller.rb +9 -0
  13. data/test/dummy/app/controllers/articles_controller.rb +27 -0
  14. data/test/dummy/app/helpers/application_helper.rb +2 -0
  15. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  16. data/test/dummy/bin/bundle +3 -0
  17. data/test/dummy/bin/rails +4 -0
  18. data/test/dummy/bin/rake +4 -0
  19. data/test/dummy/bin/setup +29 -0
  20. data/test/dummy/config.ru +4 -0
  21. data/test/dummy/config/application.rb +13 -0
  22. data/test/dummy/config/boot.rb +5 -0
  23. data/test/dummy/config/environment.rb +5 -0
  24. data/test/dummy/config/environments/development.rb +35 -0
  25. data/test/dummy/config/environments/production.rb +72 -0
  26. data/test/dummy/config/environments/test.rb +37 -0
  27. data/test/dummy/config/initializers/assets.rb +11 -0
  28. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  29. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  30. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  31. data/test/dummy/config/initializers/inflections.rb +16 -0
  32. data/test/dummy/config/initializers/mime_types.rb +4 -0
  33. data/test/dummy/config/initializers/session_store.rb +3 -0
  34. data/test/dummy/config/initializers/wrap_parameters.rb +9 -0
  35. data/test/dummy/config/locales/en.yml +23 -0
  36. data/test/dummy/config/routes.rb +3 -0
  37. data/test/dummy/config/secrets.yml +22 -0
  38. data/test/dummy/db/test.sqlite3 +0 -0
  39. data/test/dummy/log/test.log +1784 -0
  40. data/test/dummy/public/404.html +67 -0
  41. data/test/dummy/public/422.html +67 -0
  42. data/test/dummy/public/500.html +66 -0
  43. data/test/dummy/public/favicon.ico +0 -0
  44. data/test/integration/authorize_if_integration_test.rb +41 -0
  45. data/test/test_helper.rb +19 -0
  46. data/test/unit/authorize_if_unit_test.rb +113 -0
  47. metadata +170 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fea95712c0006a402eef0bff57366a89a7b6cb67
4
+ data.tar.gz: b667cf8c07496f7fa6b1970107e5de1e44b53db2
5
+ SHA512:
6
+ metadata.gz: 34aff8dfa5ddeeea9ca00539a375c3e97c719b11d86b0367b2bbfdfcbc8d0cd0d58038040ba42f5b108cd4c96fe4e20524779962366e61bae31096840f999d08
7
+ data.tar.gz: 761953381f50d9842b22183bbe2582ea680a8650d28848a0dc37bbf2f54eabc0f4c16afa5f58316c700e4e2e3458fe1dcd0aac7d916ca64e82c0a40acac736f4
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Vladimir Rybas
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,200 @@
1
+ # authorize_if
2
+
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`.
6
+
7
+ And that's it.
8
+
9
+ ## Installation
10
+
11
+ Add gem to your application's `Gemfile`:
12
+
13
+ gem 'authorize_if'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install authorize_if
22
+
23
+ ## Usage
24
+
25
+ #### `authorize_if`
26
+
27
+ Accepts any `truthy` or `falsey` Ruby object.
28
+
29
+ ```ruby
30
+ class ArticlesController
31
+ def index
32
+ authorize_if current_user
33
+ # ...
34
+ end
35
+
36
+ def show
37
+ article = Article.find(params[:id])
38
+
39
+ authorize_if article.authored_by?(current_user) ||
40
+ article.group.members.include?(current_user)
41
+ # ...
42
+ end
43
+
44
+ def edit
45
+ article = Article.find(params[:id])
46
+
47
+ authorize_if can_manage?(article)
48
+ # ...
49
+ end
50
+
51
+ private
52
+
53
+ def can_manage?(article)
54
+ # ...
55
+ end
56
+ end
57
+ ```
58
+
59
+ It raises `AuthorizeIf::NotAuthorizedError` exception, which you can
60
+ rescue right in the controller method
61
+
62
+ ```ruby
63
+ class ArticlesController
64
+ def index
65
+ authorize_if current_user
66
+ # ...
67
+
68
+ rescue AuthorizeIf::NotAuthorizedError
69
+ head 403
70
+
71
+ end
72
+ end
73
+ ```
74
+
75
+ or with `rescue_from` in `ApplicaitonController`:
76
+
77
+ ```ruby
78
+ class ApplicationController < ActionController::Base
79
+ rescue_from "AuthorizeIf::NotAuthorizedError" do |exception|
80
+ head 403
81
+ end
82
+ end
83
+ ```
84
+
85
+ You can set custom error message by using configuration block
86
+
87
+ ```ruby
88
+ class ArticlesController
89
+ def index
90
+ authorize_if(current_user) do |config|
91
+ config.error_message = "You are not authorized!"
92
+ end
93
+ # ...
94
+ end
95
+ end
96
+
97
+ class ApplicationController < ActionController::Base
98
+ rescue_from "AuthorizeIf::NotAuthorizedError" do |exception|
99
+ render text: exception.message, status: 403
100
+ end
101
+ end
102
+ ```
103
+
104
+ #### `authorize`
105
+
106
+ This method helps to extract authorization rules out of controller. It
107
+ expects corresponding authorization rule to exist.
108
+
109
+ ```ruby
110
+ class ArticlesController
111
+ def index
112
+ authorize
113
+
114
+ # ...
115
+ end
116
+
117
+ private
118
+
119
+ def authorize_index?
120
+ current_user.present?
121
+ end
122
+ end
123
+ ```
124
+
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
147
+ rule.
148
+
149
+ ```ruby
150
+ class ArticlesController
151
+ def edit
152
+ article = Article.find(params[:id])
153
+
154
+ authorize(article)
155
+
156
+ # ...
157
+ end
158
+
159
+ private
160
+
161
+ def authorize_edit?(article)
162
+ article.author == current_user
163
+ end
164
+ end
165
+ ```
166
+
167
+ It can also be customized by using configuration block.
168
+
169
+ ```ruby
170
+ class ArticlesController
171
+ def edit
172
+ article = Article.find(params[:id])
173
+
174
+ authorize(article) do |config|
175
+ config.error_message = "You are not authorized!"
176
+ end
177
+
178
+ # ...
179
+ end
180
+
181
+ private
182
+
183
+ def authorize_edit?(article)
184
+ article.author == current_user
185
+ end
186
+ end
187
+ ```
188
+
189
+ ## Contributing
190
+
191
+ 1. Fork it ( https://github.com/vrybas/authorize_if/fork )
192
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
193
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
194
+ 4. Push to the branch (`git push origin my-new-feature`)
195
+ 5. Create a new Pull Request
196
+
197
+ ## License
198
+
199
+ Copyright 2016 Vladimir Rybas. MIT License (see LICENSE for details).
200
+
data/Rakefile ADDED
@@ -0,0 +1,34 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'AuthorizeIf'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+
34
+ task default: :test
@@ -0,0 +1,138 @@
1
+ # Provides a set of methods to handle authorization scenarios.
2
+ # It is included to ActionController::Base on load.
3
+ #
4
+ 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
+ # Evaluates given object as boolean. Returns 'true' if object
13
+ # evaluates to 'true'. Raises `AuthorizeIf::NotAuthorizedError`
14
+ # if object evaluates to 'false'.
15
+ #
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.
19
+ #
20
+ # @param [Object] rule
21
+ # The authorization rule. Any "truthy" or "falsey" Ruby object.
22
+ #
23
+ # @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.
28
+ #
29
+ # @example
30
+ # class ArticlesController
31
+ # def index
32
+ # authorize_if current_user
33
+ # # => true
34
+ #
35
+ # ...
36
+ # end
37
+ #
38
+ # def edit
39
+ # @article = Article.find(params[:id])
40
+ #
41
+ # authorize_if @article.authors.include?(current_user) do |config|
42
+ # config.error_message = "You are not authorized!"
43
+ # end
44
+ # # => AuthorizeIf::NotAuthorizedError: You are not authorized!
45
+ #
46
+ # ...
47
+ # end
48
+ # end
49
+ #
50
+ #
51
+ # @return [Boolean]
52
+ # Returns 'true' if given object evaluates to 'true'.
53
+ #
54
+ # @raise [AuthorizeIf::NotAuthorizedError]
55
+ # Raised if given object evaluates to 'false'.
56
+ #
57
+ def authorize_if(rule, &block)
58
+ config = Configuration.new
59
+ block.call(config) if block
60
+
61
+ !!rule || raise(NotAuthorizedError, config.error_message)
62
+ end
63
+
64
+ # Accepts any arguments and configuration block. Calls corresponding
65
+ # authorization rule method with given arguments, except block.
66
+ #
67
+ # Then calls `#authorize_if` with the returning value of corresponding
68
+ # authorization rule as first argument, and with given configuration block.
69
+ #
70
+ # @param *args
71
+ # Any arguments, which will be given to corresponding
72
+ # authorization rule.
73
+ #
74
+ # @param [Proc] block
75
+ # The configuration block. See `#authorize_if` for complete list of
76
+ # configuration options.
77
+ #
78
+ # @example
79
+ # class ArticlesController
80
+ # def index
81
+ # authorize
82
+ # # => true
83
+ #
84
+ # ...
85
+ # end
86
+ #
87
+ # def edit
88
+ # @article = Article.find(params[:id])
89
+ #
90
+ # authorize(@article) do |config|
91
+ # config.error_message = "You are not authorized!"
92
+ # end
93
+ # # => AuthorizeIf::NotAuthorizedError: You are not authorized!
94
+ #
95
+ # ...
96
+ # end
97
+ #
98
+ # def destroy
99
+ # authorize
100
+ # # => AuthorizeIf::MissingAuthorizationRuleError: No authorization
101
+ # rule defined for action articles#destroy. Please define
102
+ # method #authorize_destroy? for ArticlesController
103
+ #
104
+ # ...
105
+ # end
106
+ #
107
+ # private
108
+ #
109
+ # def authorize_index?
110
+ # current_user.present?
111
+ # end
112
+ #
113
+ # def authorize_edit?(article)
114
+ # article.author == current_user
115
+ # end
116
+ # end
117
+ #
118
+ def authorize(*args, &block)
119
+ rule_method_name = "authorize_#{action_name}?"
120
+
121
+ unless self.respond_to?(rule_method_name, true)
122
+ msg = [
123
+ "No authorization rule defined for action",
124
+ "#{controller_name}##{action_name}.",
125
+ "Please define method ##{rule_method_name} for",
126
+ self.class.name
127
+ ].join(' ')
128
+
129
+ raise(MissingAuthorizationRuleError, msg)
130
+ end
131
+
132
+ authorize_if(self.send(rule_method_name, *args), &block)
133
+ end
134
+ end
135
+
136
+ ActiveSupport.on_load :action_controller do
137
+ include AuthorizeIf
138
+ end
@@ -0,0 +1,3 @@
1
+ module AuthorizeIf
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :authorize_if do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,28 @@
1
+ == README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
25
+
26
+
27
+ Please feel free to use a different markup language if you do not plan to run
28
+ <tt>rake doc:app</tt>.