avo 0.4.1 → 0.4.6
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of avo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/app/controllers/avo/application_controller.rb +12 -1
- data/app/controllers/avo/relations_controller.rb +1 -1
- data/app/controllers/avo/resource_overview_controller.rb +1 -6
- data/app/controllers/avo/resources_controller.rb +11 -17
- data/app/controllers/avo/search_controller.rb +3 -3
- data/app/views/layouts/avo/_javascript.html.erb +3 -3
- data/app/views/layouts/avo/_translations.html.erb +2 -2
- data/app/views/layouts/avo/application.html.erb +3 -3
- data/lib/avo/app/app.rb +10 -0
- data/lib/avo/app/fields/belongs_to.rb +12 -1
- data/lib/avo/app/fields/has_many.rb +4 -2
- data/lib/avo/app/filter.rb +1 -12
- data/lib/avo/app/resource.rb +10 -3
- data/lib/avo/app/services/authorization_service.rb +8 -0
- data/lib/avo/configuration.rb +12 -0
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/templates/initializer/avo.rb +37 -1
- data/public/avo-packs/css/application-c9595d99.css +3 -0
- data/public/avo-packs/css/application-c9595d99.css.br +0 -0
- data/public/avo-packs/css/application-c9595d99.css.gz +0 -0
- data/public/avo-packs/js/application-54cdc48985a045c704ef.js +3 -0
- data/public/avo-packs/js/{application-84e2d573c3c15df1fb7b.js.LICENSE.txt → application-54cdc48985a045c704ef.js.LICENSE.txt} +0 -0
- data/public/avo-packs/js/application-54cdc48985a045c704ef.js.br +0 -0
- data/public/avo-packs/js/application-54cdc48985a045c704ef.js.gz +0 -0
- data/public/avo-packs/js/application-54cdc48985a045c704ef.js.map +1 -0
- data/public/avo-packs/js/application-54cdc48985a045c704ef.js.map.br +0 -0
- data/public/avo-packs/js/application-54cdc48985a045c704ef.js.map.gz +0 -0
- data/public/avo-packs/manifest.json +6 -6
- data/public/avo-packs/manifest.json.br +0 -0
- data/public/avo-packs/manifest.json.gz +0 -0
- metadata +12 -12
- data/public/avo-packs/css/application-2f609d81.css +0 -3
- data/public/avo-packs/css/application-2f609d81.css.br +0 -0
- data/public/avo-packs/css/application-2f609d81.css.gz +0 -0
- data/public/avo-packs/js/application-84e2d573c3c15df1fb7b.js +0 -3
- data/public/avo-packs/js/application-84e2d573c3c15df1fb7b.js.br +0 -0
- data/public/avo-packs/js/application-84e2d573c3c15df1fb7b.js.gz +0 -0
- data/public/avo-packs/js/application-84e2d573c3c15df1fb7b.js.map +0 -1
- data/public/avo-packs/js/application-84e2d573c3c15df1fb7b.js.map.br +0 -0
- data/public/avo-packs/js/application-84e2d573c3c15df1fb7b.js.map.gz +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f524eb45dfab913083b9fc23de6c35146d59436336d3e444ae8b525b9a70e6b2
|
4
|
+
data.tar.gz: 4075e8ca48aff4aa7cbd21a52ee6b6e67535a0bcf69652ed3f9298d39fbfde2f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3c1a13390fee90c6fb892eeae21d66151a66aa29055d16437251060f341bd86eba8315caf0a249330ee5d5f4b1943276cf79862e0bb361ec07f5ba7df50fc1d
|
7
|
+
data.tar.gz: 402ded6bc6111f30321d03eb2282895acdc25761567efb42e260e7c971854a305022f13afe8d300c947792796e2e5fe17c0f36204938ce14c05f4679cc214ccc
|
data/Gemfile.lock
CHANGED
@@ -3,6 +3,9 @@ module Avo
|
|
3
3
|
rescue_from ActiveRecord::RecordInvalid, with: :exception_logger
|
4
4
|
protect_from_forgery with: :exception
|
5
5
|
before_action :init_app
|
6
|
+
before_action :_authenticate!
|
7
|
+
|
8
|
+
helper_method :_current_user
|
6
9
|
|
7
10
|
def init_app
|
8
11
|
Avo::App.boot if Avo::IN_DEVELOPMENT
|
@@ -22,6 +25,10 @@ module Avo
|
|
22
25
|
end
|
23
26
|
end
|
24
27
|
|
28
|
+
def _current_user
|
29
|
+
instance_eval(&Avo.configuration.current_user)
|
30
|
+
end
|
31
|
+
|
25
32
|
private
|
26
33
|
def resource
|
27
34
|
eager_load_files(resource_model).find params[:id]
|
@@ -54,11 +61,15 @@ module Avo
|
|
54
61
|
record = resource
|
55
62
|
end
|
56
63
|
|
57
|
-
return render_unauthorized unless AuthorizationService::authorize_action
|
64
|
+
return render_unauthorized unless AuthorizationService::authorize_action _current_user, record, params[:action]
|
58
65
|
end
|
59
66
|
|
60
67
|
def render_unauthorized
|
61
68
|
render json: { message: I18n.t('avo.unauthorized') }, status: 403
|
62
69
|
end
|
70
|
+
|
71
|
+
def _authenticate!
|
72
|
+
instance_eval(&Avo.configuration.authenticate)
|
73
|
+
end
|
63
74
|
end
|
64
75
|
end
|
@@ -4,7 +4,7 @@ module Avo
|
|
4
4
|
class ResourceOverviewController < ApplicationController
|
5
5
|
def index
|
6
6
|
resources = App.get_resources
|
7
|
-
.select { |resource| AuthorizationService::authorize
|
7
|
+
.select { |resource| AuthorizationService::authorize _current_user, resource.model, Avo.configuration.authorization_methods.stringify_keys['index'] }
|
8
8
|
.sort_by(&:name)
|
9
9
|
.map do |resource|
|
10
10
|
{
|
@@ -20,10 +20,5 @@ module Avo
|
|
20
20
|
hide_docs: Avo.configuration.hide_documentation_link,
|
21
21
|
}
|
22
22
|
end
|
23
|
-
|
24
|
-
private
|
25
|
-
def session_user
|
26
|
-
current_user.present? ? current_user : nil
|
27
|
-
end
|
28
23
|
end
|
29
24
|
end
|
@@ -10,14 +10,14 @@ module Avo
|
|
10
10
|
params[:sort_by] = params[:sort_by].present? ? params[:sort_by] : :created_at
|
11
11
|
params[:sort_direction] = params[:sort_direction].present? ? params[:sort_direction] : :desc
|
12
12
|
|
13
|
-
query = AuthorizationService.with_policy
|
13
|
+
query = AuthorizationService.with_policy _current_user, resource_model
|
14
14
|
|
15
15
|
if params[:via_resource_name].present? and params[:via_resource_id].present? and params[:via_relationship].present?
|
16
16
|
# get the related resource (via_resource)
|
17
17
|
related_model = App.get_resource_by_name(params[:via_resource_name]).model
|
18
18
|
|
19
19
|
relation = related_model.find(params[:via_resource_id]).public_send(params[:via_relationship])
|
20
|
-
query = AuthorizationService.with_policy
|
20
|
+
query = AuthorizationService.with_policy _current_user, relation
|
21
21
|
|
22
22
|
params[:per_page] = Avo.configuration.via_per_page
|
23
23
|
elsif ['has_many', 'has_and_belongs_to_many'].include? params[:for_relation]
|
@@ -52,7 +52,7 @@ module Avo
|
|
52
52
|
|
53
53
|
resources_with_fields = []
|
54
54
|
resources.each do |resource|
|
55
|
-
resources_with_fields << Avo::Resources::Resource.hydrate_resource(model: resource, resource: avo_resource, view: :index, user:
|
55
|
+
resources_with_fields << Avo::Resources::Resource.hydrate_resource(model: resource, resource: avo_resource, view: :index, user: _current_user)
|
56
56
|
end
|
57
57
|
|
58
58
|
render json: {
|
@@ -66,7 +66,7 @@ module Avo
|
|
66
66
|
|
67
67
|
def show
|
68
68
|
render json: {
|
69
|
-
resource: Avo::Resources::Resource.hydrate_resource(model: resource, resource: avo_resource, view: @view || :show, user:
|
69
|
+
resource: Avo::Resources::Resource.hydrate_resource(model: resource, resource: avo_resource, view: @view || :show, user: _current_user),
|
70
70
|
}
|
71
71
|
end
|
72
72
|
|
@@ -94,7 +94,7 @@ module Avo
|
|
94
94
|
|
95
95
|
render json: {
|
96
96
|
success: true,
|
97
|
-
resource: Avo::Resources::Resource.hydrate_resource(model: resource, resource: avo_resource, view: :show, user:
|
97
|
+
resource: Avo::Resources::Resource.hydrate_resource(model: resource, resource: avo_resource, view: :show, user: _current_user),
|
98
98
|
message: I18n.t('avo.resource_updated'),
|
99
99
|
}
|
100
100
|
end
|
@@ -117,14 +117,14 @@ module Avo
|
|
117
117
|
|
118
118
|
render json: {
|
119
119
|
success: true,
|
120
|
-
resource: Avo::Resources::Resource.hydrate_resource(model: resource, resource: avo_resource, view: :create, user:
|
120
|
+
resource: Avo::Resources::Resource.hydrate_resource(model: resource, resource: avo_resource, view: :create, user: _current_user),
|
121
121
|
message: I18n.t('avo.resource_created'),
|
122
122
|
}
|
123
123
|
end
|
124
124
|
|
125
125
|
def new
|
126
126
|
render json: {
|
127
|
-
resource: Avo::Resources::Resource.hydrate_resource(model: resource_model.new, resource: avo_resource, view: :create, user:
|
127
|
+
resource: Avo::Resources::Resource.hydrate_resource(model: resource_model.new, resource: avo_resource, view: :create, user: _current_user),
|
128
128
|
}
|
129
129
|
end
|
130
130
|
|
@@ -224,8 +224,8 @@ module Avo
|
|
224
224
|
avo_resource.get_filters.each do |filter_class|
|
225
225
|
filter = filter_class.new
|
226
226
|
|
227
|
-
if filter.
|
228
|
-
filter_defaults[filter_class.to_s] = filter.
|
227
|
+
if filter.default.present?
|
228
|
+
filter_defaults[filter_class.to_s] = filter.default
|
229
229
|
end
|
230
230
|
end
|
231
231
|
|
@@ -252,17 +252,11 @@ module Avo
|
|
252
252
|
|
253
253
|
def build_meta
|
254
254
|
{
|
255
|
-
per_page_steps: Avo.configuration.per_page_steps,
|
255
|
+
per_page_steps: [*Avo.configuration.per_page_steps, Avo.configuration.per_page.to_i].sort.uniq,
|
256
256
|
available_view_types: avo_resource.available_view_types,
|
257
257
|
default_view_type: avo_resource.default_view_type || Avo.configuration.default_view_type,
|
258
258
|
translation_key: avo_resource.translation_key,
|
259
|
-
authorization:
|
260
|
-
create: AuthorizationService::authorize(current_user, avo_resource.model, Avo.configuration.authorization_methods.stringify_keys['create']),
|
261
|
-
edit: AuthorizationService::authorize(current_user, avo_resource.model, Avo.configuration.authorization_methods.stringify_keys['edit']),
|
262
|
-
update: AuthorizationService::authorize(current_user, avo_resource.model, Avo.configuration.authorization_methods.stringify_keys['update']),
|
263
|
-
show: AuthorizationService::authorize(current_user, avo_resource.model, Avo.configuration.authorization_methods.stringify_keys['show']),
|
264
|
-
destroy: AuthorizationService::authorize(current_user, avo_resource.model, Avo.configuration.authorization_methods.stringify_keys['destroy']),
|
265
|
-
},
|
259
|
+
authorization: AuthorizationService::authorized_methods(_current_user, avo_resource.model)
|
266
260
|
}
|
267
261
|
end
|
268
262
|
end
|
@@ -9,7 +9,7 @@ module Avo
|
|
9
9
|
|
10
10
|
resources_to_search_through = App.get_resources
|
11
11
|
.select { |resource| resource.search.present? }
|
12
|
-
.select { |resource| AuthorizationService.authorize_action
|
12
|
+
.select { |resource| AuthorizationService.authorize_action _current_user, resource.model, 'index' }
|
13
13
|
.each do |resource_model|
|
14
14
|
found_resources = add_link_to_search_results(search_resource(resource_model), resource_model)
|
15
15
|
resources.push({
|
@@ -41,7 +41,7 @@ module Avo
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def search_resource(avo_resource)
|
44
|
-
avo_resource.query_search(query: params[:q], via_resource_name: params[:via_resource_name], via_resource_id: params[:via_resource_id], user:
|
44
|
+
avo_resource.query_search(query: params[:q], via_resource_name: params[:via_resource_name], via_resource_id: params[:via_resource_id], user: _current_user)
|
45
45
|
end
|
46
46
|
|
47
47
|
def authorize_user
|
@@ -49,7 +49,7 @@ module Avo
|
|
49
49
|
|
50
50
|
action = params[:action] == 'resource' ? :index : params[:action]
|
51
51
|
|
52
|
-
return render_unauthorized unless AuthorizationService::authorize_action
|
52
|
+
return render_unauthorized unless AuthorizationService::authorize_action _current_user, avo_resource.model, action
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
|
1
|
+
<%= javascript_tag nonce: true do %>
|
2
2
|
var rootPath = '<%= Avo.configuration.root_path %>';
|
3
3
|
var timezone = '<%= Avo.configuration.timezone %>';
|
4
4
|
var locale = '<%= Avo.configuration.locale %>';
|
5
5
|
var defaultViewType = '<%= Avo.configuration.default_view_type %>';
|
6
6
|
var license = <%= Avo::App.license.properties.to_json.html_safe %>;
|
7
|
-
var avoResources = <%= Avo::App.get_available_resources(
|
8
|
-
|
7
|
+
var avoResources = <%= Avo::App.get_available_resources(_current_user).as_json.html_safe %>;
|
8
|
+
<% end %>
|
@@ -30,8 +30,8 @@
|
|
30
30
|
</template>
|
31
31
|
</application-sidebar>
|
32
32
|
|
33
|
-
<div class="flex-1 h-full overflow-auto">
|
34
|
-
<div class="relative bg-white p-2 shadow-md h-16 w-full flex items-center z-50" v-if="layout !== 'blank'">
|
33
|
+
<div class="flex-1 flex flex-col h-full overflow-auto">
|
34
|
+
<div class="relative bg-white p-2 shadow-md h-16 w-full flex flex-shrink-0 items-center z-50" v-if="layout !== 'blank'">
|
35
35
|
<div class="ml-6">
|
36
36
|
<%= render_header %>
|
37
37
|
</div>
|
@@ -46,7 +46,7 @@
|
|
46
46
|
<%= yield %>
|
47
47
|
</div>
|
48
48
|
|
49
|
-
<div class="content p-8" v-else>
|
49
|
+
<div class="content p-8 flex-1 flex flex-col justify-between items-stretch" v-else>
|
50
50
|
<%= yield %>
|
51
51
|
<%= render_footer %>
|
52
52
|
</div>
|
data/lib/avo/app/app.rb
CHANGED
@@ -132,6 +132,16 @@ module Avo
|
|
132
132
|
self.get_resource name.singularize.camelize
|
133
133
|
end
|
134
134
|
|
135
|
+
# This returns the Avo resource by singular snake_cased name
|
136
|
+
#
|
137
|
+
# get_resource_by_name('User') => Avo::Resources::User
|
138
|
+
# get_resource_by_name(User) => Avo::Resources::User
|
139
|
+
def get_resource_by_model_name(name)
|
140
|
+
get_resources.find do |resource|
|
141
|
+
resource.class.name.demodulize == name.to_s
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
135
145
|
# This returns the Rails model class by singular snake_cased name
|
136
146
|
#
|
137
147
|
# get_model_class_by_name('user') => User
|
@@ -22,7 +22,8 @@ module Avo
|
|
22
22
|
fields[:searchable] = @searchable
|
23
23
|
fields[:is_relation] = true
|
24
24
|
fields[:database_id] = foreign_key model
|
25
|
-
|
25
|
+
|
26
|
+
target_resource = get_target_resource model
|
26
27
|
|
27
28
|
relation_model = model.public_send(@relation_method)
|
28
29
|
|
@@ -61,6 +62,16 @@ module Avo
|
|
61
62
|
model.class.reflections[@relation_method].foreign_key
|
62
63
|
end
|
63
64
|
end
|
65
|
+
|
66
|
+
def get_target_resource(model)
|
67
|
+
if model._reflections[id.to_s].klass.present?
|
68
|
+
App.get_resource_by_model_name model._reflections[id.to_s].klass.to_s
|
69
|
+
elsif model._reflections[id.to_s].options[:class_name].present?
|
70
|
+
App.get_resource_by_model_name model._reflections[id.to_s].options[:class_name]
|
71
|
+
else
|
72
|
+
App.get_resource_by_name class_name.to_s
|
73
|
+
end
|
74
|
+
end
|
64
75
|
end
|
65
76
|
end
|
66
77
|
end
|
@@ -6,6 +6,7 @@ module Avo
|
|
6
6
|
updatable: false,
|
7
7
|
component: 'has-many-field'
|
8
8
|
}
|
9
|
+
@through = args[:through]
|
9
10
|
|
10
11
|
super(name, **args, &block)
|
11
12
|
|
@@ -27,6 +28,7 @@ module Avo
|
|
27
28
|
fields[:relation_class] = target_resource.class.to_s
|
28
29
|
fields[:path] = target_resource.url
|
29
30
|
fields[:relationship] = :has_many
|
31
|
+
fields[:through] = @through
|
30
32
|
fields[:relationship_model] = target_resource.model.name
|
31
33
|
|
32
34
|
fields
|
@@ -40,8 +42,8 @@ module Avo
|
|
40
42
|
if @resource.present?
|
41
43
|
App.get_resources.find { |r| r.class == @resource }
|
42
44
|
else
|
43
|
-
class_name = model._reflections[id.to_s].options[:class_name].present? ? model._reflections[id.to_s].options[:class_name] : model._reflections[id.to_s].name
|
44
|
-
App.
|
45
|
+
class_name = model._reflections[id.to_s].options[:class_name].present? ? model._reflections[id.to_s].options[:class_name] : model._reflections[id.to_s].klass.name
|
46
|
+
App.get_resource_by_model_name class_name
|
45
47
|
end
|
46
48
|
end
|
47
49
|
end
|
data/lib/avo/app/filter.rb
CHANGED
@@ -4,8 +4,6 @@ module Avo
|
|
4
4
|
attr_accessor :component
|
5
5
|
attr_accessor :default
|
6
6
|
|
7
|
-
@@default = nil
|
8
|
-
|
9
7
|
def initialize
|
10
8
|
@name ||= 'Filter'
|
11
9
|
@component ||= 'boolean-filter'
|
@@ -18,7 +16,7 @@ module Avo
|
|
18
16
|
name: name,
|
19
17
|
options: options,
|
20
18
|
component: component,
|
21
|
-
default:
|
19
|
+
default: default,
|
22
20
|
filter_class: self.class.to_s,
|
23
21
|
}
|
24
22
|
end
|
@@ -32,14 +30,5 @@ module Avo
|
|
32
30
|
def id
|
33
31
|
self.class.name.underscore.gsub('/', '_')
|
34
32
|
end
|
35
|
-
|
36
|
-
# These methods helps us set a default value in the testing environment
|
37
|
-
def default_value
|
38
|
-
@@default || default
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.set_default(value)
|
42
|
-
@@default = value
|
43
|
-
end
|
44
33
|
end
|
45
34
|
end
|
data/lib/avo/app/resource.rb
CHANGED
@@ -13,7 +13,14 @@ module Avo
|
|
13
13
|
|
14
14
|
class << self
|
15
15
|
def hydrate_resource(model:, resource:, view: :index, user:)
|
16
|
-
|
16
|
+
case view
|
17
|
+
when :show
|
18
|
+
panel_name = I18n.t 'avo.resource_details', name: resource.name.downcase.upcase_first
|
19
|
+
when :edit
|
20
|
+
panel_name = I18n.t('avo.edit_item', item: resource.name.downcase).upcase_first
|
21
|
+
when :create
|
22
|
+
panel_name = I18n.t('avo.create_new_item', item: resource.name.downcase).upcase_first
|
23
|
+
end
|
17
24
|
|
18
25
|
resource_with_fields = {
|
19
26
|
id: model.id,
|
@@ -26,7 +33,7 @@ module Avo
|
|
26
33
|
fields: [],
|
27
34
|
grid_fields: {},
|
28
35
|
panels: [{
|
29
|
-
name:
|
36
|
+
name: panel_name,
|
30
37
|
component: 'panel',
|
31
38
|
}]
|
32
39
|
}
|
@@ -46,7 +53,7 @@ module Avo
|
|
46
53
|
|
47
54
|
next if furnished_field.blank?
|
48
55
|
|
49
|
-
furnished_field[:panel_name] =
|
56
|
+
furnished_field[:panel_name] = panel_name
|
50
57
|
furnished_field[:show_on_show] = field.show_on_show
|
51
58
|
|
52
59
|
if field.has_own_panel?
|
@@ -3,6 +3,7 @@ module Avo
|
|
3
3
|
class << self
|
4
4
|
def authorize(user, record, action)
|
5
5
|
return true if skip_authorization
|
6
|
+
return true if user.nil?
|
6
7
|
|
7
8
|
begin
|
8
9
|
if Pundit.policy user, record
|
@@ -24,6 +25,7 @@ module Avo
|
|
24
25
|
|
25
26
|
def with_policy(user, model)
|
26
27
|
return model if skip_authorization
|
28
|
+
return model if user.nil?
|
27
29
|
|
28
30
|
begin
|
29
31
|
Pundit.policy_scope! user, model
|
@@ -35,6 +37,12 @@ module Avo
|
|
35
37
|
def skip_authorization
|
36
38
|
Avo::App.license.lacks :authorization
|
37
39
|
end
|
40
|
+
|
41
|
+
def authorized_methods(user, record)
|
42
|
+
[:create, :edit, :update, :show, :destroy].map do |method|
|
43
|
+
[method, authorize(user, record, Avo.configuration.authorization_methods[method])]
|
44
|
+
end.to_h
|
45
|
+
end
|
38
46
|
end
|
39
47
|
end
|
40
48
|
end
|
data/lib/avo/configuration.rb
CHANGED
@@ -14,6 +14,8 @@ module Avo
|
|
14
14
|
attr_accessor :license
|
15
15
|
attr_accessor :license_key
|
16
16
|
attr_accessor :authorization_methods
|
17
|
+
attr_accessor :authenticate
|
18
|
+
attr_accessor :current_user
|
17
19
|
|
18
20
|
def initialize
|
19
21
|
@root_path = '/avo'
|
@@ -29,6 +31,8 @@ module Avo
|
|
29
31
|
@hide_documentation_link = false
|
30
32
|
@license = 'community'
|
31
33
|
@license_key = nil
|
34
|
+
@current_user = proc {}
|
35
|
+
@authenticate = proc {}
|
32
36
|
@authorization_methods = {
|
33
37
|
index: 'index?',
|
34
38
|
show: 'show?',
|
@@ -51,6 +55,14 @@ module Avo
|
|
51
55
|
'en'
|
52
56
|
end
|
53
57
|
end
|
58
|
+
|
59
|
+
def current_user_method(&block)
|
60
|
+
@current_user = block if block.present?
|
61
|
+
end
|
62
|
+
|
63
|
+
def authenticate_with(&block)
|
64
|
+
@authenticate = block if block.present?
|
65
|
+
end
|
54
66
|
end
|
55
67
|
|
56
68
|
def self.configuration
|