aspera-cli 4.19.0 → 4.21.1

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 (91) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +46 -0
  4. data/CONTRIBUTING.md +18 -4
  5. data/README.md +886 -510
  6. data/bin/asession +27 -20
  7. data/examples/build_exec +65 -76
  8. data/examples/build_exec_rubyc +40 -0
  9. data/examples/get_proto_file.rb +7 -0
  10. data/lib/aspera/agent/alpha.rb +18 -24
  11. data/lib/aspera/agent/base.rb +2 -18
  12. data/lib/aspera/agent/connect.rb +34 -15
  13. data/lib/aspera/agent/direct.rb +44 -54
  14. data/lib/aspera/agent/httpgw.rb +2 -3
  15. data/lib/aspera/agent/node.rb +11 -21
  16. data/lib/aspera/agent/{trsdk.rb → transferd.rb} +27 -51
  17. data/lib/aspera/api/alee.rb +15 -0
  18. data/lib/aspera/api/aoc.rb +139 -105
  19. data/lib/aspera/api/ats.rb +1 -1
  20. data/lib/aspera/api/cos_node.rb +1 -1
  21. data/lib/aspera/api/httpgw.rb +15 -10
  22. data/lib/aspera/api/node.rb +70 -32
  23. data/lib/aspera/ascmd.rb +56 -48
  24. data/lib/aspera/ascp/installation.rb +166 -70
  25. data/lib/aspera/ascp/management.rb +30 -8
  26. data/lib/aspera/assert.rb +10 -5
  27. data/lib/aspera/cli/formatter.rb +166 -162
  28. data/lib/aspera/cli/hints.rb +2 -1
  29. data/lib/aspera/cli/info.rb +12 -10
  30. data/lib/aspera/cli/main.rb +28 -13
  31. data/lib/aspera/cli/manager.rb +7 -2
  32. data/lib/aspera/cli/plugin.rb +17 -31
  33. data/lib/aspera/cli/plugins/alee.rb +3 -3
  34. data/lib/aspera/cli/plugins/aoc.rb +246 -208
  35. data/lib/aspera/cli/plugins/ats.rb +16 -14
  36. data/lib/aspera/cli/plugins/config.rb +154 -94
  37. data/lib/aspera/cli/plugins/console.rb +3 -3
  38. data/lib/aspera/cli/plugins/cos.rb +1 -0
  39. data/lib/aspera/cli/plugins/faspex.rb +15 -23
  40. data/lib/aspera/cli/plugins/faspex5.rb +64 -50
  41. data/lib/aspera/cli/plugins/faspio.rb +2 -2
  42. data/lib/aspera/cli/plugins/httpgw.rb +1 -1
  43. data/lib/aspera/cli/plugins/node.rb +174 -109
  44. data/lib/aspera/cli/plugins/orchestrator.rb +14 -13
  45. data/lib/aspera/cli/plugins/preview.rb +8 -9
  46. data/lib/aspera/cli/plugins/server.rb +5 -9
  47. data/lib/aspera/cli/plugins/shares.rb +2 -2
  48. data/lib/aspera/cli/sync_actions.rb +2 -2
  49. data/lib/aspera/cli/transfer_agent.rb +12 -14
  50. data/lib/aspera/cli/transfer_progress.rb +37 -17
  51. data/lib/aspera/cli/version.rb +1 -1
  52. data/lib/aspera/command_line_builder.rb +4 -5
  53. data/lib/aspera/coverage.rb +13 -1
  54. data/lib/aspera/environment.rb +75 -25
  55. data/lib/aspera/faspex_gw.rb +2 -2
  56. data/lib/aspera/json_rpc.rb +1 -1
  57. data/lib/aspera/keychain/macos_security.rb +7 -12
  58. data/lib/aspera/log.rb +3 -4
  59. data/lib/aspera/node_simulator.rb +230 -112
  60. data/lib/aspera/oauth/base.rb +64 -83
  61. data/lib/aspera/oauth/factory.rb +52 -6
  62. data/lib/aspera/oauth/generic.rb +4 -8
  63. data/lib/aspera/oauth/jwt.rb +6 -3
  64. data/lib/aspera/oauth/url_json.rb +1 -2
  65. data/lib/aspera/oauth/web.rb +5 -2
  66. data/lib/aspera/persistency_action_once.rb +16 -8
  67. data/lib/aspera/persistency_folder.rb +20 -2
  68. data/lib/aspera/preview/generator.rb +1 -1
  69. data/lib/aspera/preview/utils.rb +11 -17
  70. data/lib/aspera/products/alpha.rb +30 -0
  71. data/lib/aspera/products/connect.rb +48 -0
  72. data/lib/aspera/products/other.rb +82 -0
  73. data/lib/aspera/products/transferd.rb +54 -0
  74. data/lib/aspera/rest.rb +116 -87
  75. data/lib/aspera/secret_hider.rb +2 -2
  76. data/lib/aspera/ssh.rb +31 -24
  77. data/lib/aspera/transfer/faux_file.rb +4 -4
  78. data/lib/aspera/transfer/parameters.rb +16 -17
  79. data/lib/aspera/transfer/spec.rb +12 -12
  80. data/lib/aspera/transfer/spec.yaml +22 -20
  81. data/lib/aspera/transfer/sync.rb +2 -10
  82. data/lib/aspera/transfer/uri.rb +3 -3
  83. data/lib/aspera/uri_reader.rb +1 -1
  84. data/lib/aspera/web_auth.rb +166 -17
  85. data/lib/aspera/web_server_simple.rb +4 -3
  86. data/lib/transferd_pb.rb +86 -0
  87. data/lib/transferd_services_pb.rb +84 -0
  88. data.tar.gz.sig +0 -0
  89. metadata +58 -22
  90. metadata.gz.sig +0 -0
  91. data/lib/aspera/ascp/products.rb +0 -156
