marty 2.5.7 → 2.5.8

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: e21e7788214cabe5b48e33e15fbefcdbc30ba526f1a8870a3c5c7ab240b48b4d
4
- data.tar.gz: 285129ffcd5648deeaa816a7923efc6b146adc01ba2a75624f0a5944063c7372
3
+ metadata.gz: 17d4c8cca5e227120b347328f76f6b5c2844a3662fe4fa31c186d4ac5b422f9b
4
+ data.tar.gz: 5ae6f1ec90da4b1543ed781e2bd9b9ef88224d9b51bde8257f9e9188dc44b82c
5
5
  SHA512:
6
- metadata.gz: 16931641ca8a4478ee399f24fe50398989d35aae7353efebd550e371ad76d45de9faf465f4e139cf4bbb28ae5502fb734f0be49de1f9e054d2d85369c059b190
7
- data.tar.gz: de0f280f2a9d0077134e8d717d2e5882c0e35cb3909b9049b4127435b9cb34040bdc8de5081946be80e5085325aee769e48fe8906a919f07fcdc217486e2cf3e
6
+ metadata.gz: 5705fbd63836311b4f6b2847d9b2b2fe998a413980a5a795a98494f94e8dc0dda78dc0a3a05d994c821102e8bf8320afe6465393dd663674cb22b5cfa2b63a52
7
+ data.tar.gz: 806137fda06674d6d4fa937689a0da78898f1c4589ee1f52833030aea10537e48a76037ebbe2acc7a1c90eaccee1bb4d2af7ea325a09f93dbbc35028af5f37e9
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- marty (2.5.7)
4
+ marty (2.5.8)
5
5
  aws-sigv4 (~> 1.0, >= 1.0.2)
6
6
  axlsx (= 3.0.0pre)
7
7
  coderay
@@ -1,5 +1,6 @@
1
1
  class Marty::PromiseView < Netzke::Tree::Base
2
2
  extend ::Marty::Permissions
3
+ has_marty_permissions read: :any
3
4
 
4
5
  client_styles do |config|
5
6
  config.require :promise_view
@@ -15,11 +16,17 @@ class Marty::PromiseView < Netzke::Tree::Base
15
16
  c.include :promise_view
16
17
  end
17
18
 
18
- def configure(config)
19
+ ######################################################################
20
+
21
+ def class_can?(op)
22
+ self.class.can_perform_action?(op)
23
+ end
24
+
25
+ def configure(c)
19
26
  super
