aspera-cli 4.6.0 → 4.7.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 (96) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +427 -300
  3. data/bin/ascli +2 -1
  4. data/bin/asession +1 -0
  5. data/docs/test_env.conf +2 -0
  6. data/examples/aoc.rb +4 -3
  7. data/examples/faspex4.rb +21 -19
  8. data/examples/proxy.pac +1 -1
  9. data/examples/transfer.rb +15 -15
  10. data/lib/aspera/aoc.rb +135 -124
  11. data/lib/aspera/ascmd.rb +85 -75
  12. data/lib/aspera/ats_api.rb +11 -10
  13. data/lib/aspera/cli/basic_auth_plugin.rb +13 -14
  14. data/lib/aspera/cli/extended_value.rb +42 -33
  15. data/lib/aspera/cli/formater.rb +138 -111
  16. data/lib/aspera/cli/info.rb +17 -0
  17. data/lib/aspera/cli/listener/line_dump.rb +3 -2
  18. data/lib/aspera/cli/listener/logger.rb +2 -1
  19. data/lib/aspera/cli/listener/progress.rb +16 -18
  20. data/lib/aspera/cli/listener/progress_multi.rb +13 -16
  21. data/lib/aspera/cli/main.rb +122 -130
  22. data/lib/aspera/cli/manager.rb +146 -154
  23. data/lib/aspera/cli/plugin.rb +38 -34
  24. data/lib/aspera/cli/plugins/alee.rb +6 -6
  25. data/lib/aspera/cli/plugins/aoc.rb +273 -276
  26. data/lib/aspera/cli/plugins/ats.rb +82 -76
  27. data/lib/aspera/cli/plugins/bss.rb +14 -16
  28. data/lib/aspera/cli/plugins/config.rb +350 -306
  29. data/lib/aspera/cli/plugins/console.rb +23 -19
  30. data/lib/aspera/cli/plugins/cos.rb +18 -18
  31. data/lib/aspera/cli/plugins/faspex.rb +180 -159
  32. data/lib/aspera/cli/plugins/faspex5.rb +64 -54
  33. data/lib/aspera/cli/plugins/node.rb +147 -140
  34. data/lib/aspera/cli/plugins/orchestrator.rb +68 -66
  35. data/lib/aspera/cli/plugins/preview.rb +92 -96
  36. data/lib/aspera/cli/plugins/server.rb +79 -75
  37. data/lib/aspera/cli/plugins/shares.rb +23 -24
  38. data/lib/aspera/cli/plugins/sync.rb +20 -22
  39. data/lib/aspera/cli/transfer_agent.rb +40 -39
  40. data/lib/aspera/cli/version.rb +2 -1
  41. data/lib/aspera/colors.rb +35 -27
  42. data/lib/aspera/command_line_builder.rb +48 -34
  43. data/lib/aspera/cos_node.rb +29 -21
  44. data/lib/aspera/data_repository.rb +3 -2
  45. data/lib/aspera/environment.rb +50 -45
  46. data/lib/aspera/fasp/agent_base.rb +22 -20
  47. data/lib/aspera/fasp/agent_connect.rb +13 -11
  48. data/lib/aspera/fasp/agent_direct.rb +48 -59
  49. data/lib/aspera/fasp/agent_httpgw.rb +33 -39
  50. data/lib/aspera/fasp/agent_node.rb +15 -13
  51. data/lib/aspera/fasp/agent_trsdk.rb +12 -14
  52. data/lib/aspera/fasp/error.rb +2 -1
  53. data/lib/aspera/fasp/error_info.rb +68 -52
  54. data/lib/aspera/fasp/installation.rb +106 -94
  55. data/lib/aspera/fasp/listener.rb +1 -0
  56. data/lib/aspera/fasp/parameters.rb +83 -92
  57. data/lib/aspera/fasp/parameters.yaml +305 -249
  58. data/lib/aspera/fasp/resume_policy.rb +11 -14
  59. data/lib/aspera/fasp/transfer_spec.rb +26 -0
  60. data/lib/aspera/fasp/uri.rb +22 -21
  61. data/lib/aspera/faspex_gw.rb +55 -90
  62. data/lib/aspera/hash_ext.rb +4 -3
  63. data/lib/aspera/id_generator.rb +8 -7
  64. data/lib/aspera/keychain/encrypted_hash.rb +17 -16
  65. data/lib/aspera/keychain/macos_security.rb +6 -10
  66. data/lib/aspera/log.rb +25 -20
  67. data/lib/aspera/nagios.rb +13 -12
  68. data/lib/aspera/node.rb +30 -22
  69. data/lib/aspera/oauth.rb +175 -226
  70. data/lib/aspera/open_application.rb +4 -3
  71. data/lib/aspera/persistency_action_once.rb +6 -6
  72. data/lib/aspera/persistency_folder.rb +5 -9
  73. data/lib/aspera/preview/file_types.rb +6 -5
  74. data/lib/aspera/preview/generator.rb +25 -24
  75. data/lib/aspera/preview/options.rb +16 -14
  76. data/lib/aspera/preview/utils.rb +98 -98
  77. data/lib/aspera/{proxy_auto_config.erb.js → proxy_auto_config.js} +23 -31
  78. data/lib/aspera/proxy_auto_config.rb +111 -20
  79. data/lib/aspera/rest.rb +115 -113
  80. data/lib/aspera/rest_call_error.rb +2 -2
  81. data/lib/aspera/rest_error_analyzer.rb +23 -25
  82. data/lib/aspera/rest_errors_aspera.rb +15 -14
  83. data/lib/aspera/ssh.rb +12 -10
  84. data/lib/aspera/sync.rb +42 -41
  85. data/lib/aspera/temp_file_manager.rb +18 -14
  86. data/lib/aspera/timer_limiter.rb +2 -1
  87. data/lib/aspera/uri_reader.rb +7 -5
  88. data/lib/aspera/web_auth.rb +79 -76
  89. metadata +64 -21
  90. data/docs/Makefile +0 -65
  91. data/docs/README.erb.md +0 -4424
  92. data/docs/README.md +0 -13
  93. data/docs/diagrams.txt +0 -49
  94. data/docs/doc_tools.rb +0 -58
  95. data/lib/aspera/cli/plugins/shares2.rb +0 -114
  96. data/lib/aspera/fasp/default.rb +0 -17
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'singleton'
2
3
  require 'aspera/log'