@@ -12,18 +12,9 @@ require 'cgi'
12
12
 
13
13
  module Aspera
14
14
  module Api
15
- SAAS_DOMAIN_PROD = 'ibmaspera.com'
16
- class Alee < Aspera::Rest
17
- def initialize(entitlement_id, customer_id, api_domain: SAAS_DOMAIN_PROD, version: 'v1')
18
- super(
19
- base_url: "https://api.#{api_domain}/metering/#{version}",
20
- headers: {'X-Aspera-Entitlement-Authorization' => Rest.basic_token(entitlement_id, customer_id)}
21
- )
22
- end
23
- end
24
-
25
15
  class AoC < Aspera::Rest
26
16
  PRODUCT_NAME = 'Aspera on Cloud'
17
+ # use default workspace if it is set, else none
27
18
  DEFAULT_WORKSPACE = ''
28
19
  # Production domain of AoC
29
20
  SAAS_DOMAIN_PROD = 'ibmaspera.com' # cspell:disable-line
@@ -72,48 +63,61 @@ module Aspera
72
63
  return client_key, DataRepository.instance.item(client_key)
73
64
  end
74
65
 
75
- # base API url depends on domain, which could be "qa.xxx"
76
- def api_base_url(organization: 'api', api_domain: SAAS_DOMAIN_PROD)
77
- return "https://#{organization}.#{api_domain}"
66
+ # base API url depends on domain, which could be "qa.xxx" or self-managed domain
67
+ def api_base_url(api_domain: SAAS_DOMAIN_PROD)
68
+ return "https://api.#{api_domain}"
78
69
  end
79
70
 
80
- # split host of http://myorg.asperafiles.com in org and domain
81
- def url_parts(uri)
71
+ # split host of URL into organization and domain
72
+ def split_org_domain(uri)
73
+ Aspera.assert_type(uri, URI)
82
74
  raise "No host found in URL.Please check URL format: https://myorg.#{SAAS_DOMAIN_PROD}" if uri.host.nil?
83
75
  parts = uri.host.split('.', 2)
84
76
  Aspera.assert(parts.length == 2){"expecting a public FQDN for #{PRODUCT_NAME}"}
85
- return parts
77
+ parts[0] = nil if parts[0].eql?('api')
78
+ return %i{organization domain}.zip(parts).to_h
79
+ end
80
+
81
+ def saas_url?(url)
82
+ url.include?(SAAS_DOMAIN_PROD)
86
83
  end