20
- config.title = I18n.t('jobs.promise_view')
21
- config.model = 'Marty::VwPromise'
22
- config.attributes = [
27
+ c.title = I18n.t('jobs.promise_view')
28
+ c.model = 'Marty::VwPromise'
29
+ c.attributes = [
23
30
  { name: :title, xtype: :treecolumn },
24
31
  :user__login,
25
32
  :job_id,
@@ -29,14 +36,17 @@ class Marty::PromiseView < Netzke::Tree::Base
29
36
  :cformat,
30
37
  :error,
31
38
  ]
32
- config.root_visible = false
33
- config.paging = :none
34
- config.bbar = bbar
35
- config.read_only = true
36
- config.permissions = { update: false,
37
- create: false,
38
- delete: false,
39
- }
39
+ c.root_visible = false
40
+ c.paging = :none
41
+ c.bbar = bbar
42
+ c.read_only = true
43
+ c.permissions = {
44
+ create: class_can?(:create),
45
+ read: class_can?(:read),
46
+ update: class_can?(:update),
47
+ delete: class_can?(:delete)
48
+ }
49
+
40
50
  # garbage collect old promises (hacky to do this here)
41
51
  Marty::Promise.cleanup(false)
42
52
  end
@@ -1,56 +1,54 @@
1
1
  class Marty::RpcController < ActionController::Base
2
+ INTERNAL_SERVER_ERROR = { error: 'internal server error' }
3
+ PERMISSION_DENIED_ERROR = { error: 'Permission denied' }
4
+
2
5
  def evaluate
3
- # set default result and params in case of unexpected errors
4
- # to ensure logging capabilities
5
- result = nil
6
- api_params = {}
7
- start_time = nil
8
- auth = nil
9
-
10
- # massage request params
11
- massaged_params = massage_params(params)
12
-
13
- # resolve api config in order to determine api class and settings
14
- api_config = Marty::ApiConfig.lookup(*massaged_params.values_at(
15
- :script,
16
- :node,
17
- :attr)
18
- ) || {}
19
-
20
- # default to base class if no config is present
21
- api = api_config.present? ? api_config[:api_class].constantize :
22
- Marty::Api::Base
23
-
24
- return result = massaged_params if massaged_params.include?(:error)
25
-
26
- api_params = api.process_params(massaged_params)
27
- auth = api.is_authorized?(api_params)
28
- return result = { error: 'Permission denied' } unless auth
29
-
30
- start_time = Time.zone.now
31
- api.before_evaluate(api_params)
32
- result = api.evaluate(api_params, request, api_config)
33
- api.after_evaluate(api_params, result)
34
- rescue StandardError => e
35
- # log unexpected failures in rpc controller and respond with
36
- # generic server error
37
- Marty::Logger.log('rpc_controller', 'failure', e.message)
38
- result = { error: 'internal server error' }
39
- ensure
40
- # if logging is enabled, always log the result even on error
41
- if api_config && api_config[:logged] && api
42
- api.log(result,
43
- api_params + { start_time: start_time, auth: auth },
44
- request)
45
- end
6
+ massaged_params = massage_params(params)
7
+
8
+ # resolve api config in order to determine api class and settings
9
+ api_config = get_api_config(massaged_params) || {}
10
+
11
+ # default to base class if no config is present
12
+ api = api_config[:api_class].try(:constantize) || Marty::Api::Base
13
+
14
+ api.respond_to(self) do
15
+ begin
16
+ next massaged_params if massaged_params.include?(:error)
17
+
18
+ api_params = api.process_params(massaged_params)
19
+ auth = api.is_authorized?(api_params)
20
+
21
+ next PERMISSION_DENIED_ERROR unless auth
46
22
 
47
- api.respond_to(self) do
48
- result || { 'error' => 'internal server error' }
23
+ # allow api classes to return hashes with error key for custom responses
24
+ next auth if auth.is_a?(Hash) && auth[:error]
25
+
26
+ start_time = Time.zone.now
27
+ api.before_evaluate(api_params)
28
+
29
+ result = api.evaluate(api_params, request, api_config)
30
+ api.after_evaluate(api_params, result)
31
+
32
+ if api_config[:logged]
33
+ log_params = api_params + { start_time: start_time, auth: auth }
34
+ api.log(result, log_params, request)
35
+ end
36
+
37
+ result
38
+ rescue StandardError => e
39
+ Marty::Logger.log('rpc_controller', 'failure', e.message)
40
+ INTERNAL_SERVER_ERROR
49
41
  end
42
+ end
50
43
  end
51
44
 
52
45
  private
53
46
 
47
+ def get_api_config params
48
+ config_attrs = params.values_at(:script, :node, :attr)
49
+ Marty::ApiConfig.lookup(*config_attrs)
50
+ end
51
+
54
52
  def process_active_params params
55
53
  # must permit params before conversion to_h
56
54
  # convert hash to json and parse to get expected hash (not indifferent)
@@ -53,6 +53,23 @@ class Marty::User < Marty::Base
53
53
  authenticate_with?(login, password) || nil
54
54
  end
55
55
 
56
+ def self.ldap_login(login, password)
57
+ # IMPORTANT NOTE: if server allows anonymous LDAP access, empty
58
+ # passwords will succeed! i.e. if a valid user with empty
59
+ # password is sent in, ldap.bind will return OK.
60
+ cf = Rails.configuration.marty.ldap
61
+ ldap = Net::LDAP.new(host: cf.host,
62
+ port: cf.port,
63
+ base: cf.base_dn,
64
+ encryption: cf.encryption,
65
+ auth: {
66
+ method: :simple,
67
+ username: cf.domain + '\\' + login,
68
+ password: password,
69
+ })
70
+ ldap.bind
71
+ end
72
+
56
73
  def self.authenticate_with?(login, password)
57
74
  cf = Rails.configuration.marty
58
75
 
@@ -61,20 +78,7 @@ class Marty::User < Marty::Base
61
78
  if auth_source == 'local'
62
79
  ok = password == cf.local_password
63
80
  elsif auth_source == 'ldap'
64
- # IMPORTANT NOTE: if server allows anonymous LDAP access, empty
65
- # passwords will succeed! i.e. if a valid user with empty
66
- # password is sent in, ldap.bind will return OK.
67
- cf = Rails.configuration.marty.ldap
68
- ldap = Net::LDAP.new(host: cf.host,
69
- port: cf.port,
70
- base: cf.base_dn,
71
- encryption: cf.encryption,
72
- auth: {
73
- method: :simple,
74
- username: cf.domain + '\\' + login,
75
- password: password,
76
- })
77
- ok = ldap.bind
81
+ ok = ldap_login(login, password)
78
82
  else
79
83
  raise "bad auth_source: #{auth_source.inspect}"
80
84
  end
@@ -1,3 +1,3 @@
1
1
  module Marty
2
- VERSION = '2.5.7'
2
+ VERSION = '2.5.8'
3
3
  end
@@ -168,25 +168,28 @@ class Marty::Api::Base
168
168
  return unless hash
169
169
 
170
170
  pf = ActionDispatch::Http::ParameterFilter.new(filter_params)
171
- pf.filter(hash)
171
+ pf.filter(hash.stringify_keys)
172
172
  end
173
173
 
174
174
  def self.log_hash result, params, request
175
- res = result.is_a?(Hash) ? result.stringify_keys : result
176
175
  ret_arr = params[:return_array]
176
+
177
+ # filter sensitive information from input/output
178
+ is_hash = result.is_a?(Hash)
179
+ res = is_hash ? filter_hash(result, engine_params_filter) : result
177
180
  input = filter_hash(params[:params], engine_params_filter)
181
+ error = res['error'] if is_hash && res.include?('error')
182
+
178
183
  { script: params[:script],
179
- node: params[:node],
180
- attrs: ret_arr ? [params[:attr]] : params[:attr],
181
- input: input,
182
- output: (res.is_a?(Hash) &&
183
- res.include?('error')) ? nil : res,
184
- start_time: params[:start_time],
185
- end_time: Time.zone.now,
186
- error: (res.is_a?(Hash) &&
187
- res.include?('error')) ? res['error'] : nil,
188
- remote_ip: request.remote_ip,
189
- auth_name: params[:auth]
184
+ node: params[:node],
185
+ attrs: ret_arr ? [params[:attr]] : params[:attr],
186
+ input: input,
187
+ output: error ? nil : res,
188
+ start_time: params[:start_time],
189
+ end_time: Time.zone.now,
190
+ error: error,
191
+ remote_ip: request.remote_ip,
192
+ auth_name: params[:auth]
190
193
  }
191
194
  end
192
195
 
@@ -1,4 +1,6 @@
1
1
  module Marty::Diagnostic; class DelayedJobWorkers < Base
2
+ DIAG_NAME = 'Delayed Workers / Node'
3
+ DIAG_CONFIG_TARGET = 'DIAG_DELAYED_TARGET'
2
4
  diagnostic_fn do
3
5
  my_ip = Node.my_ip
4
6
  workers = Database.current_connections.map do |c|
@@ -6,7 +8,16 @@ module Marty::Diagnostic; class DelayedJobWorkers < Base
6
8
  name = c['application_name']
7
9
  name if name.include?('delayed') && (ip == my_ip || ip == '127.0.0.1')
8
10
  end.compact.uniq.count
9
- { 'Delayed Workers / Node' => workers.zero? ? error(workers) : workers }
11
+
12
+ target_count = Marty::Config[DIAG_CONFIG_TARGET]
13
+
14
+ next { DIAG_NAME => workers.zero? ? error(workers) : workers } unless
15
+ target_count
16
+
17
+ next { DIAG_NAME => error("invalid type for #{DIAG_CONFIG_TARGET}") } unless
18
+ target_count.is_a?(Integer)
19
+
20
+ { DIAG_NAME => workers == target_count ? workers : error(workers) }
10
21
  end
11
22
  end
12
23
  end
@@ -2,12 +2,13 @@ require 'spec_helper'
2
2
  require 'job_helper'
3
3
 
4
4
  describe Marty::Diagnostic::DelayedJobWorkers do
5
- def sample_data ip = nil, error = false
5
+ def sample_data opts={}
6
+ ip, error, status = opts.values_at(:ip, :error, :status)
6
7
  {
7
8
  ip || Marty::Helper.my_ip => {
8
9
  'Delayed Workers / Node' => {
9
10
  'description' => error ? '3' : '4',
10
- 'status' => true,
11
+ 'status' => status,
11
12
  'consistent' => nil
12
13
  },
13
14
  }
@@ -16,10 +17,10 @@ describe Marty::Diagnostic::DelayedJobWorkers do
16
17
 
17
18
  def sample_aggregate error = false
18
19
  [
19
- sample_data(ip = '0.0.0.0'),
20
- sample_data(ip = '0.0.0.1'),
21
- sample_data(ip = '0.0.0.2', error = error),
22
- sample_data(ip = '0.0.0.3'),
20
+ sample_data(ip: '0.0.0.0'),
21
+ sample_data(ip: '0.0.0.1'),
22
+ sample_data(ip: '0.0.0.2', error: error),
23
+ sample_data(ip: '0.0.0.3'),
23
24
  ].reduce(:merge)
24
25
  end
25
26
 
@@ -37,8 +38,10 @@ describe Marty::Diagnostic::DelayedJobWorkers do
37
38
  expect(described_class.consistent?(inconsistent)).to eq(false)
38
39
  end
39
40
 
40
- it 'recognizes zero workers as an error' do
41
- data = described_class.generate.values[0]
42
- expect(data['Delayed Workers / Node']['status']).to eq(false)
41
+ it 'allows a config to set the target workers' do
42
+ Marty::Config['DIAG_DELAYED_TARGET'] = 2
43
+ start_delayed_job
44
+ expect(described_class.generate).to eq(sample_data(status: false))
45
+ stop_delayed_job
43
46
  end
44
47
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: marty
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.7
4
+ version: 2.5.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arman Bostani
@@ -429,7 +429,6 @@ files:
429
429
  - other/marty/diagnostic/connections.rb
430
430
  - other/marty/diagnostic/database.rb
431
431
  - other/marty/diagnostic/delayed_job_version.rb
432
- - other/marty/diagnostic/delayed_job_worker_total_count.rb
433
432
  - other/marty/diagnostic/delayed_job_workers.rb
434
433
  - other/marty/diagnostic/environment_variables.rb
435
434
  - other/marty/diagnostic/fatal.rb
@@ -1,10 +0,0 @@
1
- module Marty::Diagnostic; class DelayedJobWorkerTotalCount < Base
2
- diagnostic_fn(aggregatable: false) do
3
- count = Database.current_connections.map do |c|
4
- [c['application_name'], c['client_addr'] || '127.0.0.1'] if
5
- c['application_name'].include?('delayed')
6
- end.compact.uniq.count
7
- { 'Delayed Workers' => count.zero? ? error(count) : count }
8
- end
9
- end
10
- end