active_record_api-rest 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f46306ab7aa8dfd69c9d099776f1fc095c2e9188eee1ece50edc83b87543ac69
4
- data.tar.gz: 59fc5ee48bfa4341773b76b41e7f543f0aefe6973332751aaa931b49a6197fb8
3
+ metadata.gz: d6c7bfa36f4f4e1cf3a3013003dc091864a44e6a2f0df9c47886ce37b7c4a88f
4
+ data.tar.gz: 5929dfad290e2789a5acbfa574cde379c409d4de125679966c0ed5e98f230edf
5
5
  SHA512:
6
- metadata.gz: 421c5a6f00e821c52d51d1b940664e9f8498b049ab77fbec9adb955564b7053ccc804c2310d7322d3e3806f801b536c890c46baf4d23a6a07d63abefb0d8aee1
7
- data.tar.gz: 69b974c414193b3667f0e5327e0e60e12939b6024937452c2d3f7b6ed7f05582eb339828b6f3ac5d8d52eadb155ac68d6e3e573a7f70a2085b22c2790fb7d4d2
6
+ metadata.gz: a524c311c0cd8ecda10d96d82a9900b68853e108c96d59109e5493dce0052a6ee31348807a2f423a0234ce011bbf272eccf3d39ca2063e095ca585ef951033b1
7
+ data.tar.gz: b3c7af25eb3864129781d0cdc564c33a65ba14da22001601b5450a517267466fa865e1dd63b0b48d6d26b89137c61b9f227c8a06ddbfe7675ba50abe5ce9b719
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- active_record_api-rest (1.0.1)
4
+ active_record_api-rest (1.0.3)
5
5
  active_attr
6
6
  active_model_serializers
7
7
  rails (>= 5.1)
@@ -1,12 +1,13 @@
1
- # module ActiveRecordApi
2
- # module Rest
3
- # class AccessDeniedException < Exception
4
- # attr_reader :action
5
- # attr_reader :controller
6
- # def initialize(controller, action)
7
- # @action = action
8
- # @controller = controller
9
- # end
10
- # end
11
- # end
12
- # end
1
+ module ActiveRecordApi
2
+ module Rest
3
+ class AccessDeniedException < Exception
4
+ attr_reader :action
5
+ attr_reader :controller
6
+ def initialize(controller, action, message)
7
+ super(message)
8
+ @action = action
9
+ @controller = controller
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,32 +1,60 @@
1
1
  module ActiveRecordApi
2
2
  module Rest
3
3
  class ApplicationPolicy
4
+ class Scope
5
+ attr_reader :user, :scope
6
+
7
+ def initialize(user, scope)
8
+ @user = user
9
+ @scope = scope
10
+ end
11
+
12
+ def resolve
13
+ @scope.where(id: false)
14
+ end
15
+ end
16
+
4
17
  attr_reader :user
5
- attr_reader :entity
18
+ attr_reader :model_class
19
+
20
+ READ = 'read'.freeze
21
+ MANAGE = 'manage'.freeze
6
22
 
7
- def initialize(user, entity)
23
+ def initialize(user, model_class)
8
24
  @user = user
9
- @entity = entity
25
+ @model_class = model_class
10
26
  end
11
27
 
12
28
  def index?
13
- true
29
+ can?(READ)
14
30
  end
15
31
 
16
32
  def show?
17
- true
33
+ can?(READ)
18
34
  end
19
35
 
20
36
  def create?
21
- true
37
+ can?(MANAGE)
22
38
  end
23
39
 
24
40
  def update?
25
- true
41
+ can?(MANAGE)
26
42
  end
27
43
 
28
44
  def destroy?
29
- true
45
+ can?(MANAGE)
46
+ end
47
+
48
+ protected
49
+
50
+ def can?(action)
51
+ user.full_permissions.include?("#{service_name}__#{@model_class.name.downcase}:#{action}")
52
+ end
53
+
54
+ private
55
+
56
+ def service_name
57
+ File.basename(Rails.root.to_s)
30
58
  end
31
59
  end
32
60
  end
@@ -1,6 +1,12 @@
1
1
  module ActiveRecordApi
2
2
  module Rest
3
3
  class BadSessionException < Exception
4
+ attr_reader :action
5
+ attr_reader :controller
6
+ def initialize(controller, action)
7
+ @action = action
8
+ @controller = controller
9
+ end
4
10
  end
5
11
  end
6
12
  end
@@ -60,7 +60,7 @@ module ActiveRecordApi
60
60
  end
61
61
 
62
62
  def load_model
63
- @model ||= model_klass.find(params[:id])
63
+ @model ||= scope_filter(model_klass).find(params[:id])
64
64
  end
65
65
 
66
66
  def initialize_model
@@ -68,10 +68,16 @@ module ActiveRecordApi
68
68
  end
69
69
 
70
70
  def authorize
