authorize_action 1.0.0

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