3
4
 
@@ -5,13 +6,12 @@ module Aspera
5
6
  module Fasp
6
7
  # implements a simple resume policy
7
8
  class ResumePolicy
8
-
9
9
  # list of supported parameters and default values
10
10
  DEFAULTS={
11
- :iter_max => 7,
12
- :sleep_initial => 2,
13
- :sleep_factor => 2,
14
- :sleep_max => 60
11
+ iter_max: 7,
12
+ sleep_initial: 2,
13
+ sleep_factor: 2,
14
+ sleep_max: 60
15
15
  }
16
16
 
17
17
  # @param params see DEFAULTS
@@ -20,12 +20,9 @@ module Aspera
20
20
  if !params.nil?
21
21
  raise "expecting Hash (or nil), but have #{params.class}" unless params.is_a?(Hash)
22
22
  params.each do |k,v|
23
- if DEFAULTS.has_key?(k)
24
- raise "#{k} must be Integer" unless v.is_a?(Integer)
25
- @parameters[k]=v
26
- else
27
- raise "unknown resume parameter: #{k}, expect one of #{DEFAULTS.keys.map{|i|i.to_s}.join(",")}"
28
- end
23
+ raise "unknown resume parameter: #{k}, expect one of #{DEFAULTS.keys.map(&:to_s).join(',')}" unless DEFAULTS.has_key?(k)
24
+ raise "#{k} must be Integer" unless v.is_a?(Integer)
25
+ @parameters[k]=v
29
26
  end
30
27
  end
31
28
  Log.log.debug("resume params=#{@parameters}")
@@ -45,9 +42,9 @@ module Aspera
45
42
  block.call
46
43
  break
47
44
  rescue Fasp::Error => e
48
- Log.log.warn("An error occured: #{e.message}" );
45
+ Log.log.warn("An error occured: #{e.message}");
49
46
  # failure in ascp
50
- if e.retryable? then
47
+ if e.retryable?
51
48
  # exit if we exceed the max number of retry
52
49
  raise Fasp::Error,'Maximum number of retry reached' if remaining_resumes <= 0
53
50
  else
@@ -61,7 +58,7 @@ module Aspera
61
58
 
62
59
  # take this retry in account
63
60
  remaining_resumes-=1
64
- Log.log.warn( "resuming in #{sleep_seconds} seconds (retry left:#{remaining_resumes})" );
61
+ Log.log.warn("resuming in #{sleep_seconds} seconds (retry left:#{remaining_resumes})");
65
62
 
66
63
  # wait a bit before retrying, maybe network condition will be better
