aspera-cli 4.14.0 → 4.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +54 -3
  4. data/CONTRIBUTING.md +7 -7
  5. data/README.md +1457 -880
  6. data/bin/ascli +18 -9
  7. data/bin/asession +12 -14
  8. data/examples/proxy.pac +1 -1
  9. data/lib/aspera/aoc.rb +198 -127
  10. data/lib/aspera/ascmd.rb +24 -14
  11. data/lib/aspera/cli/basic_auth_plugin.rb +9 -6
  12. data/lib/aspera/cli/error.rb +17 -0
  13. data/lib/aspera/cli/extended_value.rb +47 -12
  14. data/lib/aspera/cli/formatter.rb +260 -171
  15. data/lib/aspera/cli/hints.rb +80 -0
  16. data/lib/aspera/cli/main.rb +101 -147
  17. data/lib/aspera/cli/manager.rb +160 -124
  18. data/lib/aspera/cli/plugin.rb +70 -59
  19. data/lib/aspera/cli/plugins/alee.rb +0 -1
  20. data/lib/aspera/cli/plugins/aoc.rb +239 -273
  21. data/lib/aspera/cli/plugins/ats.rb +8 -5
  22. data/lib/aspera/cli/plugins/bss.rb +2 -2
  23. data/lib/aspera/cli/plugins/config.rb +516 -375
  24. data/lib/aspera/cli/plugins/console.rb +40 -0
  25. data/lib/aspera/cli/plugins/cos.rb +4 -5
  26. data/lib/aspera/cli/plugins/faspex.rb +99 -84
  27. data/lib/aspera/cli/plugins/faspex5.rb +179 -148
  28. data/lib/aspera/cli/plugins/node.rb +219 -153
  29. data/lib/aspera/cli/plugins/orchestrator.rb +52 -17
  30. data/lib/aspera/cli/plugins/preview.rb +46 -32
  31. data/lib/aspera/cli/plugins/server.rb +57 -17
  32. data/lib/aspera/cli/plugins/shares.rb +34 -12
  33. data/lib/aspera/cli/sync_actions.rb +68 -0
  34. data/lib/aspera/cli/transfer_agent.rb +45 -55
  35. data/lib/aspera/cli/transfer_progress.rb +74 -0
  36. data/lib/aspera/cli/version.rb +1 -1
  37. data/lib/aspera/colors.rb +3 -1
  38. data/lib/aspera/command_line_builder.rb +14 -11
  39. data/lib/aspera/cos_node.rb +3 -2
  40. data/lib/aspera/environment.rb +17 -6
  41. data/lib/aspera/fasp/agent_aspera.rb +126 -0
  42. data/lib/aspera/fasp/agent_base.rb +31 -77
  43. data/lib/aspera/fasp/agent_connect.rb +21 -22
  44. data/lib/aspera/fasp/agent_direct.rb +88 -102
  45. data/lib/aspera/fasp/agent_httpgw.rb +196 -192
  46. data/lib/aspera/fasp/agent_node.rb +41 -34
  47. data/lib/aspera/fasp/agent_trsdk.rb +75 -34
  48. data/lib/aspera/fasp/error_info.rb +2 -2
  49. data/lib/aspera/fasp/faux_file.rb +52 -0
  50. data/lib/aspera/fasp/installation.rb +43 -184
  51. data/lib/aspera/fasp/management.rb +244 -0
  52. data/lib/aspera/fasp/parameters.rb +59 -26
  53. data/lib/aspera/fasp/parameters.yaml +75 -8
  54. data/lib/aspera/fasp/products.rb +162 -0
  55. data/lib/aspera/fasp/transfer_spec.rb +1 -1
  56. data/lib/aspera/fasp/uri.rb +4 -4
  57. data/lib/aspera/faspex_gw.rb +2 -2
  58. data/lib/aspera/faspex_postproc.rb +2 -2
  59. data/lib/aspera/hash_ext.rb +2 -2
  60. data/lib/aspera/json_rpc.rb +49 -0
  61. data/lib/aspera/line_logger.rb +23 -0
  62. data/lib/aspera/log.rb +57 -16
  63. data/lib/aspera/node.rb +97 -14
  64. data/lib/aspera/oauth.rb +36 -18
  65. data/lib/aspera/open_application.rb +4 -4
  66. data/lib/aspera/persistency_folder.rb +2 -2
  67. data/lib/aspera/preview/file_types.rb +4 -2
  68. data/lib/aspera/preview/generator.rb +22 -35
  69. data/lib/aspera/preview/options.rb +2 -0
  70. data/lib/aspera/preview/terminal.rb +24 -13
  71. data/lib/aspera/preview/utils.rb +19 -26
  72. data/lib/aspera/rest.rb +103 -72
  73. data/lib/aspera/rest_call_error.rb +1 -1
  74. data/lib/aspera/rest_error_analyzer.rb +15 -14
  75. data/lib/aspera/rest_errors_aspera.rb +37 -34
  76. data/lib/aspera/secret_hider.rb +14 -16
  77. data/lib/aspera/ssh.rb +4 -1
  78. data/lib/aspera/sync.rb +128 -122
  79. data/lib/aspera/temp_file_manager.rb +10 -3
  80. data/lib/aspera/web_auth.rb +10 -7
  81. data/lib/aspera/web_server_simple.rb +9 -4
  82. data.tar.gz.sig +0 -0
  83. metadata +33 -15
  84. metadata.gz.sig +0 -0
  85. data/lib/aspera/cli/listener/line_dump.rb +0 -19
  86. data/lib/aspera/cli/listener/logger.rb +0 -22
  87. data/lib/aspera/cli/listener/progress.rb +0 -50
  88. data/lib/aspera/cli/listener/progress_multi.rb +0 -84
  89. data/lib/aspera/cli/plugins/sync.rb +0 -44
  90. data/lib/aspera/fasp/listener.rb +0 -13
