avo 0.5.0.beta1 → 0.5.0.beta6
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 +4 -4
- data/Gemfile.lock +1 -5
- data/README.md +4 -0
- data/app/components/avo/index/grid_item_component.html.erb +8 -8
- data/app/components/avo/index/grid_item_component.rb +6 -12
- data/app/components/avo/index/resource_controls_component.html.erb +1 -1
- data/app/components/avo/index/resource_grid_component.html.erb +1 -1
- data/app/components/avo/index/resource_table_component.html.erb +2 -2
- data/app/components/avo/index/table_row_component.html.erb +1 -1
- data/app/controllers/avo/actions_controller.rb +2 -4
- data/app/controllers/avo/application_controller.rb +6 -3
- data/app/controllers/avo/base_controller.rb +10 -7
- data/app/controllers/avo/relations_controller.rb +1 -1
- data/app/controllers/avo/search_controller.rb +1 -1
- data/app/frontend/packs/application.js +1 -1
- data/app/views/avo/base/_actions.html.erb +1 -7
- data/app/views/avo/base/_boolean_filter.html.erb +1 -1
- data/app/views/avo/base/_filters.html.erb +3 -11
- data/app/views/avo/base/_select_filter.html.erb +1 -1
- data/app/views/avo/home/_resources.html.erb +0 -1
- data/app/views/avo/partials/_table_header.html.erb +1 -1
- data/app/views/avo/sidebar/_sidebar.html.erb +1 -1
- data/app/views/layouts/avo/_filter_wrapper.html.erb +1 -1
- data/app/views/layouts/avo/application.html.erb +5 -0
- data/avo.gemspec +0 -1
- data/config/webpacker.yml +10 -23
- data/lib/avo.rb +5 -16
- data/lib/avo/app.rb +190 -0
- data/lib/avo/base_action.rb +123 -0
- data/lib/avo/base_resource.rb +323 -0
- data/lib/avo/configuration.rb +8 -0
- data/lib/avo/engine.rb +12 -31
- data/lib/avo/{app/fields → fields}/badge_field.rb +1 -1
- data/lib/avo/{app/fields/field.rb → fields/base_field.rb} +3 -7
- data/lib/avo/{app/fields/belongs_to.rb → fields/belongs_to_field.rb} +3 -3
- data/lib/avo/{app/fields → fields}/boolean_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/boolean_group_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/code_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/country_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/currency_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/date_field.rb +0 -2
- data/lib/avo/{app/fields → fields}/date_time_field.rb +0 -2
- data/lib/avo/{app/fields → fields}/external_image_field.rb +5 -4
- data/lib/avo/{app/fields → fields}/field_extensions/has_field_name.rb +0 -0
- data/lib/avo/{app/fields → fields}/field_extensions/visible_in_different_views.rb +1 -1
- data/lib/avo/{app/fields → fields}/file_field.rb +1 -2
- data/lib/avo/{app/fields → fields}/files_field.rb +1 -2
- data/lib/avo/{app/fields → fields}/gravatar_field.rb +1 -1
- data/lib/avo/{app/fields/has_and_belongs_to_many.rb → fields/has_and_belongs_to_many_field.rb} +1 -1
- data/lib/avo/{app/fields/has_many.rb → fields/has_many_field.rb} +1 -1
- data/lib/avo/{app/fields/has_one.rb → fields/has_one_field.rb} +1 -1
- data/lib/avo/{app/fields → fields}/heading_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/hidden_field.rb +0 -2
- data/lib/avo/{app/fields → fields}/id_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/key_value_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/markdown_field.rb +1 -3
- data/lib/avo/{app/fields → fields}/number_field.rb +0 -2
- data/lib/avo/{app/fields → fields}/password_field.rb +0 -2
- data/lib/avo/{app/fields → fields}/select_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/status_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/text_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/textarea_field.rb +0 -2
- data/lib/avo/{app/fields → fields}/trix_field.rb +1 -3
- data/lib/avo/filters/base_filter.rb +20 -0
- data/lib/avo/filters/boolean_filter.rb +7 -0
- data/lib/avo/filters/select_filter.rb +7 -0
- data/lib/avo/{app/grid_fields → grid_fields}/body_field.rb +0 -2
- data/lib/avo/{app/grid_fields → grid_fields}/grid_field.rb +0 -0
- data/lib/avo/{app/grid_fields → grid_fields}/preview_field.rb +0 -2
- data/lib/avo/{app/grid_fields → grid_fields}/title_field.rb +0 -2
- data/lib/avo/licensing/community_license.rb +6 -0
- data/lib/avo/licensing/h_q.rb +88 -0
- data/lib/avo/licensing/license.rb +50 -0
- data/lib/avo/licensing/license_manager.rb +22 -0
- data/lib/avo/licensing/null_license.rb +14 -0
- data/lib/avo/licensing/pro_license.rb +11 -0
- data/lib/avo/loaders/actions_loader.rb +6 -0
- data/lib/avo/loaders/fields_loader.rb +27 -0
- data/lib/avo/loaders/filters_loader.rb +6 -0
- data/lib/avo/loaders/loader.rb +15 -0
- data/lib/avo/services/authorization_service.rb +93 -0
- data/lib/avo/services/panel_service.rb +27 -0
- data/lib/avo/{app/tools_manager.rb → tools_manager.rb} +0 -0
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/action_generator.rb +11 -5
- data/lib/generators/avo/controller_generator.rb +14 -8
- data/lib/generators/avo/filter_generator.rb +14 -8
- data/lib/generators/avo/install_generator.rb +14 -10
- data/lib/generators/avo/locales_generator.rb +16 -0
- data/lib/generators/avo/partials_generator.rb +14 -0
- data/lib/generators/avo/resource_generator.rb +33 -15
- data/lib/generators/avo/templates/{action.rb → action.tt} +2 -4
- data/lib/generators/avo/templates/filters/boolean_filter.tt +11 -0
- data/lib/generators/avo/templates/filters/select_filter.tt +11 -0
- data/lib/generators/avo/templates/initializer/{avo.rb → avo.tt} +6 -4
- data/lib/generators/avo/templates/locales/avo.en.yml +17 -0
- data/lib/generators/avo/templates/partials/_footer.html.erb +3 -0
- data/lib/generators/avo/templates/partials/_header.html.erb +1 -0
- data/lib/generators/avo/templates/{views → partials}/_logo.html.erb +0 -0
- data/lib/generators/avo/templates/{views → partials}/_scripts.html.erb +0 -0
- data/lib/generators/avo/templates/resource/controller.tt +2 -0
- data/lib/generators/avo/templates/resource/resource.tt +17 -0
- data/public/avo-packs/css/{application-3598cfbb.css → application-c75ac28c.css} +1 -1
- data/public/avo-packs/css/application-c75ac28c.css.br +0 -0
- data/public/avo-packs/css/{application-3598cfbb.css.gz → application-c75ac28c.css.gz} +0 -0
- data/public/avo-packs/js/{application-6ba2bd1bca05d69b96e0.js → application-8849c6e2c8f75d55c666.js} +3 -3
- data/public/avo-packs/js/{application-6ba2bd1bca05d69b96e0.js.LICENSE.txt → application-8849c6e2c8f75d55c666.js.LICENSE.txt} +0 -0
- data/public/avo-packs/js/application-8849c6e2c8f75d55c666.js.br +0 -0
- data/public/avo-packs/js/application-8849c6e2c8f75d55c666.js.gz +0 -0
- data/public/avo-packs/js/{application-6ba2bd1bca05d69b96e0.js.map → application-8849c6e2c8f75d55c666.js.map} +1 -1
- data/public/avo-packs/js/application-8849c6e2c8f75d55c666.js.map.br +0 -0
- data/public/avo-packs/js/{application-6ba2bd1bca05d69b96e0.js.map.gz → application-8849c6e2c8f75d55c666.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 +78 -93
- data/app/controllers/avo/resource_overview_controller.rb +0 -26
- data/config/webpacker_packed.yml +0 -86
- data/lib/avo/app/action.rb +0 -162
- data/lib/avo/app/actions_loader.rb +0 -11
- data/lib/avo/app/app.rb +0 -181
- data/lib/avo/app/fields_loader.rb +0 -29
- data/lib/avo/app/filter.rb +0 -34
- data/lib/avo/app/filters/boolean_filter.rb +0 -13
- data/lib/avo/app/filters/select_filter.rb +0 -13
- data/lib/avo/app/licensing/community_license.rb +0 -4
- data/lib/avo/app/licensing/hq.rb +0 -86
- data/lib/avo/app/licensing/license.rb +0 -48
- data/lib/avo/app/licensing/license_manager.rb +0 -25
- data/lib/avo/app/licensing/null_license.rb +0 -12
- data/lib/avo/app/licensing/pro_license.rb +0 -9
- data/lib/avo/app/resource.rb +0 -291
- data/lib/avo/app/resource_grid_fields.rb +0 -30
- data/lib/avo/app/services/authorization_service.rb +0 -110
- data/lib/avo/app/services/panel_service.rb +0 -25
- data/lib/avo/app/tool.rb +0 -5
- data/lib/generators/avo/templates/filters/boolean_filter.rb +0 -17
- data/lib/generators/avo/templates/filters/select_filter.rb +0 -17
- data/lib/generators/avo/templates/resource/%plural_name%_controller.tt +0 -2
- data/lib/generators/avo/templates/resource/%singular_name%.tt +0 -20
- data/lib/generators/avo/templates/views/_footer.html.erb +0 -3
- data/lib/generators/avo/templates/views/_header.html.erb +0 -1
- data/lib/generators/avo/views_generator.rb +0 -8
- data/public/avo-packs/css/application-3598cfbb.css.br +0 -0
- data/public/avo-packs/js/application-6ba2bd1bca05d69b96e0.js.br +0 -0
- data/public/avo-packs/js/application-6ba2bd1bca05d69b96e0.js.gz +0 -0
- data/public/avo-packs/js/application-6ba2bd1bca05d69b96e0.js.map.br +0 -0
File without changes
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Avo
|
2
|
+
module Licensing
|
3
|
+
class HQ
|
4
|
+
attr_accessor :current_request
|
5
|
+
|
6
|
+
ENDPOINT = 'https://avohq.io/api/v1/licenses/check' unless const_defined?(:ENDPOINT)
|
7
|
+
CACHE_KEY = 'avo.hq.response' unless const_defined?(:CACHE_KEY)
|
8
|
+
REQUEST_TIMEOUT = 5 unless const_defined?(:REQUEST_TIMEOUT) # seconds
|
9
|
+
|
10
|
+
def initialize(current_request)
|
11
|
+
@current_request = current_request
|
12
|
+
@cache_store = Avo::App.cache_store
|
13
|
+
end
|
14
|
+
|
15
|
+
def response
|
16
|
+
@hq_response or request
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def request
|
21
|
+
return cached_response if has_cached_response
|
22
|
+
|
23
|
+
begin
|
24
|
+
perform_and_cache_request
|
25
|
+
rescue HTTParty::Error => exception
|
26
|
+
cache_and_return_error 'HTTP client error.', exception.message
|
27
|
+
rescue Net::OpenTimeout => exception
|
28
|
+
cache_and_return_error 'Request timeout.', exception.message
|
29
|
+
rescue SocketError => exception
|
30
|
+
cache_and_return_error 'Connection error.', exception.message
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def perform_and_cache_request
|
35
|
+
hq_response = perform_request
|
36
|
+
|
37
|
+
return cache_and_return_error 'Avo HQ Internal server error.', hq_response.body if hq_response.code == 500
|
38
|
+
|
39
|
+
cache_response 1.hour.to_i, hq_response.parsed_response if hq_response.code == 200
|
40
|
+
end
|
41
|
+
|
42
|
+
def cache_response(time, response)
|
43
|
+
response.merge!(
|
44
|
+
expiry: time,
|
45
|
+
**payload,
|
46
|
+
).stringify_keys!
|
47
|
+
|
48
|
+
@cache_store.write(CACHE_KEY, response, expires_in: time)
|
49
|
+
|
50
|
+
@hq_response = response
|
51
|
+
|
52
|
+
response
|
53
|
+
end
|
54
|
+
|
55
|
+
def perform_request
|
56
|
+
puts 'Performing request to avohq.io API to check license availability.'.inspect if Rails.env.development?
|
57
|
+
|
58
|
+
HTTParty.post ENDPOINT, body: payload.to_json, headers: { 'Content-type': 'application/json' }, timeout: REQUEST_TIMEOUT
|
59
|
+
end
|
60
|
+
|
61
|
+
def payload
|
62
|
+
{
|
63
|
+
license: Avo.configuration.license,
|
64
|
+
license_key: Avo.configuration.license_key,
|
65
|
+
avo_version: Avo::VERSION,
|
66
|
+
rails_version: Rails::VERSION::STRING,
|
67
|
+
ruby_version: RUBY_VERSION,
|
68
|
+
environment: Rails.env,
|
69
|
+
ip: current_request.ip,
|
70
|
+
host: current_request.host,
|
71
|
+
port: current_request.port,
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def cache_and_return_error(error, exception_message = '')
|
76
|
+
cache_response 5.minutes.to_i, { error: error, exception_message: exception_message }.stringify_keys
|
77
|
+
end
|
78
|
+
|
79
|
+
def has_cached_response
|
80
|
+
@cache_store.exist? CACHE_KEY
|
81
|
+
end
|
82
|
+
|
83
|
+
def cached_response
|
84
|
+
@cache_store.read CACHE_KEY
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Avo
|
2
|
+
module Licensing
|
3
|
+
class License
|
4
|
+
attr_accessor :id
|
5
|
+
attr_accessor :response
|
6
|
+
attr_accessor :valid
|
7
|
+
|
8
|
+
def initialize(response)
|
9
|
+
@response = response
|
10
|
+
@id = response['id']
|
11
|
+
@valid = response['valid']
|
12
|
+
end
|
13
|
+
|
14
|
+
def valid?
|
15
|
+
valid
|
16
|
+
end
|
17
|
+
|
18
|
+
def invalid?
|
19
|
+
!valid?
|
20
|
+
end
|
21
|
+
|
22
|
+
def pro?
|
23
|
+
id == 'pro'
|
24
|
+
end
|
25
|
+
|
26
|
+
def error
|
27
|
+
@response['error']
|
28
|
+
end
|
29
|
+
|
30
|
+
def properties
|
31
|
+
@response.slice('valid', 'id', 'error').symbolize_keys
|
32
|
+
end
|
33
|
+
|
34
|
+
def abilities
|
35
|
+
[]
|
36
|
+
end
|
37
|
+
|
38
|
+
def can(ability)
|
39
|
+
abilities.include? ability
|
40
|
+
end
|
41
|
+
|
42
|
+
def cant(ability)
|
43
|
+
!can ability
|
44
|
+
end
|
45
|
+
|
46
|
+
alias_method :has, :can
|
47
|
+
alias_method :lacks, :cant
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Avo
|
2
|
+
module Licensing
|
3
|
+
class LicenseManager
|
4
|
+
def initialize(hq_response)
|
5
|
+
@hq_response = hq_response
|
6
|
+
end
|
7
|
+
|
8
|
+
def license
|
9
|
+
return NullLicense.new if Rails.env.test? and ENV['RUN_WITH_NULL_LICENSE'] == '1'
|
10
|
+
|
11
|
+
case @hq_response['id']
|
12
|
+
when 'community'
|
13
|
+
CommunityLicense.new @hq_response
|
14
|
+
when 'pro'
|
15
|
+
ProLicense.new @hq_response
|
16
|
+
else
|
17
|
+
NullLicense.new @hq_response
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Avo
|
2
|
+
module Loaders
|
3
|
+
class FieldsLoader < Loader
|
4
|
+
def add_field(field)
|
5
|
+
@bag.push field
|
6
|
+
end
|
7
|
+
|
8
|
+
def method_missing(method, *args, &block)
|
9
|
+
matched_field = Avo::App.fields.find do |field|
|
10
|
+
field[:name].to_s == method.to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
if matched_field.present? and matched_field[:class].present?
|
14
|
+
klass = matched_field[:class]
|
15
|
+
|
16
|
+
if block.present?
|
17
|
+
field = klass.new(args[0], **args[1] || {}, &block)
|
18
|
+
else
|
19
|
+
field = klass.new(args[0], **args[1] || {})
|
20
|
+
end
|
21
|
+
|
22
|
+
add_field field
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module Avo
|
2
|
+
module Services
|
3
|
+
class AuthorizationService
|
4
|
+
attr_accessor :user
|
5
|
+
attr_accessor :record
|
6
|
+
|
7
|
+
def initialize(user = nil, record = nil)
|
8
|
+
@user = user
|
9
|
+
@record = record
|
10
|
+
end
|
11
|
+
|
12
|
+
def authorize(action, **args)
|
13
|
+
self.class.authorize(user, record, action, **args)
|
14
|
+
end
|
15
|
+
|
16
|
+
def set_record(record)
|
17
|
+
@record = record
|
18
|
+
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def set_user(user)
|
23
|
+
@user = user
|
24
|
+
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def authorize_action(action, **args)
|
29
|
+
self.class.authorize_action(user, record, action, **args)
|
30
|
+
end
|
31
|
+
|
32
|
+
def apply_policy(model)
|
33
|
+
self.class.apply_policy(user, model)
|
34
|
+
end
|
35
|
+
|
36
|
+
class << self
|
37
|
+
def authorize(user, record, action, **args)
|
38
|
+
return true if skip_authorization
|
39
|
+
return true if user.nil?
|
40
|
+
|
41
|
+
begin
|
42
|
+
if Pundit.policy user, record
|
43
|
+
Pundit.authorize user, record, action
|
44
|
+
end
|
45
|
+
|
46
|
+
true
|
47
|
+
rescue Pundit::NotDefinedError => error
|
48
|
+
false
|
49
|
+
rescue => error
|
50
|
+
if args[:raise_exception] == false
|
51
|
+
false
|
52
|
+
else
|
53
|
+
raise error
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def authorize_action(user, record, action, **args)
|
59
|
+
action = Avo.configuration.authorization_methods.stringify_keys[action.to_s]
|
60
|
+
|
61
|
+
return true if action.nil?
|
62
|
+
|
63
|
+
authorize user, record, action, **args
|
64
|
+
end
|
65
|
+
|
66
|
+
def apply_policy(user, model)
|
67
|
+
return model if skip_authorization
|
68
|
+
return model if user.nil?
|
69
|
+
|
70
|
+
begin
|
71
|
+
Pundit.policy_scope! user, model
|
72
|
+
rescue => exception
|
73
|
+
model
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def skip_authorization
|
78
|
+
Avo::App.license.lacks :authorization
|
79
|
+
end
|
80
|
+
|
81
|
+
def authorized_methods(user, record)
|
82
|
+
[:new, :edit, :update, :show, :destroy].map do |method|
|
83
|
+
[method, authorize(user, record, Avo.configuration.authorization_methods[method])]
|
84
|
+
end.to_h
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_policy(user, record)
|
88
|
+
Pundit.policy user, record
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Avo
|
2
|
+
module Services
|
3
|
+
class PanelService
|
4
|
+
attr_accessor :request
|
5
|
+
attr_accessor :params
|
6
|
+
attr_accessor :resource
|
7
|
+
|
8
|
+
def initialize(request: nil, resource: nil)
|
9
|
+
@request = request
|
10
|
+
@params = request.params
|
11
|
+
end
|
12
|
+
|
13
|
+
def default_panel_name
|
14
|
+
return @request[:via_relation_param].capitalize if @request[:via_relation_param] == 'has_one'
|
15
|
+
|
16
|
+
case @view
|
17
|
+
when :show
|
18
|
+
I18n.t('avo.resource_details', item: @resource.name.downcase, title: @resource.model_title).upcase_first
|
19
|
+
when :edit
|
20
|
+
I18n.t('avo.update_item', item: @resource.name.downcase, title: @resource.model_title).upcase_first
|
21
|
+
when :new
|
22
|
+
I18n.t('avo.create_new_item', item: @resource.name.downcase).upcase_first
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
File without changes
|
data/lib/avo/version.rb
CHANGED
@@ -1,8 +1,14 @@
|
|
1
|
-
|
2
|
-
source_root File.expand_path('templates', __dir__)
|
3
|
-
namespace 'avo:action'
|
1
|
+
require 'rails/generators'
|
4
2
|
|
5
|
-
|
6
|
-
|
3
|
+
module Generators
|
4
|
+
module Avo
|
5
|
+
class ActionGenerator < Rails::Generators::NamedBase
|
6
|
+
source_root File.expand_path('templates', __dir__)
|
7
|
+
namespace 'avo:action'
|
8
|
+
|
9
|
+
def create_resource_file
|
10
|
+
template 'action.rb', "app/avo/actions/#{singular_name}.rb"
|
11
|
+
end
|
12
|
+
end
|
7
13
|
end
|
8
14
|
end
|