aspera-cli 4.14.0 → 4.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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