data/lib/aspera/sync.rb CHANGED
@@ -1,22 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # cspell:words logdir
3
+ # cspell:words logdir bidi watchd cooloff asyncadmin
4
4
 
5
5
  require 'aspera/command_line_builder'
6
6
  require 'aspera/fasp/installation'
7
+ require 'aspera/log'
7
8
  require 'json'
8
9
  require 'base64'
10
+ require 'open3'
11
+ require 'English'
9
12
 
10
13
  module Aspera
11
14
  # builds command line arg for async
12
- class Sync
13
- # default is push
15
+ module Sync
16
+ # sync direction, default is push
14
17
  DIRECTIONS = %i[push pull bidi].freeze
15
- DIRECTION_TO_REQUEST_TYPE = {
16
- push: :sync_upload,
17
- pull: :sync_download,
18
- bidi: :sync
19
- }.freeze
20
18
  PARAMS_VX_INSTANCE =
21
19
  {
22
20
  'alt_logdir' => { cli: { type: :opt_with_arg}, accepted_types: :string},
@@ -82,132 +80,140 @@ module Aspera
82
80
  }.freeze
83
81
 
84
82
  ASYNC_EXECUTABLE = 'async'
83
+ ASYNC_ADMIN_EXECUTABLE = 'asyncadmin'
85
84
 
86
- private_constant :PARAMS_VX_INSTANCE, :PARAMS_VX_SESSION, :PARAMS_VX_KEYS, :ASYNC_EXECUTABLE, :TS_TO_PARAMS_V2
87
-
88
- attr_reader :env_args
85
+ private_constant :PARAMS_VX_INSTANCE, :PARAMS_VX_SESSION, :PARAMS_VX_KEYS, :TS_TO_PARAMS_V2, :ASYNC_EXECUTABLE, :ASYNC_ADMIN_EXECUTABLE
86
+
87
+ class << self
88
+ # Set remote_dir in sync parameters based on transfer spec
89
+ # @param params [Hash] sync parameters, old or new format
90
+ # @param remote_dir_key [String] key to update in above hash
91
+ # @param transfer_spec [Hash] transfer spec
92
+ def update_remote_dir(sync_params, remote_dir_key, transfer_spec)
93
+ if transfer_spec.dig(*%w[tags aspera node file_id])
94
+ # in AoC, use gen4
95
+ sync_params[remote_dir_key] = '/'
96
+ elsif transfer_spec['cookie']&.start_with?('aspera.shares2')
97
+ # TODO : something more generic, independent of Shares
98
+ # in Shares, the actual folder on remote end is not always the same as the name of the share
99
+ actual_remote = transfer_spec['paths']&.first&.[]('source')
100
+ sync_params[remote_dir_key] = actual_remote if actual_remote
101
+ end
102
+ nil
103
+ end
89
104
 