67
64
  sleep(sleep_seconds)
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ require 'aspera/fasp/parameters'
3
+
4
+ module Aspera
5
+ module Fasp
6
+ # parameters for Transfer Spec
7
+ class TransferSpec
8
+ # default transfer username for access key based transfers
9
+ ACCESS_KEY_TRANSFER_USER='xfer'
10
+ SSH_PORT=33_001
11
+ UDP_PORT=33_001
12
+ AK_TSPEC_BASE={
13
+ 'remote_user' => ACCESS_KEY_TRANSFER_USER,
14
+ 'ssh_port' => SSH_PORT,
15
+ 'fasp_port' => UDP_PORT
16
+ }
17
+ # define constants for enums of parameters: <paramater>_<enum>, e.g. CIPHER_AES_128
18
+ Aspera::Fasp::Parameters.description.each do |k,v|
19
+ next unless v[:enum].is_a?(Array)
20
+ v[:enum].each do |enum|
21
+ TransferSpec.const_set("#{k.to_s.upcase}_#{enum.upcase.gsub(/[^A-Z0-9]/,'_')}", enum.freeze)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'aspera/log'
2
3
  require 'aspera/command_line_builder'
3
4
 
@@ -15,33 +16,33 @@ module Aspera
15
16
  result_ts['remote_host']=@fasp_uri.host
16
17
  result_ts['remote_user']=@fasp_uri.user
17
18
  result_ts['ssh_port']=@fasp_uri.port
18
- result_ts['paths']=[{"source"=>URI.decode_www_form_component(@fasp_uri.path)}]
19
+ result_ts['paths']=[{'source'=>URI.decode_www_form_component(@fasp_uri.path)}]
19
20
  # faspex does not encode trailing base64 encoded tags, fix that
20
21
  fixed_query = @fasp_uri.query.gsub(/(=+)$/){|x|'%3D'*x.length}
21
22
 
22
- URI::decode_www_form(fixed_query).each do |i|
23
+ URI.decode_www_form(fixed_query).each do |i|
23
24
  name=i[0]
24
25
  value=i[1]
25
26
  case name
26
- when 'cookie'; result_ts['cookie']=value
27
- when 'token'; result_ts['token']=value
28
- when 'policy'; result_ts['rate_policy']=value
29
- when 'httpport'; result_ts['http_fallback_port']=value.to_i
30
- when 'targetrate'; result_ts['target_rate_kbps']=value.to_i
31
- when 'minrate'; result_ts['min_rate_kbps']=value.to_i
32
- when 'port'; result_ts['fasp_port']=value.to_i
33
- when 'enc'; result_ts['cipher']=value.gsub('-','') # aes-128 -> aes128
34
- when 'tags64'; result_ts['tags']=JSON.parse(Base64.strict_decode64(value))
35
- when 'bwcap'; result_ts['target_rate_cap_kbps']=value.to_i
36
- when 'createpath'; result_ts['create_dir']=CommandLineBuilder.yes_to_true(value)
37
- when 'fallback'; result_ts['http_fallback']=CommandLineBuilder.yes_to_true(value)
38
- when 'lockpolicy'; result_ts['lock_rate_policy']=CommandLineBuilder.yes_to_true(value)
39
- when 'lockminrate'; result_ts['lock_min_rate']=CommandLineBuilder.yes_to_true(value)
40
- when 'sshfp'; result_ts['sshfp']=value
41
- when 'auth'; Log.log.debug("ignoring #{name}=#{value}") # TODO: translate into transfer spec ? yes/no
42
- when 'v'; Log.log.debug("ignoring #{name}=#{value}") # TODO: translate into transfer spec ? 2
43
- when 'protect'; Log.log.debug("ignoring #{name}=#{value}") # TODO: translate into transfer spec ?
44
- else Log.log.error("non managed URI value: #{name} = #{value}")
27
+ when 'cookie' then result_ts['cookie']=value
28
+ when 'token' then result_ts['token']=value
29
+ when 'sshfp' then result_ts['sshfp']=value
30
+ when 'policy' then result_ts['rate_policy']=value
31
+ when 'httpport' then result_ts['http_fallback_port']=value.to_i
32
+ when 'targetrate' then result_ts['target_rate_kbps']=value.to_i
33
+ when 'minrate' then result_ts['min_rate_kbps']=value.to_i
34
+ when 'port' then result_ts['fasp_port']=value.to_i
35
+ when 'bwcap' then result_ts['target_rate_cap_kbps']=value.to_i
36
+ when 'enc' then result_ts['cipher']=value.gsub(/^aes/,'aes-').gsub(/cfb$/,'-cfb').gsub(/gcm$/,'-gcm').gsub(/--/,'-')
37
+ when 'tags64' then result_ts['tags']=JSON.parse(Base64.strict_decode64(value))
38
+ when 'createpath' then result_ts['create_dir']=CommandLineBuilder.yes_to_true(value)
39
+ when 'fallback' then result_ts['http_fallback']=CommandLineBuilder.yes_to_true(value)
40
+ when 'lockpolicy' then result_ts['lock_rate_policy']=CommandLineBuilder.yes_to_true(value)
41
+ when 'lockminrate' then result_ts['lock_min_rate']=CommandLineBuilder.yes_to_true(value)
42
+ when 'auth' then Log.log.debug("ignoring auth #{name}=#{value}") # TODO: translate into transfer spec ? yes/no
43
+ when 'v' then Log.log.debug("ignoring v #{name}=#{value}") # TODO: translate into transfer spec ? 2
44
+ when 'protect' then Log.log.debug("ignoring protect #{name}=#{value}") # TODO: translate into transfer spec ?
45
+ else Log.log.warn("URI parameter ignored: #{name} = #{value}")
45
46
  end