71
- user = current_user
72
- raise BadSessionException if user.nil?
73
- policy = ("#{controller_name.classify}Policy".safe_constantize) ? "#{controller_name.classify}Policy".constantize.new(user, model) : ApplicationPolicy.new(user, model)
74
- raise AccessDeniedException.new(controller_name, action_name) unless policy.send("#{action_name}?")
71
+ raise BadSessionException.new(controller_name, action_name) if current_user.nil?
72
+ raise AccessDeniedException.new(controller_name, action_name, 'Insufficient permissions') unless policy.send("#{action_name}?")
73
+ end
74
+
75
+ def scope_filter(scope)
76
+ "#{policy.class.name}::Scope".constantize.new(current_user, scope).resolve
77
+ end
78
+
79
+ def policy
80
+ @policy ||= ("#{controller_name.classify}Policy".safe_constantize) ? "#{controller_name.classify}Policy".constantize.new(current_user, model_klass) : ApplicationPolicy.new(current_user, model_klass)
75
81
  end
76
82
  end
77
83
  end
@@ -8,9 +8,13 @@ module ActiveRecordApi
8
8
  render status: :not_found, json: { base: exception.message }
9
9
  end
10
10
 
11
- # rescue_from AccessDeniedException do |exception|
12
- # render status: :forbidden, json: { base: "Access denied on #{exception.action} #{exception.controller}" }
13
- # end
11
+ rescue_from BadSessionException do |exception|
12
+ render status: :unauthorized, json: { base: "No user for session on #{exception.action} #{exception.controller}" }
13
+ end
14
+
15
+ rescue_from AccessDeniedException do |exception|
16
+ render status: :forbidden, json: { base: "Access denied on #{exception.action} #{exception.controller}", message: exception.message }
17
+ end
14
18
  end
15
19
  end
16
20
  end
@@ -36,7 +36,7 @@ module ActiveRecordApi
36
36
  end
37
37
 
38
38
  def load_models
39
- @models = model_klass.where(filtered_params)
39
+ @models = scope_filter(model_klass).where(filtered_params)
40
40
  @total = models.count
41
41
  page_models
42
42
  end
@@ -1,15 +1,14 @@
1
1
  shared_examples 'all::rest::actions' do
2
- let(:authorize_read) { mock_valid_auth(permission_name(model_klass, 'r'), model.organization_id) }
3
- let(:unauthorize_read) { mock_valid_auth(permission_name(model_klass, ''), -1) }
4
- let(:authorize_create) { mock_valid_auth(permission_name(model_klass, 'c'), model.organization_id) }
5
- let(:unauthorize_create) { mock_valid_auth(permission_name(model_klass, ''), -1) }
6
- let(:authorize_update) { mock_valid_auth(permission_name(model_klass, 'u'), model.organization_id) }
7
- let(:unauthorize_update) { mock_valid_auth(permission_name(model_klass, ''), -1) }
8
- let(:authorize_delete) { mock_valid_auth(permission_name(model_klass, 'd'), model.organization_id) }
9
- let(:unauthorize_delete) { mock_valid_auth(permission_name(model_klass, ''), -1) }
2
+ let(:authorize_read) { mock_valid_auth([permission_name(model_klass, 'read')]) }
3
+ let(:unauthorize_read) { mock_valid_auth([permission_name(model_klass, '')]) }
4
+ let(:authorize_create) { mock_valid_auth([permission_name(model_klass, 'manage')]) }
5
+ let(:unauthorize_create) { mock_valid_auth([permission_name(model_klass, '')]) }
6
+ let(:authorize_update) { mock_valid_auth([permission_name(model_klass, 'manage')]) }
7
+ let(:unauthorize_update) { mock_valid_auth([permission_name(model_klass, '')]) }
8
+ let(:authorize_delete) { mock_valid_auth([permission_name(model_klass, 'manage')]) }
9
+ let(:unauthorize_delete) { mock_valid_auth([permission_name(model_klass, '')]) }
10
10
  let(:factory_symbol) { model_klass.to_s.underscore.to_sym }
11
- let(:index_non_accessible_data) { create factory_symbol, organization_id: (model.organization_id + 1) }
12
- let(:model_array) { [model] + create_list(factory_symbol, 4, organization_id: model.organization_id) }
11
+ let(:model_array) { [model] + create_list(factory_symbol, 4) }
13
12
  let(:base_model_klass) do
14
13
  if model_klass.superclass == ApplicationRecord
15
14
  model_klass
@@ -59,14 +58,21 @@ shared_examples 'get::show' do
59
58
  it { expect(JSON.parse(response.body)['base']).to include "Couldn't find #{base_model_klass} with 'id'=-1" }
60
59
  end
61
60
  end
62
- # context 'when not authorized' do
63
- # before(:each) do
64
- # unauthorize_read
65
- # get :show, params: { id: model.to_param }
66
- # end
67
- # it { expect(response.status).to eq 403 }
68
- # it { expect(JSON.parse(response.body)['base']).to include 'Access denied on show' }
69
- # end
61
+ context 'when not authorized' do
62
+ before(:each) do
63
+ unauthorize_read
64
+ get :show, params: { id: model.to_param }
65
+ end
66
+ it { expect(response.status).to eq 403 }
67
+ it { expect(JSON.parse(response.body)['base']).to include 'Access denied on show' }
68
+ end
69
+ context 'when bad session' do
70
+ before(:each) do
71
+ get :show, params: { id: model.to_param }
72
+ end
73
+ it { expect(response.status).to eq 401 }
74
+ it { expect(JSON.parse(response.body)['base']).to include 'No user for session on show' }
75
+ end
70
76
  end