90
- # @param sync_params [Hash] sync parameters, old or new format
91
- # @param node_sync [Object|nil]
92
- def initialize(sync_params, node_sync)
93
- raise StandardError, 'parameter must be Hash' unless sync_params.is_a?(Hash)
94
- raise 'node_sync misses method transfer_spec' unless node_sync.nil? || node_sync.respond_to?(:transfer_spec)
95
- @env_args = {
96
- args: [],
97
- env: {}
98
- }
99
- if sync_params.key?('local')
100
- # async native JSON format (v2)
101
- raise StandardError, 'remote must be Hash' unless sync_params['remote'].is_a?(Hash)
102
- unless node_sync.nil?
103
- transfer_spec = node_sync.transfer_spec(sync_params['direction'], sync_params['local']['path'], sync_params['remote']['path'])
104
- # async native JSON format
105
- raise StandardError, 'local must be Hash' unless sync_params['local'].is_a?(Hash)
106
- TS_TO_PARAMS_V2.each do |ts_param, sy_path|
107
- next unless transfer_spec.key?(ts_param)
108
- sy_dig = sy_path.split('.')
109
- param = sy_dig.pop
110
- hash = sy_dig.empty? ? sync_params : sync_params[sy_dig.first]
111
- hash = sync_params[sy_dig.first] = {} if hash.nil?
112
- hash[param] = transfer_spec[ts_param]
105
+ # @param sync_params [Hash] sync parameters, old or new format
106
+ # @param block [nil, Proc] block to generate transfer spec, takes: direction (one of DIRECTIONS), local_dir, remote_dir
107
+ def start(sync_params, &block)
108
+ raise 'Internal Error: sync_params parameter must be Hash' unless sync_params.is_a?(Hash)
109
+ env_args = {
110
+ args: [],
111
+ env: {}
112
+ }
113
+ if sync_params.key?('local')
114
+ # async native JSON format (v2)
115
+ raise StandardError, 'remote must be Hash' unless sync_params['remote'].is_a?(Hash)
116
+ if block
117
+ transfer_spec = yield((sync_params['direction'] || 'push').to_sym, sync_params['local']['path'], sync_params['remote']['path'])
118
+ # async native JSON format
119
+ raise StandardError, 'sync parameter "local" must be Hash' unless sync_params['local'].is_a?(Hash)
120
+ TS_TO_PARAMS_V2.each do |ts_param, sy_path|
121
+ next unless transfer_spec.key?(ts_param)
122
+ sy_dig = sy_path.split('.')
123
+ param = sy_dig.pop
124
+ hash = sy_dig.empty? ? sync_params : sync_params[sy_dig.first]
125
+ hash = sync_params[sy_dig.first] = {} if hash.nil?
126
+ hash[param] = transfer_spec[ts_param]
127
+ end
128
+ sync_params['remote']['connect_mode'] ||= sync_params['remote'].key?('ws_port') ? 'ws' : 'ssh'
129
+ sync_params['remote']['private_key_paths'] ||= Fasp::Installation.instance.aspera_token_ssh_key_paths if transfer_spec.key?('token')
130
+ update_remote_dir(sync_params['remote'], 'path', transfer_spec)
113
131
  end
114
- # 'remote.path',
115
- sync_params['remote']['connect_mode'] ||= sync_params['remote'].key?('ws_port') ? 'ws' : 'ssh'
116
- sync_params['remote']['private_key_paths'] ||= Fasp::Installation.instance.bypass_keys if transfer_spec.key?('token')
117
- sync_params['remote']['path'] ||= '/' if transfer_spec.dig(*%w[tags aspera node file_id])
118
- end
119
- @env_args[:args] = ["--conf64=#{Base64.strict_encode64(JSON.generate(sync_params))}"]
120
- elsif sync_params.key?('sessions')
121
- # ascli JSON format (v1)
122
- unless node_sync.nil?
123
- sync_params['sessions'].each do |session|
124
- transfer_spec = node_sync.transfer_spec(session['direction'], session['local_dir'], session['remote_dir'])
125
- PARAMS_VX_SESSION.each do |async_param, behavior|
126
- if behavior.key?(:ts)
127
- tspec_param = behavior[:ts].is_a?(TrueClass) ? async_param : behavior[:ts].to_s
128
- session[async_param] ||= transfer_spec[tspec_param] if transfer_spec.key?(tspec_param)
132
+ env_args[:args] = ["--conf64=#{Base64.strict_encode64(JSON.generate(sync_params))}"]
133
+ elsif sync_params.key?('sessions')
134
+ # ascli JSON format (v1)
135
+ if block
136
+ sync_params['sessions'].each do |session|
137
+ transfer_spec = yield((session['direction'] || 'push').to_sym, session['local_dir'], session['remote_dir'])
138
+ PARAMS_VX_SESSION.each do |async_param, behavior|
139
+ if behavior.key?(:ts)
140
+ tspec_param = behavior[:ts].is_a?(TrueClass) ? async_param : behavior[:ts].to_s
141
+ session[async_param] ||= transfer_spec[tspec_param] if transfer_spec.key?(tspec_param)
142
+ end
129
143
  end
144
+ session['private_key_paths'] = Fasp::Installation.instance.aspera_token_ssh_key_paths if transfer_spec.key?('token')
145
+ update_remote_dir(session, 'remote_dir', transfer_spec)
130
146
  end