87
84
 
88
85
  # @param url [String] URL of AoC public link
89
86
  # @return [Hash] information about public link, or nil if not a public link
90
87
  def link_info(url)
91
- final_uri = Rest.new(base_url: url, redirect_max: MAX_AOC_URL_REDIRECT).read('')[:http].uri
92
- raise 'AoC shall redirect to login page' if final_uri.query.nil?
93
- decoded_query = Rest.decode_query(final_uri.query)
88
+ final_uri = Rest.new(base_url: url, redirect_max: MAX_AOC_URL_REDIRECT).call(operation: 'GET')[:http].uri
89
+ Log.log.trace1{Log.dump(:final_uri, final_uri)}
90
+ org_domain = split_org_domain(final_uri)
91
+ if (m = final_uri.path.match(%r{/oauth2/([^/]+)/login$}))
92
+ org_domain[:organization] = m[1] if org_domain[:organization].nil?
93
+ else
94
+ Log.log.debug{"path=#{final_uri.path} does not end with /login"}
95
+ end
96
+ raise 'AoC shall redirect to login page with a query' if final_uri.query.nil?
97
+ query = Rest.query_to_h(final_uri.query)
98
+ Log.log.trace1{Log.dump(:query, query)}
94
99
  # is that a public link ?
95
- if decoded_query.key?('token')
100
+ if query.key?('token')
96
101
  Log.log.warn{"Unknown pub link path: #{final_uri.path}"} unless PUBLIC_LINK_PATHS.include?(final_uri.path)
97
102
  # ok we get it !
98
103
  return {
99
- instance_domain: url_parts(final_uri)[1],
104
+ instance_domain: org_domain[:domain],
100
105
  url: "https://#{final_uri.host}",
101
- token: decoded_query['token']
106
+ token: query['token']
102
107
  }
103
108
  end
104
- Log.log.debug{"path=#{final_uri.path} does not end with /login"} unless final_uri.path.end_with?('/login')
105
- if decoded_query['state']
109
+ if query['state']
106
110
  # can be a private link
107
- state_uri = URI.parse(decoded_query['state'])
108
- if state_uri.query && decoded_query['redirect_uri']
109
- decoded_state = Rest.decode_query(state_uri.query)
111
+ state_uri = URI.parse(query['state'])
112
+ if state_uri.query && query['redirect_uri']
113
+ decoded_state = Rest.query_to_h(state_uri.query)
110
114
  if decoded_state.key?('short_link_url')
111
115
  if (m = state_uri.path.match(%r{/files/workspaces/([0-9]+)/all/([0-9]+):([0-9]+)}))