71
77
  end
72
78
 
@@ -98,27 +104,17 @@ shared_examples 'get::index' do
98
104
  it { expect(response.headers['x-link-next']).to eq "#{host}#{request.path}?limit=1&previous_id=#{next_previous_id}" }
99
105
  it { expect(response.body).to be_json_eql model_klass.where('id > ?', previous_id).limit(1).map { |o| serializer.new(o) }.to_json }
100
106
  end
101
-
102
- # context 'when only access some of the data' do
103
- # before(:each) do
104
- # index_non_accessible_data
105
- # get :index
106
- # end
107
- # it { expect(response.status).to eq 200 }
108
- # it { expect(response.headers['x-total']).to eq 1 }
109
- # it { expect(response.body).to be_json_eql [serializer.new(model)].to_json }
110
- # end
111
107
  end
112
- # context 'when not authorized' do
113
- # before(:each) do
114
- # unauthorize_read
115
- # end
116
- # before(:each) do
117
- # get :index
118
- # end
119
- # it { expect(response.status).to eq 403 }
120
- # it { expect(JSON.parse(response.body)['base']).to include 'Access denied on index' }
121
- # end
108
+ context 'when not authorized' do
109
+ before(:each) do
110
+ unauthorize_read
111
+ end
112
+ before(:each) do
113
+ get :index
114
+ end
115
+ it { expect(response.status).to eq 403 }
116
+ it { expect(JSON.parse(response.body)['base']).to include 'Access denied on index' }
117
+ end
122
118
  end
123
119
  end
124
120
 
@@ -154,14 +150,14 @@ shared_examples 'put::update' do
154
150
  it { expect(response.body).to be_json_eql({ base: 'Extra parameters are not allow: foobars' }.to_json) }
155
151
  end
156
152
  end
157
- # context 'when not authorized' do
158
- # before(:each) do
159
- # unauthorize_update
160
- # get :show, params: new_attributes
161
- # end
162
- # it { expect(response.status).to eq 403 }
163
- # it { expect(JSON.parse(response.body)['base']).to include 'Access denied on show' }
164
- # end
153
+ context 'when not authorized' do
154
+ before(:each) do
155
+ unauthorize_update
156
+ get :show, params: new_attributes
157
+ end
158
+ it { expect(response.status).to eq 403 }
159
+ it { expect(JSON.parse(response.body)['base']).to include 'Access denied on show' }
160
+ end
165
161
  end
166
162
  end
167
163
 
@@ -192,14 +188,14 @@ shared_examples 'post::create' do
192
188
  end
193
189
  end
194
190
  end
195
- # context 'when not authorized' do
196
- # before(:each) do
197
- # unauthorize_create
198
- # post :create, params: new_attributes
199
- # end
200
- # it { expect(response.status).to eq 403 }
201
- # it { expect(JSON.parse(response.body)['base']).to include 'Access denied on create' }
202
- # end
191
+ context 'when not authorized' do
192
+ before(:each) do
193
+ unauthorize_create
194
+ post :create, params: new_attributes
195
+ end
196
+ it { expect(response.status).to eq 403 }
197
+ it { expect(JSON.parse(response.body)['base']).to include 'Access denied on create' }
198
+ end
203
199
  end
204
200
  end
205
201
 
@@ -210,19 +206,19 @@ shared_examples 'delete::delete' do
210
206
  authorize_delete
211
207
  end
212
208
  it 'remove record' do
213
- expect {
214
- expect_any_instance_of(model_klass).to receive(:destroyed_bus_cleanup_message_publish) if model.respond_to? :destroyed_bus_cleanup_message_publish
215
- delete :destroy, params: { id: model.id }
216
- }.to change(model_klass, :count).by(-1)
209
+ model
210
+ before_count = model_klass.count
211
+ delete :destroy, params: { id: model.id }
212
+ expect(model_klass.count).to eq(before_count - 1)
213
+ end
214
+ end
215
+ context 'when not authorized' do
216
+ before(:each) do
217
+ unauthorize_delete
218
+ delete :destroy, params: { id: model.id }
217
219
  end
220
+ it { expect(response.status).to eq 403 }
221
+ it { expect(JSON.parse(response.body)['base']).to include 'Access denied on destroy' }
218
222
  end
219
- # context 'when not authorized' do
220
- # before(:each) do
221
- # unauthorize_delete
222
- # delete :destroy, params: { id: model.id }
223
- # end
224
- # it { expect(response.status).to eq 403 }
225
- # it { expect(JSON.parse(response.body)['base']).to include 'Access denied on destroy' }
226
- # end
227
223
  end
228
224
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ActiveRecordApi
4
4
  module Rest
5
- VERSION = '1.0.3'.freeze
5
+ VERSION = '1.0.4'.freeze
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_api-rest
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Full Measure Education
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-03-15 00:00:00.000000000 Z
11
+ date: 2019-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler