authorizy 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +23 -9
- data/lib/authorizy/core.rb +6 -6
- data/lib/authorizy/expander.rb +7 -11
- data/lib/authorizy/extension.rb +8 -6
- data/lib/authorizy/version.rb +1 -1
- data/spec/authorizy/config_spec.rb +7 -0
- data/spec/authorizy/configure_spec.rb +9 -0
- data/spec/authorizy/cop/controller_spec.rb +1 -1
- data/spec/authorizy/extension/authorizy_question_spec.rb +24 -0
- data/spec/authorizy/rspec_spec.rb +20 -1
- data/spec/support/models/authorizy_cop.rb +4 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d53108a017e691256dd6118c843aa217dc549628499721a2cda193d522289652
|
4
|
+
data.tar.gz: 4799bf0eb35c6f9695fe6b55eceaa4ed29a373fcfc3e7fbebaeee38af40ec4e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab9a47d232ffd388efbc5a34eb0c8c8560f8ffc854e42683cd305d35af64d1823179946bb09cbb38a735ce50c9a2245e2f0988835cf359c082bf454992dc91fa
|
7
|
+
data.tar.gz: 2d7fdedc111586256e9920fd5041d7b3fff9cb87c6133e8452404b85c372f66ada4828bbf4a5ce9e264dffbd16ee9096a9404cfda4ddec2af9dfb613a916ed1b
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/authorizy.svg)](https://badge.fury.io/rb/authorizy)
|
5
5
|
[![Maintainability](https://api.codeclimate.com/v1/badges/f312587b4f126bb13e85/maintainability)](https://codeclimate.com/github/wbotelhos/authorizy/maintainability)
|
6
6
|
[![Coverage](https://codecov.io/gh/wbotelhos/authorizy/branch/main/graph/badge.svg)](https://codecov.io/gh/wbotelhos/authorizy)
|
7
|
-
[![Sponsor](https://img.shields.io/badge/sponsor-%3C3-green)](https://
|
7
|
+
[![Sponsor](https://img.shields.io/badge/sponsor-%3C3-green)](https://github.com/sponsors/wbotelhos)
|
8
8
|
|
9
9
|
A JSON based Authorization.
|
10
10
|
|
@@ -22,7 +22,7 @@ Run the following task to create Authorizy migration and initialize.
|
|
22
22
|
rails g authorizy:install
|
23
23
|
```
|
24
24
|
|
25
|
-
Then execute the migration to
|
25
|
+
Then execute the migration to add the column `authorizy` to your `users` table.
|
26
26
|
|
27
27
|
```sh
|
28
28
|
rake db:migrate
|
@@ -208,15 +208,29 @@ Using on view:
|
|
208
208
|
<% end %>
|
209
209
|
```
|
210
210
|
|
211
|
+
Usually, we use the helper to check DB permission, not the runtime permission using the Cop file, although you can do it. Just remember that the parameters will be related to the current page, not the action you're protecting.
|
212
|
+
|
211
213
|
Using on jBuilder view:
|
212
214
|
|
213
215
|
```ruby
|
214
|
-
|
216
|
+
if authorizy?(:users, :create)
|
217
|
+
link_to('Create', new_users_url)
|
218
|
+
end
|
219
|
+
```
|
220
|
+
|
221
|
+
But if you want to simulate the access on that resource you can manually provide the same parameters dispatched when you normally access that resource:
|
222
|
+
|
223
|
+
```ruby
|
224
|
+
if authorizy?(:users, :create, params: { role: 'admin' })
|
225
|
+
link_to('Create', new_users_url(role: 'admin'))
|
226
|
+
end
|
215
227
|
```
|
216
228
|
|
229
|
+
Now you're providing the same parameters used in runtime when the user accesses the link, so now, we can check the "future" access and prevent or allow it before happens.
|
230
|
+
|
217
231
|
# Specs
|
218
232
|
|
219
|
-
To test some routes you'll need to give or not permission to the user, for that you have
|
233
|
+
To test some routes you'll need to give or not permission to the user, for that you have two ways, where the first is the user via session:
|
220
234
|
|
221
235
|
```ruby
|
222
236
|
before do
|
@@ -238,7 +252,7 @@ end
|
|
238
252
|
|
239
253
|
## Checks
|
240
254
|
|
241
|
-
We have a couple of
|
255
|
+
We have a couple of checks, here is the order:
|
242
256
|
|
243
257
|
1. `Authorizy::BaseCop#access?`;
|
244
258
|
2. `session[:permissions]`;
|
@@ -247,15 +261,15 @@ We have a couple of check, here is the order:
|
|
247
261
|
|
248
262
|
## Performance
|
249
263
|
|
250
|
-
If you have few permissions, you can save the permissions in the session and avoid
|
264
|
+
If you have few permissions, you can save the permissions in the session and avoid hitting the database many times, but if you have a couple of them, maybe it's a good idea to save them in some place like [Redis](https://redis.io).
|
251
265
|
|
252
266
|
## Management
|
253
267
|
|
254
|
-
It's a good idea you keep your permissions in the database, so the customer can change it
|
268
|
+
It's a good idea you keep your permissions in the database, so the customer can change it dynamically. You can load all permissions when the user is logged in and cache it later. For cache expiration, you can trigger a refresh every time that the permissions change.
|
255
269
|
|
256
270
|
## Database Structure
|
257
271
|
|
258
|
-
Inside database you can use the following relation to
|
272
|
+
Inside the database, you can use the following relation to dynamically change your permissions:
|
259
273
|
|
260
274
|
```ruby
|
261
275
|
plans -> plans_permissions <- permissions
|
@@ -269,7 +283,7 @@ plans -> plans_permissions <- permissions
|
|
269
283
|
|
270
284
|
## RSpec
|
271
285
|
|
272
|
-
You can test
|
286
|
+
You can test your app by passing through all Authorizy layers:
|
273
287
|
|
274
288
|
```ruby
|
275
289
|
user = User.create!(permission: { permissions: [[:users, :create]] })
|
data/lib/authorizy/core.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Authorizy
|
4
4
|
class Core
|
5
|
-
def initialize(user, params, session, cop:)
|
5
|
+
def initialize(user, params, session, cop: nil)
|
6
6
|
@cop = cop
|
7
7
|
@params = params
|
8
8
|
@session = session
|
@@ -12,13 +12,13 @@ module Authorizy
|
|
12
12
|
def access?
|
13
13
|
return false if @user.blank?
|
14
14
|
|
15
|
-
return true if @cop
|
16
|
-
|
17
|
-
|
15
|
+
return true if @cop&.access?
|
16
|
+
return true if session_permissions.any? { |tuple| route_match?(tuple) }
|
17
|
+
return true if user_permissions.any? { |tuple| route_match?(tuple) }
|
18
18
|
|
19
|
-
return
|
19
|
+
return false unless @cop.respond_to?(cop_controller)
|
20
20
|
|
21
|
-
|
21
|
+
@cop.public_send(cop_controller) == true
|
22
22
|
end
|
23
23
|
|
24
24
|
private
|
data/lib/authorizy/expander.rb
CHANGED
@@ -19,7 +19,7 @@ module Authorizy
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
actions = [
|
22
|
+
actions = [aliases[action]].flatten.compact
|
23
23
|
|
24
24
|
next if actions.blank?
|
25
25
|
|
@@ -34,7 +34,12 @@ module Authorizy
|
|
34
34
|
private
|
35
35
|
|
36
36
|
def aliases
|
37
|
-
|
37
|
+
default = {
|
38
|
+
'create' => 'new',
|
39
|
+
'update' => 'edit',
|
40
|
+
}
|
41
|
+
|
42
|
+
default.merge(Authorizy.config.aliases.stringify_keys)
|
38
43
|
end
|
39
44
|
|
40
45
|
def controller_dependency(controller, action)
|
@@ -44,15 +49,6 @@ module Authorizy
|
|
44
49
|
permissions.map { |c, a| [c.to_s, a.to_s] }
|
45
50
|
end
|
46
51
|
|
47
|
-
def default_aliases
|
48
|
-
{
|
49
|
-
'create' => 'new',
|
50
|
-
'edit' => 'update',
|
51
|
-
'new' => 'create',
|
52
|
-
'update' => 'edit',
|
53
|
-
}.merge(aliases)
|
54
|
-
end
|
55
|
-
|
56
52
|
def dependencies
|
57
53
|
Authorizy.config.dependencies.deep_stringify_keys
|
58
54
|
end
|
data/lib/authorizy/extension.rb
CHANGED
@@ -13,21 +13,23 @@ module Authorizy
|
|
13
13
|
Authorizy.config.denied.call(self)
|
14
14
|
end
|
15
15
|
|
16
|
-
def authorizy?(controller, action)
|
16
|
+
def authorizy?(controller, action, custom_params: {})
|
17
17
|
params['controller'] = controller
|
18
18
|
params['action'] = action
|
19
19
|
|
20
|
-
|
20
|
+
parameters = params.merge(custom_params)
|
21
|
+
|
22
|
+
Authorizy::Core.new(authorizy_user, parameters, session, cop: authorizy_cop(parameters)).access?
|
21
23
|
end
|
22
24
|
|
23
25
|
private
|
24
26
|
|
25
|
-
def
|
26
|
-
Authorizy.config.
|
27
|
+
def authorizy_cop(parameters = params)
|
28
|
+
Authorizy.config.cop.new(authorizy_user, parameters, session)
|
27
29
|
end
|
28
30
|
|
29
|
-
def
|
30
|
-
Authorizy.config.
|
31
|
+
def authorizy_user
|
32
|
+
Authorizy.config.current_user.call(self)
|
31
33
|
end
|
32
34
|
end
|
33
35
|
end
|
data/lib/authorizy/version.rb
CHANGED
@@ -19,7 +19,7 @@ RSpec.describe DummyController, '#authorizy', type: :controller do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
context 'when method resturns true' do
|
22
|
-
it '
|
22
|
+
it 'does not deny the access' do
|
23
23
|
config_mock(cop: AuthorizyCop, current_user: user) do
|
24
24
|
get :action, params: { access: true }
|
25
25
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'support/controllers/dummy_controller'
|
4
|
+
require 'support/models/authorizy_cop'
|
4
5
|
|
5
6
|
RSpec.describe DummyController, '#authorizy?', type: :controller do
|
6
7
|
context 'when config returns no current user' do
|
@@ -46,5 +47,28 @@ RSpec.describe DummyController, '#authorizy?', type: :controller do
|
|
46
47
|
end
|
47
48
|
end
|
48
49
|
end
|
50
|
+
|
51
|
+
context 'when custom params is provided' do
|
52
|
+
let!(:core) { instance_double('Authorizy::Core', access?: true) }
|
53
|
+
let!(:parameters) { ActionController::Parameters.new(controller: 'controller', action: 'action', key: 'value') }
|
54
|
+
|
55
|
+
it 'forwards to core' do
|
56
|
+
expect(Authorizy::Core).to receive(:new)
|
57
|
+
.with(user, parameters, session, cop: config.cop)
|
58
|
+
.and_return(core)
|
59
|
+
|
60
|
+
config_mock(current_user: user) do
|
61
|
+
controller.helpers.authorizy?('controller', 'action', custom_params: { key: 'value' })
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'when custom params is provided' do
|
67
|
+
it 'forwards to cop' do
|
68
|
+
config_mock(cop: AuthorizyCop, current_user: user) do
|
69
|
+
controller.helpers.authorizy?('custom_params', 'action', custom_params: { custom: 'true' })
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
49
73
|
end
|
50
74
|
end
|
@@ -1,11 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'authorizy/rspec'
|
4
|
+
require 'support/models/authorizy_cop'
|
5
|
+
|
3
6
|
RSpec.describe RSpec::Matchers, '#be_authorized' do
|
4
|
-
it '
|
7
|
+
it 'builds the correct description' do
|
5
8
|
matcher = be_authorized('controller', 'action', params: { params: true }, session: { session: true })
|
6
9
|
|
7
10
|
expect(matcher.description).to eq %(
|
8
11
|
be authorized "controller", "action", and {:params=>{:params=>true}, :session=>{:session=>true}}
|
9
12
|
).squish
|
10
13
|
end
|
14
|
+
|
15
|
+
it 'has the positive question helper method' do
|
16
|
+
user = User.new
|
17
|
+
|
18
|
+
config_mock(cop: AuthorizyCop, current_user: user) do
|
19
|
+
expect(user).to be_authorized('dummy', 'any', params: { access: 'true' })
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'has the negative question helper method' do
|
24
|
+
user = User.new
|
25
|
+
|
26
|
+
config_mock(cop: AuthorizyCop, current_user: user) do
|
27
|
+
expect(user).not_to be_authorized('dummy', 'any', params: { access: 'false' })
|
28
|
+
end
|
29
|
+
end
|
11
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: authorizy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Washington Botelho
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-02-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -168,6 +168,8 @@ files:
|
|
168
168
|
- spec/authorizy/config/field_spec.rb
|
169
169
|
- spec/authorizy/config/initialize_spec.rb
|
170
170
|
- spec/authorizy/config/redirect_url_spec.rb
|
171
|
+
- spec/authorizy/config_spec.rb
|
172
|
+
- spec/authorizy/configure_spec.rb
|
171
173
|
- spec/authorizy/cop/controller_spec.rb
|
172
174
|
- spec/authorizy/cop/model_spec.rb
|
173
175
|
- spec/authorizy/cop/namespaced_controller_spec.rb
|
@@ -209,7 +211,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
209
211
|
- !ruby/object:Gem::Version
|
210
212
|
version: '0'
|
211
213
|
requirements: []
|
212
|
-
rubygems_version: 3.
|
214
|
+
rubygems_version: 3.4.19
|
213
215
|
signing_key:
|
214
216
|
specification_version: 4
|
215
217
|
summary: A JSON based Authorization.
|
@@ -223,6 +225,8 @@ test_files:
|
|
223
225
|
- spec/authorizy/config/field_spec.rb
|
224
226
|
- spec/authorizy/config/initialize_spec.rb
|
225
227
|
- spec/authorizy/config/redirect_url_spec.rb
|
228
|
+
- spec/authorizy/config_spec.rb
|
229
|
+
- spec/authorizy/configure_spec.rb
|
226
230
|
- spec/authorizy/cop/controller_spec.rb
|
227
231
|
- spec/authorizy/cop/model_spec.rb
|
228
232
|
- spec/authorizy/cop/namespaced_controller_spec.rb
|