46
47
  end
47
48
  return result_ts
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
1
2
  require 'aspera/log'
2
3
  require 'aspera/aoc'
3
- require 'aspera/fasp/default'
4
+ require 'aspera/fasp/transfer_spec'
4
5
  require 'aspera/cli/main'
5
6
  require 'webrick'
6
7
  require 'webrick/https'
@@ -12,7 +13,8 @@ module Aspera
12
13
  # this class answers the Faspex /send API and creates a package on Aspera on Cloud
13
14
  class FaspexGW
14
15
  class FxGwServlet < WEBrick::HTTPServlet::AbstractServlet
15
- def initialize(server,a_aoc_api_user,a_workspace_id)
16
+ def initialize(_server,a_aoc_api_user,a_workspace_id)
17
+ super
16
18
  @aoc_api_user=a_aoc_api_user
17
19
  @aoc_workspace_id=a_workspace_id
18
20
  end
@@ -30,27 +32,27 @@ module Aspera
30
32
  # }
31
33
  # }
32
34
  def process_faspex_send(request, response)
33
- raise "no payload" if request.body.nil?
35
+ raise 'no payload' if request.body.nil?
34
36
  faspex_pkg_parameters=JSON.parse(request.body)
35
37
  faspex_pkg_delivery=faspex_pkg_parameters['delivery']
36
- Log.log.debug "faspex pkg create parameters=#{faspex_pkg_parameters}"
38
+ Log.log.debug("faspex pkg create parameters=#{faspex_pkg_parameters}")
37
39
 
38
40
  # get recipient ids
39
41
  files_pkg_recipients=[]
40
42
  faspex_pkg_delivery['recipients'].each do |recipient_email|
41
- user_lookup=@aoc_api_user.read("contacts",{'current_workspace_id'=>@aoc_workspace_id,'q'=>recipient_email})[:data]
42
- raise StandardError,"no such unique user: #{recipient_email} / #{user_lookup}" unless !user_lookup.nil? and user_lookup.length == 1
43
+ user_lookup=@aoc_api_user.read('contacts',{'current_workspace_id'=>@aoc_workspace_id,'q'=>recipient_email})[:data]
44
+ raise StandardError,"no such unique user: #{recipient_email} / #{user_lookup}" unless !user_lookup.nil? && user_lookup.length.eql?(1)
43
45
  recipient_user_info=user_lookup.first
44
- files_pkg_recipients.push({"id"=>recipient_user_info['source_id'],"type"=>recipient_user_info['source_type']})
46
+ files_pkg_recipients.push({'id'=>recipient_user_info['source_id'],'type'=>recipient_user_info['source_type']})
45
47
  end
46
48
 
47
49
  # create a new package with one file
48
- the_package=@aoc_api_user.create("packages",{
49
- "file_names"=>faspex_pkg_delivery['sources'][0]['paths'],
50
- "name"=>faspex_pkg_delivery['title'],
51
- "note"=>faspex_pkg_delivery['note'],
52
- "recipients"=>files_pkg_recipients,
53
- "workspace_id"=>@aoc_workspace_id})[:data]
50
+ the_package=@aoc_api_user.create('packages',{
51
+ 'file_names' =>faspex_pkg_delivery['sources'][0]['paths'],
52
+ 'name' =>faspex_pkg_delivery['title'],
53
+ 'note' =>faspex_pkg_delivery['note'],
54
+ 'recipients' =>files_pkg_recipients,
55
+ 'workspace_id'=>@aoc_workspace_id})[:data]
54
56
 
55
57
  # get node information for the node on which package must be created
56
58
  node_info=@aoc_api_user.read("nodes/#{the_package['node_id']}")[:data]
@@ -59,50 +61,50 @@ module Aspera
59
61
  node_auth_bearer_token=@aoc_api_user.oauth_token(scope: AoC.node_scope(node_info['access_key'],AoC::SCOPE_NODE_USER))
60
62
 
61
63
  # tell Files what to expect in package: 1 transfer (can also be done after transfer)
