porteiro 0.0.4 → 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 +4 -4
- data/.gitignore +5 -0
- data/Gemfile +0 -1
- data/LICENSE.txt +1 -1
- data/README.md +14 -4
- data/Rakefile +8 -1
- data/lib/porteiro.rb +33 -41
- data/lib/porteiro/policy_finder.rb +35 -22
- data/lib/porteiro/version.rb +1 -1
- data/porteiro.gemspec +8 -8
- data/test/policy_finder_test.rb +82 -0
- data/test/porteiro_test.rb +162 -0
- data/test/support/application_policy.rb +12 -0
- data/test/support/comments_policy.rb +21 -0
- data/test/support/mock_user.rb +6 -0
- data/test/support/test_controller.rb +27 -0
- data/test/support/test_helper.rb +8 -0
- metadata +40 -45
- data/.rspec +0 -1
- data/spec/porteiro_spec.rb +0 -93
- data/spec/spec_helper.rb +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8df7f6dcfe31a88b0ca3a25dd320944b58a93807
|
4
|
+
data.tar.gz: 9318d0767c05a425f71cb92e860254d83fc29358
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc0806ec204f27d8f937c8f0132cecd385926bcb5dbb17aa8f7d794d42d634c55451a5e6527ed92a99c390d9046914cd8f5437beade5c264759aee8c50356c4c
|
7
|
+
data.tar.gz: bb537dbc6492707b0850d561da4c7b39f8e77ed3fdf2a8a6c4c5dafdf543786b39788d2bbd4ce51f72818bc5de46875b664622f68923ef35c520bb4e26cc5224
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,17 @@
|
|
1
1
|
# Porteiro
|
2
2
|
|
3
|
-
|
3
|
+
Porteiro is pundit for controllers. Policies are meant for authorizing requests through controller actions.
|
4
|
+
|
5
|
+
## Features:
|
6
|
+
|
7
|
+
- Supports policy fallback, so you can create a default policy that will be used in the absence of a
|
8
|
+
defined policy. To use this, define a method in your controller called default_policy and add a string with the name
|
9
|
+
of the class to be used. E.g..
|
10
|
+
|
11
|
+
def default_policy
|
12
|
+
'ApplicationPolicy'
|
13
|
+
end
|
14
|
+
|
4
15
|
|
5
16
|
## Installation
|
6
17
|
|
@@ -18,12 +29,11 @@ Or install it yourself as:
|
|
18
29
|
|
19
30
|
## Usage
|
20
31
|
|
21
|
-
TODO: Write usage instructions here
|
22
32
|
|
23
33
|
## Contributing
|
24
34
|
|
25
|
-
1. Fork it
|
35
|
+
1. Fork it ( https://github.com/[my-github-username]/porteiro/fork )
|
26
36
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
37
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
38
|
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
-
5. Create new Pull Request
|
39
|
+
5. Create a new Pull Request
|
data/Rakefile
CHANGED
data/lib/porteiro.rb
CHANGED
@@ -1,60 +1,52 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require "active_support/concern"
|
4
|
-
require "active_support/inflector"
|
1
|
+
require 'porteiro/version'
|
2
|
+
require 'porteiro/policy_finder'
|
5
3
|
|
6
4
|
module Porteiro
|
7
|
-
extend ActiveSupport::Concern
|
8
5
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
class << self
|
6
|
+
UnauthorizedAction = Class.new(StandardError) do
|
7
|
+
attr_accessor :user, :policy, :context
|
8
|
+
end
|
14
9
|
|
15
|
-
|
16
|
-
# ClassMethod to find policy with PolicyFinder using the current_user
|
17
|
-
# and request params.
|
18
|
-
##
|
10
|
+
AuthorizationNotPerformed = Class.new(StandardError)
|
19
11
|
|
20
|
-
|
21
|
-
|
22
|
-
|
12
|
+
def authorize!(other_action_name=nil)
|
13
|
+
policy_authorized!
|
14
|
+
policy = porteiro_policy
|
15
|
+
policy_action = porteiro_action(other_action_name)
|
16
|
+
unless policy.public_send(policy_action)
|
17
|
+
error = UnauthorizedAction.new("#{policy.class}: #{policy_action}")
|
18
|
+
error.user, error.policy, error.context = porteiro_user, policy, policy_action
|
19
|
+
raise error
|
23
20
|
end
|
21
|
+
true
|
22
|
+
end
|
24
23
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
attr_writer :default_policy
|
24
|
+
def porteiro_policy
|
25
|
+
PolicyFinder.call(
|
26
|
+
self,
|
27
|
+
porteiro_user,
|
28
|
+
porteiro_default_policy
|
29
|
+
)
|
30
|
+
end
|
33
31
|
|
32
|
+
def porteiro_action(other_action_name=nil)
|
33
|
+
name = other_action_name || action_name
|
34
|
+
[name.to_s, '?'].join
|
34
35
|
end
|
35
36
|
|
36
|
-
|
37
|
-
|
38
|
-
# If this is not called, no policy will be looked up.
|
39
|
-
##
|
37
|
+
def porteiro_default_policy
|
38
|
+
end
|
40
39
|
|
41
|
-
def
|
42
|
-
|
43
|
-
policy_obj = policy
|
44
|
-
controller_action = policy_obj.params.fetch(:action)
|
45
|
-
policy_obj.send("#{controller_action}?") ? true : (raise NotAuthorizedError, "You aren't permitted to access this resource")
|
40
|
+
def porteiro_user
|
41
|
+
current_user
|
46
42
|
end
|
47
43
|
|
48
44
|
def verify_authorized
|
49
|
-
|
50
|
-
end
|
51
|
-
|
52
|
-
def policy
|
53
|
-
@policy || Porteiro.policy(porteiro_user, params)
|
45
|
+
raise AuthorizationNotPerformed unless @_porteiro_policy_authorized
|
54
46
|
end
|
55
47
|
|
56
|
-
def
|
57
|
-
|
48
|
+
def policy_authorized!
|
49
|
+
@_porteiro_policy_authorized = true
|
58
50
|
end
|
59
51
|
|
60
52
|
end
|
@@ -1,38 +1,51 @@
|
|
1
|
+
require 'active_support/core_ext/string/inflections'
|
2
|
+
|
1
3
|
module Porteiro
|
2
4
|
class PolicyFinder
|
3
5
|
|
4
|
-
|
6
|
+
PolicyNotFound = Class.new(StandardError)
|
7
|
+
|
8
|
+
def self.call(context, user, default_policy=nil)
|
9
|
+
service = new(context, user, default_policy)
|
10
|
+
service.call
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :context, :user, :default_policy
|
14
|
+
def initialize(context, user, default_policy=nil)
|
15
|
+
@context = context
|
16
|
+
@user = user
|
17
|
+
@default_policy = default_policy
|
18
|
+
end
|
5
19
|
|
6
|
-
def
|
7
|
-
|
8
|
-
@req_params = req_params
|
9
|
-
@klass = fetch_klass_from_params
|
20
|
+
def call
|
21
|
+
policy.new(user, context)
|
10
22
|
end
|
11
23
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
raise PolicyUndefinedError, "You must define your default policy: #{Porteiro.default_policy}"
|
24
|
+
def policy
|
25
|
+
policy = safe_constantize(policy_class_name)
|
26
|
+
if !policy && default_policy
|
27
|
+
policy = safe_constantize(default_policy)
|
17
28
|
end
|
29
|
+
raise PolicyNotFound, "#{policy_class_name} could not be found" unless policy
|
30
|
+
policy
|
18
31
|
end
|
19
32
|
|
20
|
-
def
|
21
|
-
|
33
|
+
def policy_class_name
|
34
|
+
[controller_name, 'Policy'].join
|
35
|
+
end
|
36
|
+
|
37
|
+
def controller_name
|
38
|
+
context.params[:controller].camelize
|
22
39
|
end
|
23
40
|
|
24
|
-
##
|
25
|
-
# Finds policy and instantiates it. If policy doesn't exist, the default
|
26
|
-
# policy is instantiated. This removes the need to define every policy if
|
27
|
-
# you want to use method_missing in the default policy.
|
28
|
-
##
|
29
41
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
42
|
+
private
|
43
|
+
|
44
|
+
def safe_constantize(name)
|
45
|
+
::Object.const_get(name.to_s)
|
46
|
+
rescue ::NameError
|
47
|
+
nil
|
34
48
|
end
|
35
49
|
|
36
50
|
end
|
37
51
|
end
|
38
|
-
|
data/lib/porteiro/version.rb
CHANGED
data/porteiro.gemspec
CHANGED
@@ -8,20 +8,20 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Porteiro::VERSION
|
9
9
|
spec.authors = ["bradwheel"]
|
10
10
|
spec.email = ["bradley.m.wheel@gmail.com"]
|
11
|
-
spec.
|
12
|
-
spec.
|
11
|
+
spec.summary = %q{API Authorization for controllers.}
|
12
|
+
spec.description = %q{Pundit for controllers only.}
|
13
13
|
spec.homepage = ""
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
|
-
spec.files = `git ls-files`.split(
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency "activesupport"
|
22
|
-
|
23
|
-
spec.add_development_dependency "
|
24
|
-
spec.add_development_dependency "pry"
|
25
|
-
spec.add_development_dependency "bundler", "~> 1.3"
|
21
|
+
spec.add_dependency "activesupport"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
26
24
|
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "minitest-reporters"
|
26
|
+
spec.add_development_dependency "pry"
|
27
27
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'support/test_helper'
|
2
|
+
require 'support/test_controller'
|
3
|
+
require 'support/mock_user'
|
4
|
+
require 'support/comments_policy'
|
5
|
+
require 'porteiro/policy_finder'
|
6
|
+
|
7
|
+
module Porteiro
|
8
|
+
describe PolicyFinder do
|
9
|
+
|
10
|
+
|
11
|
+
before do
|
12
|
+
@context = ::TestController.new(
|
13
|
+
'comments',
|
14
|
+
'index',
|
15
|
+
{format: :json, action: 'index', controller: 'comments'}
|
16
|
+
)
|
17
|
+
@user = ::MockUser.new
|
18
|
+
@policy_finder = PolicyFinder.new(@context, @user)
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
describe '#call' do
|
23
|
+
|
24
|
+
it 'finds policy by controller name' do
|
25
|
+
@policy_finder.call.must_be_instance_of ::CommentsPolicy
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#policy_class_name' do
|
31
|
+
|
32
|
+
it 'returns the controller name concatenated with Policy' do
|
33
|
+
@policy_finder.policy_class_name.must_equal 'CommentsPolicy'
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'when controller is nested' do
|
37
|
+
|
38
|
+
it 'retains the class hierarchy' do
|
39
|
+
context = ::TestController.new(
|
40
|
+
'comments',
|
41
|
+
'index',
|
42
|
+
{format: :json, action: 'index', controller: 'user/posts/comments'}
|
43
|
+
)
|
44
|
+
policy_finder = PolicyFinder.new(context, @user)
|
45
|
+
policy_finder.policy_class_name.must_equal 'User::Posts::CommentsPolicy'
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#controller_name' do
|
53
|
+
|
54
|
+
it 'returns the controller name camelized' do
|
55
|
+
@policy_finder.controller_name.must_equal 'Comments'
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'when controller is nested' do
|
59
|
+
|
60
|
+
it 'retains the class hierarchy' do
|
61
|
+
context = ::TestController.new(
|
62
|
+
'comments',
|
63
|
+
'index',
|
64
|
+
{format: :json, action: 'index', controller: 'user/posts/comments'}
|
65
|
+
)
|
66
|
+
@policy_finder = PolicyFinder.new(context, @user)
|
67
|
+
@policy_finder.controller_name.must_equal 'User::Posts::Comments'
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#safe_constantize'do
|
75
|
+
|
76
|
+
it { @policy_finder.send(:safe_constantize, 'Object').must_equal Object }
|
77
|
+
it { @policy_finder.send(:safe_constantize, 'Obbject').must_be_nil }
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'support/test_helper'
|
2
|
+
require 'support/comments_policy'
|
3
|
+
require 'support/application_policy'
|
4
|
+
require 'support/mock_user'
|
5
|
+
|
6
|
+
describe Porteiro do
|
7
|
+
|
8
|
+
|
9
|
+
before do
|
10
|
+
::TestController.include(Porteiro)
|
11
|
+
@context = ::TestController.new(
|
12
|
+
'comments',
|
13
|
+
'index',
|
14
|
+
{format: :json, action: 'index', controller: 'comments'}
|
15
|
+
)
|
16
|
+
@brad = ::MockUser.new('brad')
|
17
|
+
@joe = ::MockUser.new('joe')
|
18
|
+
@context.current_user = @joe
|
19
|
+
@context.other_user = @brad
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
describe '#porteiro_policy' do
|
24
|
+
|
25
|
+
it 'calls PolicyFinder with context and porteiro_user' do
|
26
|
+
mock = ::Minitest::Mock.new
|
27
|
+
mock.expect(:call, nil, [@context, @joe, nil])
|
28
|
+
|
29
|
+
Porteiro::PolicyFinder.stub(:call, mock) do
|
30
|
+
@context.stub(:porteiro_user, @joe) do
|
31
|
+
@context.porteiro_policy
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
mock.verify
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#porteiro_action' do
|
41
|
+
|
42
|
+
it 'returns the action_name concatenated with ?' do
|
43
|
+
@context.porteiro_action.must_equal 'index?'
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'returns the other action name when supplied' do
|
47
|
+
@context.porteiro_action('create').must_equal 'create?'
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#porteiro_user' do
|
53
|
+
|
54
|
+
describe 'when porteiro_user is not set' do
|
55
|
+
|
56
|
+
it 'returns current_user' do
|
57
|
+
@context.porteiro_user.name.must_equal @joe.name
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
describe 'when porteiro_user is defined' do
|
63
|
+
|
64
|
+
before do
|
65
|
+
@context.instance_eval do
|
66
|
+
def porteiro_user
|
67
|
+
other_user
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'returns set user' do
|
73
|
+
@context.porteiro_user.name.must_equal @brad.name
|
74
|
+
end
|
75
|
+
|
76
|
+
after do
|
77
|
+
@context.instance_eval do
|
78
|
+
undef :porteiro_user
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '#authorize' do
|
87
|
+
|
88
|
+
describe 'when can access' do
|
89
|
+
|
90
|
+
it 'returns true' do
|
91
|
+
@context.authorize!.must_equal true
|
92
|
+
end
|
93
|
+
|
94
|
+
describe 'when policy verification is not ran' do
|
95
|
+
|
96
|
+
it 'raises Porteiro::AuthorizationNotPerformed' do
|
97
|
+
proc { @context.verify_authorized }.must_raise Porteiro::AuthorizationNotPerformed
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
describe 'when cannot access' do
|
105
|
+
|
106
|
+
it 'raises Porteiro::ActionUnauthorized' do
|
107
|
+
context = ::TestController.new(
|
108
|
+
'comments',
|
109
|
+
'create',
|
110
|
+
{format: :json, action: 'index', controller: 'comments'}
|
111
|
+
)
|
112
|
+
|
113
|
+
proc { context.authorize! }.must_raise Porteiro::UnauthorizedAction
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
describe 'policy default' do
|
121
|
+
|
122
|
+
before do
|
123
|
+
@context = ::TestController.new(
|
124
|
+
'posts',
|
125
|
+
'create',
|
126
|
+
{format: :json, action: 'create', controller: 'posts'}
|
127
|
+
)
|
128
|
+
end
|
129
|
+
|
130
|
+
describe 'when given a default policy' do
|
131
|
+
|
132
|
+
before do
|
133
|
+
@context.instance_eval do
|
134
|
+
def porteiro_default_policy
|
135
|
+
'::ApplicationPolicy'
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'uses default' do
|
141
|
+
@context.authorize!.must_equal true
|
142
|
+
end
|
143
|
+
|
144
|
+
after do
|
145
|
+
@context.instance_eval do
|
146
|
+
undef :porteiro_default_policy
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
describe 'when not given a default policy' do
|
153
|
+
|
154
|
+
it 'raises Porteiro::PolicyNotFound if not given' do
|
155
|
+
proc { @context.authorize! }.must_raise Porteiro::PolicyFinder::PolicyNotFound
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class TestController
|
2
|
+
|
3
|
+
attr_reader :controller_name, :action_name, :params
|
4
|
+
|
5
|
+
def initialize(controller_name, action_name, params)
|
6
|
+
@controller_name = controller_name
|
7
|
+
@action_name = action_name
|
8
|
+
@params = params
|
9
|
+
end
|
10
|
+
|
11
|
+
def current_user
|
12
|
+
@current_user
|
13
|
+
end
|
14
|
+
|
15
|
+
def current_user=(user)
|
16
|
+
@current_user = user
|
17
|
+
end
|
18
|
+
|
19
|
+
def other_user
|
20
|
+
@other_user
|
21
|
+
end
|
22
|
+
|
23
|
+
def other_user=(user)
|
24
|
+
@other_user = user
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
metadata
CHANGED
@@ -1,108 +1,93 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: porteiro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- bradwheel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: '1.6'
|
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:
|
40
|
+
version: '1.6'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: minitest-reporters
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ~>
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '1.3'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ~>
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '1.3'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rake
|
70
|
+
name: pry
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
86
72
|
requirements:
|
87
|
-
- -
|
73
|
+
- - ">="
|
88
74
|
- !ruby/object:Gem::Version
|
89
75
|
version: '0'
|
90
76
|
type: :development
|
91
77
|
prerelease: false
|
92
78
|
version_requirements: !ruby/object:Gem::Requirement
|
93
79
|
requirements:
|
94
|
-
- -
|
80
|
+
- - ">="
|
95
81
|
- !ruby/object:Gem::Version
|
96
82
|
version: '0'
|
97
|
-
description:
|
83
|
+
description: Pundit for controllers only.
|
98
84
|
email:
|
99
85
|
- bradley.m.wheel@gmail.com
|
100
86
|
executables: []
|
101
87
|
extensions: []
|
102
88
|
extra_rdoc_files: []
|
103
89
|
files:
|
104
|
-
- .gitignore
|
105
|
-
- .rspec
|
90
|
+
- ".gitignore"
|
106
91
|
- Gemfile
|
107
92
|
- LICENSE.txt
|
108
93
|
- README.md
|
@@ -111,8 +96,13 @@ files:
|
|
111
96
|
- lib/porteiro/policy_finder.rb
|
112
97
|
- lib/porteiro/version.rb
|
113
98
|
- porteiro.gemspec
|
114
|
-
-
|
115
|
-
-
|
99
|
+
- test/policy_finder_test.rb
|
100
|
+
- test/porteiro_test.rb
|
101
|
+
- test/support/application_policy.rb
|
102
|
+
- test/support/comments_policy.rb
|
103
|
+
- test/support/mock_user.rb
|
104
|
+
- test/support/test_controller.rb
|
105
|
+
- test/support/test_helper.rb
|
116
106
|
homepage: ''
|
117
107
|
licenses:
|
118
108
|
- MIT
|
@@ -123,20 +113,25 @@ require_paths:
|
|
123
113
|
- lib
|
124
114
|
required_ruby_version: !ruby/object:Gem::Requirement
|
125
115
|
requirements:
|
126
|
-
- -
|
116
|
+
- - ">="
|
127
117
|
- !ruby/object:Gem::Version
|
128
118
|
version: '0'
|
129
119
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
120
|
requirements:
|
131
|
-
- -
|
121
|
+
- - ">="
|
132
122
|
- !ruby/object:Gem::Version
|
133
123
|
version: '0'
|
134
124
|
requirements: []
|
135
125
|
rubyforge_project:
|
136
|
-
rubygems_version: 2.
|
126
|
+
rubygems_version: 2.2.2
|
137
127
|
signing_key:
|
138
128
|
specification_version: 4
|
139
|
-
summary: Authorization for controllers
|
129
|
+
summary: API Authorization for controllers.
|
140
130
|
test_files:
|
141
|
-
-
|
142
|
-
-
|
131
|
+
- test/policy_finder_test.rb
|
132
|
+
- test/porteiro_test.rb
|
133
|
+
- test/support/application_policy.rb
|
134
|
+
- test/support/comments_policy.rb
|
135
|
+
- test/support/mock_user.rb
|
136
|
+
- test/support/test_controller.rb
|
137
|
+
- test/support/test_helper.rb
|
data/.rspec
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
--format documentation
|
data/spec/porteiro_spec.rb
DELETED
@@ -1,93 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Porteiro do
|
4
|
-
|
5
|
-
let!(:current_user) {User.new}
|
6
|
-
let!(:controller) {ControllerClass.new(current_user)}
|
7
|
-
|
8
|
-
|
9
|
-
describe "#porteiro_user" do
|
10
|
-
|
11
|
-
it "returns the current_user" do
|
12
|
-
expect(controller.porteiro_user).to eq current_user
|
13
|
-
end
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
describe "#policy" do
|
18
|
-
|
19
|
-
it "returns the instance of policy finder" do
|
20
|
-
expect(controller.policy.user).to eq(Porteiro.policy(controller.porteiro_user, controller.params).user)
|
21
|
-
expect(controller.policy.params).to eq(Porteiro.policy(controller.porteiro_user, controller.params).params)
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
describe "#default_policy" do
|
27
|
-
|
28
|
-
it "uses ApplicationPolicy as a default unless specified" do
|
29
|
-
expect(Porteiro.default_policy).to eq "ApplicationPolicy"
|
30
|
-
end
|
31
|
-
|
32
|
-
it "uses the specified default policy if supplied" do
|
33
|
-
Porteiro.default_policy=("SuppliedPolicy")
|
34
|
-
expect(Porteiro.default_policy).to eq "SuppliedPolicy"
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
38
|
-
|
39
|
-
describe Porteiro::PolicyFinder do
|
40
|
-
|
41
|
-
it "finds the correct policy from controller params" do
|
42
|
-
policy = Porteiro::PolicyFinder.new(controller.current_user, controller.params)
|
43
|
-
expect(policy.klass).to eq "Document"
|
44
|
-
end
|
45
|
-
|
46
|
-
context "when policy doesn't exist" do
|
47
|
-
|
48
|
-
it "instantiates the default policy" do
|
49
|
-
Porteiro.default_policy = "ApplicationPolicy"
|
50
|
-
policy = Porteiro::PolicyFinder.new(controller.current_user, controller.params).find!
|
51
|
-
expect(policy).to be_instance_of(ApplicationPolicy)
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
55
|
-
|
56
|
-
context "when policy does exist" do
|
57
|
-
|
58
|
-
|
59
|
-
before(:each) do
|
60
|
-
class DocumentPolicy < ApplicationPolicy; end
|
61
|
-
end
|
62
|
-
|
63
|
-
it "instantiates the correct policy" do
|
64
|
-
policy = Porteiro::PolicyFinder.new(controller.current_user, controller.params).find!
|
65
|
-
expect(policy).to be_instance_of(DocumentPolicy)
|
66
|
-
end
|
67
|
-
|
68
|
-
end
|
69
|
-
|
70
|
-
end
|
71
|
-
|
72
|
-
describe "#authorize_user_access!" do
|
73
|
-
|
74
|
-
context "when the action is permitted" do
|
75
|
-
|
76
|
-
it "returns true" do
|
77
|
-
expect(controller.authorize_user_access!).to be(true)
|
78
|
-
end
|
79
|
-
|
80
|
-
end
|
81
|
-
|
82
|
-
context "when the action is not permitted" do
|
83
|
-
|
84
|
-
it "raises Porteiro::NotAuthorizedError" do
|
85
|
-
controller.params[:action] = "edit"
|
86
|
-
expect {controller.authorize_user_access!}.to raise_error(Porteiro::NotAuthorizedError)
|
87
|
-
end
|
88
|
-
|
89
|
-
end
|
90
|
-
|
91
|
-
end
|
92
|
-
|
93
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
require "porteiro"
|
2
|
-
require "pry"
|
3
|
-
|
4
|
-
class User < Struct.new(:name); end
|
5
|
-
|
6
|
-
class ControllerClass
|
7
|
-
include Porteiro
|
8
|
-
|
9
|
-
attr_accessor :current_user
|
10
|
-
|
11
|
-
def initialize(user)
|
12
|
-
@current_user = user
|
13
|
-
end
|
14
|
-
|
15
|
-
def params
|
16
|
-
@params ||= {controller: "document", action: "index"}
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
|
22
|
-
class ApplicationPolicy
|
23
|
-
|
24
|
-
def initialize(user, params)
|
25
|
-
@user = user
|
26
|
-
@params = params
|
27
|
-
end
|
28
|
-
attr_reader :user, :params
|
29
|
-
|
30
|
-
def index?
|
31
|
-
true
|
32
|
-
end
|
33
|
-
|
34
|
-
def show?
|
35
|
-
true
|
36
|
-
end
|
37
|
-
|
38
|
-
def edit?
|
39
|
-
false
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|