131
- session['private_key_paths'] = Fasp::Installation.instance.bypass_keys if transfer_spec.key?('token')
132
- session['remote_dir'] = '/' if transfer_spec.dig(*%w[tags aspera node file_id])
133
147
  end
134
- end
135
- raise StandardError, "Only 'sessions', and optionally 'instance' keys are allowed" unless
136
- sync_params.keys.push('instance').uniq.sort.eql?(PARAMS_VX_KEYS)
137
- raise StandardError, 'sessions key must be Array' unless sync_params['sessions'].is_a?(Array)
138
- raise StandardError, 'sessions key requires at least one Hash' unless sync_params['sessions'].first.is_a?(Hash)
148
+ raise StandardError, "Only 'sessions', and optionally 'instance' keys are allowed" unless
149
+ sync_params.keys.push('instance').uniq.sort.eql?(PARAMS_VX_KEYS)
150
+ raise StandardError, 'sessions key must be Array' unless sync_params['sessions'].is_a?(Array)
151
+ raise StandardError, 'sessions key requires at least one Hash' unless sync_params['sessions'].first.is_a?(Hash)
152
+
153
+ if sync_params.key?('instance')
154
+ raise StandardError, 'instance key must be Hash' unless sync_params['instance'].is_a?(Hash)
155
+ instance_builder = Aspera::CommandLineBuilder.new(sync_params['instance'], PARAMS_VX_INSTANCE)
156
+ instance_builder.process_params
157
+ instance_builder.add_env_args(env_args)
158
+ end
139
159
 
140
- if sync_params.key?('instance')
141
- raise StandardError, 'instance key must be Hash' unless sync_params['instance'].is_a?(Hash)
142
- instance_builder = Aspera::CommandLineBuilder.new(sync_params['instance'], PARAMS_VX_INSTANCE)
143
- instance_builder.process_params
144
- instance_builder.add_env_args(@env_args[:env], @env_args[:args])
160
+ sync_params['sessions'].each do |session_params|
161
+ raise StandardError, 'sessions must contain hashes' unless session_params.is_a?(Hash)
162
+ raise StandardError, 'session must contain at least name' unless session_params.key?('name')
163
+ session_builder = Aspera::CommandLineBuilder.new(session_params, PARAMS_VX_SESSION)
164
+ session_builder.process_params
165
+ session_builder.add_env_args(env_args)
166
+ end
167
+ else
168
+ raise 'At least one of `local` or `sessions` must be present in async parameters'
145
169
  end