62
- @aoc_api_user.update("packages/#{the_package['id']}",{"sent"=>true,"transfers_expected"=>1})
64
+ @aoc_api_user.update("packages/#{the_package['id']}",{'sent'=>true,'transfers_expected'=>1})
65
+
66
+ # to return an error:
67
+ # response.status=400
68
+ # return 'ERROR HERE'
63
69
 
64
- if false
65
- response.status=400
66
- return "ERROR HERE"
67
- end
68
70
  # TODO: check about xfer_*
69
71
  ts_tags={
70
- "aspera" => {
71
- "files" => { "package_id" => the_package['id'], "package_operation" => "upload" },
72
- "node" => { "access_key" => node_info['access_key'], "file_id" => the_package['contents_file_id'] },
73
- "xfer_id" => SecureRandom.uuid,
74
- "xfer_retry" => 3600 } }
72
+ 'aspera' => {
73
+ 'files' => { 'package_id' => the_package['id'], 'package_operation' => 'upload' },
74
+ 'node' => { 'access_key' => node_info['access_key'], 'file_id' => the_package['contents_file_id'] },
75
+ 'xfer_id' => SecureRandom.uuid,
76
+ 'xfer_retry' => 3600 } }
75
77
  # this transfer spec is for transfer to AoC
76
78
  faspex_transfer_spec={
77
79
  'direction' => 'send',
78
80
  'remote_host' => node_info['host'],
79
- 'remote_user' => Fasp::Default::ACCESS_KEY_TRANSFER_USER,
80
- 'ssh_port' => Fasp::Default::SSH_PORT,
81
- 'fasp_port' => Fasp::Default::UDP_PORT,
81
+ 'remote_user' => Fasp::TransferSpec::ACCESS_KEY_TRANSFER_USER,
82
+ 'ssh_port' => Fasp::TransferSpec::SSH_PORT,
83
+ 'fasp_port' => Fasp::TransferSpec::UDP_PORT,
82
84
  'tags' => ts_tags,
83
85
  'token' => node_auth_bearer_token,
84
86
  'paths' => [{'destination' => '/'}],
85
87
  'cookie' => 'unused',
86
88
  'create_dir' => true,
87
89
  'rate_policy' => 'fair',
88
- 'rate_policy_allowed' => 'fixed',
89
- 'min_rate_cap_kbps' => nil,
90
- 'min_rate_kbps' => 0,
90
+ 'rate_policy_allowed' => 'fixed',
91
+ 'min_rate_cap_kbps' => nil,
92
+ 'min_rate_kbps' => 0,
91
93
  'target_rate_percentage' => nil,
92
- 'lock_target_rate' => nil,
93
- 'fasp_url' => 'unused',
94
- 'lock_min_rate' => true,
95
- 'lock_rate_policy' => true,
96
- 'source_root' => '',
97
- 'content_protection' => nil,
98
- 'target_rate_cap_kbps' => 20000, # TODO: is this value useful ?
99
- 'target_rate_kbps' => 10000, # TODO: get from where?
100
- 'cipher' => 'aes-128',
101
- 'cipher_allowed' => nil,
102
- 'http_fallback' => false,
103
- 'http_fallback_port' => nil,
104
- 'https_fallback_port' => nil,
105
- 'destination_root' => '/'
94
+ 'lock_target_rate' => nil,
95
+ 'fasp_url' => 'unused',
96
+ 'lock_min_rate' => true,
97
+ 'lock_rate_policy' => true,
98
+ 'source_root' => '',
99
+ 'content_protection' => nil,
100
+ 'target_rate_cap_kbps' => 20_000, # TODO: is this value useful ?
101
+ 'target_rate_kbps' => 10_000, # TODO: get from where?
102
+ 'cipher' => 'aes-128',
103
+ 'cipher_allowed' => nil,
104
+ 'http_fallback' => false,
105
+ 'http_fallback_port' => nil,
106
+ 'https_fallback_port' => nil,
107
+ 'destination_root' => '/'
106
108
  }
107
109
  # but we place it in a Faspex package creation response
108
110
  faspex_package_create_result={
@@ -111,28 +113,27 @@ module Aspera
111
113
  }
112
114
  Log.log.info("faspex_package_create_result=#{faspex_package_create_result}")
113
115
  response.status=200
114
- response.content_type = "application/json"
116
+ response.content_type = 'application/json'
115
117
  response.body=JSON.generate(faspex_package_create_result)
116
118
  end
117
119
 
118
- def do_GET (request, response)
120
+ def do_GET(request, response) # rubocop:disable Naming/MethodName
119
121
  case request.path
120
122
  when '/aspera/faspex/send'
