marty 9.3.0 → 9.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gemignore +2 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +34 -1
- data/Gemfile +1 -0
- data/Rakefile +10 -0
- data/app/assets/javascripts/marty/cable.js +21 -9
- data/app/channels/application_cable/connection.rb +1 -1
- data/app/channels/marty/notification_channel.rb +4 -1
- data/app/components/marty/api_config_view.rb +1 -1
- data/app/components/marty/api_log_view.rb +1 -1
- data/app/components/marty/auth_app.rb +8 -1
- data/app/components/marty/auth_app/client/auth_app.js +6 -0
- data/app/components/marty/data_grid_view.rb +6 -6
- data/app/components/marty/extras/misc.rb +1 -1
- data/app/components/marty/log_view.rb +1 -1
- data/app/components/marty/posting_grid.rb +1 -1
- data/app/components/marty/script_form.rb +3 -3
- data/app/components/marty/user_view.rb +1 -1
- data/app/components/marty/users/user_view.rb +1 -1
- data/app/controllers/marty/application_controller.rb +7 -7
- data/app/controllers/marty/delayed_job_controller.rb +7 -4
- data/app/controllers/marty/diagnostic/controller.rb +1 -1
- data/app/controllers/marty/job_controller.rb +2 -2
- data/app/models/marty/api_auth.rb +3 -3
- data/app/models/marty/api_config.rb +1 -1
- data/app/models/marty/base_rule.rb +1 -1
- data/app/models/marty/config.rb +5 -5
- data/app/models/marty/data_grid.rb +3 -3
- data/app/models/marty/delorean_rule.rb +2 -2
- data/app/models/marty/grid_index_boolean.rb +2 -2
- data/app/models/marty/grid_index_int4range.rb +1 -1
- data/app/models/marty/grid_index_integer.rb +1 -1
- data/app/models/marty/grid_index_numrange.rb +1 -1
- data/app/models/marty/grid_index_string.rb +1 -1
- data/app/models/marty/import_type.rb +2 -2
- data/app/models/marty/notifications/notification.rb +2 -1
- data/app/models/marty/posting.rb +6 -6
- data/app/models/marty/posting_type.rb +2 -2
- data/app/models/marty/promise.rb +4 -3
- data/app/models/marty/script.rb +7 -7
- data/app/models/marty/tag.rb +5 -5
- data/app/models/marty/token.rb +1 -1
- data/app/models/marty/user.rb +11 -10
- data/app/models/marty/user_role.rb +2 -2
- data/app/models/marty/vw_promise.rb +2 -1
- data/app/services/marty/background_job/update_schedule.rb +1 -1
- data/app/services/marty/data_grid/constraint.rb +4 -3
- data/app/services/marty/jobs/schedule.rb +2 -2
- data/lib/marty/data_change.rb +1 -1
- data/lib/marty/data_conversion.rb +1 -1
- data/lib/marty/migrations.rb +2 -2
- data/lib/marty/rpc_call.rb +2 -1
- data/lib/marty/rule_script_set.rb +1 -3
- data/lib/marty/util.rb +2 -2
- data/lib/marty/version.rb +1 -1
- data/lib/tasks/scripts_tasks.rake +2 -2
- data/marty.gemspec +5 -1
- data/spec/controllers/job_controller_spec.rb +7 -7
- data/spec/controllers/rpc_controller_spec.rb +8 -8
- data/spec/controllers/rpc_import_spec.rb +3 -3
- data/spec/features/data_blame_report_spec.rb +1 -1
- data/spec/features/data_grid_spec.rb +101 -3
- data/spec/features/enum_values_report_spec.rb +1 -1
- data/spec/features/extjs_spec.rb +1 -1
- data/spec/features/jobs_dashboard_spec.rb +2 -2
- data/spec/features/log_view_spec.rb +1 -1
- data/spec/features/reporting_spec.rb +3 -3
- data/spec/features/scripting_spec.rb +3 -3
- data/spec/features/scripting_test_spec.rb +3 -3
- data/spec/features/user_list_report_spec.rb +1 -1
- data/spec/fixtures/misc/data_grid_6.txt +9 -0
- data/spec/fixtures/misc/data_grid_7.txt +7 -0
- data/spec/fixtures/misc/data_grid_8.txt +10 -0
- data/spec/fixtures/misc/data_grid_9.txt +10 -0
- data/spec/lib/data_blame_spec.rb +1 -1
- data/spec/lib/data_importer_spec.rb +4 -4
- data/spec/lib/delorean_query_spec.rb +1 -1
- data/spec/lib/logger_spec.rb +1 -1
- data/spec/lib/mcfly_model_spec.rb +2 -2
- data/spec/lib/table_report_spec.rb +1 -1
- data/spec/models/api_auth_spec.rb +2 -2
- data/spec/models/data_grid_spec.rb +3 -3
- data/spec/models/posting_spec.rb +12 -12
- data/spec/models/promise_spec.rb +1 -1
- data/spec/models/rule_spec.rb +1 -1
- data/spec/models/script_spec.rb +1 -1
- data/spec/other/diagnostic/delayed_job_version_spec.rb +1 -1
- data/spec/spec_helper.rb +3 -0
- data/spec/support/netzke.rb +2 -2
- data/spec/support/setup.rb +1 -1
- data/spec/support/simplecov_helper.rb +94 -0
- data/spec/support/users.rb +2 -2
- metadata +8 -3
- data/.gitlab-ci.yml +0 -117
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a8acd94fdad2d0427eaea410e20f8df3acccec4ddb55d6932c8ac558a4f320cb
|
4
|
+
data.tar.gz: e6d14dc726a688d44bc575c512678522890c90b2cb848167f7dc2a2a661de034
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 03a0f36614dfde9a168825250d41a94c8c7a5912b83d2ee347fa0ed9fdaf10da1d08b28b0ff8497dccf4ef0999d76eadbfb8bd320fde1e4a6636a307297a8df7
|
7
|
+
data.tar.gz: '039559d4fd376ce6741a9fa8ea71a7276daba6df5050dcf3950f24e78cc2bb8c5944cb425e45dbc6ce4a7b6f32b5e69a0c27bd74f5dcf664271476f1da3b8771'
|
data/.gemignore
ADDED
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
inherit_from: .rubocop_todo.yml
|
2
|
-
require:
|
2
|
+
require:
|
3
|
+
- rubocop-performance
|
4
|
+
- rubocop-rails
|
3
5
|
|
4
6
|
AllCops:
|
5
7
|
TargetRubyVersion: 2.4.2
|
@@ -46,3 +48,34 @@ Style/SymbolArray:
|
|
46
48
|
Security/MarshalLoad:
|
47
49
|
Exclude:
|
48
50
|
- 'lib/marty/cache_adapters/redis.rb'
|
51
|
+
|
52
|
+
Rails/TimeZone:
|
53
|
+
EnforcedStyle: strict
|
54
|
+
|
55
|
+
Rails/OutputSafety:
|
56
|
+
Exclude:
|
57
|
+
- 'app/components/marty/main_auth_app.rb'
|
58
|
+
|
59
|
+
Rails/HelperInstanceVariable:
|
60
|
+
Exclude:
|
61
|
+
- 'app/helpers/marty/script_set.rb' # It's a class, not a helper
|
62
|
+
|
63
|
+
Rails/SkipsModelValidations:
|
64
|
+
Exclude:
|
65
|
+
- 'app/models/marty/promise.rb'
|
66
|
+
|
67
|
+
Rails/DynamicFindBy:
|
68
|
+
Exclude:
|
69
|
+
- 'app/models/marty/data_grid.rb' # Enum
|
70
|
+
- 'app/models/marty/enum.rb' # Enum
|
71
|
+
- 'spec/features/**/*'
|
72
|
+
- 'spec/support/**/*'
|
73
|
+
|
74
|
+
Rails/ApplicationRecord:
|
75
|
+
Enabled: false
|
76
|
+
|
77
|
+
Rails/ApplicationJob:
|
78
|
+
Enabled: false
|
79
|
+
|
80
|
+
Rails/ApplicationController:
|
81
|
+
Enabled: false
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -26,3 +26,13 @@ load 'rails/tasks/engine.rake'
|
|
26
26
|
Bundler::GemHelper.install_tasks
|
27
27
|
|
28
28
|
task default: 'app:spec'
|
29
|
+
|
30
|
+
namespace :marty do
|
31
|
+
desc 'Merge the results of various SimpleCov coverage reports'
|
32
|
+
task merge_coverage_reports: :environment do
|
33
|
+
require_relative 'spec/support/simplecov_helper'
|
34
|
+
SimpleCovHelper.configure_profile
|
35
|
+
puts 'Merging code coverage reports...'
|
36
|
+
SimpleCovHelper.merge_all_results!
|
37
|
+
end
|
38
|
+
end
|
@@ -4,13 +4,25 @@
|
|
4
4
|
(function() {
|
5
5
|
this.RailsApp || (this.RailsApp = {});
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
this.RailsApp.startActionCable = () => {
|
8
|
+
// Already started
|
9
|
+
if (RailsApp.cable) {
|
10
|
+
return false;
|
11
|
+
}
|
12
|
+
|
13
|
+
const protocol =
|
14
|
+
window.location.protocol.slice(0, 5) === "https" ? "wss" : "ws";
|
15
|
+
|
16
|
+
if (window.location.port === "") {
|
17
|
+
RailsApp.cable = ActionCable.createConsumer(
|
18
|
+
`${protocol}://${window.location.hostname}/cable`
|
19
|
+
);
|
20
|
+
} else {
|
21
|
+
RailsApp.cable = ActionCable.createConsumer(
|
22
|
+
`${protocol}://${window.location.hostname}:${window.location.port}/cable`
|
23
|
+
);
|
24
|
+
}
|
25
|
+
|
26
|
+
return true;
|
27
|
+
};
|
16
28
|
}.call(this));
|
@@ -1,7 +1,10 @@
|
|
1
1
|
module Marty
|
2
2
|
class NotificationChannel < ::ApplicationCable::Channel
|
3
3
|
def subscribed
|
4
|
-
reject && return unless
|
4
|
+
reject && return unless
|
5
|
+
Rails.application.config.marty.enable_action_cable
|
6
|
+
|
7
|
+
reject && return if current_user.blank?
|
5
8
|
stream_from "marty_notifications_#{current_user.id}"
|
6
9
|
end
|
7
10
|
end
|
@@ -103,7 +103,7 @@ class Marty::ApiLogView < Marty::Grid
|
|
103
103
|
c.field_config = {
|
104
104
|
xtype: :displayfield,
|
105
105
|
}
|
106
|
-
c.getter = lambda { |r| Time.at(r.timestamp) }
|
106
|
+
c.getter = lambda { |r| Time.zone.at(r.timestamp) }
|
107
107
|
c.sorting_scope = lambda { |r, dir| r.order('timestamp ' + dir.to_s) }
|
108
108
|
|
109
109
|
# FIXME?: The UI AR/PG DateTime workaround requires the timestamp to be cast
|
@@ -5,6 +5,13 @@
|
|
5
5
|
require 'marty/notifications/window'
|
6
6
|
|
7
7
|
class Marty::AuthApp < Marty::SimpleApp
|
8
|
+
def configure(c)
|
9
|
+
super
|
10
|
+
|
11
|
+
enable_action_cable = Rails.application.config.marty.enable_action_cable
|
12
|
+
client_config[:marty_enable_action_cable] = enable_action_cable
|
13
|
+
end
|
14
|
+
|
8
15
|
client_class do |c|
|
9
16
|
c.include :auth_app
|
10
17
|
end
|
@@ -44,7 +51,7 @@ class Marty::AuthApp < Marty::SimpleApp
|
|
44
51
|
def unread_notifications_count
|
45
52
|
user = Mcfly.whodunnit
|
46
53
|
|
47
|
-
return 0
|
54
|
+
return 0 if user.blank?
|
48
55
|
|
49
56
|
user.unread_web_notifications_count
|
50
57
|
end
|
@@ -118,7 +118,13 @@
|
|
118
118
|
},
|
119
119
|
|
120
120
|
netzkeInitComponentCallback() {
|
121
|
+
if (!this.config.clientConfig.marty_enable_action_cable) {
|
122
|
+
return;
|
123
|
+
}
|
124
|
+
|
121
125
|
try {
|
126
|
+
RailsApp.startActionCable();
|
127
|
+
|
122
128
|
const subscription = RailsApp.cable.subscriptions.subscriptions.find(
|
123
129
|
(sub) => sub.identifier === '{"channel":"Marty::NotificationChannel"}'
|
124
130
|
);
|
@@ -116,9 +116,9 @@ module Marty; class DataGridView < McflyGridPanel
|
|
116
116
|
Marty::RoleType.from_nice_names(plist)
|
117
117
|
end
|
118
118
|
dg.permissions = {
|
119
|
-
view: view.
|
120
|
-
edit_data: edit_data.
|
121
|
-
edit_all: edit_all.
|
119
|
+
view: view.presence || [],
|
120
|
+
edit_data: edit_data.presence || [],
|
121
|
+
edit_all: edit_all.presence || [],
|
122
122
|
}
|
123
123
|
dg.save!
|
124
124
|
end
|
@@ -142,7 +142,7 @@ module Marty; class DataGridView < McflyGridPanel
|
|
142
142
|
endpoint :edit_window__edit_form__submit do |params|
|
143
143
|
data = ActiveSupport::JSON.decode(params[:data])
|
144
144
|
|
145
|
-
dg = DataGrid.
|
145
|
+
dg = DataGrid.find_by(id: data['id'])
|
146
146
|
|
147
147
|
begin
|
148
148
|
dg.update_from_import(data['name'], data['export'])
|
@@ -169,7 +169,7 @@ module Marty; class DataGridView < McflyGridPanel
|
|
169
169
|
endpoint :show_grid do |params|
|
170
170
|
record_id = params[:record_id]
|
171
171
|
|
172
|
-
dg = DataGrid.
|
172
|
+
dg = DataGrid.find_by(id: record_id)
|
173
173
|
|
174
174
|
return client.netzke_notify('No data grid.') unless dg
|
175
175
|
|
@@ -193,7 +193,7 @@ module Marty; class DataGridView < McflyGridPanel
|
|
193
193
|
endpoint :edit_grid do |params|
|
194
194
|
record_id = params[:record_id]
|
195
195
|
|
196
|
-
dg = DataGrid.
|
196
|
+
dg = DataGrid.find_by(id: record_id)
|
197
197
|
|
198
198
|
return client.netzke_notify('No data grid.') unless dg
|
199
199
|
|
@@ -13,7 +13,7 @@ module Marty::Extras::Misc
|
|
13
13
|
renderer: "function(v){return ('0' + v).slice (-2);}",
|
14
14
|
# FIXME: a little bogus since this is computed statically. lambda
|
15
15
|
# didn't work.
|
16
|
-
default_value:
|
16
|
+
default_value: Time.zone.today.month
|
17
17
|
}
|
18
18
|
def self.numberfield_cfg(decimal_places)
|
19
19
|
{
|
@@ -63,7 +63,7 @@ class Marty::LogView < Marty::Grid
|
|
63
63
|
c.field_config = {
|
64
64
|
xtype: :displayfield,
|
65
65
|
}
|
66
|
-
c.getter = lambda { |r| Time.at(r.timestamp) }
|
66
|
+
c.getter = lambda { |r| Time.zone.at(r.timestamp) }
|
67
67
|
c.sorting_scope = lambda { |r, dir| r.order('timestamp ' + dir.to_s) }
|
68
68
|
|
69
69
|
# FIXME?: The UI AR/PG DateTime workaround requires the timestamp to be cast
|
@@ -42,7 +42,7 @@ class Marty::PostingGrid < Marty::Grid
|
|
42
42
|
# Prepare an HTML popup with session details such that the
|
43
43
|
# contents can be easily pasted into a spreadsheet.
|
44
44
|
|
45
|
-
pt = Marty::Posting.
|
45
|
+
pt = Marty::Posting.find_by(id: record_id)
|
46
46
|
|
47
47
|
dt = pt.created_dt.to_s == 'Infinity' ? '---' :
|
48
48
|
pt.created_dt.strftime('%Y-%m-%d %I:%M %p')
|
@@ -61,7 +61,7 @@ class Marty::ScriptForm < Marty::Form
|
|
61
61
|
data[k] = nil if v.blank? || v == 'null'
|
62
62
|
end
|
63
63
|
|
64
|
-
@record = script = Marty::Script.
|
64
|
+
@record = script = Marty::Script.find_by(id: data['id'])
|
65
65
|
|
66
66
|
unless script
|
67
67
|
client.netzke_notify 'no record'
|
@@ -81,7 +81,7 @@ class Marty::ScriptForm < Marty::Form
|
|
81
81
|
end
|
82
82
|
|
83
83
|
begin
|
84
|
-
dev = Marty::Tag.
|
84
|
+
dev = Marty::Tag.find_by(name: 'DEV')
|
85
85
|
Marty::ScriptSet.new(dev).parse_check(script.name, data['body'])
|
86
86
|
rescue Delorean::ParseError => e
|
87
87
|
client.netzke_notify e.message
|
@@ -106,7 +106,7 @@ class Marty::ScriptForm < Marty::Form
|
|
106
106
|
return client.netzke_notify('Permission Denied') unless
|
107
107
|
self.class.has_any_perm?
|
108
108
|
|
109
|
-
script = Marty::Script.
|
109
|
+
script = Marty::Script.find_by(id: script_id)
|
110
110
|
|
111
111
|
return client.netzke_notify('bad script') unless script
|
112
112
|
|
@@ -24,7 +24,7 @@ class Marty::ApplicationController < ActionController::Base
|
|
24
24
|
reset_session
|
25
25
|
reset_signed_cookies
|
26
26
|
else
|
27
|
-
session[:atime] = Time.now.utc.to_i
|
27
|
+
session[:atime] = Time.zone.now.utc.to_i
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -35,13 +35,13 @@ class Marty::ApplicationController < ActionController::Base
|
|
35
35
|
|
36
36
|
if session_lifetime
|
37
37
|
return true unless session[:ctime] &&
|
38
|
-
(Time.now.utc.to_i -
|
38
|
+
(Time.zone.now.utc.to_i -
|
39
39
|
session[:ctime].to_i <= session_lifetime.to_i * 60)
|
40
40
|
end
|
41
41
|
|
42
42
|
if session_timeout
|
43
43
|
return true unless session[:atime] &&
|
44
|
-
(Time.now.utc.to_i - session[:atime].to_i <= session_timeout.to_i * 60)
|
44
|
+
(Time.zone.now.utc.to_i - session[:atime].to_i <= session_timeout.to_i * 60)
|
45
45
|
end
|
46
46
|
|
47
47
|
false
|
@@ -49,8 +49,8 @@ class Marty::ApplicationController < ActionController::Base
|
|
49
49
|
|
50
50
|
def start_user_session(user)
|
51
51
|
session[:user_id] = user.id
|
52
|
-
session[:ctime] = Time.now.utc.to_i
|
53
|
-
session[:atime] = Time.now.utc.to_i
|
52
|
+
session[:ctime] = Time.zone.now.utc.to_i
|
53
|
+
session[:atime] = Time.zone.now.utc.to_i
|
54
54
|
|
55
55
|
set_signed_cookies
|
56
56
|
end
|
@@ -119,12 +119,12 @@ class Marty::ApplicationController < ActionController::Base
|
|
119
119
|
|
120
120
|
def failed_authentication(login)
|
121
121
|
logger.info("Failed authentication for '#{login}' " +
|
122
|
-
"from #{request.remote_ip} at #{Time.now.utc}")
|
122
|
+
"from #{request.remote_ip} at #{Time.zone.now.utc}")
|
123
123
|
end
|
124
124
|
|
125
125
|
def successful_authentication(user)
|
126
126
|
logger.info("Successful authentication for '#{user.login}' " +
|
127
|
-
"from #{request.remote_ip} at #{Time.now.utc}")
|
127
|
+
"from #{request.remote_ip} at #{Time.zone.now.utc}")
|
128
128
|
set_user(user)
|
129
129
|
end
|
130
130
|
|
@@ -1,4 +1,6 @@
|
|
1
|
-
class Marty::DelayedJobController <
|
1
|
+
class Marty::DelayedJobController < ApplicationController
|
2
|
+
# FIXME: We probably don't need this endpoint anymore.
|
3
|
+
# It's not used by lambda
|
2
4
|
def trigger
|
3
5
|
work_off_job if delayed_job.present?
|
4
6
|
render json: { status: :ok }, status: :ok
|
@@ -7,7 +9,7 @@ class Marty::DelayedJobController < ActionController::Base
|
|
7
9
|
private
|
8
10
|
|
9
11
|
def delayed_job
|
10
|
-
return
|
12
|
+
return if params['id'].blank?
|
11
13
|
|
12
14
|
@delayed_job ||= ::Delayed::Job.find_by(id: params['id'])
|
13
15
|
end
|
@@ -15,8 +17,9 @@ class Marty::DelayedJobController < ActionController::Base
|
|
15
17
|
def work_off_job
|
16
18
|
return if delayed_job.locked_at.present?
|
17
19
|
|
18
|
-
::Delayed::Job.
|
19
|
-
|
20
|
+
::Delayed::Job.find_by(id: delayed_job.id)&.update!(
|
21
|
+
locked_at: ::Delayed::Job.db_time_now, locked_by: 'Lambda'
|
22
|
+
)
|
20
23
|
|
21
24
|
w = ::Delayed::Worker.new
|
22
25
|
w.run(delayed_job)
|
@@ -8,7 +8,7 @@ module Marty::Diagnostic; class Controller < ActionController::Base
|
|
8
8
|
def op
|
9
9
|
@result = Reporter.run(request)
|
10
10
|
rescue NameError
|
11
|
-
render file: 'public/400', formats: [:html], status:
|
11
|
+
render file: 'public/400', formats: [:html], status: :bad_request, layout: false
|
12
12
|
else
|
13
13
|
respond_to do |format|
|
14
14
|
format.html { @result = display_parameters }
|
@@ -1,8 +1,8 @@
|
|
1
|
-
class Marty::JobController <
|
1
|
+
class Marty::JobController < ApplicationController
|
2
2
|
def download
|
3
3
|
job_id = params['job_id']
|
4
4
|
|
5
|
-
promise = Marty::Promise.
|
5
|
+
promise = Marty::Promise.find_by(id: job_id)
|
6
6
|
|
7
7
|
if promise
|
8
8
|
format = promise.cformat
|
@@ -3,7 +3,7 @@ class Marty::ApiAuth < Marty::Base
|
|
3
3
|
|
4
4
|
KEY_SIZE = 19
|
5
5
|
|
6
|
-
|
6
|
+
validates :app_name, :api_key, :script_name, presence: true
|
7
7
|
|
8
8
|
class ApiAuthValidator < ActiveModel::Validator
|
9
9
|
def validate(api)
|
@@ -18,8 +18,8 @@ class Marty::ApiAuth < Marty::Base
|
|
18
18
|
validates_with ApiAuthValidator
|
19
19
|
|
20
20
|
mcfly_validates_uniqueness_of :api_key, scope: [:script_name]
|
21
|
-
|
22
|
-
:obsoleted_dt]
|
21
|
+
validates :app_name, uniqueness: { scope: [:script_name,
|
22
|
+
:obsoleted_dt] }
|
23
23
|
|
24
24
|
before_validation do
|
25
25
|
self.api_key = Marty::ApiAuth.generate_key if
|