authorize_action 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ea616d0e04fe1d10782138a9703afd606c193fd8
4
+ data.tar.gz: 5b0e67d8cb38d9863cd5336871f4351057241662
5
+ SHA512:
6
+ metadata.gz: af325e32de44eacb20318980a019f6725ba5e0e69e109e4e8c7e5b4f52417d71a09c127d4b69248c0a70f8f913a500a678ee0c187fa11b7f9c417b16822ea768
7
+ data.tar.gz: d0089969c565d7dc1d3860a3e329c0a9287f5c62efaa1b49b640315aff10cc4520408be5cff15d30eb8d551918815889a1e204ef535d798feac0be9e57964109
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ rvm:
2
+ - 2.0.0
3
+ - 2.1.6
4
+ - 2.2.2
5
+ - ruby-head
6
+ notifications:
7
+ recipients:
8
+ - jarmo.p@gmail.com
9
+ matrix:
10
+ allow_failures:
11
+ - rvm: ruby-head
data/CHANGES.md ADDED
@@ -0,0 +1,3 @@
1
+ ### 1.0.0 - 2015/07/05
2
+
3
+ * Initial release.
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem "byebug", require: false
6
+ gem "coveralls", require: false
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) Jarmo Pertman
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,267 @@
1
+ # AuthorizeAction
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/authorize_action.svg)](http://badge.fury.io/rb/authorize_action)
4
+ [![Build Status](https://api.travis-ci.org/jarmo/authorize_action.png)](http://travis-ci.org/jarmo/authorize_action)
5
+ [![Coverage Status](https://coveralls.io/repos/jarmo/authorize_action/badge.svg?branch=master)](https://coveralls.io/r/jarmo/authorize_action?branch=master)
6
+ [![Dependency Status](https://gemnasium.com/jarmo/authorize_action.png)](https://gemnasium.com/jarmo/authorize_action)
7
+ [![Code Climate](https://codeclimate.com/github/jarmo/authorize_action/badges/gpa.svg)](https://codeclimate.com/github/jarmo/authorize_action)
8
+
9
+ Really **secure** and **simple** authorization library for your [Rails](http://rubyonrails.org/), [Sinatra](http://www.sinatrarb.com/) or whatever web framework, which doesn't suck.
10
+
11
+ According to [Ruby Toolbox](https://www.ruby-toolbox.com/categories/rails_authorization) there are
12
+ at least 28 authorization libraries/frameworks available just for Rails. And yet, they all suck.
13
+ At least that's why I've never used any of them in my projects.
14
+ All of this is the reason I've finally decided to create my own library to solve
15
+ the problem of authorization once and for all for all Ruby (web) frameworks.
16
+
17
+ Here are a few reasons, why [authorize_action](https://github.com/jarmo/authorize_action) is better
18
+ compared to all the rest:
19
+
20
+ * Is **secure** by default
21
+ * _authorize_action_ uses a **white-list** approach, which means that all controller actions
22
+ are forbidden by default. No more security breaches when you forget to write an authorization rule.
23
+
24
+ * Does only **one** thing and does it well
25
+ * _authorize_action_ doesn't deal with any other thing except **authorization**.
26
+ It does not provide any authentication (see [Devise](https://github.com/plataformatec/devise) for that),
27
+ roles or permissions functionality. It just checks if a user has access to a controller action or not. That's it.
28
+
29
+ * Has a really **simple** API
30
+ * _authorize_action_ doesn't have _gazillion_ different API methods, separate DSL
31
+ or _"Getting Started"_ wiki pages. It just has a **few methods** to do all the heavy lifting.
32
+ And it's really easy to understand by looking at the code in your project,
33
+ who has access to which controller action.
34
+
35
+ * Is **framework-agnostic**
36
+ * Although _authorize_action_ is made to work with _Rails_ and _Sinatra_ by default,
37
+ it has an **easy** way to add support for whatever framework.
38
+
39
+ * No **database/ORM** dependencies
40
+ * _authorize_action_ **doesn't force** you to use any database/ORM - handle
41
+ your roles/permissions however you like.
42
+
43
+ * No **external** dependencies
44
+ * _authorize_action_ doesn't have any direct external dependencies, which
45
+ makes auditing its code and upgrading it really **painless**.
46
+
47
+ * Has a **lightweight** codebase
48
+ * Due to the simplicity of _authorize_action_ its codebase is really simple, clean and foolproof.
49
+ Entire codebase used in _production_ is under **100 lines**.
50
+ If you're not sure what exactly happens when you use _authorize_action_ in your project
51
+ then you can understand it all quickly by looking at [the code](https://github.com/jarmo/authorize_action/tree/master/lib).
52
+
53
+ * Is thoroughly **tested**
54
+ * _authorize_action_ has **100% code-coverage** and all tests are ran automatically
55
+ prior to each release making it impossible to ship a faulty version accidentally.
56
+
57
+ * Follows **Semantic Versioning**
58
+ * Although _authorize_action_ is a relatively new library for now,
59
+ it's going to follow [Semantic Versioning](http://semver.org/),
60
+ which adds some additional guarantees to developers.
61
+
62
+ ## Installation
63
+
64
+ Add this line to your application's Gemfile:
65
+
66
+ ```ruby
67
+ gem 'authorize_action'
68
+ ```
69
+
70
+ And then execute:
71
+
72
+ $ bundle
73
+
74
+ Or install it yourself as:
75
+
76
+ $ gem install authorize_action
77
+
78
+ ## Usage
79
+
80
+ * Load _authorize_action_ gem
81
+ * Include framework specific module into base controller
82
+ * Define authorization rules for each controller/class
83
+ * Call `#authorize_action!` method before executing action
84
+
85
+ ### Rails
86
+
87
+ ```ruby
88
+ class ApplicationController < ActionController::Base
89
+ # Include authorize_action methods
90
+ include AuthorizeAction::Rails
91
+
92
+ # Check action authorization before action.
93
+ # By default all actions are forbidden!
94
+ before_action :authorize_action!
95
+
96
+ protected
97
+
98
+ # Helper method for administrator role
99
+ def admin?
100
+ # ...
101
+ end
102
+ end
103
+
104
+ class PostsController < ApplicationController
105
+ # Everyone has access to :index
106
+ def index
107
+ # ...
108
+ end
109
+
110
+ # Only post owner has access to :edit
111
+ def edit
112
+ # ...
113
+ end
114
+
115
+ # Authorization rules have to be defined for each controller
116
+ # action to specify the actual access rules.
117
+ self.authorization_rules = {
118
+ # Calling Proc object for :index action returns true
119
+ # thus everyone will have access to that action
120
+ index: -> { true },
121
+
122
+ # Calling Proc object for :edit action returns true only
123
+ # when Post owner matches current_user
124
+ edit: -> { Post.find(params[:id]).owner == current_user },
125
+
126
+ # Calling referenced #admin? method for :destroy action
127
+ # returns true only for administrators
128
+ destroy: -> :admin?
129
+ }
130
+ end
131
+ ```
132
+
133
+ ### Sinatra
134
+
135
+ ```ruby
136
+ require "authorize_action"
137
+
138
+ class Blog < Sinatra::Base
139
+ # Include authorize_action methods
140
+ include AuthorizeAction::Sinatra
141
+
142
+ # Check action authorization before action.
143
+ # By default all actions are forbidden.
144
+ # Allow requests to `public/` directory if you want.
145
+ before { authorize_action! unless request.path_info.start_with?(settings.public_folder) }
146
+
147
+ # Everyone has access to reading posts
148
+ get "/posts" do
149
+ # ...
150
+ end
151
+
152
+ # Only post owner has access to editing post
153
+ get "/posts/:id/edit" do
154
+ # ...
155
+ end
156
+
157
+ # Only administrator can delete posts
158
+ delete "/posts/:id" do
159
+ # ...
160
+ end
161
+
162
+ # Authorization rules have to be defined for each route
163
+ # to specify the actual access rules.
164
+ self.authorization_rules = {
165
+ # Calling Proc object for `GET /posts` action returns true
166
+ # thus everyone will have access to that action
167
+ action(:get, "/posts") => -> { true },
168
+
169
+ # Calling Proc object for `GET /posts/:id/edit` action
170
+ # returns true only when Post owner matches current_user
171
+ action(:get, "/posts/:id/edit") => -> { Post.find(params[:id]).owner == current_user },
172
+
173
+ # Calling referenced #admin? method for `DELETE /posts/:id` action
174
+ # returns true only for administrators
175
+ action(:delete, "/posts/:id") => :admin?
176
+ }
177
+
178
+ # Helper method for administrator role
179
+ def admin?
180
+ # ...
181
+ end
182
+
183
+ end
184
+ ```
185
+
186
+ ### Other
187
+
188
+ ```ruby
189
+ class BaseController
190
+ # Include authorize_action generic methods
191
+ include AuthorizeAction
192
+
193
+ # Call #authorize_action! before executing any controller actions.
194
+ before_any_action :authorize_action!
195
+
196
+ private
197
+
198
+ # Override AuthorizeAction#current_action_name to implement it.
199
+ # It is expected to return a Symbol/String object with an unique
200
+ # controller action identifier.
201
+ def current_action_name
202
+ # ...
203
+ end
204
+
205
+ # Override AuthorizeAction#forbid_action! to halt execution
206
+ # of controller action by rendering HTTP 403.
207
+ def forbid_action!
208
+ # ...
209
+ end
210
+
211
+ # Set authorization rules where keys are in the exact same format
212
+ # as returned by #current_action_name
213
+ # and values are Proc objects returning booleans.
214
+ self.authorization_rules = {
215
+ # ...
216
+ }
217
+ end
218
+ ```
219
+
220
+ ## Tips & Tricks
221
+
222
+ ### Administrator Has Access to Every Action
223
+
224
+ There is no API for giving access to administrator for every possible action.
225
+ Nevertheless it can be achieved easily by just following
226
+ object-oriented programming principles.
227
+
228
+ Example below is based on Rails and Devise, but
229
+ the idea is the same for whatever framework:
230
+
231
+ ```ruby
232
+ class ApplicationController < ActionController::Base
233
+ include AuthorizeAction::Rails
234
+
235
+ before_action :authorize_action!
236
+
237
+ # Override AuthorizeAction#authorize_action! to
238
+ # give access to administrator for every action or
239
+ # fall back to default AuthorizeAction behavior.
240
+ def authorize_action!
241
+ current_user.admin? || super
242
+ end
243
+ end
244
+ ```
245
+
246
+ Please make sure that you really-really need to do that!
247
+
248
+ ### Protecting Your Views
249
+
250
+ You have protected your actions with _authorize_action_ and your models with [Strong Parameters](https://github.com/rails/strong_parameters) (or something similar), but what about views?
251
+
252
+ Again, there is no separate API for that, but why not use regular Ruby methods to do that?
253
+
254
+ Here's an example:
255
+ ```ruby
256
+ # views/posts/edit.html.erb
257
+
258
+ <% if current_user.admin? %>
259
+ <%= link_to "Delete", @post, method: :delete
260
+ <% end %>
261
+ ```
262
+
263
+ Next step would be to create some helper class or module for roles.
264
+
265
+ ## License
266
+
267
+ Copyright (c) Jarmo Pertman (jarmo.p@gmail.com). See [LICENSE](https://github.com/jarmo/authorize_action/blob/master/LICENSE.txt) for details.
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require "rspec/core/rake_task"
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
7
+ task build: :spec
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "authorize_action"
7
+ spec.version = "1.0.0"
8
+ spec.authors = ["Jarmo Pertman"]
9
+ spec.email = ["jarmo.p@gmail.com"]
10
+ spec.summary = %q{Really secure and simple authorization library for your Rails, Sinatra or whatever web framework, which doesn't suck.}
11
+ spec.homepage = "https://github.com/jarmo/authorize_action"
12
+ spec.license = "MIT"
13
+
14
+ spec.files = `git ls-files -z`.split("\x0")
15
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_development_dependency "bundler", "~> 1.7"
20
+ spec.add_development_dependency "rake", "~> 10.0"
21
+ spec.add_development_dependency "rspec", "~> 3.1.0"
22
+ end
@@ -0,0 +1,31 @@
1
+ module AuthorizeAction
2
+ autoload :Rails, File.expand_path("authorize_action/rails", __dir__)
3
+ autoload :Sinatra, File.expand_path("authorize_action/sinatra", __dir__)
4
+
5
+ def authorize_action!
6
+ authorization_rule = self.class.authorization_rules && self.class.authorization_rules[current_action_name]
7
+ action_permitted = case authorization_rule
8
+ when Proc then instance_exec(&authorization_rule)
9
+ when Symbol then send(authorization_rule)
10
+ end
11
+ forbid_action! unless action_permitted
12
+ end
13
+
14
+ def self.included(base)
15
+ base.extend(ClassMethods)
16
+ end
17
+
18
+ module ClassMethods
19
+ attr_accessor :authorization_rules
20
+ end
21
+
22
+ private
23
+
24
+ def forbid_action!
25
+ raise NotImplementedError
26
+ end
27
+
28
+ def current_action_name
29
+ raise NotImplementedError
30
+ end
31
+ end
@@ -0,0 +1,19 @@
1
+ module AuthorizeAction
2
+ module Rails
3
+ include AuthorizeAction
4
+
5
+ def self.included(base)
6
+ AuthorizeAction.included(base)
7
+ end
8
+
9
+ private
10
+
11
+ def forbid_action!
12
+ head(:forbidden)
13
+ end
14
+
15
+ def current_action_name
16
+ action_name.to_sym
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,29 @@
1
+ module AuthorizeAction
2
+ module Sinatra
3
+ include AuthorizeAction
4
+
5
+ def self.included(base)
6
+ AuthorizeAction.included(base)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+ def action(request_method, request_path)
12
+ request_method = request_method.to_s.upcase
13
+ *_, route = routes[request_method].find {|pattern, _| request_path.match(pattern) }
14
+ route && route.instance_variable_get(:@route_name) && route.instance_variable_get(:@route_name).to_sym || "#{request_method} #{request_path}".to_sym
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def forbid_action!
21
+ halt(403)
22
+ end
23
+
24
+ def current_action_name
25
+ self.class.action(request.request_method, request.path_info)
26
+ end
27
+ end
28
+ end
29
+
@@ -0,0 +1,24 @@
1
+ require "spec_helper"
2
+
3
+ describe AuthorizeAction::Rails do
4
+ let(:authorizator) { Class.new { include AuthorizeAction::Rails }.new }
5
+
6
+ it "#authorize_action! delegates to AuthorizeAction#authorize_action!" do
7
+ expect_any_instance_of(AuthorizeAction).to receive(:authorize_action!)
8
+
9
+ authorizator.authorize_action!
10
+ end
11
+
12
+ it "#forbid_action! calls Rails' #head(:forbidden)" do
13
+ expect(authorizator).to receive(:head).with(:forbidden).and_return(:forbidden_result)
14
+
15
+ expect(authorizator.send(:forbid_action!)).to eq(:forbidden_result)
16
+ end
17
+
18
+ it "#current_action_name calls Rails' #action_name" do
19
+ expect(authorizator).to receive(:action_name).and_return("action-name")
20
+
21
+ expect(authorizator.send(:current_action_name)).to eq("action-name".to_sym)
22
+ end
23
+
24
+ end
@@ -0,0 +1,92 @@
1
+ require "spec_helper"
2
+
3
+ describe AuthorizeAction::Sinatra do
4
+ let(:authorizator) { Class.new { include AuthorizeAction::Sinatra }.new }
5
+
6
+ it "#authorize_action! delegates to AuthorizeAction#authorize_action!" do
7
+ expect_any_instance_of(AuthorizeAction).to receive(:authorize_action!)
8
+
9
+ authorizator.authorize_action!
10
+ end
11
+
12
+ it "#forbid_action! calls Sintra's #halt(403)" do
13
+ expect(authorizator).to receive(:halt).with(403).and_return(:forbidden_result)
14
+
15
+ expect(authorizator.send(:forbid_action!)).to eq(:forbidden_result)
16
+ end
17
+
18
+ it "#current_action_name finds Sinatra's action name from request" do
19
+ request = double("request", request_method: "GET", path_info: "/foo/bar")
20
+ allow(authorizator).to receive(:request).and_return(request)
21
+ expect(authorizator.class).to receive(:action).and_return("action-name".to_sym)
22
+
23
+ expect(authorizator.send(:current_action_name)).to eq("action-name".to_sym)
24
+ end
25
+
26
+ context "#action" do
27
+ it "returns request path when no Sinatra route found" do
28
+ route_handler = -> {}
29
+ route_handler.instance_variable_set(:@route_name, "GET /foo/:bar")
30
+ routes = {
31
+ "GET" => [
32
+ # /foo/:bar
33
+ [/\A\/foo\/([^\/?#]+)\z/, ["bar"], [], route_handler]
34
+ ]
35
+ }
36
+ expect(authorizator.class).to receive(:routes).and_return(routes)
37
+
38
+ expect(authorizator.class.action(:get, "/bar/baz")).to eq("GET /bar/baz".to_sym)
39
+ end
40
+
41
+ it "returns request path when Sinatra route found, but no route name exists" do
42
+ route_handler = -> {}
43
+ route_handler.instance_variable_set(:@route_name, nil)
44
+ routes = {
45
+ "GET" => [
46
+ # /foo/:bar
47
+ [/\A\/foo\/([^\/?#]+)\z/, ["bar"], [], route_handler]
48
+ ]
49
+ }
50
+ expect(authorizator.class).to receive(:routes).and_return(routes)
51
+
52
+ expect(authorizator.class.action(:get, "/foo/baz")).to eq("GET /foo/baz".to_sym)
53
+ end
54
+
55
+ it "returns Sinatra's GET method route name" do
56
+ route_handler1 = -> {}
57
+ route_handler1.instance_variable_set(:@route_name, "GET /bar/:baz")
58
+ route_handler2 = -> {}
59
+ route_handler2.instance_variable_set(:@route_name, "GET /foo/:bar")
60
+ routes = {
61
+ "GET" => [
62
+ # /bar/:baz
63
+ [/\A\/bar\/([^\/?#]+)\z/, ["baz"], [], route_handler1],
64
+ # /foo/:bar
65
+ [/\A\/foo\/([^\/?#]+)\z/, ["bar"], [], route_handler2]
66
+ ]
67
+ }
68
+ expect(authorizator.class).to receive(:routes).and_return(routes)
69
+
70
+ expect(authorizator.class.action(:get, "/foo/baz")).to eq("GET /foo/:bar".to_sym)
71
+ end
72
+
73
+ it "returns Sinatra's POST method route name" do
74
+ route_handler1 = -> {}
75
+ route_handler1.instance_variable_set(:@route_name, "POST /bar/:baz")
76
+ route_handler2 = -> {}
77
+ route_handler2.instance_variable_set(:@route_name, "POST /foo/:bar")
78
+ routes = {
79
+ "POST" => [
80
+ # /bar/:baz
81
+ [/\A\/bar\/([^\/?#]+)\z/, ["baz"], [], route_handler1],
82
+ # /foo/:bar
83
+ [/\A\/foo\/([^\/?#]+)\z/, ["bar"], [], route_handler2]
84
+ ]
85
+ }
86
+ expect(authorizator.class).to receive(:routes).and_return(routes)
87
+
88
+ expect(authorizator.class.action(:post, "/foo/baz")).to eq("POST /foo/:bar".to_sym)
89
+ end
90
+ end
91
+
92
+ end
@@ -0,0 +1,77 @@
1
+ require "spec_helper"
2
+
3
+ describe AuthorizeAction do
4
+ let(:authorizator) { Class.new { include AuthorizeAction }.new }
5
+
6
+ context "#authorize_action!" do
7
+ it "forbids action when authorization rules are not defined" do
8
+ allow(authorizator).to receive(:current_action_name).and_return(:action)
9
+ expect(authorizator).to receive(:forbid_action!)
10
+
11
+ authorizator.class.authorization_rules = nil
12
+ authorizator.authorize_action!
13
+ end
14
+
15
+ it "forbids action when authorization rules are empty" do
16
+ allow(authorizator).to receive(:current_action_name).and_return(:action)
17
+ expect(authorizator).to receive(:forbid_action!)
18
+
19
+ authorizator.class.authorization_rules = {}
20
+ authorizator.authorize_action!
21
+ end
22
+
23
+ it "forbids action when authorization rule is not defined for current action" do
24
+ allow(authorizator).to receive(:current_action_name).and_return(:action)
25
+ expect(authorizator).to receive(:forbid_action!)
26
+
27
+ authorizator.class.authorization_rules = {other_action: -> { false }}
28
+ authorizator.authorize_action!
29
+ end
30
+
31
+ it "forbids action when authorization rule returns false" do
32
+ allow(authorizator).to receive(:current_action_name).and_return(:action)
33
+ expect(authorizator).to receive(:forbid_action!)
34
+
35
+ authorizator.class.authorization_rules = {action: -> { false }}
36
+ authorizator.authorize_action!
37
+ end
38
+
39
+ it "allows action when authorization rule returns true" do
40
+ allow(authorizator).to receive(:current_action_name).and_return(:action)
41
+ expect(authorizator).to_not receive(:forbid_action!)
42
+
43
+ authorizator.class.authorization_rules = {action: -> { true }}
44
+ authorizator.authorize_action!
45
+ end
46
+
47
+ it "allows action when authorization rule returns truthy value" do
48
+ allow(authorizator).to receive(:current_action_name).and_return(:action)
49
+ expect(authorizator).to_not receive(:forbid_action!)
50
+
51
+ authorizator.class.authorization_rules = {action: -> { "truthy" }}
52
+ authorizator.authorize_action!
53
+ end
54
+
55
+ it "executes instance method if authorization rule is defined as Symbol" do
56
+ allow(authorizator).to receive(:current_action_name).and_return(:action)
57
+ expect(authorizator).to receive(:admin?).and_return(true)
58
+ expect(authorizator).to_not receive(:forbid_action!)
59
+
60
+ authorizator.class.authorization_rules = {action: :admin?}
61
+ authorizator.authorize_action!
62
+ end
63
+ end
64
+
65
+ it "#authorization_rules are not defined by default" do
66
+ expect(authorizator.class.authorization_rules).to be_nil
67
+ end
68
+
69
+ it "#forbid_action! is not implemented by default" do
70
+ expect { authorizator.send(:forbid_action!) }.to raise_error(NotImplementedError)
71
+ end
72
+
73
+ it "#current_action_name is not implemented by default" do
74
+ expect { authorizator.send(:current_action_name) }.to raise_error(NotImplementedError)
75
+ end
76
+
77
+ end
@@ -0,0 +1,12 @@
1
+ require "simplecov"
2
+ require "coveralls"
3
+
4
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
5
+ SimpleCov.start
6
+
7
+ require File.expand_path("../lib/authorize_action", __dir__)
8
+
9
+ RSpec.configure do |config|
10
+ config.order = :random
11
+ config.color = true
12
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: authorize_action
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Jarmo Pertman
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 3.1.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.1.0
55
+ description:
56
+ email:
57
+ - jarmo.p@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".travis.yml"
64
+ - CHANGES.md
65
+ - Gemfile
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - authorize_action.gemspec
70
+ - lib/authorize_action.rb
71
+ - lib/authorize_action/rails.rb
72
+ - lib/authorize_action/sinatra.rb
73
+ - spec/authorize_action/rails_spec.rb
74
+ - spec/authorize_action/sinatra_spec.rb
75
+ - spec/authorize_action_spec.rb
76
+ - spec/spec_helper.rb
77
+ homepage: https://github.com/jarmo/authorize_action
78
+ licenses:
79
+ - MIT
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.4.5
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: Really secure and simple authorization library for your Rails, Sinatra or
101
+ whatever web framework, which doesn't suck.
102
+ test_files:
103
+ - spec/authorize_action/rails_spec.rb
104
+ - spec/authorize_action/sinatra_spec.rb
105
+ - spec/authorize_action_spec.rb
106
+ - spec/spec_helper.rb