112
- redirect_uri = URI.parse(decoded_query['redirect_uri'])
113
- parts = url_parts(redirect_uri)
116
+ redirect_uri = URI.parse(query['redirect_uri'])
117
+ org_domain = split_org_domain(redirect_uri)
114
118
  return {
115
- instance_domain: parts[1],
116
- organization: parts[0],
119
+ instance_domain: org_domain[:domain],
120
+ organization: org_domain[:organization],
117
121
  url: "https://#{redirect_uri.host}",
118
122
  private_link: {
119
123
  workspace_id: m[1],
@@ -125,10 +129,10 @@ module Aspera
125
129
  end
126
130
  end
127
131
  end
128
- parts = url_parts(URI.parse(url))
132
+ Log.log.debug{Log.dump(:org_domain, org_domain)}
129
133
  return {
130
- instance_domain: parts[1],
131
- organization: parts[0]
134
+ instance_domain: org_domain[:domain],
135
+ organization: org_domain[:organization]
132
136
  }
133
137
  end
134
138
  end
@@ -149,7 +153,8 @@ module Aspera
149
153
  @workspace_name = workspace
150
154
  @cache_user_info = nil
151
155
  @cache_url_token_info = nil
152
- @context_cache = nil
156
+ @workspace_info = nil
157
+ @home_info = nil
153
158
  auth_params = {
154
159
  type: :oauth2,
155
160
  client_id: client_id,
@@ -187,6 +192,7 @@ module Aspera
187
192
  }
188
193
  # add jwt payload for global client id
189
194
  auth_params[:payload][:org] = url_info[:organization] if GLOBAL_CLIENT_APPS.include?(auth_params[:client_id])
195
+ auth_params[:cache_ids] = [url_info[:organization]]
190
196
  when :url_json
191
197
  auth_params[:url] = {grant_type: 'url_token'} # URL arguments
192
198
  auth_params[:json] = {url_token: url_info[:token]} # JSON body
@@ -206,7 +212,7 @@ module Aspera
206
212
  return nil unless auth_params[:grant_method].eql?(:url_json)
207
213
  return @cache_url_token_info unless @cache_url_token_info.nil?
208
214
  # TODO: can there be several in list ?
209
- @cache_url_token_info = read('url_tokens')[:data].first
215
+ @cache_url_token_info = read('url_tokens').first
210
216
  return @cache_url_token_info
211
217
  end
212
218
 
@@ -225,7 +231,7 @@ module Aspera
225
231
  # get our user's default information
226
232
  @cache_user_info =
227
233
  begin
228
- read('self')[:data]
234
+ read('self')
229
235
  rescue StandardError => e
230
236
  raise e if exception
231
237
  Log.log.debug{"ignoring error: #{e}"}
@@ -235,11 +241,20 @@ module Aspera
235
241
  return @cache_user_info
236
242
  end
237
243
 
238
- # @param application [Symbol] :files or :packages
244
+ def workspace
245
+ raise 'internal error: AoC workspace context is not set' if @workspace_info.nil?
246
+ @workspace_info
247
+ end
248
+
249
+ def home
250
+ raise 'internal error: AoC home context is not set' if @home_info.nil?
251
+ @home_info
252
+ end
253
+
254
+ # Set the application context
255
+ # @param application [Symbol,NilClass] :files or :packages
239
256
  # @return [Hash] current context information: workspace, and home node/file if app is "Files"
240
- def context(application = nil)
241
- return @context_cache unless @context_cache.nil?
242
- Aspera.assert(!application.nil?){'application must be set once'}
257
+ def context=(application)
243
258
  Aspera.assert_values(application, %i[files packages])
244
259
  ws_id =
245
260
  if !public_link.nil?
@@ -249,9 +264,10 @@ module Aspera
249
264
  Log.log.debug('Using workspace of private link')
250
265
  private_link[:workspace_id]
251
266
  elsif @workspace_name.eql?(DEFAULT_WORKSPACE)
252
- Log.log.debug('Using default workspace'.green)
253
- raise 'User does not have default workspace, please specify workspace' if current_user_info['default_workspace_id'].nil?
254
- current_user_info['default_workspace_id']
267
+ if !current_user_info['default_workspace_id'].nil?
268
+ Log.log.debug('Using default workspace'.green)
269
+ current_user_info['default_workspace_id']
270
+ end
255
271
  elsif @workspace_name.nil?
256
272
  nil
257
273
  else
@@ -261,39 +277,49 @@ module Aspera
261
277
  if ws_id.nil?
262
278
  nil
263
279
  else
264
- read("workspaces/#{ws_id}")[:data]
280
+ read("workspaces/#{ws_id}")
265
281
  end
266
- @context_cache = if ws_info.nil?
267
- {
268
- workspace_id: nil,
269
- workspace_name: 'Shared folders'
270
- }
271
- else
272
- {
273
- workspace_id: ws_info['id'],
274
- workspace_name: ws_info['name']
275
- }
276
- end
277
- return @context_cache unless application.eql?(:files)
278
- if !public_link.nil?
279
- assert_public_link_types(['view_shared_file'])
280
- @context_cache[:home_node_id] = public_link['data']['node_id']
281
- @context_cache[:home_file_id] = public_link['data']['file_id']
282
- elsif !private_link.nil?
283
- @context_cache[:home_node_id] = private_link[:node_id]
284
- @context_cache[:home_file_id] = private_link[:file_id]
285
- elsif ws_info
286
- @context_cache[:home_node_id] = ws_info['home_node_id']
287
- @context_cache[:home_file_id] = ws_info['home_file_id']
288
- else
289
- # not part of any workspace, but has some folder shared
290
- user_info = current_user_info(exception: true) rescue {'read_only_home_node_id' => nil, 'read_only_home_file_id' => nil}
291
- @context_cache[:home_node_id] = user_info['read_only_home_node_id']
292
- @context_cache[:home_file_id] = user_info['read_only_home_file_id']
293
- end
294
- raise "Cannot get user's home node id, check your default workspace or specify one" if @context_cache[:home_node_id].to_s.empty?
295
- Log.log.debug{Log.dump(:context, @context_cache)}
296
- return @context_cache
282
+ @workspace_info =
283
+ if ws_info.nil?
284
+ {
285
+ id: nil,
286
+ name: 'Shared folders'
287
+ }
288
+ else
289
+ {
290
+ id: ws_info['id'],
291
+ name: ws_info['name']
292
+ }
293
+ end
294
+ Log.log.debug{Log.dump(:context, @workspace_info)}
295
+ return nil unless application.eql?(:files)
296
+ @home_info =
297
+ if !public_link.nil?
298
+ assert_public_link_types(['view_shared_file'])
299
+ {
300
+ node_id: public_link['data']['node_id'],
301
+ file_id: public_link['data']['file_id']
302
+ }
303
+ elsif !private_link.nil?
304
+ {
305
+ node_id: private_link[:node_id],
306
+ file_id: private_link[:file_id]
307
+ }
308
+ elsif ws_info
309
+ {
310
+ node_id: ws_info['home_node_id'],
311
+ file_id: ws_info['home_file_id']
312
+ }
313
+ else
314
+ # not part of any workspace, but has some folder shared
315
+ user_info = current_user_info(exception: true) rescue {'read_only_home_node_id' => nil, 'read_only_home_file_id' => nil}
316
+ {
317
+ node_id: user_info['read_only_home_node_id'],
318
+ file_id: user_info['read_only_home_file_id']
319
+ }
320
+ end
321
+ raise "Cannot get user's home node id, check your default workspace or specify one" if @home_info[:node_id].to_s.empty?
322
+ Log.log.debug{Log.dump(:context, @home_info)}
297
323
  end
298
324
 
299
325
  # @param node_id [String] identifier of node in AoC
@@ -304,9 +330,9 @@ module Aspera
304
330
  # @returns [Node] a node API for access key
305
331
  def node_api_from(node_id:, workspace_id: nil, workspace_name: nil, scope: Node::SCOPE_USER, package_info: nil)
306
332
  Aspera.assert_type(node_id, String)
307
- node_info = read("nodes/#{node_id}")[:data]
333
+ node_info = read("nodes/#{node_id}")
308
334
  if workspace_name.nil? && !workspace_id.nil?
309
- workspace_name = read("workspaces/#{workspace_id}")[:data]['name']
335
+ workspace_name = read("workspaces/#{workspace_id}")['name']
310
336
  end
311
337
  app_info = {
312
338
  api: self, # for callback
@@ -346,7 +372,7 @@ module Aspera
346
372
  pkg_data['recipients'].first.is_a?(Hash) &&
347
373
  pkg_data['recipients'].first.key?('type') &&
348
374
  pkg_data['recipients'].first['type'].eql?('dropbox')
349
- meta_schema = read("dropboxes/#{pkg_data['recipients'].first['id']}")[:data]['metadata_schema']
375
+ meta_schema = read("dropboxes/#{pkg_data['recipients'].first['id']}")['metadata_schema']
350
376
  if meta_schema.nil? || meta_schema.empty?
351
377
  Log.log.debug('no metadata in shared inbox')
352
378
  return
@@ -390,7 +416,7 @@ module Aspera
390
416
  # email: user, else dropbox
391
417
  entity_type = short_recipient_info.include?('@') ? 'contacts' : 'dropboxes'
392
418
  begin
393
- full_recipient_info = lookup_by_name(entity_type, short_recipient_info, {'current_workspace_id' => ws_id})
419
+ full_recipient_info = lookup_by_name(entity_type, short_recipient_info, query: {'current_workspace_id' => ws_id})
394
420
  rescue RuntimeError => e
395
421
  raise e unless e.message.start_with?(ENTITY_NOT_FOUND)
396
422
  # dropboxes cannot be created on the fly
@@ -399,7 +425,7 @@ module Aspera
399
425
  full_recipient_info = create('contacts', {
400
426
  'current_workspace_id' => ws_id,
401
427
  'email' => short_recipient_info
402
- }.merge(new_user_option))[:data]
428
+ }.merge(new_user_option))
403
429
  end
404
430
  short_recipient_info = if entity_type.eql?('dropboxes')
405
431
  {'id' => full_recipient_info['id'], 'type' => 'dropbox'}
@@ -422,13 +448,12 @@ module Aspera
422
448
  case pkg_data['metadata']
423
449
  when Array, NilClass # no action
424
450
  when Hash
425
- api_meta = []
426
- pkg_data['metadata'].each do |k, v|
427
- api_meta.push({
451
+ api_meta = pkg_data['metadata'].map do |k, v|
452
+ {
428
453
  # 'input_type' => 'single-dropdown',
429
454
  'name' => k,
430
455
  'values' => v.is_a?(Array) ? v : [v]
431
- })
456
+ }
432
457
  end
433
458
  pkg_data['metadata'] = api_meta
434
459
  else Aspera.error_unexpected_value(pkg_meta.class)
@@ -453,7 +478,7 @@ module Aspera
453
478
  validate_metadata(package_data) if validate_meta
454
479
 
455
480
  # create a new package container
456
- created_package = create('packages', package_data)[:data]
481
+ created_package = create('packages', package_data)
457
482
 
458
483
  package_node_api = node_api_from(
459
484
  node_id: created_package['node_id'],
@@ -463,7 +488,7 @@ module Aspera
463
488
  # tell AoC what to expect in package: 1 transfer (can also be done after transfer)
464
489
  # TODO: if multi session was used we should probably tell
465
490
  # also, currently no "multi-source" , i.e. only from client-side files, unless "node" agent is used
466
- update("packages/#{created_package['id']}", {'sent' => true, 'transfers_expected' => 1})[:data]
491
+ update("packages/#{created_package['id']}", {'sent' => true, 'transfers_expected' => 1})
467
492
 
468
493
  return {
469
494
  spec: package_node_api.transfer_spec_gen4(created_package['contents_file_id'], Transfer::Spec::DIRECTION_SEND),
@@ -524,14 +549,14 @@ module Aspera
524
549
  ID_AK_ADMIN = 'ASPERA_ACCESS_KEY_ADMIN'
525
550
  # Callback from Plugins::Node
526
551
  # add application specific tags to permissions creation
527
- # @param create_param [Hash] parameters for creating permissions
552
+ # @param perm_data [Hash] parameters for creating permissions
528
553
  # @param app_info [Hash] application information
529
- def permissions_set_create_params(create_param:, app_info:)
554
+ def permissions_set_create_params(perm_data:, app_info:)
530
555
  # workspace shared folder:
531
556
  # access_id = "#{ID_AK_ADMIN}_WS_#{app_info[:workspace_id]}"
532
- default_params = {
557
+ defaults = {
533
558
  # 'access_type' => 'user', # mandatory: user or group
534
- # 'access_id' => access_id, # id of user or group
559
+ # 'access_id' => access_id, # id of user or group or special
535
560
  'tags' => {
536
561
  Transfer::Spec::TAG_RESERVED => {
537
562
  'files' => {
@@ -543,6 +568,7 @@ module Aspera
543
568
  'shared_by_name' => current_user_info['name'],
544
569
  'shared_by_email' => current_user_info['email'],
545
570
  # 'shared_with_name' => access_id,
571
+ # 'share_as' => new_name_for_folder,
546
572
  'access_key' => app_info[:node_info]['access_key'],
547
573
  'node' => app_info[:node_info]['name']
548
574
  }
@@ -550,34 +576,42 @@ module Aspera
550
576
  }
551
577
  }
552
578
  }
553
- create_param.deep_merge!(default_params)
554
- if create_param.key?('with')
555
- contact_info = lookup_by_name(
556
- 'contacts',
557
- create_param['with'],
558
- {'current_workspace_id' => app_info[:workspace_id], 'context' => 'share_folder'})
559
- create_param.delete('with')
560
- create_param['access_type'] = contact_info['source_type']
561
- create_param['access_id'] = contact_info['source_id']
562
- create_param['tags'][Transfer::Spec::TAG_RESERVED]['files']['workspace']['shared_with_name'] = contact_info['email']
579
+ perm_data.deep_merge!(defaults)
580
+ tag_workspace = perm_data['tags'][Transfer::Spec::TAG_RESERVED]['files']['workspace']
581
+ case perm_data['with']
582
+ when NilClass
583
+ when ''
584
+ perm_data['access_type'] = 'user'
585
+ perm_data['access_id'] = "#{ID_AK_ADMIN}_WS_#{app_info[:workspace_id]}"
586
+ tag_workspace['shared_with_name'] = perm_data['access_id']
587
+ else
588
+ entity_info = lookup_by_name('contacts', perm_data['with'], query: {'current_workspace_id' => app_info[:workspace_id]})
589
+ perm_data['access_type'] = entity_info['source_type']
590
+ perm_data['access_id'] = entity_info['source_id']
591
+ tag_workspace['shared_with_name'] = entity_info['email']
592
+ end
593
+ perm_data.delete('with')
594
+ if perm_data.key?('as')
595
+ tag_workspace['share_as'] = perm_data['as']
596
+ perm_data.delete('as')
563
597
  end
564
598
  # optional
565
- app_info[:opt_link_name] = create_param.delete('link_name')
599
+ app_info[:opt_link_name] = perm_data.delete('link_name')
566
600
  end
567
601
 
568
602
  # Callback from Plugins::Node
569
603
  # send shared folder event to AoC
570
- # @param created_data [Hash] response from permission creation
604
+ # @param event_data [Hash] response from permission creation
571
605
  # @param app_info [Hash] hash with app info
572
606
  # @param types [Array] event types
573
- def permissions_send_event(created_data:, app_info:, types: PERMISSIONS_CREATED)
607
+ def permissions_send_event(event_data:, app_info:, types: PERMISSIONS_CREATED)
574
608
  Aspera.assert_type(types, Array)
575
609
  Aspera.assert(!types.empty?)
576
610
  event_creation = {
577
611
  'types' => types,
578
612
  'node_id' => app_info[:node_info]['id'],
579
613
  'workspace_id' => app_info[:workspace_id],
580
- 'data' => created_data
614
+ 'data' => event_data
581
615
  }
582
616
  # (optional). The name of the folder to be displayed to the destination user.
583
617
  # Use it if its value is different from the "share_as" field.
@@ -34,7 +34,7 @@ module Aspera
34
34
  if @all_servers_cache.nil?
35
35
  @all_servers_cache = []
36
36
  CLOUD_NAME.each_key do |name|
37
- read("servers/#{name.to_s.upcase}")[:data].each do |i|
37
+ read("servers/#{name.to_s.upcase}").each do |i|
38
38
  @all_servers_cache.push(i)
39
39
  end
40
40
  end
@@ -19,7 +19,7 @@ module Aspera
19
19
  Aspera.assert(service_credentials.key?(field)){"service_credentials must have a field: #{field}"}
20
20
  end
21
21
  # read endpoints from service provided in service credentials
22
- endpoints = Aspera::Rest.new(base_url: service_credentials['endpoints']).read('')[:data]
22
+ endpoints = Aspera::Rest.new(base_url: service_credentials['endpoints']).read('')
23
23
  Aspera::Log.dump('endpoints', endpoints)
24
24
  endpoint = endpoints.dig('service-endpoints', 'regional', bucket_region, 'public', bucket_region)
25
25
  raise "no such region: #{bucket_region}" if endpoint.nil?
@@ -138,7 +138,7 @@ module Aspera
138
138
  def upload(transfer_spec)
139
139
  # identify this session uniquely
140
140
  session_id = SecureRandom.uuid
141
- @notify_cb&.call(session_id: nil, type: :pre_start, info: 'starting')
141
+ @notify_cb&.call(:pre_start, session_id: nil, info: 'starting')
142
142
  # process files to send, modify `paths` in transfer_spec
143
143
  files_to_send = process_upload_list(transfer_spec)
144
144
  # total size of all files is last element
@@ -147,7 +147,7 @@ module Aspera
147
147
  Log.log.trace1{Log.dump(:files_to_send, files_to_send)}
148
148
  # TODO: check that this is available in endpoints: @api_info['endpoints']
149
149
  upload_url = File.join(@gw_root_url, @upload_version, 'upload')
150
- @notify_cb&.call(session_id: nil, type: :pre_start, info: 'connecting wss')
150
+ @notify_cb&.call(:pre_start, session_id: nil, info: 'connecting wss')
151
151
  # open web socket to end point (equivalent to Net::HTTP.start)
152
152
  http_session = Rest.start_http_session(upload_url)
153
153
  # get the underlying socket i/o
@@ -172,11 +172,11 @@ module Aspera
172
172
  }
173
173
  # start read thread after handshake
174
174
  @ws_read_thread = Thread.new {process_read_thread}
175
- @notify_cb&.call(session_id: session_id, type: :session_start)
176
- @notify_cb&.call(session_id: session_id, type: :session_size, info: total_bytes_to_transfer)
175
+ @notify_cb&.call(:session_start, session_id: session_id)
176
+ @notify_cb&.call(:session_size, session_id: session_id, info: total_bytes_to_transfer)
177
177
  sleep(1)
178
178
  # notify progress bar
179
- @notify_cb&.call(type: :session_size, session_id: session_id, info: total_bytes_to_transfer)
179
+ @notify_cb&.call(:session_size, session_id: session_id, info: total_bytes_to_transfer)
180
180
  # first step send transfer spec
181
181
  ws_snd_json(MSG_SEND_TRANSFER_SPEC, transfer_spec)
182
182
  # current file index
@@ -223,7 +223,7 @@ module Aspera
223
223
  raise e
224
224
  end
225
225
  session_sent_bytes += slice_bin_data.length
226
- @notify_cb&.call(type: :transfer, session_id: session_id, info: session_sent_bytes)
226
+ @notify_cb&.call(:transfer, session_id: session_id, info: session_sent_bytes)
227
227
  slice_info[:slice] += 1
228
228
  end
229
229
  ensure
@@ -232,8 +232,8 @@ module Aspera
232
232
  file_index += 1
233
233
  end
234
234
  # throttling may have skipped last one
235
- @notify_cb&.call(type: :transfer, session_id: session_id, info: session_sent_bytes)
236
- @notify_cb&.call(type: :end, session_id: session_id)
235
+ @notify_cb&.call(:transfer, session_id: session_id, info: session_sent_bytes)
236
+ @notify_cb&.call(:end, session_id: session_id)
237
237
  ws_send(ws_type: :close, data: nil)
238
238
  Log.log.debug("Finished upload, waiting for end of #{THR_RECV} thread.")
239
239
  @ws_read_thread.join
@@ -256,7 +256,7 @@ module Aspera
256
256
  end
257
257
  transfer_spec['download_name'] = download_name
258
258
  end
259
- creation = create('download', {'transfer_spec' => transfer_spec})[:data]
259
+ creation = create('download', {'transfer_spec' => transfer_spec})
260
260
  transfer_uuid = creation['url'].split('/').last
261
261
  file_name =
262
262
  if transfer_spec['zip_required'] || transfer_spec['paths'].length > 1
@@ -274,6 +274,11 @@ module Aspera
274
274
  return @api_info
275
275
  end
276
276
 
277
+ # @return the base url of the gateway
278
+ def base_url
279
+ return @gw_root_url
280
+ end
281
+
277
282
  # @param url [String] URL of the HTTP Gateway, without version
278
283
  def initialize(
279
284
  url:,
@@ -299,7 +304,7 @@ module Aspera
299
304
  @synchronous = synchronous
300
305
  @notify_cb = notify_cb
301
306
  # get API info
302
- @api_info = read('info')[:data].freeze
307
+ @api_info = read('info').freeze
303
308
  Log.log.debug{Log.dump(:api_info, @api_info)}
304
309
  # web socket endpoint: by default use v2 (newer gateways), without base64 encoding
305
310
  # is the latest supported? else revert to old api