121
123
  process_faspex_send(request, response)
122
124
  else
123
125
  response.status=400
124
- return "ERROR HERE"
125
- raise "unsupported path: #{request.path}"
126
+ return 'ERROR HERE'
126
127
  end
127
128
  end
128
129
  end # FxGwServlet
129
130
 
130
131
  class NewUserServlet < WEBrick::HTTPServlet::AbstractServlet
131
- def do_GET (request, response)
132
+ def do_GET(request, response) # rubocop:disable Naming/MethodName
132
133
  case request.path
133
134
  when '/newuser'
134
135
  response.status=200
135
- response.content_type = "text/html"
136
+ response.content_type = 'text/html'
136
137
  response.body='<html><body>hello world</body></html>'
137
138
  else
138
139
  raise "unsupported path: [#{request.path}]"
@@ -140,50 +141,14 @@ module Aspera
140
141
  end
141
142
  end
142
143
 
143
- def fill_self_signed_cert(options)
144
- key = OpenSSL::PKey::RSA.new(4096)
145
- cert = OpenSSL::X509::Certificate.new
146
- cert.subject = cert.issuer = OpenSSL::X509::Name.parse("/C=FR/O=Test/OU=Test/CN=Test")
147
- cert.not_before = Time.now
148
- cert.not_after = Time.now + 365 * 24 * 60 * 60
149
- cert.public_key = key.public_key
150
- cert.serial = 0x0
151
- cert.version = 2
152
- ef = OpenSSL::X509::ExtensionFactory.new
153
- ef.issuer_certificate = cert
154
- ef.subject_certificate = cert
155
- cert.extensions = [
156
- ef.create_extension("basicConstraints","CA:TRUE", true),
157
- ef.create_extension("subjectKeyIdentifier", "hash"),
158
- # ef.create_extension("keyUsage", "cRLSign,keyCertSign", true),
159
- ]
160
- cert.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always,issuer:always"))
161
- cert.sign(key, OpenSSL::Digest::SHA256.new)
162
- options[:SSLPrivateKey] = key
163
- options[:SSLCertificate] = cert
164
- end
165
-
166
144
  def initialize(a_aoc_api_user,a_workspace_id)
167
145
  webrick_options = {
168
- :app => FaspexGW,
169
- :Port => 9443,
170
- :Logger => Log.log,
171
- #:DocumentRoot => Cli::Main.gem_root,
172
- :SSLEnable => true,
173
- :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE,
146
+ Port: 9443,
147
+ Logger: Log.log,
148
+ SSLEnable: true,
149
+ SSLVerifyClient: OpenSSL::SSL::VERIFY_NONE,
150
+ SSLCertName: [['CN',WEBrick::Utils.getservername]]
174
151
  }
175
- case 1
176
- when 0
177
- # generate self signed cert
178
- webrick_options[:SSLCertName] = [ [ 'CN',WEBrick::Utils::getservername ] ]
179
- Log.log.error(">>>#{webrick_options[:SSLCertName]}")
180
- when 1
181
- fill_self_signed_cert(webrick_options)
182
- when 2
183
- # TODO: args to set certificate of server
184
- webrick_options[:SSLPrivateKey] =OpenSSL::PKey::RSA.new(File.read('/Users/laurent/workspace/Tools/certificate/myserver.key'))
185
- webrick_options[:SSLCertificate] = OpenSSL::X509::Certificate.new(File.read('/Users/laurent/workspace/Tools/certificate/myserver.crt'))
186
- end
187
152
  Log.log.info("Server started on port #{webrick_options[:Port]}")
188
153
  @server = WEBrick::HTTPServer.new(webrick_options)
189
154
  @server.mount('/aspera/faspex', FxGwServlet,a_aoc_api_user,a_workspace_id)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # for older rubies
2
3
  unless Hash.method_defined?(:dig)
3
4
  class Hash
@@ -11,18 +12,18 @@ end
11
12
 
12
13
  class ::Hash
13
14
  def deep_merge(second)
14
- self.merge(second){|key,v1,v2|Hash===v1&&Hash===v2 ? v1.deep_merge(v2) : v2}
15
+ merge(second){|_key,v1,v2|Hash===v1&&Hash===v2 ? v1.deep_merge(v2) : v2}
15
16
  end
16
17
 
17
18
  def deep_merge!(second)
18
- self.merge!(second){|key,v1,v2|Hash===v1&&Hash===v2 ? v1.deep_merge!(v2) : v2}
19
+ merge!(second){|_key,v1,v2|Hash===v1&&Hash===v2 ? v1.deep_merge!(v2) : v2}
19
20
  end
20
21
  end
21
22
 
22
23
  unless Hash.method_defined?(:symbolize_keys)