146
-
147
- sync_params['sessions'].each do |session_params|
148
- raise StandardError, 'sessions must contain hashes' unless session_params.is_a?(Hash)
149
- raise StandardError, 'session must contain at least name' unless session_params.key?('name')
150
- session_builder = Aspera::CommandLineBuilder.new(session_params, PARAMS_VX_SESSION)
151
- session_builder.process_params
152
- session_builder.add_env_args(@env_args[:env], @env_args[:args])
170
+ Log.log.debug{Log.dump(:sync_params, sync_params)}
171
+
172
+ Log.log.debug{"execute: #{env_args[:env].map{|k, v| "#{k}=\"#{v}\""}.join(' ')} \"#{ASYNC_EXECUTABLE}\" \"#{env_args[:args].join('" "')}\""}
173
+ res = system(env_args[:env], [ASYNC_EXECUTABLE, ASYNC_EXECUTABLE], *env_args[:args])
174
+ Log.log.debug{"result=#{res}"}
175
+ case res
176
+ when true then return nil
177
+ when false then raise "failed: #{$CHILD_STATUS}"
178
+ when nil then raise "not started: #{$CHILD_STATUS}"
179
+ else raise 'internal error: unspecified case'
153
180
  end
154
- else
155
- raise 'At least one of `local` or `sessions` must be present in async parameters'
156
181
  end
157
- Log.dump(:sync, sync_params)
158
- end
159
182
 
160
- def start
161
- Log.log.debug{"execute: #{@env_args[:env].map{|k, v| "#{k}=\"#{v}\""}.join(' ')} \"#{ASYNC_EXECUTABLE}\" \"#{@env_args[:args].join('" "')}\""}
162
- res = system(@env_args[:env], [ASYNC_EXECUTABLE, ASYNC_EXECUTABLE], *@env_args[:args])
163
- Log.log.debug{"result=#{res}"}
164
- case res
165
- when true then return nil
166
- when false then raise "failed: #{$CHILD_STATUS}"
167
- when nil then raise "not started: #{$CHILD_STATUS}"
168
- else raise 'internal error: unspecified case'
169
- end
170
- end
171
- end # end Sync
172
-
173
- class SyncAdmin
174
- ASYNC_ADMIN_EXECUTABLE = 'asyncadmin'
175
- private_constant :ASYNC_ADMIN_EXECUTABLE
176
- def initialize(sync_params, session_name)
177
- @cmdline = [ASYNC_ADMIN_EXECUTABLE, '--quiet']
178
- if sync_params.key?('local')
179
- raise 'Missing session name' if sync_params['name'].nil?
180
- raise 'Session not found' unless session_name.nil? || session_name.eql?(sync_params['name'])
181
- @cmdline.push("--name=#{sync_params['name']}")
182
- if sync_params.key?('local_db_dir')
183
- @cmdline.push("--local-db-dir=#{sync_params['local_db_dir']}")
184
- elsif sync_params.dig('local', 'path')
185
- @cmdline.push("--local-dir=#{sync_params.dig('local', 'path')}")
186
- else
187
- raise 'Missing either local_db_dir or local.path'
188
- end
189
- elsif sync_params.key?('sessions')
190
- session = session_name.nil? ? sync_params['sessions'].first : sync_params['sessions'].find{|s|s['name'].eql?(session_name)}
191
- raise 'Session not found' if session.nil?
192
- raise 'Missing session name' if session['name'].nil?
193
- @cmdline.push("--name=#{session['name']}")
194
- if session.key?('local_db_dir')
195
- @cmdline.push("--local-db-dir=#{session['local_db_dir']}")
196
- elsif session.key?('local_dir')
197
- @cmdline.push("--local-dir=#{session['local_dir']}")
183
+ def admin_status(sync_params, session_name)
184
+ command_line = [ASYNC_ADMIN_EXECUTABLE, '--quiet']
185
+ if sync_params.key?('local')
186
+ raise 'Missing session name' if sync_params['name'].nil?
187
+ raise 'Session not found' unless session_name.nil? || session_name.eql?(sync_params['name'])
188
+ command_line.push("--name=#{sync_params['name']}")
189
+ if sync_params.key?('local_db_dir')
190
+ command_line.push("--local-db-dir=#{sync_params['local_db_dir']}")
191
+ elsif sync_params.dig('local', 'path')
192
+ command_line.push("--local-dir=#{sync_params.dig('local', 'path')}")
193
+ else
194
+ raise 'Missing either local_db_dir or local.path'
195
+ end
196
+ elsif sync_params.key?('sessions')
197
+ session = session_name.nil? ? sync_params['sessions'].first : sync_params['sessions'].find{|s|s['name'].eql?(session_name)}
198
+ raise "Session #{session_name} not found in #{sync_params['sessions'].map{|s|s['name']}.join(',')}" if session.nil?
199
+ raise 'Missing session name' if session['name'].nil?
200
+ command_line.push("--name=#{session['name']}")
201
+ if session.key?('local_db_dir')
202
+ command_line.push("--local-db-dir=#{session['local_db_dir']}")
203
+ elsif session.key?('local_dir')
204
+ command_line.push("--local-dir=#{session['local_dir']}")
205
+ else
206
+ raise 'Missing either local_db_dir or local_dir'
207
+ end
198
208
  else
199
- raise 'Missing either local_db_dir or local_dir'
209
+ raise 'At least one of `local` or `sessions` must be present in async parameters'
200
210
  end
201
- else
202
- raise 'At least one of `local` or `sessions` must be present in async parameters'
211
+ Log.log.debug{"execute: #{command_line.join(' ')}"}
212
+ stdout, stderr, status = Open3.capture3(*command_line)
213
+ Log.log.debug{"status=#{status}, stderr=#{stderr}"}
214
+ raise "Sync failed: #{status.exitstatus} : #{stderr}" unless status.success?
215
+ return stdout.split("\n").each_with_object({}){|l, m|i = l.split(':', 2); m[i.first.lstrip] = i.last.lstrip} # rubocop:disable Style/Semicolon
203
216
  end
204
217
  end
205
-
206
- def status
207
- stdout, stderr, status = Open3.capture3(*@cmdline)
208
- Log.log.debug{"status=#{status}, stderr=#{stderr}"}
209
- raise "Sync failed: #{status.exitstatus} : #{stderr}" unless status.success?
210
- return stdout.split("\n").each_with_object({}){|l, m|i = l.split(/: */); m[i.first.lstrip] = i.last.lstrip} # rubocop:disable Style/Semicolon
211
- end
212
- end
213
- end
218
+ end # end Sync
219
+ end # end Aspera
@@ -14,14 +14,21 @@ module Aspera
14
14
  FILE_LIST_AGE_MAX_SEC = SEC_IN_DAY * 5
15
15
  private_constant :SEC_IN_DAY, :FILE_LIST_AGE_MAX_SEC
16
16
  include Singleton
17
+ attr_accessor :cleanup_on_exit
18
+
17
19
  def initialize
18
20
  @created_files = []
21
+ @cleanup_on_exit = true
22
+ end
23
+
24
+ def delete_file(filepath)
25
+ File.delete(filepath) if @cleanup_on_exit
19
26
  end
20
27
 
21
28
  # call this on process exit
22
29
  def cleanup
23
30
  @created_files.each do |filepath|
24
- File.delete(filepath) if File.file?(filepath)
31
+ delete_file(filepath) if File.file?(filepath)
25
32
  end
26
33
  @created_files = []
27
34
  end
@@ -29,7 +36,7 @@ module Aspera
29
36
  # ensure that provided folder exists, or create it, generate a unique filename
30
37
  # @return path to that unique file
31
38
  def new_file_path_in_folder(temp_folder, add_base = '')
32
- FileUtils.mkdir_p(temp_folder) unless Dir.exist?(temp_folder)
39
+ FileUtils.mkdir_p(temp_folder)
33
40
  new_file = File.join(temp_folder, add_base + SecureRandom.uuid)
34
41
  @created_files.push(new_file)
35
42
  new_file
@@ -54,7 +61,7 @@ module Aspera
54
61
  # check age of file, delete too old
55
62
  if File.file?(file_path) && (age_sec > FILE_LIST_AGE_MAX_SEC)
56
63
  Log.log.debug{"garbage collecting #{name}"}
57
- File.delete(file_path)
64
+ delete_file(file_path)
58
65
  end
59
66
  end
60
67
  end
@@ -6,20 +6,22 @@ require 'stringio'
6
6
  module Aspera
7
7
  # servlet called on callback: it records the callback request
8
8
  class WebAuthServlet < WEBrick::HTTPServlet::AbstractServlet
9
- def initialize(server, application) # additional args get here
9
+ # @param server [WEBrick::HTTPServer]
10
+ # @param web_auth [WebAuth]
11
+ def initialize(server, web_auth)
10
12
  Log.log.debug('WebAuthServlet initialize')
11
13
  super(server)
12
- @app = application
14
+ @web_auth = web_auth
13
15
  end
14
16
 
15
17
  def service(request, response)
16
18
  Log.log.debug{"received request from browser #{request.request_method} #{request.path}"}
17
19
  raise WEBrick::HTTPStatus::MethodNotAllowed, "unexpected method: #{request.request_method}" unless request.request_method.eql?('GET')
18
- raise WEBrick::HTTPStatus::NotFound, "unexpected path: #{request.path}" unless request.path.eql?(@app.expected_path)
20
+ raise WEBrick::HTTPStatus::NotFound, "unexpected path: #{request.path}" unless request.path.eql?(@web_auth.expected_path)
19
21
  # acquire lock and signal change
20
- @app.mutex.synchronize do
21
- @app.query = request.query
22
- @app.cond.signal
22
+ @web_auth.mutex.synchronize do
23
+ @web_auth.query = request.query
24
+ @web_auth.cond.signal
23
25
  end
24
26
  response.status = 200
25
27
  response.content_type = 'text/html'
@@ -42,7 +44,8 @@ module Aspera
42
44
  @cond = ConditionVariable.new
43
45
  @expected_path = uri.path.empty? ? '/' : uri.path
44
46
  @query = nil
45
- mount(@expected_path, WebAuthServlet, self) # additional args provided to constructor
47
+ # last argument (self) is provided to constructor of servlet
48
+ mount(@expected_path, WebAuthServlet, self)
46
49
  Thread.new { start }
47
50
  end
48
51
 
@@ -8,12 +8,17 @@ require 'openssl'
8
8
  module Aspera
9
9
  class WebServerSimple < WEBrick::HTTPServer
10
10
  CERT_PARAMETERS = %i[key cert chain].freeze
11
+ GENERIC_ISSUER = '/C=FR/O=Test/OU=Test/CN=Test'
12
+ ONE_YEAR_SECONDS = 365 * 24 * 60 * 60
13
+
14
+ private_constant :CERT_PARAMETERS, :GENERIC_ISSUER, :ONE_YEAR_SECONDS
15
+
11
16
  class << self
12
17
  # generates and adds self signed cert to provided webrick options
13
- def fill_self_signed_cert(cert, key)
14
- cert.subject = cert.issuer = OpenSSL::X509::Name.parse('/C=FR/O=Test/OU=Test/CN=Test')
18
+ def fill_self_signed_cert(cert, key, digest = 'SHA256')
19
+ cert.subject = cert.issuer = OpenSSL::X509::Name.parse(GENERIC_ISSUER)
15
20
  cert.not_before = Time.now
16
- cert.not_after = Time.now + 365 * 24 * 60 * 60
21
+ cert.not_after = Time.now + ONE_YEAR_SECONDS
17
22
  cert.public_key = key.public_key
18
23
  cert.serial = 0x0
19
24
  cert.version = 2
@@ -26,7 +31,7 @@ module Aspera
26
31
  # ef.create_extension('keyUsage', 'cRLSign,keyCertSign', true),
27
32
  ]
28
33
  cert.add_extension(ef.create_extension('authorityKeyIdentifier', 'keyid:always,issuer:always'))
29
- cert.sign(key, OpenSSL::Digest.new('SHA256'))
34
+ cert.sign(key, OpenSSL::Digest.new(digest))
30
35
  end
31
36
  end
32
37
 
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aspera-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.14.0
4
+ version: 4.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Laurent Martin
@@ -37,24 +37,24 @@ cert_chain:
37
37
  eTf9kxhVM40wGQOECVNA8UsEEZHD48eF+csUYZtAJOF5oxTI8UyV9T/o6CgO0c9/
38
38
  Gzz+Qm5ULOUcPiJLjSpaiTrkiIVYiDGnqNSr6R1Hb1c=
39
39
  -----END CERTIFICATE-----
40
- date: 2023-09-22 00:00:00.000000000 Z
40
+ date: 2023-11-17 00:00:00.000000000 Z
41
41
  dependencies:
42
42
  - !ruby/object:Gem::Dependency
43
- name: execjs
43
+ name: blankslate
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: '2.0'
48
+ version: '3.1'
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: '2.0'
55
+ version: '3.1'
56
56
  - !ruby/object:Gem::Dependency
57
- name: jwt
57
+ name: execjs
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
60
  - - "~>"
@@ -68,19 +68,19 @@ dependencies:
68
68
  - !ruby/object:Gem::Version
69
69
  version: '2.0'
70
70
  - !ruby/object:Gem::Dependency
71
- name: net-smtp
71
+ name: jwt
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
74
  - - "~>"
75
75
  - !ruby/object:Gem::Version
76
- version: '0.3'
76
+ version: '2.0'
77
77
  type: :runtime
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
81
  - - "~>"
82
82
  - !ruby/object:Gem::Version
83
- version: '0.3'
83
+ version: '2.0'
84
84
  - !ruby/object:Gem::Dependency
85
85
  name: net-ssh
86
86
  requirement: !ruby/object:Gem::Requirement
@@ -221,6 +221,20 @@ dependencies:
221
221
  - - "~>"
222
222
  - !ruby/object:Gem::Version
223
223
  version: '0.3'
224
+ - !ruby/object:Gem::Dependency
225
+ name: rmagick
226
+ requirement: !ruby/object:Gem::Requirement
227
+ requirements:
228
+ - - "~>"
229
+ - !ruby/object:Gem::Version
230
+ version: '5.3'
231
+ type: :development
232
+ prerelease: false
233
+ version_requirements: !ruby/object:Gem::Requirement
234
+ requirements:
235
+ - - "~>"
236
+ - !ruby/object:Gem::Version
237
+ version: '5.3'
224
238
  - !ruby/object:Gem::Dependency
225
239
  name: bundler
226
240
  requirement: !ruby/object:Gem::Requirement
@@ -369,13 +383,11 @@ files:
369
383
  - lib/aspera/ascmd.rb
370
384
  - lib/aspera/ats_api.rb
371
385
  - lib/aspera/cli/basic_auth_plugin.rb
386
+ - lib/aspera/cli/error.rb
372
387
  - lib/aspera/cli/extended_value.rb
373
388
  - lib/aspera/cli/formatter.rb
389
+ - lib/aspera/cli/hints.rb
374
390
  - lib/aspera/cli/info.rb
375
- - lib/aspera/cli/listener/line_dump.rb
376
- - lib/aspera/cli/listener/logger.rb
377
- - lib/aspera/cli/listener/progress.rb
378
- - lib/aspera/cli/listener/progress_multi.rb
379
391
  - lib/aspera/cli/main.rb
380
392
  - lib/aspera/cli/manager.rb
381
393
  - lib/aspera/cli/plugin.rb
@@ -393,8 +405,9 @@ files:
393
405
  - lib/aspera/cli/plugins/preview.rb
394
406
  - lib/aspera/cli/plugins/server.rb
395
407
  - lib/aspera/cli/plugins/shares.rb
396
- - lib/aspera/cli/plugins/sync.rb
408
+ - lib/aspera/cli/sync_actions.rb
397
409
  - lib/aspera/cli/transfer_agent.rb
410
+ - lib/aspera/cli/transfer_progress.rb
398
411
  - lib/aspera/cli/version.rb
399
412
  - lib/aspera/colors.rb
400
413
  - lib/aspera/command_line_builder.rb
@@ -407,6 +420,7 @@ files:
407
420
  - lib/aspera/data/6
408
421
  - lib/aspera/data_repository.rb
409
422
  - lib/aspera/environment.rb
423
+ - lib/aspera/fasp/agent_aspera.rb
410
424
  - lib/aspera/fasp/agent_base.rb
411
425
  - lib/aspera/fasp/agent_connect.rb
412
426
  - lib/aspera/fasp/agent_direct.rb
@@ -415,10 +429,12 @@ files:
415
429
  - lib/aspera/fasp/agent_trsdk.rb
416
430
  - lib/aspera/fasp/error.rb
417
431
  - lib/aspera/fasp/error_info.rb
432
+ - lib/aspera/fasp/faux_file.rb
418
433
  - lib/aspera/fasp/installation.rb
419
- - lib/aspera/fasp/listener.rb
434
+ - lib/aspera/fasp/management.rb
420
435
  - lib/aspera/fasp/parameters.rb
421
436
  - lib/aspera/fasp/parameters.yaml
437
+ - lib/aspera/fasp/products.rb
422
438
  - lib/aspera/fasp/resume_policy.rb
423
439
  - lib/aspera/fasp/transfer_spec.rb
424
440
  - lib/aspera/fasp/uri.rb
@@ -426,8 +442,10 @@ files:
426
442
  - lib/aspera/faspex_postproc.rb
427
443
  - lib/aspera/hash_ext.rb
428
444
  - lib/aspera/id_generator.rb
445
+ - lib/aspera/json_rpc.rb
429
446
  - lib/aspera/keychain/encrypted_hash.rb
430
447
  - lib/aspera/keychain/macos_security.rb
448
+ - lib/aspera/line_logger.rb
431
449
  - lib/aspera/log.rb
432
450
  - lib/aspera/nagios.rb
433
451
  - lib/aspera/node.rb
metadata.gz.sig CHANGED
Binary file
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'aspera/fasp/listener'
4
- require 'json'
5
-
6
- module Aspera
7
- module Cli
8
- module Listener
9
- # listener for FASP transfers (debug)
10
- # FASP event listener display management events as JSON
11
- class LineDump < Aspera::Fasp::Listener
12
- def event_enhanced(data)
13
- $stdout.puts(JSON.generate(data))
14
- $stdout.flush
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'aspera/fasp/listener'
4
- require 'aspera/log'
5
-
6
- module Aspera
7
- module Cli
8
- module Listener
9
- # listener for FASP transfers (debug)
10
- class Logger < Aspera::Fasp::Listener
11
- def event_struct(data)
12
- Log.log.debug(data.to_s)
13
- Log.log.error((data['Description']).to_s) if data['Type'].eql?('FILEERROR')
14
- end
15
-
16
- def event_enhanced(data)
17
- Log.log.debug(JSON.generate(data))
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'aspera/fasp/listener'
4
- require 'aspera/environment'
5
- require 'ruby-progressbar'
6
-
7
- module Aspera
8
- module Cli
9
- module Listener
10
- # a listener to FASP event that displays a progress bar
11
- class Progress < Aspera::Fasp::Listener
12
- def initialize
13
- super
14
- @progress = nil
15
- @cumulative = 0
16
- end
17
-
18
- def event_struct(data)
19
- case data['Type']
20
- when 'NOTIFICATION'
21
- if data.key?('PreTransferBytes')
22
- @progress = ProgressBar.create(
23
- format: '%a %B %p%% %r Mbps %e',
24
- rate_scale: lambda{|rate|rate / Environment::BYTES_PER_MEBIBIT},
25
- title: 'progress',
26
- total: data['PreTransferBytes'].to_i)
27
- end
28
- when 'STOP'
29
- # stop event when one file is completed
30
- @cumulative += data['Size'].to_i
31
- when 'STATS'
32
- if @progress.nil?
33
- puts '.'
34
- else
35
- @progress.progress = data.key?('Bytescont') ? @cumulative + data['Bytescont'].to_i : data['TransferBytes'].to_i
36
- end
37
- when 'DONE'
38
- if @progress.nil?
39
- # terminate progress by going to next line
40
- puts "\n"
41
- else
42
- @progress.progress = @progress.total
43
- @progress = nil
44
- end
45
- end
46
- end
47
- end
48
- end
49
- end
50
- end