23
24
  class Hash
24
25
  def symbolize_keys
25
- return self.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
26
+ return each_with_object({}){|(k,v),memo| memo[k.to_sym] = v; }
26
27
  end
27
28
  end
28
29
  end
@@ -1,22 +1,23 @@
1
+ # frozen_string_literal: true
1
2
  require 'uri'
2
3
 
3
4
  module Aspera
4
5
  class IdGenerator
5
6
  ID_SEPARATOR='_'
6
- WINDOWS_PROTECTED_CHAR=%r{[/:"<>\\\*\?]}
7
+ WINDOWS_PROTECTED_CHAR=%r{[/:"<>\\*?]}
7
8
  PROTECTED_CHAR_REPLACE='_'
8
9
  private_constant :ID_SEPARATOR,:PROTECTED_CHAR_REPLACE,:WINDOWS_PROTECTED_CHAR
9
10
  def self.from_list(object_id)
10
11
  if object_id.is_a?(Array)
11
- object_id=object_id.select{|i|!i.nil?}.map do |i|
12
- (i.is_a?(String) and i.start_with?('https://')) ? URI.parse(i).host : i.to_s
12
+ object_id=object_id.reject(&:nil?).map do |i|
13
+ i.is_a?(String) && i.start_with?('https://') ? URI.parse(i).host : i.to_s
13
14
  end.join(ID_SEPARATOR)
14
15
  end
15
- raise "id must be a String" unless object_id.is_a?(String)
16
+ raise 'id must be a String' unless object_id.is_a?(String)
16
17
  return object_id.
17
- gsub(WINDOWS_PROTECTED_CHAR,PROTECTED_CHAR_REPLACE). # remove windows forbidden chars
18
- gsub('.',PROTECTED_CHAR_REPLACE). # keep dot for extension only (nicer)
19
- downcase
18
+ gsub(WINDOWS_PROTECTED_CHAR,PROTECTED_CHAR_REPLACE). # remove windows forbidden chars
19
+ gsub('.',PROTECTED_CHAR_REPLACE). # keep dot for extension only (nicer)
20
+ downcase
20
21
  end
21
22
  end
22
23
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'openssl'
2
3
 
3
4
  module Aspera
@@ -12,7 +13,7 @@ module Aspera
12
13
  @cipher.encrypt
13
14
  @cipher.key = @key
14
15
  s = @cipher.update(value) + @cipher.final
15
- s.unpack('H*').first
16
+ s.unpack1('H*')
16
17
  end
17
18
 
18
19
  def decrypt(value)
@@ -28,20 +29,20 @@ module Aspera
28
29
  SEPARATOR='%'
29
30
  private_constant :SEPARATOR
30
31
  def initialize(values)
31
- raise "values shall be Hash" unless values.is_a?(Hash)
32
+ raise 'values shall be Hash' unless values.is_a?(Hash)
32
33
  @all_secrets=values
33
34
  end
34
35
 
35
36
  def set(options)
36
- raise "options shall be Hash" unless options.is_a?(Hash)
37
+ raise 'options shall be Hash' unless options.is_a?(Hash)
37
38
  unsupported=options.keys-[:username,:url,:secret,:description]
38
39
  raise "unsupported options: #{unsupported}" unless unsupported.empty?
39
40
  username=options[:username]
40
- raise "options shall have username" if username.nil?
41
+ raise 'options shall have username' if username.nil?
41
42
  url=options[:url]
42
- raise "options shall have username" if url.nil?
43
+ raise 'options shall have username' if url.nil?
43
44
  secret=options[:secret]
44
- raise "options shall have secret" if secret.nil?
45
+ raise 'options shall have secret' if secret.nil?
45
46
  key=[url,username].join(SEPARATOR)
46
47
  raise "secret #{key} already exist, delete first" if @all_secrets.has_key?(key)
47
48
  obj={username: username, url: url, secret: SimpleCipher.new(key).encrypt(secret)}
@@ -60,20 +61,20 @@ module Aspera
60
61
  o=v.clone
61
62
  o.delete(:secret)
62
63
  o[:description]||=''
63
- else raise "error"
64
+ else raise 'error'
64
65
  end
65
- o[:description]=v[:description] if v.is_a?(Hash) and v[:description].is_a?(String)
66
+ o[:description]=v[:description] if v.is_a?(Hash) && v[:description].is_a?(String)
66
67
  result.push(o)
67
68
  end
68
69
  return result
69
70
  end
70
71
 
71
72
  def delete(options)
72
- raise "options shall be Hash" unless options.is_a?(Hash)
73
+ raise 'options shall be Hash' unless options.is_a?(Hash)
73
74
  unsupported=options.keys-[:username,:url]
74
75
  raise "unsupported options: #{unsupported}" unless unsupported.empty?
75
76
  username=options[:username]
76
- raise "options shall have username" if username.nil?
77
+ raise 'options shall have username' if username.nil?
77
78
  url=options[:url]
78
79
  key=nil
79
80
  if !url.nil?
@@ -81,17 +82,17 @@ module Aspera
81
82
  key=extk if @all_secrets.has_key?(extk)
82
83
  end
83
84
  # backward compatibility: TODO: remove in future ? (make url mandatory ?)
84
- key=username if key.nil? and @all_secrets.has_key?(username)
85
- raise "no such secret" if key.nil?
85
+ key=username if key.nil? && @all_secrets.has_key?(username)
86
+ raise 'no such secret' if key.nil?
86
87
  @all_secrets.delete(key)
87
88
  end
88
89
 
89
90
  def get(options)
90
- raise "options shall be Hash" unless options.is_a?(Hash)
91
+ raise 'options shall be Hash' unless options.is_a?(Hash)
91
92
  unsupported=options.keys-[:username,:url]
92
93
  raise "unsupported options: #{unsupported}" unless unsupported.empty?
93
94
  username=options[:username]
94
- raise "options shall have username" if username.nil?
95
+ raise 'options shall have username' if username.nil?
95
96
  url=options[:url]
96
97
  val=nil
97
98
  if !url.nil?
@@ -104,14 +105,14 @@ module Aspera
104
105
  result=options.clone
105
106
  case val
106
107
  when NilClass
107
- raise "no such secret"
108
+ raise 'no such secret'
108
109
  when String
109
110
  result.merge!({secret: val, description: ''})
110
111
  when Hash
111
112
  key=[url,username].join(SEPARATOR)
112
113
  plain=SimpleCipher.new(key).decrypt(val[:secret])
113
114
  result.merge!({secret: plain, description: val[:description]})
114
- else raise "error"
115
+ else raise 'error'
115
116
  end
116
117
  return result
117
118
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'security'
2
3
 
3
4
  # enhance the gem to support other keychains
@@ -5,7 +6,7 @@ module Security
5
6
  class Keychain
6
7
  class << self
7
8
  def by_name(name)
8
- keychains_from_output(`security list-keychains`).select{|kc|kc.filename.end_with?("/#{name}.keychain-db")}.first
9
+ keychains_from_output('security list-keychains').select{|kc|kc.filename.end_with?("/#{name}.keychain-db")}.first
9
10
  end
10
11
  end
11
12
  end
@@ -13,7 +14,7 @@ module Security
13
14
  class Password
14
15
  class << self
15
16
  # add some login to original method
16
- alias_method :orig_flags_for_options, :flags_for_options
17
+ alias orig_flags_for_options flags_for_options
17
18
  def flags_for_options(options = {})
18
19
  keychain=options.delete(:keychain)
19
20
  url=options.delete(:url)
@@ -24,7 +25,7 @@ module Security
24
25
  raise 'host required in URL' if uri.host.nil?
25
26
  options[:s]=uri.host
26
27
  options[:p]=uri.path unless ['','/'].include?(uri.path)
27
- options[:P]=uri.port unless uri.port.eql?(443) and !url.include?(':443/')
28
+ options[:P]=uri.port unless uri.port.eql?(443) && !url.include?(':443/')
28
29
  end
29
30
  flags=[orig_flags_for_options(options)]
30
31
  flags.push(keychain.filename) unless keychain.nil?
@@ -39,11 +40,7 @@ module Aspera
39
40
  # keychain based on macOS keychain, using `security` cmmand line
40
41
  class MacosSecurity
41
42
  def initialize(name=nil)
42
- if name.nil?
43
- @keychain=Security::Keychain.default_keychain
44
- else
45
- @keychain=Security::Keychain.by_name(name)
46
- end
43
+ @keychain=name.nil? ? Security::Keychain.default_keychain : Security::Keychain.by_name(name)
47
44
  raise "no such keychain #{name}" if @keychain.nil?
48
45
  end
49
46
 
@@ -58,7 +55,6 @@ module Aspera
58
55
  secret=options[:secret]
59
56
  raise 'options shall have secret' if secret.nil?
60
57
  raise 'set not implemented'
61
- self
62
58
  end
63
59
 
64
60
  def get(options)
@@ -87,7 +83,7 @@ module Aspera
87
83
  username=options[:username]
88
84
  raise 'options shall have username' if username.nil?
89
85
  url=options[:url]
90
- raise 'delete not implemented'
86
+ raise "delete not implemented #{url}"
91
87
  end
92
88
  end
93
89
  end