aspera-cli 4.24.0 → 4.24.2
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.
- checksums.yaml +4 -4
 - checksums.yaml.gz.sig +0 -0
 - data/CHANGELOG.md +19 -1
 - data/README.md +1264 -941
 - data/bin/ascli +20 -1
 - data/bin/asession +23 -27
 - data/lib/aspera/agent/base.rb +10 -21
 - data/lib/aspera/agent/connect.rb +2 -3
 - data/lib/aspera/agent/desktop.rb +2 -2
 - data/lib/aspera/agent/direct.rb +49 -32
 - data/lib/aspera/agent/factory.rb +31 -0
 - data/lib/aspera/api/aoc.rb +79 -49
 - data/lib/aspera/api/faspex.rb +212 -0
 - data/lib/aspera/api/node.rb +99 -84
 - data/lib/aspera/ascp/installation.rb +22 -21
 - data/lib/aspera/ascp/management.rb +119 -23
 - data/lib/aspera/assert.rb +14 -8
 - data/lib/aspera/cli/extended_value.rb +15 -15
 - data/lib/aspera/cli/formatter.rb +7 -5
 - data/lib/aspera/cli/hints.rb +8 -0
 - data/lib/aspera/cli/info.rb +4 -4
 - data/lib/aspera/cli/main.rb +56 -71
 - data/lib/aspera/cli/manager.rb +7 -4
 - data/lib/aspera/cli/plugins/alee.rb +2 -1
 - data/lib/aspera/cli/plugins/aoc.rb +110 -186
 - data/lib/aspera/cli/plugins/ats.rb +4 -4
 - data/lib/aspera/cli/plugins/base.rb +335 -0
 - data/lib/aspera/cli/plugins/basic_auth.rb +45 -0
 - data/lib/aspera/cli/plugins/config.rb +263 -221
 - data/lib/aspera/cli/plugins/console.rb +15 -15
 - data/lib/aspera/cli/plugins/cos.rb +2 -2
 - data/lib/aspera/cli/plugins/factory.rb +78 -0
 - data/lib/aspera/cli/plugins/faspex.rb +17 -20
 - data/lib/aspera/cli/plugins/faspex5.rb +79 -193
 - data/lib/aspera/cli/plugins/faspio.rb +14 -13
 - data/lib/aspera/cli/plugins/httpgw.rb +13 -12
 - data/lib/aspera/cli/plugins/node.rb +34 -32
 - data/lib/aspera/cli/plugins/oauth.rb +48 -0
 - data/lib/aspera/cli/plugins/orchestrator.rb +15 -13
 - data/lib/aspera/cli/plugins/preview.rb +4 -4
 - data/lib/aspera/cli/plugins/server.rb +15 -13
 - data/lib/aspera/cli/plugins/shares.rb +18 -15
 - data/lib/aspera/cli/sync_actions.rb +1 -1
 - data/lib/aspera/cli/transfer_agent.rb +24 -20
 - data/lib/aspera/cli/transfer_progress.rb +6 -6
 - data/lib/aspera/cli/version.rb +3 -3
 - data/lib/aspera/cli/wizard.rb +74 -65
 - data/lib/aspera/colors.rb +6 -0
 - data/lib/aspera/command_line_builder.rb +45 -50
 - data/lib/aspera/command_line_converter.rb +2 -1
 - data/lib/aspera/coverage.rb +1 -1
 - data/lib/aspera/data_repository.rb +1 -1
 - data/lib/aspera/environment.rb +13 -9
 - data/lib/aspera/faspex_gw.rb +6 -4
 - data/lib/aspera/faspex_postproc.rb +1 -1
 - data/lib/aspera/keychain/macos_security.rb +1 -1
 - data/lib/aspera/log.rb +88 -37
 - data/lib/aspera/nagios.rb +1 -1
 - data/lib/aspera/oauth/base.rb +17 -10
 - data/lib/aspera/oauth/factory.rb +8 -8
 - data/lib/aspera/oauth/web.rb +2 -2
 - data/lib/aspera/products/connect.rb +4 -3
 - data/lib/aspera/products/desktop.rb +1 -4
 - data/lib/aspera/products/other.rb +9 -1
 - data/lib/aspera/products/transferd.rb +0 -1
 - data/lib/aspera/rest.rb +126 -83
 - data/lib/aspera/ssh.rb +3 -3
 - data/lib/aspera/sync/args.schema.yaml +46 -3
 - data/lib/aspera/sync/conf.schema.yaml +130 -94
 - data/lib/aspera/sync/operations.rb +71 -74
 - data/lib/aspera/temp_file_manager.rb +17 -5
 - data/lib/aspera/transfer/error.rb +16 -7
 - data/lib/aspera/transfer/parameters.rb +34 -20
 - data/lib/aspera/transfer/resumer.rb +74 -0
 - data/lib/aspera/transfer/spec.rb +4 -3
 - data/lib/aspera/transfer/spec.schema.yaml +132 -51
 - data/lib/aspera/transfer/spec_doc.rb +41 -35
 - data/lib/aspera/uri_reader.rb +1 -1
 - data/lib/aspera/web_auth.rb +6 -6
 - data.tar.gz.sig +0 -0
 - metadata +9 -7
 - metadata.gz.sig +2 -2
 - data/lib/aspera/cli/basic_auth_plugin.rb +0 -43
 - data/lib/aspera/cli/plugin.rb +0 -333
 - data/lib/aspera/cli/plugin_factory.rb +0 -81
 - data/lib/aspera/resumer.rb +0 -77
 - data/lib/aspera/transfer/error_info.rb +0 -91
 
| 
         @@ -1,7 +1,8 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            # cspell:ignore initdemo genkey pubkey asperasoft filelists
         
     | 
| 
       4 
     | 
    
         
            -
            require 'aspera/cli/ 
     | 
| 
      
 4 
     | 
    
         
            +
            require 'aspera/cli/plugins/basic_auth'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'aspera/cli/plugins/factory'
         
     | 
| 
       5 
6 
     | 
    
         
             
            require 'aspera/cli/extended_value'
         
     | 
| 
       6 
7 
     | 
    
         
             
            require 'aspera/cli/special_values'
         
     | 
| 
       7 
8 
     | 
    
         
             
            require 'aspera/cli/version'
         
     | 
| 
         @@ -10,8 +11,8 @@ require 'aspera/cli/info' 
     | 
|
| 
       10 
11 
     | 
    
         
             
            require 'aspera/cli/transfer_progress'
         
     | 
| 
       11 
12 
     | 
    
         
             
            require 'aspera/cli/wizard'
         
     | 
| 
       12 
13 
     | 
    
         
             
            require 'aspera/ascp/installation'
         
     | 
| 
      
 14 
     | 
    
         
            +
            require 'aspera/sync/operations'
         
     | 
| 
       13 
15 
     | 
    
         
             
            require 'aspera/products/transferd'
         
     | 
| 
       14 
     | 
    
         
            -
            require 'aspera/transfer/error_info'
         
     | 
| 
       15 
16 
     | 
    
         
             
            require 'aspera/transfer/parameters'
         
     | 
| 
       16 
17 
     | 
    
         
             
            require 'aspera/transfer/spec'
         
     | 
| 
       17 
18 
     | 
    
         
             
            require 'aspera/transfer/spec_doc'
         
     | 
| 
         @@ -36,93 +37,34 @@ require 'erb' 
     | 
|
| 
       36 
37 
     | 
    
         
             
            module Aspera
         
     | 
| 
       37 
38 
     | 
    
         
             
              module Cli
         
     | 
| 
       38 
39 
     | 
    
         
             
                module Plugins
         
     | 
| 
       39 
     | 
    
         
            -
                  #  
     | 
| 
       40 
     | 
    
         
            -
                  class Config <  
     | 
| 
       41 
     | 
    
         
            -
                    # folder in $HOME for application files (config, cache)
         
     | 
| 
       42 
     | 
    
         
            -
                    ASPERA_HOME_FOLDER_NAME = '.aspera'
         
     | 
| 
       43 
     | 
    
         
            -
                    # default config file
         
     | 
| 
       44 
     | 
    
         
            -
                    DEFAULT_CONFIG_FILENAME = 'config.yaml'
         
     | 
| 
       45 
     | 
    
         
            -
                    # reserved preset names
         
     | 
| 
       46 
     | 
    
         
            -
                    CONF_PRESET_CONFIG = 'config'
         
     | 
| 
       47 
     | 
    
         
            -
                    CONF_PRESET_VERSION = 'version'
         
     | 
| 
       48 
     | 
    
         
            -
                    CONF_PRESET_DEFAULTS = 'default'
         
     | 
| 
       49 
     | 
    
         
            -
                    CONF_PRESET_GLOBAL = 'global_common_defaults'
         
     | 
| 
       50 
     | 
    
         
            -
                    # special name to identify value of default
         
     | 
| 
       51 
     | 
    
         
            -
                    GLOBAL_DEFAULT_KEYWORD = 'GLOBAL'
         
     | 
| 
       52 
     | 
    
         
            -
                    CONF_GLOBAL_SYM = :config
         
     | 
| 
       53 
     | 
    
         
            -
                    # folder containing custom plugins in user's config folder
         
     | 
| 
       54 
     | 
    
         
            -
                    ASPERA_PLUGINS_FOLDERNAME = 'plugins'
         
     | 
| 
       55 
     | 
    
         
            -
                    PERSISTENCY_FOLDER = 'persist_store'
         
     | 
| 
       56 
     | 
    
         
            -
                    ASPERA = 'aspera'
         
     | 
| 
       57 
     | 
    
         
            -
                    SERVER_COMMAND = 'server'
         
     | 
| 
       58 
     | 
    
         
            -
                    DIR_SDK = 'sdk'
         
     | 
| 
       59 
     | 
    
         
            -
                    DEMO_SERVER = 'demo'
         
     | 
| 
       60 
     | 
    
         
            -
                    DEMO_PRESET = 'demoserver' # cspell: disable-line
         
     | 
| 
       61 
     | 
    
         
            -
                    EMAIL_TEST_TEMPLATE = <<~END_OF_TEMPLATE
         
     | 
| 
       62 
     | 
    
         
            -
                      From: <%=from_name%> <<%=from_email%>>
         
     | 
| 
       63 
     | 
    
         
            -
                      To: <<%=to%>>
         
     | 
| 
       64 
     | 
    
         
            -
                      Subject: #{Info::GEM_NAME} email test
         
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
                      This email was sent to test #{Info::CMD_NAME}.
         
     | 
| 
       67 
     | 
    
         
            -
                    END_OF_TEMPLATE
         
     | 
| 
       68 
     | 
    
         
            -
                    # special extended values
         
     | 
| 
       69 
     | 
    
         
            -
                    EXTEND_PRESET = :preset
         
     | 
| 
       70 
     | 
    
         
            -
                    EXTEND_VAULT = :vault
         
     | 
| 
       71 
     | 
    
         
            -
                    PRESET_DIG_SEPARATOR = '.'
         
     | 
| 
       72 
     | 
    
         
            -
                    DEFAULT_CHECK_NEW_VERSION_DAYS = 7
         
     | 
| 
       73 
     | 
    
         
            -
                    COFFEE_IMAGE_URL = 'https://enjoyjava.com/wp-content/uploads/2018/01/How-to-make-strong-coffee.jpg'
         
     | 
| 
       74 
     | 
    
         
            -
                    GEM_CHECK_DATE_FMT = '%Y/%m/%d'
         
     | 
| 
       75 
     | 
    
         
            -
                    # for testing only
         
     | 
| 
       76 
     | 
    
         
            -
                    SELF_SIGNED_CERT = OpenSSL::SSL.const_get(:enon_yfirev.to_s.upcase.reverse) # cspell: disable-line
         
     | 
| 
       77 
     | 
    
         
            -
                    CONF_OVERVIEW_KEYS = %w[preset parameter value].freeze
         
     | 
| 
       78 
     | 
    
         
            -
                    SMTP_CONF_PARAMS = %i[server tls ssl port domain username password from_name from_email].freeze
         
     | 
| 
       79 
     | 
    
         
            -
                    private_constant :DEFAULT_CONFIG_FILENAME,
         
     | 
| 
       80 
     | 
    
         
            -
                      :CONF_PRESET_CONFIG,
         
     | 
| 
       81 
     | 
    
         
            -
                      :CONF_PRESET_VERSION,
         
     | 
| 
       82 
     | 
    
         
            -
                      :CONF_PRESET_DEFAULTS,
         
     | 
| 
       83 
     | 
    
         
            -
                      :CONF_PRESET_GLOBAL,
         
     | 
| 
       84 
     | 
    
         
            -
                      :ASPERA_PLUGINS_FOLDERNAME,
         
     | 
| 
       85 
     | 
    
         
            -
                      :ASPERA,
         
     | 
| 
       86 
     | 
    
         
            -
                      :DEMO_SERVER,
         
     | 
| 
       87 
     | 
    
         
            -
                      :DEMO_PRESET,
         
     | 
| 
       88 
     | 
    
         
            -
                      :EMAIL_TEST_TEMPLATE,
         
     | 
| 
       89 
     | 
    
         
            -
                      :EXTEND_PRESET,
         
     | 
| 
       90 
     | 
    
         
            -
                      :EXTEND_VAULT,
         
     | 
| 
       91 
     | 
    
         
            -
                      :DEFAULT_CHECK_NEW_VERSION_DAYS,
         
     | 
| 
       92 
     | 
    
         
            -
                      :SERVER_COMMAND,
         
     | 
| 
       93 
     | 
    
         
            -
                      :PRESET_DIG_SEPARATOR,
         
     | 
| 
       94 
     | 
    
         
            -
                      :COFFEE_IMAGE_URL,
         
     | 
| 
       95 
     | 
    
         
            -
                      :SELF_SIGNED_CERT,
         
     | 
| 
       96 
     | 
    
         
            -
                      :PERSISTENCY_FOLDER,
         
     | 
| 
       97 
     | 
    
         
            -
                      :CONF_OVERVIEW_KEYS,
         
     | 
| 
       98 
     | 
    
         
            -
                      :SMTP_CONF_PARAMS
         
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
      
 40 
     | 
    
         
            +
                  # Manage the CLI config file
         
     | 
| 
      
 41 
     | 
    
         
            +
                  class Config < Base
         
     | 
| 
       100 
42 
     | 
    
         
             
                    class << self
         
     | 
| 
       101 
     | 
    
         
            -
                      #  
     | 
| 
      
 43 
     | 
    
         
            +
                      # Folder containing plugins in the gem's main folder
         
     | 
| 
       102 
44 
     | 
    
         
             
                      def gem_plugins_folder
         
     | 
| 
       103 
45 
     | 
    
         
             
                        File.dirname(File.expand_path(__FILE__))
         
     | 
| 
       104 
46 
     | 
    
         
             
                      end
         
     | 
| 
       105 
47 
     | 
    
         | 
| 
       106 
48 
     | 
    
         
             
                      # @return main folder where code is, i.e. .../lib
         
     | 
| 
       107 
     | 
    
         
            -
                      #  
     | 
| 
      
 49 
     | 
    
         
            +
                      # Go up as many times as englobing modules (not counting class, as it is a file)
         
     | 
| 
       108 
50 
     | 
    
         
             
                      def gem_src_root
         
     | 
| 
       109 
51 
     | 
    
         
             
                        # Module.nesting[2] is Cli::Plugins
         
     | 
| 
       110 
52 
     | 
    
         
             
                        File.expand_path(Module.nesting[2].to_s.gsub('::', '/').gsub(%r{[^/]+}, '..'), gem_plugins_folder)
         
     | 
| 
       111 
53 
     | 
    
         
             
                      end
         
     | 
| 
       112 
54 
     | 
    
         | 
| 
       113 
     | 
    
         
            -
                      #  
     | 
| 
      
 55 
     | 
    
         
            +
                      # Deep clone hash so that it does not get modified in case of display and secret hide
         
     | 
| 
       114 
56 
     | 
    
         
             
                      def deep_clone(val)
         
     | 
| 
       115 
57 
     | 
    
         
             
                        return Marshal.load(Marshal.dump(val))
         
     | 
| 
       116 
58 
     | 
    
         
             
                      end
         
     | 
| 
       117 
59 
     | 
    
         | 
| 
       118 
     | 
    
         
            -
                      # return product family folder (~/.aspera)
         
     | 
| 
      
 60 
     | 
    
         
            +
                      # @return product family folder (~/.aspera)
         
     | 
| 
       119 
61 
     | 
    
         
             
                      def module_family_folder
         
     | 
| 
       120 
62 
     | 
    
         
             
                        user_home_folder = Dir.home
         
     | 
| 
       121 
63 
     | 
    
         
             
                        Aspera.assert(Dir.exist?(user_home_folder), type: Cli::Error){"Home folder does not exist: #{user_home_folder}. Check your user environment."}
         
     | 
| 
       122 
64 
     | 
    
         
             
                        return File.join(user_home_folder, ASPERA_HOME_FOLDER_NAME)
         
     | 
| 
       123 
65 
     | 
    
         
             
                      end
         
     | 
| 
       124 
66 
     | 
    
         | 
| 
       125 
     | 
    
         
            -
                      # return  
     | 
| 
      
 67 
     | 
    
         
            +
                      # @return [String] Product config folder (~/.aspera/<name>)
         
     | 
| 
       126 
68 
     | 
    
         
             
                      def default_app_main_folder(app_name:)
         
     | 
| 
       127 
69 
     | 
    
         
             
                        Aspera.assert_type(app_name, String)
         
     | 
| 
       128 
70 
     | 
    
         
             
                        Aspera.assert(!app_name.empty?)
         
     | 
| 
         @@ -131,7 +73,7 @@ module Aspera 
     | 
|
| 
       131 
73 
     | 
    
         
             
                    end
         
     | 
| 
       132 
74 
     | 
    
         | 
| 
       133 
75 
     | 
    
         
             
                    def initialize(**_)
         
     | 
| 
       134 
     | 
    
         
            -
                      #  
     | 
| 
      
 76 
     | 
    
         
            +
                      # We need to defer parsing of options until we have the config file, so we can use @extend with @preset
         
     | 
| 
       135 
77 
     | 
    
         
             
                      super
         
     | 
| 
       136 
78 
     | 
    
         
             
                      @use_plugin_defaults = true
         
     | 
| 
       137 
79 
     | 
    
         
             
                      @config_presets = nil
         
     | 
| 
         @@ -147,12 +89,12 @@ module Aspera 
     | 
|
| 
       147 
89 
     | 
    
         
             
                      @option_cache_tokens = true
         
     | 
| 
       148 
90 
     | 
    
         
             
                      @main_folder = nil
         
     | 
| 
       149 
91 
     | 
    
         
             
                      @option_config_file = nil
         
     | 
| 
       150 
     | 
    
         
            -
                      #  
     | 
| 
      
 92 
     | 
    
         
            +
                      # Store is used for ruby https
         
     | 
| 
       151 
93 
     | 
    
         
             
                      @certificate_store = nil
         
     | 
| 
       152 
     | 
    
         
            -
                      #  
     | 
| 
      
 94 
     | 
    
         
            +
                      # Paths are used for ascp
         
     | 
| 
       153 
95 
     | 
    
         
             
                      @certificate_paths = nil
         
     | 
| 
       154 
96 
     | 
    
         
             
                      @progress_bar = nil
         
     | 
| 
       155 
     | 
    
         
            -
                      #  
     | 
| 
      
 97 
     | 
    
         
            +
                      # Option to set main folder
         
     | 
| 
       156 
98 
     | 
    
         
             
                      options.declare(
         
     | 
| 
       157 
99 
     | 
    
         
             
                        :home, 'Home folder for tool',
         
     | 
| 
       158 
100 
     | 
    
         
             
                        handler: {o: self, m: :main_folder},
         
     | 
| 
         @@ -161,38 +103,38 @@ module Aspera 
     | 
|
| 
       161 
103 
     | 
    
         
             
                      )
         
     | 
| 
       162 
104 
     | 
    
         
             
                      options.parse_options!
         
     | 
| 
       163 
105 
     | 
    
         
             
                      Log.log.debug{"#{Info::CMD_NAME} folder: #{@main_folder}"}
         
     | 
| 
       164 
     | 
    
         
            -
                      #  
     | 
| 
      
 106 
     | 
    
         
            +
                      # Data persistency manager, created by config plugin, set for global object
         
     | 
| 
       165 
107 
     | 
    
         
             
                      context.persistency = PersistencyFolder.new(File.join(@main_folder, PERSISTENCY_FOLDER))
         
     | 
| 
       166 
     | 
    
         
            -
                      #  
     | 
| 
       167 
     | 
    
         
            -
                       
     | 
| 
       168 
     | 
    
         
            -
                       
     | 
| 
       169 
     | 
    
         
            -
                      #  
     | 
| 
      
 108 
     | 
    
         
            +
                      # Set folders for plugin lookup
         
     | 
| 
      
 109 
     | 
    
         
            +
                      Plugins::Factory.instance.add_lookup_folder(self.class.gem_plugins_folder)
         
     | 
| 
      
 110 
     | 
    
         
            +
                      Plugins::Factory.instance.add_lookup_folder(File.join(@main_folder, ASPERA_PLUGINS_FOLDERNAME))
         
     | 
| 
      
 111 
     | 
    
         
            +
                      # Option to set config file
         
     | 
| 
       170 
112 
     | 
    
         
             
                      options.declare(
         
     | 
| 
       171 
113 
     | 
    
         
             
                        :config_file, 'Path to YAML file with preset configuration',
         
     | 
| 
       172 
114 
     | 
    
         
             
                        handler: {o: self, m: :option_config_file},
         
     | 
| 
       173 
115 
     | 
    
         
             
                        default: File.join(@main_folder, DEFAULT_CONFIG_FILENAME)
         
     | 
| 
       174 
116 
     | 
    
         
             
                      )
         
     | 
| 
       175 
117 
     | 
    
         
             
                      options.parse_options!
         
     | 
| 
       176 
     | 
    
         
            -
                      #  
     | 
| 
      
 118 
     | 
    
         
            +
                      # Read config file (set @config_presets)
         
     | 
| 
       177 
119 
     | 
    
         
             
                      read_config_file
         
     | 
| 
       178 
     | 
    
         
            -
                      #  
     | 
| 
      
 120 
     | 
    
         
            +
                      # Add preset handler (needed for smtp)
         
     | 
| 
       179 
121 
     | 
    
         
             
                      ExtendedValue.instance.set_handler(EXTEND_PRESET, lambda{ |v| preset_by_name(v)})
         
     | 
| 
       180 
122 
     | 
    
         
             
                      ExtendedValue.instance.set_handler(EXTEND_VAULT, lambda{ |v| vault_value(v)})
         
     | 
| 
       181 
     | 
    
         
            -
                      #  
     | 
| 
      
 123 
     | 
    
         
            +
                      # Load defaults before it can be overridden
         
     | 
| 
       182 
124 
     | 
    
         
             
                      add_plugin_default_preset(CONF_GLOBAL_SYM)
         
     | 
| 
       183 
     | 
    
         
            -
                      #  
     | 
| 
      
 125 
     | 
    
         
            +
                      # Vault options
         
     | 
| 
       184 
126 
     | 
    
         
             
                      options.declare(:secret, 'Secret for access keys')
         
     | 
| 
       185 
127 
     | 
    
         
             
                      options.declare(:vault, 'Vault for secrets', types: Hash, default: {})
         
     | 
| 
       186 
128 
     | 
    
         
             
                      options.declare(:vault_password, 'Vault password')
         
     | 
| 
       187 
129 
     | 
    
         
             
                      options.parse_options!
         
     | 
| 
       188 
     | 
    
         
            -
                      #  
     | 
| 
       189 
     | 
    
         
            -
                       
     | 
| 
       190 
     | 
    
         
            -
                      #  
     | 
| 
      
 130 
     | 
    
         
            +
                      # Declare generic plugin options only after handlers are declared
         
     | 
| 
      
 131 
     | 
    
         
            +
                      Base.declare_options(options)
         
     | 
| 
      
 132 
     | 
    
         
            +
                      # Configuration options
         
     | 
| 
       191 
133 
     | 
    
         
             
                      options.declare(:no_default, 'Do not load default configuration for plugin', values: :none, short: 'N'){@use_plugin_defaults = false}
         
     | 
| 
       192 
134 
     | 
    
         
             
                      options.declare(:preset, 'Load the named option preset from current config file', short: 'P', handler: {o: self, m: :option_preset})
         
     | 
| 
       193 
135 
     | 
    
         
             
                      options.declare(:version_check_days, 'Period in days to check new version (zero to disable)', coerce: Integer, default: DEFAULT_CHECK_NEW_VERSION_DAYS)
         
     | 
| 
       194 
136 
     | 
    
         
             
                      options.declare(:plugin_folder, 'Folder where to find additional plugins', handler: {o: self, m: :option_plugin_folder})
         
     | 
| 
       195 
     | 
    
         
            -
                      #  
     | 
| 
      
 137 
     | 
    
         
            +
                      # Declare wizard options
         
     | 
| 
       196 
138 
     | 
    
         
             
                      @wizard = Wizard.new(self, @main_folder)
         
     | 
| 
       197 
139 
     | 
    
         
             
                      # Transfer SDK options
         
     | 
| 
       198 
140 
     | 
    
         
             
                      options.declare(:ascp_path, 'Ascp: Path to ascp', handler: {o: Ascp::Installation.instance, m: :ascp_path})
         
     | 
| 
         @@ -201,7 +143,7 @@ module Aspera 
     | 
|
| 
       201 
143 
     | 
    
         
             
                      options.declare(:locations_url, 'Ascp: URL to get locations of Aspera Transfer Daemon', handler: {o: Ascp::Installation.instance, m: :transferd_urls})
         
     | 
| 
       202 
144 
     | 
    
         
             
                      options.declare(:sdk_folder, 'Ascp: SDK folder path', handler: {o: Products::Transferd, m: :sdk_directory})
         
     | 
| 
       203 
145 
     | 
    
         
             
                      options.declare(:progress_bar, 'Display progress bar', values: :bool, default: Environment.terminal?)
         
     | 
| 
       204 
     | 
    
         
            -
                      #  
     | 
| 
      
 146 
     | 
    
         
            +
                      # Email options
         
     | 
| 
       205 
147 
     | 
    
         
             
                      options.declare(:smtp, 'Email: SMTP configuration', types: Hash)
         
     | 
| 
       206 
148 
     | 
    
         
             
                      options.declare(:notify_to, 'Email: Recipient for notification of transfers')
         
     | 
| 
       207 
149 
     | 
    
         
             
                      options.declare(:notify_template, 'Email: ERB template for notification of transfers')
         
     | 
| 
         @@ -222,21 +164,21 @@ module Aspera 
     | 
|
| 
       222 
164 
     | 
    
         
             
                      if sdk_dir.nil?
         
     | 
| 
       223 
165 
     | 
    
         
             
                        @sdk_default_location = true
         
     | 
| 
       224 
166 
     | 
    
         
             
                        Log.log.debug('SDK folder is not set, checking default')
         
     | 
| 
       225 
     | 
    
         
            -
                        #  
     | 
| 
       226 
     | 
    
         
            -
                        sdk_dir = self.class.default_app_main_folder(app_name:  
     | 
| 
       227 
     | 
    
         
            -
                        Log.log.debug{" 
     | 
| 
      
 167 
     | 
    
         
            +
                        # New location
         
     | 
| 
      
 168 
     | 
    
         
            +
                        sdk_dir = self.class.default_app_main_folder(app_name: TRANSFERD_APP_NAME)
         
     | 
| 
      
 169 
     | 
    
         
            +
                        Log.log.debug{"Checking: #{sdk_dir}"}
         
     | 
| 
       228 
170 
     | 
    
         
             
                        if !Dir.exist?(sdk_dir)
         
     | 
| 
       229 
     | 
    
         
            -
                          Log.log.debug{" 
     | 
| 
       230 
     | 
    
         
            -
                          #  
     | 
| 
       231 
     | 
    
         
            -
                          former_sdk_folder = File.join(self.class.default_app_main_folder(app_name: Info::CMD_NAME),  
     | 
| 
       232 
     | 
    
         
            -
                          Log.log.debug{" 
     | 
| 
      
 171 
     | 
    
         
            +
                          Log.log.debug{"No such folder: #{sdk_dir}"}
         
     | 
| 
      
 172 
     | 
    
         
            +
                          # Former location
         
     | 
| 
      
 173 
     | 
    
         
            +
                          former_sdk_folder = File.join(self.class.default_app_main_folder(app_name: Info::CMD_NAME), TRANSFERD_APP_NAME)
         
     | 
| 
      
 174 
     | 
    
         
            +
                          Log.log.debug{"Checking: #{former_sdk_folder}"}
         
     | 
| 
       233 
175 
     | 
    
         
             
                          sdk_dir = former_sdk_folder if Dir.exist?(former_sdk_folder)
         
     | 
| 
       234 
176 
     | 
    
         
             
                        end
         
     | 
| 
       235 
     | 
    
         
            -
                        Log.log.debug{" 
     | 
| 
      
 177 
     | 
    
         
            +
                        Log.log.debug{"Using: #{sdk_dir}"}
         
     | 
| 
       236 
178 
     | 
    
         
             
                        Products::Transferd.sdk_directory = sdk_dir
         
     | 
| 
       237 
179 
     | 
    
         
             
                      end
         
     | 
| 
       238 
180 
     | 
    
         
             
                      pac_script = options.get_option(:fpac)
         
     | 
| 
       239 
     | 
    
         
            -
                      #  
     | 
| 
      
 181 
     | 
    
         
            +
                      # Create PAC executor
         
     | 
| 
       240 
182 
     | 
    
         
             
                      if !pac_script.nil?
         
     | 
| 
       241 
183 
     | 
    
         
             
                        @pac_exec = ProxyAutoConfig.new(pac_script).register_uri_generic
         
     | 
| 
       242 
184 
     | 
    
         
             
                        proxy_user_pass = options.get_option(:proxy_credentials)
         
     | 
| 
         @@ -249,23 +191,54 @@ module Aspera 
     | 
|
| 
       249 
191 
     | 
    
         
             
                      RestParameters.instance.user_agent = Info::CMD_NAME
         
     | 
| 
       250 
192 
     | 
    
         
             
                      RestParameters.instance.progress_bar = @progress_bar
         
     | 
| 
       251 
193 
     | 
    
         
             
                      RestParameters.instance.session_cb = lambda{ |http_session| update_http_session(http_session)}
         
     | 
| 
       252 
     | 
    
         
            -
                       
     | 
| 
      
 194 
     | 
    
         
            +
                      # Check http options that are global
         
     | 
| 
      
 195 
     | 
    
         
            +
                      keys_to_delete = []
         
     | 
| 
      
 196 
     | 
    
         
            +
                      @option_http_options.each do |k, v|
         
     | 
| 
       253 
197 
     | 
    
         
             
                        method = "#{k}=".to_sym
         
     | 
| 
       254 
     | 
    
         
            -
                        RestParameters.instance. 
     | 
| 
       255 
     | 
    
         
            -
             
     | 
| 
      
 198 
     | 
    
         
            +
                        if RestParameters.instance.respond_to?(method)
         
     | 
| 
      
 199 
     | 
    
         
            +
                          keys_to_delete.push(k)
         
     | 
| 
      
 200 
     | 
    
         
            +
                          RestParameters.instance.send(method, v)
         
     | 
| 
      
 201 
     | 
    
         
            +
                        elsif k.eql?('ssl_options')
         
     | 
| 
      
 202 
     | 
    
         
            +
                          keys_to_delete.push(k)
         
     | 
| 
      
 203 
     | 
    
         
            +
                          # NOTE: here is a hack that allows setting SSLContext options
         
     | 
| 
      
 204 
     | 
    
         
            +
                          Aspera.assert_type(v, Array){'ssl_options'}
         
     | 
| 
      
 205 
     | 
    
         
            +
                          # Start with default options
         
     | 
| 
      
 206 
     | 
    
         
            +
                          ssl_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:options]
         
     | 
| 
      
 207 
     | 
    
         
            +
                          v.each do |opt|
         
     | 
| 
      
 208 
     | 
    
         
            +
                            case opt
         
     | 
| 
      
 209 
     | 
    
         
            +
                            when Integer
         
     | 
| 
      
 210 
     | 
    
         
            +
                              ssl_options = opt
         
     | 
| 
      
 211 
     | 
    
         
            +
                            when String
         
     | 
| 
      
 212 
     | 
    
         
            +
                              name = "OP_#{opt.start_with?('-') ? opt[1..] : opt}".upcase
         
     | 
| 
      
 213 
     | 
    
         
            +
                              raise Cli::BadArgument, "Unknown ssl_option: #{name}, use one of: #{OpenSSL::SSL.constants.grep(/^OP_/).map{ |c| c.to_s.sub(/^OP_/, '')}.join(', ')}" if !OpenSSL::SSL.const_defined?(name)
         
     | 
| 
      
 214 
     | 
    
         
            +
                              if opt.start_with?('-')
         
     | 
| 
      
 215 
     | 
    
         
            +
                                ssl_options &= ~OpenSSL::SSL.const_get(name)
         
     | 
| 
      
 216 
     | 
    
         
            +
                              else
         
     | 
| 
      
 217 
     | 
    
         
            +
                                ssl_options |= OpenSSL::SSL.const_get(name)
         
     | 
| 
      
 218 
     | 
    
         
            +
                              end
         
     | 
| 
      
 219 
     | 
    
         
            +
                            else
         
     | 
| 
      
 220 
     | 
    
         
            +
                              Aspera.error_unexpected_value(opt.class.name){'Expected String or Integer in ssl_options'}
         
     | 
| 
      
 221 
     | 
    
         
            +
                            end
         
     | 
| 
      
 222 
     | 
    
         
            +
                          end
         
     | 
| 
      
 223 
     | 
    
         
            +
                          OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:options] = ssl_options
         
     | 
| 
      
 224 
     | 
    
         
            +
                        elsif OAuth::Factory.instance.parameters.key?(k.to_sym)
         
     | 
| 
      
 225 
     | 
    
         
            +
                          keys_to_delete.push(k)
         
     | 
| 
      
 226 
     | 
    
         
            +
                          OAuth::Factory.instance.parameters[k.to_sym] = v
         
     | 
| 
      
 227 
     | 
    
         
            +
                        end
         
     | 
| 
       256 
228 
     | 
    
         
             
                      end
         
     | 
| 
      
 229 
     | 
    
         
            +
                      keys_to_delete.each{ |k| @option_http_options.delete(k)}
         
     | 
| 
       257 
230 
     | 
    
         
             
                      OAuth::Factory.instance.persist_mgr = persistency if @option_cache_tokens
         
     | 
| 
       258 
     | 
    
         
            -
                      OAuth::Web. 
     | 
| 
      
 231 
     | 
    
         
            +
                      OAuth::Web.additional_info = "#{Info::CMD_NAME} v#{Cli::VERSION}"
         
     | 
| 
       259 
232 
     | 
    
         
             
                      Transfer::Parameters.file_list_folder = File.join(@main_folder, 'filelists')
         
     | 
| 
       260 
233 
     | 
    
         
             
                      RestErrorAnalyzer.instance.log_file = File.join(@main_folder, 'rest_exceptions.log')
         
     | 
| 
       261 
     | 
    
         
            -
                      #  
     | 
| 
      
 234 
     | 
    
         
            +
                      # Register aspera REST call error handlers
         
     | 
| 
       262 
235 
     | 
    
         
             
                      RestErrorsAspera.register_handlers
         
     | 
| 
       263 
236 
     | 
    
         
             
                    end
         
     | 
| 
       264 
237 
     | 
    
         | 
| 
       265 
238 
     | 
    
         
             
                    attr_accessor :main_folder, :option_cache_tokens, :option_insecure, :option_warn_insecure_cert, :option_http_options
         
     | 
| 
       266 
239 
     | 
    
         
             
                    attr_reader :option_ignore_cert_host_port, :progress_bar
         
     | 
| 
       267 
240 
     | 
    
         | 
| 
       268 
     | 
    
         
            -
                    #  
     | 
| 
      
 241 
     | 
    
         
            +
                    # Add files, folders or default locations to the certificate store
         
     | 
| 
       269 
242 
     | 
    
         
             
                    # @param path_list [Array<String>] list of paths to add
         
     | 
| 
       270 
243 
     | 
    
         
             
                    # @return the list of paths
         
     | 
| 
       271 
244 
     | 
    
         
             
                    def trusted_cert_locations=(path_list)
         
     | 
| 
         @@ -307,14 +280,14 @@ module Aspera 
     | 
|
| 
       307 
280 
     | 
    
         
             
                      @certificate_paths.uniq!
         
     | 
| 
       308 
281 
     | 
    
         
             
                    end
         
     | 
| 
       309 
282 
     | 
    
         | 
| 
       310 
     | 
    
         
            -
                    #  
     | 
| 
      
 283 
     | 
    
         
            +
                    # @return only files
         
     | 
| 
       311 
284 
     | 
    
         
             
                    def trusted_cert_locations
         
     | 
| 
       312 
285 
     | 
    
         
             
                      locations = @certificate_paths
         
     | 
| 
       313 
286 
     | 
    
         
             
                      if locations.nil?
         
     | 
| 
       314 
     | 
    
         
            -
                        #  
     | 
| 
      
 287 
     | 
    
         
            +
                        # Compute default locations
         
     | 
| 
       315 
288 
     | 
    
         
             
                        self.trusted_cert_locations = SpecialValues::DEF
         
     | 
| 
       316 
289 
     | 
    
         
             
                        locations = @certificate_paths
         
     | 
| 
       317 
     | 
    
         
            -
                        #  
     | 
| 
      
 290 
     | 
    
         
            +
                        # Restore defaults
         
     | 
| 
       318 
291 
     | 
    
         
             
                        @certificate_paths = @certificate_store = nil
         
     | 
| 
       319 
292 
     | 
    
         
             
                      end
         
     | 
| 
       320 
293 
     | 
    
         
             
                      return locations
         
     | 
| 
         @@ -357,7 +330,7 @@ module Aspera 
     | 
|
| 
       357 
330 
     | 
    
         
             
                      return ignore_cert
         
     | 
| 
       358 
331 
     | 
    
         
             
                    end
         
     | 
| 
       359 
332 
     | 
    
         | 
| 
       360 
     | 
    
         
            -
                    #  
     | 
| 
      
 333 
     | 
    
         
            +
                    # Called every time a new REST HTTP session is opened to set user-provided options
         
     | 
| 
       361 
334 
     | 
    
         
             
                    # @param http_session [Net::HTTP] the newly created HTTP/S session object
         
     | 
| 
       362 
335 
     | 
    
         
             
                    def update_http_session(http_session)
         
     | 
| 
       363 
336 
     | 
    
         
             
                      http_session.set_debug_output(LineLogger.new(:trace2)) if Log.instance.logger.trace2?
         
     | 
| 
         @@ -367,38 +340,12 @@ module Aspera 
     | 
|
| 
       367 
340 
     | 
    
         
             
                      Log.log.debug{"Using cert store #{http_session.cert_store} (#{@certificate_store})"} unless http_session.cert_store.nil?
         
     | 
| 
       368 
341 
     | 
    
         
             
                      @option_http_options.each do |k, v|
         
     | 
| 
       369 
342 
     | 
    
         
             
                        method = "#{k}=".to_sym
         
     | 
| 
       370 
     | 
    
         
            -
                        #  
     | 
| 
      
 343 
     | 
    
         
            +
                        # Check if accessor is a method of Net::HTTP
         
     | 
| 
       371 
344 
     | 
    
         
             
                        # continue_timeout= read_timeout= write_timeout=
         
     | 
| 
       372 
345 
     | 
    
         
             
                        if http_session.respond_to?(method)
         
     | 
| 
       373 
346 
     | 
    
         
             
                          http_session.send(method, v)
         
     | 
| 
       374 
     | 
    
         
            -
                        elsif k.eql?('ssl_options')
         
     | 
| 
       375 
     | 
    
         
            -
                          # NOTE: here is a hack that allows setting SSLContext options
         
     | 
| 
       376 
     | 
    
         
            -
                          Aspera.assert_type(v, Array){'ssl_options'}
         
     | 
| 
       377 
     | 
    
         
            -
                          # more dynamic method, but more complex:
         
     | 
| 
       378 
     | 
    
         
            -
                          # Net::HTTP::SSL_ATTRIBUTES.push(:options) unless Net::HTTP::SSL_ATTRIBUTES.include?(:options)
         
     | 
| 
       379 
     | 
    
         
            -
                          # Net::HTTP::SSL_IVNAMES.push(:@options) unless Net::HTTP::SSL_IVNAMES.include?(:@options)
         
     | 
| 
       380 
     | 
    
         
            -
                          # Start with default options
         
     | 
| 
       381 
     | 
    
         
            -
                          ssl_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:options]
         
     | 
| 
       382 
     | 
    
         
            -
                          v.each do |opt|
         
     | 
| 
       383 
     | 
    
         
            -
                            case opt
         
     | 
| 
       384 
     | 
    
         
            -
                            when Integer
         
     | 
| 
       385 
     | 
    
         
            -
                              ssl_options = opt
         
     | 
| 
       386 
     | 
    
         
            -
                            when String
         
     | 
| 
       387 
     | 
    
         
            -
                              name = "OP_#{opt.start_with?('-') ? opt[1..] : opt}".upcase
         
     | 
| 
       388 
     | 
    
         
            -
                              raise Cli::BadArgument, "No such ssl_option: #{name}, use one of: #{OpenSSL::SSL.constants.grep(/^OP_/).map{ |c| c.to_s.sub(/^OP_/, '')}.join(', ')}" if !OpenSSL::SSL.const_defined?(name)
         
     | 
| 
       389 
     | 
    
         
            -
                              if opt.start_with?('-')
         
     | 
| 
       390 
     | 
    
         
            -
                                ssl_options &= ~OpenSSL::SSL.const_get(name)
         
     | 
| 
       391 
     | 
    
         
            -
                              else
         
     | 
| 
       392 
     | 
    
         
            -
                                ssl_options |= OpenSSL::SSL.const_get(name)
         
     | 
| 
       393 
     | 
    
         
            -
                              end
         
     | 
| 
       394 
     | 
    
         
            -
                            else
         
     | 
| 
       395 
     | 
    
         
            -
                              Aspera.error_unexpected_value(opt.class.name){'Expected String or Integer in ssl_options'}
         
     | 
| 
       396 
     | 
    
         
            -
                            end
         
     | 
| 
       397 
     | 
    
         
            -
                          end
         
     | 
| 
       398 
     | 
    
         
            -
                          # http_session.instance_variable_set(:@options, ssl_options)
         
     | 
| 
       399 
     | 
    
         
            -
                          OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:options] = ssl_options
         
     | 
| 
       400 
347 
     | 
    
         
             
                        else
         
     | 
| 
       401 
     | 
    
         
            -
                          Log.log.error{" 
     | 
| 
      
 348 
     | 
    
         
            +
                          Log.log.error{"Unknown HTTP session attribute: #{k}"}
         
     | 
| 
       402 
349 
     | 
    
         
             
                        end
         
     | 
| 
       403 
350 
     | 
    
         
             
                      end
         
     | 
| 
       404 
351 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -426,35 +373,35 @@ module Aspera 
     | 
|
| 
       426 
373 
     | 
    
         
             
                    end
         
     | 
| 
       427 
374 
     | 
    
         | 
| 
       428 
375 
     | 
    
         
             
                    def periodic_check_newer_gem_version
         
     | 
| 
       429 
     | 
    
         
            -
                      #  
     | 
| 
      
 376 
     | 
    
         
            +
                      # Get verification period
         
     | 
| 
       430 
377 
     | 
    
         
             
                      delay_days = options.get_option(:version_check_days, mandatory: true).to_i
         
     | 
| 
       431 
     | 
    
         
            -
                      #  
     | 
| 
      
 378 
     | 
    
         
            +
                      # Check only if not zero day
         
     | 
| 
       432 
379 
     | 
    
         
             
                      return if delay_days.eql?(0)
         
     | 
| 
       433 
     | 
    
         
            -
                      #  
     | 
| 
      
 380 
     | 
    
         
            +
                      # Get last date from persistency
         
     | 
| 
       434 
381 
     | 
    
         
             
                      last_check_array = []
         
     | 
| 
       435 
382 
     | 
    
         
             
                      check_date_persist = PersistencyActionOnce.new(
         
     | 
| 
       436 
383 
     | 
    
         
             
                        manager: persistency,
         
     | 
| 
       437 
384 
     | 
    
         
             
                        data:    last_check_array,
         
     | 
| 
       438 
385 
     | 
    
         
             
                        id:      'version_last_check'
         
     | 
| 
       439 
386 
     | 
    
         
             
                      )
         
     | 
| 
       440 
     | 
    
         
            -
                      #  
     | 
| 
      
 387 
     | 
    
         
            +
                      # Get persisted date or nil
         
     | 
| 
       441 
388 
     | 
    
         
             
                      current_date = Date.today
         
     | 
| 
       442 
389 
     | 
    
         
             
                      last_check_days = (current_date - Date.strptime(last_check_array.first, GEM_CHECK_DATE_FMT)) rescue nil
         
     | 
| 
       443 
390 
     | 
    
         
             
                      Log.log.debug{"gem check new version: #{delay_days}, #{last_check_days}, #{current_date}, #{last_check_array}"}
         
     | 
| 
       444 
391 
     | 
    
         
             
                      return if !last_check_days.nil? && last_check_days < delay_days
         
     | 
| 
       445 
     | 
    
         
            -
                      #  
     | 
| 
      
 392 
     | 
    
         
            +
                      # Generate timestamp
         
     | 
| 
       446 
393 
     | 
    
         
             
                      last_check_array[0] = current_date.strftime(GEM_CHECK_DATE_FMT)
         
     | 
| 
       447 
394 
     | 
    
         
             
                      check_date_persist.save
         
     | 
| 
       448 
     | 
    
         
            -
                      #  
     | 
| 
      
 395 
     | 
    
         
            +
                      # Compare this version and the one on internet
         
     | 
| 
       449 
396 
     | 
    
         
             
                      check_data = check_gem_version
         
     | 
| 
       450 
397 
     | 
    
         
             
                      Log.log.warn do
         
     | 
| 
       451 
398 
     | 
    
         
             
                        "A new version is available: #{check_data[:latest]}. You have #{check_data[:current]}. Upgrade with: gem update #{check_data[:name]}"
         
     | 
| 
       452 
399 
     | 
    
         
             
                      end if check_data[:need_update]
         
     | 
| 
       453 
400 
     | 
    
         
             
                    end
         
     | 
| 
       454 
401 
     | 
    
         | 
| 
       455 
     | 
    
         
            -
                    #  
     | 
| 
      
 402 
     | 
    
         
            +
                    # Loads default parameters of plugin if no -P parameter
         
     | 
| 
       456 
403 
     | 
    
         
             
                    # and if there is a section defined for the plugin in the "default" section
         
     | 
| 
       457 
     | 
    
         
            -
                    #  
     | 
| 
      
 404 
     | 
    
         
            +
                    # Try to find: conf[conf["default"][plugin_str]]
         
     | 
| 
       458 
405 
     | 
    
         
             
                    # @param plugin_name_sym : symbol for plugin name
         
     | 
| 
       459 
406 
     | 
    
         
             
                    def add_plugin_default_preset(plugin_name_sym)
         
     | 
| 
       460 
407 
     | 
    
         
             
                      default_config_name = get_plugin_default_config_name(plugin_name_sym)
         
     | 
| 
         @@ -463,7 +410,7 @@ module Aspera 
     | 
|
| 
       463 
410 
     | 
    
         
             
                      return
         
     | 
| 
       464 
411 
     | 
    
         
             
                    end
         
     | 
| 
       465 
412 
     | 
    
         | 
| 
       466 
     | 
    
         
            -
                    #  
     | 
| 
      
 413 
     | 
    
         
            +
                    # Get the default global preset, or set default one
         
     | 
| 
       467 
414 
     | 
    
         
             
                    def global_default_preset
         
     | 
| 
       468 
415 
     | 
    
         
             
                      result = get_plugin_default_config_name(CONF_GLOBAL_SYM)
         
     | 
| 
       469 
416 
     | 
    
         
             
                      if result.nil?
         
     | 
| 
         @@ -473,12 +420,25 @@ module Aspera 
     | 
|
| 
       473 
420 
     | 
    
         
             
                      return result
         
     | 
| 
       474 
421 
     | 
    
         
             
                    end
         
     | 
| 
       475 
422 
     | 
    
         | 
| 
      
 423 
     | 
    
         
            +
                    def defaults_set(plugin_name, preset_name, preset_values, option_default, option_override)
         
     | 
| 
      
 424 
     | 
    
         
            +
                      @config_presets[CONF_PRESET_DEFAULTS] ||= {}
         
     | 
| 
      
 425 
     | 
    
         
            +
                      raise Cli::Error, "A default configuration already exists for plugin '#{plugin_name}' (use --override=yes or --default=no)" \
         
     | 
| 
      
 426 
     | 
    
         
            +
                        if !option_override && option_default && @config_presets[CONF_PRESET_DEFAULTS].key?(plugin_name)
         
     | 
| 
      
 427 
     | 
    
         
            +
                      raise Cli::Error, "Preset already exists: #{preset_name}  (use --override=yes or provide alternate name on command line)" \
         
     | 
| 
      
 428 
     | 
    
         
            +
                        if !option_override && @config_presets.key?(preset_name)
         
     | 
| 
      
 429 
     | 
    
         
            +
                      if option_default
         
     | 
| 
      
 430 
     | 
    
         
            +
                        formatter.display_status("Setting config preset as default for #{plugin_name}")
         
     | 
| 
      
 431 
     | 
    
         
            +
                        @config_presets[CONF_PRESET_DEFAULTS][plugin_name.to_s] = preset_name
         
     | 
| 
      
 432 
     | 
    
         
            +
                      end
         
     | 
| 
      
 433 
     | 
    
         
            +
                      @config_presets[preset_name] = preset_values
         
     | 
| 
      
 434 
     | 
    
         
            +
                    end
         
     | 
| 
      
 435 
     | 
    
         
            +
             
     | 
| 
       476 
436 
     | 
    
         
             
                    def set_preset_key(preset, param_name, param_value)
         
     | 
| 
       477 
437 
     | 
    
         
             
                      Aspera.assert_values(param_name.class, [String, Symbol]){'parameter'}
         
     | 
| 
       478 
438 
     | 
    
         
             
                      param_name = param_name.to_s
         
     | 
| 
       479 
439 
     | 
    
         
             
                      selected_preset = @config_presets[preset]
         
     | 
| 
       480 
440 
     | 
    
         
             
                      if selected_preset.nil?
         
     | 
| 
       481 
     | 
    
         
            -
                        Log.log.debug{" 
     | 
| 
      
 441 
     | 
    
         
            +
                        Log.log.debug{"Unknown preset name: #{preset}, initializing"}
         
     | 
| 
       482 
442 
     | 
    
         
             
                        selected_preset = @config_presets[preset] = {}
         
     | 
| 
       483 
443 
     | 
    
         
             
                      end
         
     | 
| 
       484 
444 
     | 
    
         
             
                      Aspera.assert_type(selected_preset, Hash){"#{preset}.#{param_name}"}
         
     | 
| 
         @@ -494,8 +454,8 @@ module Aspera 
     | 
|
| 
       494 
454 
     | 
    
         
             
                      nil
         
     | 
| 
       495 
455 
     | 
    
         
             
                    end
         
     | 
| 
       496 
456 
     | 
    
         | 
| 
       497 
     | 
    
         
            -
                    #  
     | 
| 
       498 
     | 
    
         
            -
                    #  
     | 
| 
      
 457 
     | 
    
         
            +
                    # Set parameter and value in global config
         
     | 
| 
      
 458 
     | 
    
         
            +
                    # Creates one if none already created
         
     | 
| 
       499 
459 
     | 
    
         
             
                    # @return preset name that contains global default
         
     | 
| 
       500 
460 
     | 
    
         
             
                    def set_global_default(key, value)
         
     | 
| 
       501 
461 
     | 
    
         
             
                      set_preset_key(global_default_preset, key, value)
         
     | 
| 
         @@ -505,18 +465,18 @@ module Aspera 
     | 
|
| 
       505 
465 
     | 
    
         
             
                    attr_reader :gem_url
         
     | 
| 
       506 
466 
     | 
    
         
             
                    attr_accessor :option_config_file
         
     | 
| 
       507 
467 
     | 
    
         | 
| 
       508 
     | 
    
         
            -
                    # @return the hash from name (also expands possible includes)
         
     | 
| 
       509 
468 
     | 
    
         
             
                    # @param config_name name of the preset in config file
         
     | 
| 
       510 
469 
     | 
    
         
             
                    # @param include_path used to detect and avoid include loops
         
     | 
| 
      
 470 
     | 
    
         
            +
                    # @return copy of the hash from name (also expands possible includes)
         
     | 
| 
       511 
471 
     | 
    
         
             
                    def preset_by_name(config_name, include_path = [])
         
     | 
| 
       512 
472 
     | 
    
         
             
                      raise Cli::Error, 'loop in include' if include_path.include?(config_name)
         
     | 
| 
       513 
     | 
    
         
            -
                      include_path = include_path.clone #  
     | 
| 
      
 473 
     | 
    
         
            +
                      include_path = include_path.clone # Avoid messing up if there are multiple branches
         
     | 
| 
       514 
474 
     | 
    
         
             
                      current = @config_presets
         
     | 
| 
       515 
475 
     | 
    
         
             
                      config_name.split(PRESET_DIG_SEPARATOR).each do |name|
         
     | 
| 
       516 
476 
     | 
    
         
             
                        Aspera.assert_type(current, Hash, type: Cli::Error){"sub key: #{include_path}"}
         
     | 
| 
       517 
477 
     | 
    
         
             
                        include_path.push(name)
         
     | 
| 
       518 
478 
     | 
    
         
             
                        current = current[name]
         
     | 
| 
       519 
     | 
    
         
            -
                        raise Cli::Error, " 
     | 
| 
      
 479 
     | 
    
         
            +
                        raise Cli::Error, "Unknown config preset: #{include_path}" if current.nil?
         
     | 
| 
       520 
480 
     | 
    
         
             
                      end
         
     | 
| 
       521 
481 
     | 
    
         
             
                      current = self.class.deep_clone(current) unless current.is_a?(String)
         
     | 
| 
       522 
482 
     | 
    
         
             
                      return ExtendedValue.instance.evaluate(current)
         
     | 
| 
         @@ -534,11 +494,11 @@ module Aspera 
     | 
|
| 
       534 
494 
     | 
    
         
             
                      Aspera.assert_values(value.class, [String, Array]){'plugin folder'}
         
     | 
| 
       535 
495 
     | 
    
         
             
                      value = [value] if value.is_a?(String)
         
     | 
| 
       536 
496 
     | 
    
         
             
                      Aspera.assert(value.all?(String)){'plugin folder'}
         
     | 
| 
       537 
     | 
    
         
            -
                      value.each{ |f|  
     | 
| 
      
 497 
     | 
    
         
            +
                      value.each{ |f| Plugins::Factory.instance.add_lookup_folder(f)}
         
     | 
| 
       538 
498 
     | 
    
         
             
                    end
         
     | 
| 
       539 
499 
     | 
    
         | 
| 
       540 
500 
     | 
    
         
             
                    def option_plugin_folder
         
     | 
| 
       541 
     | 
    
         
            -
                      return  
     | 
| 
      
 501 
     | 
    
         
            +
                      return Plugins::Factory.instance.lookup_folders
         
     | 
| 
       542 
502 
     | 
    
         
             
                    end
         
     | 
| 
       543 
503 
     | 
    
         | 
| 
       544 
504 
     | 
    
         
             
                    def option_preset; 'write-only option'; end
         
     | 
| 
         @@ -558,14 +518,14 @@ module Aspera 
     | 
|
| 
       558 
518 
     | 
    
         
             
                      JSON.generate(@config_presets).hash
         
     | 
| 
       559 
519 
     | 
    
         
             
                    end
         
     | 
| 
       560 
520 
     | 
    
         | 
| 
       561 
     | 
    
         
            -
                    #  
     | 
| 
      
 521 
     | 
    
         
            +
                    # Read config file and validate format
         
     | 
| 
       562 
522 
     | 
    
         
             
                    def read_config_file
         
     | 
| 
       563 
523 
     | 
    
         
             
                      Log.log.debug{"config file is: #{@option_config_file}".red}
         
     | 
| 
       564 
     | 
    
         
            -
                      #  
     | 
| 
      
 524 
     | 
    
         
            +
                      # Files search for configuration, by default the one given by user
         
     | 
| 
       565 
525 
     | 
    
         
             
                      search_files = [@option_config_file]
         
     | 
| 
       566 
     | 
    
         
            -
                      #  
     | 
| 
      
 526 
     | 
    
         
            +
                      # Find first existing file (or nil)
         
     | 
| 
       567 
527 
     | 
    
         
             
                      conf_file_to_load = search_files.find{ |f| File.exist?(f)}
         
     | 
| 
       568 
     | 
    
         
            -
                      #  
     | 
| 
      
 528 
     | 
    
         
            +
                      # If no file found, create default config
         
     | 
| 
       569 
529 
     | 
    
         
             
                      if conf_file_to_load.nil?
         
     | 
| 
       570 
530 
     | 
    
         
             
                        Log.log.warn{"No config file found. New configuration file: #{@option_config_file}"}
         
     | 
| 
       571 
531 
     | 
    
         
             
                        @config_presets = {CONF_PRESET_CONFIG => {CONF_PRESET_VERSION => 'new file'}}
         
     | 
| 
         @@ -578,16 +538,16 @@ module Aspera 
     | 
|
| 
       578 
538 
     | 
    
         
             
                      files_to_copy = []
         
     | 
| 
       579 
539 
     | 
    
         
             
                      Log.dump(:available_presets, @config_presets, level: :trace1)
         
     | 
| 
       580 
540 
     | 
    
         
             
                      Aspera.assert_type(@config_presets, Hash){'config file YAML'}
         
     | 
| 
       581 
     | 
    
         
            -
                      #  
     | 
| 
      
 541 
     | 
    
         
            +
                      # Check there is at least the config section
         
     | 
| 
       582 
542 
     | 
    
         
             
                      Aspera.assert(@config_presets.key?(CONF_PRESET_CONFIG)){"Cannot find key: #{CONF_PRESET_CONFIG}"}
         
     | 
| 
       583 
543 
     | 
    
         
             
                      version = @config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION]
         
     | 
| 
       584 
544 
     | 
    
         
             
                      raise Error, 'No version found in config section.' if version.nil?
         
     | 
| 
       585 
545 
     | 
    
         
             
                      Log.log.debug{"conf version: #{version}"}
         
     | 
| 
       586 
546 
     | 
    
         
             
                      # VVV if there are any conversion needed, those happen here.
         
     | 
| 
       587 
     | 
    
         
            -
                      #  
     | 
| 
      
 547 
     | 
    
         
            +
                      # Fix bug in 4.4 (creating key "true" in "default" preset)
         
     | 
| 
       588 
548 
     | 
    
         
             
                      @config_presets[CONF_PRESET_DEFAULTS].delete(true) if @config_presets[CONF_PRESET_DEFAULTS].is_a?(Hash)
         
     | 
| 
       589 
549 
     | 
    
         
             
                      # ^^^ Place new compatibility code before this line
         
     | 
| 
       590 
     | 
    
         
            -
                      #  
     | 
| 
      
 550 
     | 
    
         
            +
                      # Set version to current
         
     | 
| 
       591 
551 
     | 
    
         
             
                      @config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION] = Cli::VERSION
         
     | 
| 
       592 
552 
     | 
    
         
             
                      unless files_to_copy.empty?
         
     | 
| 
       593 
553 
     | 
    
         
             
                        Log.log.warn('Copying referenced files')
         
     | 
| 
         @@ -602,7 +562,7 @@ module Aspera 
     | 
|
| 
       602 
562 
     | 
    
         
             
                    rescue StandardError => e
         
     | 
| 
       603 
563 
     | 
    
         
             
                      Log.log.debug{"-> #{e.class.name} : #{e}"}
         
     | 
| 
       604 
564 
     | 
    
         
             
                      if File.exist?(@option_config_file)
         
     | 
| 
       605 
     | 
    
         
            -
                        #  
     | 
| 
      
 565 
     | 
    
         
            +
                        # Then there is a problem with that file.
         
     | 
| 
       606 
566 
     | 
    
         
             
                        new_name = "#{@option_config_file}.pre#{Cli::VERSION}.manual_conversion_needed"
         
     | 
| 
       607 
567 
     | 
    
         
             
                        File.rename(@option_config_file, new_name)
         
     | 
| 
       608 
568 
     | 
    
         
             
                        Log.log.warn{"Renamed config file to #{new_name}."}
         
     | 
| 
         @@ -661,13 +621,13 @@ module Aspera 
     | 
|
| 
       661 
621 
     | 
    
         
             
                      when :show
         
     | 
| 
       662 
622 
     | 
    
         
             
                        return Main.result_text(Ascp::Installation.instance.path(:ascp))
         
     | 
| 
       663 
623 
     | 
    
         
             
                      when :info
         
     | 
| 
       664 
     | 
    
         
            -
                        #  
     | 
| 
      
 624 
     | 
    
         
            +
                        # Collect info from ascp executable
         
     | 
| 
       665 
625 
     | 
    
         
             
                        data = Ascp::Installation.instance.ascp_info
         
     | 
| 
       666 
     | 
    
         
            -
                        #  
     | 
| 
      
 626 
     | 
    
         
            +
                        # Add command line transfer spec
         
     | 
| 
       667 
627 
     | 
    
         
             
                        data['ts'] = transfer.option_transfer_spec
         
     | 
| 
       668 
     | 
    
         
            -
                        #  
     | 
| 
      
 628 
     | 
    
         
            +
                        # Add keys
         
     | 
| 
       669 
629 
     | 
    
         
             
                        DataRepository::ELEMENTS.each_with_object(data){ |i, h| h[i.to_s] = DataRepository.instance.item(i)}
         
     | 
| 
       670 
     | 
    
         
            -
                        #  
     | 
| 
      
 630 
     | 
    
         
            +
                        # Declare those as secrets
         
     | 
| 
       671 
631 
     | 
    
         
             
                        SecretHider::ADDITIONAL_KEYS_TO_HIDE.concat(DataRepository::ELEMENTS.map(&:to_s))
         
     | 
| 
       672 
632 
     | 
    
         
             
                        return Main.result_single_object(data)
         
     | 
| 
       673 
633 
     | 
    
         
             
                      when :products
         
     | 
| 
         @@ -682,13 +642,13 @@ module Aspera 
     | 
|
| 
       682 
642 
     | 
    
         
             
                          return Main.result_nothing
         
     | 
| 
       683 
643 
     | 
    
         
             
                        end
         
     | 
| 
       684 
644 
     | 
    
         
             
                      when :install
         
     | 
| 
       685 
     | 
    
         
            -
                        #  
     | 
| 
       686 
     | 
    
         
            -
                        Products::Transferd.sdk_directory = self.class.default_app_main_folder(app_name:  
     | 
| 
      
 645 
     | 
    
         
            +
                        # Reset to default location, if older default was used
         
     | 
| 
      
 646 
     | 
    
         
            +
                        Products::Transferd.sdk_directory = self.class.default_app_main_folder(app_name: TRANSFERD_APP_NAME) if @sdk_default_location
         
     | 
| 
       687 
647 
     | 
    
         
             
                        version = options.get_next_argument('transferd version', mandatory: false)
         
     | 
| 
       688 
648 
     | 
    
         
             
                        n, v = Ascp::Installation.instance.install_sdk(url: options.get_option(:sdk_url, mandatory: true), version: version)
         
     | 
| 
       689 
649 
     | 
    
         
             
                        return Main.result_status("Installed #{n} version #{v}")
         
     | 
| 
       690 
650 
     | 
    
         
             
                      when :spec
         
     | 
| 
       691 
     | 
    
         
            -
                        fields, data = Transfer::SpecDoc.man_table(Formatter)
         
     | 
| 
      
 651 
     | 
    
         
            +
                        fields, data = Transfer::SpecDoc.man_table(Formatter, include_option: true)
         
     | 
| 
       692 
652 
     | 
    
         
             
                        return Main.result_object_list(data, fields: fields.map(&:to_s))
         
     | 
| 
       693 
653 
     | 
    
         
             
                      when :schema
         
     | 
| 
       694 
654 
     | 
    
         
             
                        schema = Transfer::Spec::SCHEMA.merge({'$comment'=>'DO NOT EDIT, this file was generated from the YAML.'})
         
     | 
| 
         @@ -698,7 +658,7 @@ module Aspera 
     | 
|
| 
       698 
658 
     | 
    
         
             
                        return Main.result_single_object(schema)
         
     | 
| 
       699 
659 
     | 
    
         
             
                      when :errors
         
     | 
| 
       700 
660 
     | 
    
         
             
                        error_data = []
         
     | 
| 
       701 
     | 
    
         
            -
                         
     | 
| 
      
 661 
     | 
    
         
            +
                        Ascp::Management::ERRORS.each_pair do |code, prop|
         
     | 
| 
       702 
662 
     | 
    
         
             
                          error_data.push(code: code, mnemonic: prop[:c], retry: prop[:r], info: prop[:a])
         
     | 
| 
       703 
663 
     | 
    
         
             
                        end
         
     | 
| 
       704 
664 
     | 
    
         
             
                        return Main.result_object_list(error_data)
         
     | 
| 
         @@ -711,8 +671,8 @@ module Aspera 
     | 
|
| 
       711 
671 
     | 
    
         
             
                      command = options.get_next_command(%i[list install])
         
     | 
| 
       712 
672 
     | 
    
         
             
                      case command
         
     | 
| 
       713 
673 
     | 
    
         
             
                      when :install
         
     | 
| 
       714 
     | 
    
         
            -
                        #  
     | 
| 
       715 
     | 
    
         
            -
                        Products::Transferd.sdk_directory = self.class.default_app_main_folder(app_name:  
     | 
| 
      
 674 
     | 
    
         
            +
                        # Reset to default location, if older default was used
         
     | 
| 
      
 675 
     | 
    
         
            +
                        Products::Transferd.sdk_directory = self.class.default_app_main_folder(app_name: TRANSFERD_APP_NAME) if @sdk_default_location
         
     | 
| 
       716 
676 
     | 
    
         
             
                        version = options.get_next_argument('transferd version', mandatory: false)
         
     | 
| 
       717 
677 
     | 
    
         
             
                        n, v = Ascp::Installation.instance.install_sdk(url: options.get_option(:sdk_url, mandatory: true), version: version)
         
     | 
| 
       718 
678 
     | 
    
         
             
                        return Main.result_status("Installed #{n} version #{v}")
         
     | 
| 
         @@ -727,9 +687,9 @@ module Aspera 
     | 
|
| 
       727 
687 
     | 
    
         
             
                      Aspera.error_unreachable_line
         
     | 
| 
       728 
688 
     | 
    
         
             
                    end
         
     | 
| 
       729 
689 
     | 
    
         | 
| 
       730 
     | 
    
         
            -
                    #  
     | 
| 
      
 690 
     | 
    
         
            +
                    # Legacy actions available globally
         
     | 
| 
       731 
691 
     | 
    
         
             
                    PRESET_GBL_ACTIONS = %i[list overview lookup secure].freeze
         
     | 
| 
       732 
     | 
    
         
            -
                    #  
     | 
| 
      
 692 
     | 
    
         
            +
                    # Operations requiring that preset exists
         
     | 
| 
       733 
693 
     | 
    
         
             
                    PRESET_EXIST_ACTIONS = %i[show delete get unset].freeze
         
     | 
| 
       734 
694 
     | 
    
         
             
                    # require id
         
     | 
| 
       735 
695 
     | 
    
         
             
                    PRESET_INSTANCE_ACTIONS = %i[initialize update ask set].concat(PRESET_EXIST_ACTIONS).freeze
         
     | 
| 
         @@ -739,13 +699,13 @@ module Aspera 
     | 
|
| 
       739 
699 
     | 
    
         
             
                      action = options.get_next_command(PRESET_ALL_ACTIONS) if action.nil?
         
     | 
| 
       740 
700 
     | 
    
         
             
                      name = instance_identifier if name.nil? && PRESET_INSTANCE_ACTIONS.include?(action)
         
     | 
| 
       741 
701 
     | 
    
         
             
                      name = global_default_preset if name.eql?(GLOBAL_DEFAULT_KEYWORD)
         
     | 
| 
       742 
     | 
    
         
            -
                      #  
     | 
| 
      
 702 
     | 
    
         
            +
                      # Those operations require existing option
         
     | 
| 
       743 
703 
     | 
    
         
             
                      raise "no such preset: #{name}" if PRESET_EXIST_ACTIONS.include?(action) && !@config_presets.key?(name)
         
     | 
| 
       744 
704 
     | 
    
         
             
                      case action
         
     | 
| 
       745 
705 
     | 
    
         
             
                      when :list
         
     | 
| 
       746 
706 
     | 
    
         
             
                        return Main.result_value_list(@config_presets.keys, name: 'name')
         
     | 
| 
       747 
707 
     | 
    
         
             
                      when :overview
         
     | 
| 
       748 
     | 
    
         
            -
                        #  
     | 
| 
      
 708 
     | 
    
         
            +
                        # Display process modifies the value (hide secrets): we do not want to save removed secrets
         
     | 
| 
       749 
709 
     | 
    
         
             
                        data = self.class.deep_clone(@config_presets)
         
     | 
| 
       750 
710 
     | 
    
         
             
                        formatter.hide_secrets(data)
         
     | 
| 
       751 
711 
     | 
    
         
             
                        result = []
         
     | 
| 
         @@ -799,7 +759,7 @@ module Aspera 
     | 
|
| 
       799 
759 
     | 
    
         
             
                        end
         
     | 
| 
       800 
760 
     | 
    
         
             
                        return Main.result_status("Updated: #{name}")
         
     | 
| 
       801 
761 
     | 
    
         
             
                      when :lookup
         
     | 
| 
       802 
     | 
    
         
            -
                         
     | 
| 
      
 762 
     | 
    
         
            +
                        BasicAuth.declare_options(options)
         
     | 
| 
       803 
763 
     | 
    
         
             
                        url = options.get_option(:url, mandatory: true)
         
     | 
| 
       804 
764 
     | 
    
         
             
                        user = options.get_option(:username, mandatory: true)
         
     | 
| 
       805 
765 
     | 
    
         
             
                        result = lookup_preset(url: url, username: user)
         
     | 
| 
         @@ -850,6 +810,7 @@ module Aspera 
     | 
|
| 
       850 
810 
     | 
    
         
             
                      coffee
         
     | 
| 
       851 
811 
     | 
    
         
             
                      image
         
     | 
| 
       852 
812 
     | 
    
         
             
                      ascp
         
     | 
| 
      
 813 
     | 
    
         
            +
                      sync
         
     | 
| 
       853 
814 
     | 
    
         
             
                      transferd
         
     | 
| 
       854 
815 
     | 
    
         
             
                      email_test
         
     | 
| 
       855 
816 
     | 
    
         
             
                      smtp_settings
         
     | 
| 
         @@ -867,7 +828,7 @@ module Aspera 
     | 
|
| 
       867 
828 
     | 
    
         
             
                    def execute_action
         
     | 
| 
       868 
829 
     | 
    
         
             
                      action = options.get_next_command(ACTIONS)
         
     | 
| 
       869 
830 
     | 
    
         
             
                      case action
         
     | 
| 
       870 
     | 
    
         
            -
                      when :preset #  
     | 
| 
      
 831 
     | 
    
         
            +
                      when :preset # Newer syntax
         
     | 
| 
       871 
832 
     | 
    
         
             
                        return execute_preset
         
     | 
| 
       872 
833 
     | 
    
         
             
                      when :open
         
     | 
| 
       873 
834 
     | 
    
         
             
                        Environment.instance.open_editor(@option_config_file.to_s)
         
     | 
| 
         @@ -877,12 +838,12 @@ module Aspera 
     | 
|
| 
       877 
838 
     | 
    
         
             
                        section = "##{section}" unless section.nil?
         
     | 
| 
       878 
839 
     | 
    
         
             
                        Environment.instance.open_uri("#{Info::DOC_URL}#{section}")
         
     | 
| 
       879 
840 
     | 
    
         
             
                        return Main.result_nothing
         
     | 
| 
       880 
     | 
    
         
            -
                      when :genkey #  
     | 
| 
      
 841 
     | 
    
         
            +
                      when :genkey # Generate new rsa key
         
     | 
| 
       881 
842 
     | 
    
         
             
                        private_key_path = options.get_next_argument('private key file path')
         
     | 
| 
       882 
843 
     | 
    
         
             
                        private_key_length = options.get_next_argument('size in bits', mandatory: false, validation: Integer, default: OAuth::Jwt::DEFAULT_PRIV_KEY_LENGTH)
         
     | 
| 
       883 
844 
     | 
    
         
             
                        OAuth::Jwt.generate_rsa_private_key(path: private_key_path, length: private_key_length)
         
     | 
| 
       884 
845 
     | 
    
         
             
                        return Main.result_status("Generated #{private_key_length} bit RSA key: #{private_key_path}")
         
     | 
| 
       885 
     | 
    
         
            -
                      when :pubkey #  
     | 
| 
      
 846 
     | 
    
         
            +
                      when :pubkey # Get pub key
         
     | 
| 
       886 
847 
     | 
    
         
             
                        private_key_pem = options.get_next_argument('private key PEM value')
         
     | 
| 
       887 
848 
     | 
    
         
             
                        return Main.result_text(OpenSSL::PKey::RSA.new(private_key_pem).public_key.to_s)
         
     | 
| 
       888 
849 
     | 
    
         
             
                      when :remote_certificate
         
     | 
| 
         @@ -898,7 +859,7 @@ module Aspera 
     | 
|
| 
       898 
859 
     | 
    
         
             
                        when :name
         
     | 
| 
       899 
860 
     | 
    
         
             
                          return Main.result_text(remote_chain.first.subject.to_a.find{ |name, _, _| name == 'CN'}[1])
         
     | 
| 
       900 
861 
     | 
    
         
             
                        end
         
     | 
| 
       901 
     | 
    
         
            -
                      when :echo #  
     | 
| 
      
 862 
     | 
    
         
            +
                      when :echo # Display the content of a value given on command line
         
     | 
| 
       902 
863 
     | 
    
         
             
                        return Main.result_auto(options.get_next_argument('value', validation: nil))
         
     | 
| 
       903 
864 
     | 
    
         
             
                      when :download
         
     | 
| 
       904 
865 
     | 
    
         
             
                        file_url = options.get_next_argument('source URL').chomp
         
     | 
| 
         @@ -916,20 +877,20 @@ module Aspera 
     | 
|
| 
       916 
877 
     | 
    
         
             
                          return Main.result_object_list(OAuth::Factory.instance.persisted_tokens)
         
     | 
| 
       917 
878 
     | 
    
         
             
                        when :show
         
     | 
| 
       918 
879 
     | 
    
         
             
                          data = OAuth::Factory.instance.get_token_info(instance_identifier)
         
     | 
| 
       919 
     | 
    
         
            -
                          raise Cli::Error, ' 
     | 
| 
      
 880 
     | 
    
         
            +
                          raise Cli::Error, 'Unknown identifier' if data.nil?
         
     | 
| 
       920 
881 
     | 
    
         
             
                          return Main.result_single_object(data)
         
     | 
| 
       921 
882 
     | 
    
         
             
                        end
         
     | 
| 
       922 
883 
     | 
    
         
             
                      when :plugins
         
     | 
| 
       923 
884 
     | 
    
         
             
                        case options.get_next_command(%i[list create])
         
     | 
| 
       924 
885 
     | 
    
         
             
                        when :list
         
     | 
| 
       925 
886 
     | 
    
         
             
                          result = []
         
     | 
| 
       926 
     | 
    
         
            -
                           
     | 
| 
       927 
     | 
    
         
            -
                            plugin_class =  
     | 
| 
      
 887 
     | 
    
         
            +
                          Plugins::Factory.instance.plugin_list.each do |name|
         
     | 
| 
      
 888 
     | 
    
         
            +
                            plugin_class = Plugins::Factory.instance.plugin_class(name)
         
     | 
| 
       928 
889 
     | 
    
         
             
                            result.push({
         
     | 
| 
       929 
890 
     | 
    
         
             
                              plugin: name,
         
     | 
| 
       930 
891 
     | 
    
         
             
                              detect: Formatter.tick(plugin_class.respond_to?(:detect)),
         
     | 
| 
       931 
     | 
    
         
            -
                              wizard: Formatter.tick(plugin_class. 
     | 
| 
       932 
     | 
    
         
            -
                              path:    
     | 
| 
      
 892 
     | 
    
         
            +
                              wizard: Formatter.tick(plugin_class.instance_methods.include?(:wizard)),
         
     | 
| 
      
 893 
     | 
    
         
            +
                              path:   Plugins::Factory.instance.plugin_source(name)
         
     | 
| 
       933 
894 
     | 
    
         
             
                            })
         
     | 
| 
       934 
895 
     | 
    
         
             
                          end
         
     | 
| 
       935 
896 
     | 
    
         
             
                          return Main.result_object_list(result, fields: %w[plugin detect wizard path])
         
     | 
| 
         @@ -938,25 +899,27 @@ module Aspera 
     | 
|
| 
       938 
899 
     | 
    
         
             
                          destination_folder = options.get_next_argument('folder', mandatory: false) || File.join(@main_folder, ASPERA_PLUGINS_FOLDERNAME)
         
     | 
| 
       939 
900 
     | 
    
         
             
                          plugin_file = File.join(destination_folder, "#{plugin_name}.rb")
         
     | 
| 
       940 
901 
     | 
    
         
             
                          content = <<~END_OF_PLUGIN_CODE
         
     | 
| 
       941 
     | 
    
         
            -
                            require 'aspera/cli/ 
     | 
| 
      
 902 
     | 
    
         
            +
                            require 'aspera/cli/plugins/base'
         
     | 
| 
       942 
903 
     | 
    
         
             
                            module Aspera
         
     | 
| 
       943 
904 
     | 
    
         
             
                              module Cli
         
     | 
| 
       944 
905 
     | 
    
         
             
                                module Plugins
         
     | 
| 
       945 
     | 
    
         
            -
                                  class #{plugin_name. 
     | 
| 
      
 906 
     | 
    
         
            +
                                  class #{plugin_name.snake_to_capital} < Base
         
     | 
| 
       946 
907 
     | 
    
         
             
                                    ACTIONS=[]
         
     | 
| 
       947 
     | 
    
         
            -
                                    def execute_action 
     | 
| 
       948 
     | 
    
         
            -
             
     | 
| 
       949 
     | 
    
         
            -
             
     | 
| 
       950 
     | 
    
         
            -
             
     | 
| 
       951 
     | 
    
         
            -
             
     | 
| 
      
 908 
     | 
    
         
            +
                                    def execute_action
         
     | 
| 
      
 909 
     | 
    
         
            +
                                      return Main.result_status('You called plugin #{plugin_name}')
         
     | 
| 
      
 910 
     | 
    
         
            +
                                    end
         
     | 
| 
      
 911 
     | 
    
         
            +
                                  end
         
     | 
| 
      
 912 
     | 
    
         
            +
                                end
         
     | 
| 
      
 913 
     | 
    
         
            +
                              end
         
     | 
| 
      
 914 
     | 
    
         
            +
                            end
         
     | 
| 
       952 
915 
     | 
    
         
             
                          END_OF_PLUGIN_CODE
         
     | 
| 
       953 
916 
     | 
    
         
             
                          File.write(plugin_file, content)
         
     | 
| 
       954 
917 
     | 
    
         
             
                          return Main.result_status("Created #{plugin_file}")
         
     | 
| 
       955 
918 
     | 
    
         
             
                        end
         
     | 
| 
       956 
919 
     | 
    
         
             
                      when :detect, :wizard
         
     | 
| 
       957 
     | 
    
         
            -
                        #  
     | 
| 
      
 920 
     | 
    
         
            +
                        # Interactive mode
         
     | 
| 
       958 
921 
     | 
    
         
             
                        options.ask_missing_mandatory = true
         
     | 
| 
       959 
     | 
    
         
            -
                        #  
     | 
| 
      
 922 
     | 
    
         
            +
                        # Detect plugins by url and optional query
         
     | 
| 
       960 
923 
     | 
    
         
             
                        apps = @wizard.identify_plugins_for_url.freeze
         
     | 
| 
       961 
924 
     | 
    
         
             
                        return Main.result_object_list(apps) if action.eql?(:detect)
         
     | 
| 
       962 
925 
     | 
    
         
             
                        return @wizard.find(apps)
         
     | 
| 
         @@ -966,6 +929,13 @@ module Aspera 
     | 
|
| 
       966 
929 
     | 
    
         
             
                        return Main.result_image(options.get_next_argument('image URI or blob'))
         
     | 
| 
       967 
930 
     | 
    
         
             
                      when :ascp
         
     | 
| 
       968 
931 
     | 
    
         
             
                        execute_action_ascp
         
     | 
| 
      
 932 
     | 
    
         
            +
                      when :sync
         
     | 
| 
      
 933 
     | 
    
         
            +
                        case options.get_next_command(%i[spec])
         
     | 
| 
      
 934 
     | 
    
         
            +
                        when :spec
         
     | 
| 
      
 935 
     | 
    
         
            +
                          fields, data = Transfer::SpecDoc.man_table(Formatter, include_option: true, agent_columns: false, schema: Sync::Operations::CONF_SCHEMA)
         
     | 
| 
      
 936 
     | 
    
         
            +
                          return Main.result_object_list(data, fields: fields.map(&:to_s))
         
     | 
| 
      
 937 
     | 
    
         
            +
                        else Aspera.error_unreachable_line
         
     | 
| 
      
 938 
     | 
    
         
            +
                        end
         
     | 
| 
       969 
939 
     | 
    
         
             
                      when :transferd
         
     | 
| 
       970 
940 
     | 
    
         
             
                        execute_action_transferd
         
     | 
| 
       971 
941 
     | 
    
         
             
                      when :gem
         
     | 
| 
         @@ -973,6 +943,7 @@ module Aspera 
     | 
|
| 
       973 
943 
     | 
    
         
             
                        when :path then return Main.result_text(self.class.gem_src_root)
         
     | 
| 
       974 
944 
     | 
    
         
             
                        when :version then return Main.result_text(Cli::VERSION)
         
     | 
| 
       975 
945 
     | 
    
         
             
                        when :name then return Main.result_text(Info::GEM_NAME)
         
     | 
| 
      
 946 
     | 
    
         
            +
                        else Aspera.error_unreachable_line
         
     | 
| 
       976 
947 
     | 
    
         
             
                        end
         
     | 
| 
       977 
948 
     | 
    
         
             
                      when :folder
         
     | 
| 
       978 
949 
     | 
    
         
             
                        return Main.result_text(@main_folder)
         
     | 
| 
         @@ -984,7 +955,7 @@ module Aspera 
     | 
|
| 
       984 
955 
     | 
    
         
             
                      when :smtp_settings
         
     | 
| 
       985 
956 
     | 
    
         
             
                        return Main.result_single_object(email_settings)
         
     | 
| 
       986 
957 
     | 
    
         
             
                      when :proxy_check
         
     | 
| 
       987 
     | 
    
         
            -
                        #  
     | 
| 
      
 958 
     | 
    
         
            +
                        # Ensure fpac was provided
         
     | 
| 
       988 
959 
     | 
    
         
             
                        options.get_option(:fpac, mandatory: true)
         
     | 
| 
       989 
960 
     | 
    
         
             
                        server_url = options.get_next_argument('server url')
         
     | 
| 
       990 
961 
     | 
    
         
             
                        return Main.result_text(@pac_exec.get_proxies(server_url))
         
     | 
| 
         @@ -1022,11 +993,11 @@ module Aspera 
     | 
|
| 
       1022 
993 
     | 
    
         
             
                    # @return [Hash] email server setting with defaults if not defined
         
     | 
| 
       1023 
994 
     | 
    
         
             
                    def email_settings
         
     | 
| 
       1024 
995 
     | 
    
         
             
                      smtp = options.get_option(:smtp, mandatory: true)
         
     | 
| 
       1025 
     | 
    
         
            -
                      #  
     | 
| 
      
 996 
     | 
    
         
            +
                      # Change keys from string into symbol
         
     | 
| 
       1026 
997 
     | 
    
         
             
                      smtp = smtp.symbolize_keys
         
     | 
| 
       1027 
998 
     | 
    
         
             
                      unsupported = smtp.keys - SMTP_CONF_PARAMS
         
     | 
| 
       1028 
999 
     | 
    
         
             
                      raise Cli::Error, "Unsupported SMTP parameter: #{unsupported.join(', ')}, use: #{SMTP_CONF_PARAMS.join(', ')}" unless unsupported.empty?
         
     | 
| 
       1029 
     | 
    
         
            -
                      #  
     | 
| 
      
 1000 
     | 
    
         
            +
                      # Defaults
         
     | 
| 
       1030 
1001 
     | 
    
         
             
                      # smtp[:ssl] = nil (false)
         
     | 
| 
       1031 
1002 
     | 
    
         
             
                      smtp[:tls] = !smtp[:ssl] unless smtp.key?(:tls)
         
     | 
| 
       1032 
1003 
     | 
    
         
             
                      smtp[:port] ||= if smtp[:tls]
         
     | 
| 
         @@ -1039,7 +1010,7 @@ module Aspera 
     | 
|
| 
       1039 
1010 
     | 
    
         
             
                      smtp[:from_email] ||= smtp[:username] if smtp.key?(:username)
         
     | 
| 
       1040 
1011 
     | 
    
         
             
                      smtp[:from_name] ||= smtp[:from_email].sub(/@.*$/, '').gsub(/[^a-zA-Z]/, ' ').capitalize if smtp.key?(:username)
         
     | 
| 
       1041 
1012 
     | 
    
         
             
                      smtp[:domain] ||= smtp[:from_email].sub(/^.*@/, '') if smtp.key?(:from_email)
         
     | 
| 
       1042 
     | 
    
         
            -
                      #  
     | 
| 
      
 1013 
     | 
    
         
            +
                      # Check minimum required
         
     | 
| 
       1043 
1014 
     | 
    
         
             
                      %i[server port domain].each do |n|
         
     | 
| 
       1044 
1015 
     | 
    
         
             
                        Aspera.assert(smtp.key?(n)){"Missing mandatory smtp parameter: #{n}"}
         
     | 
| 
       1045 
1016 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -1047,8 +1018,8 @@ module Aspera 
     | 
|
| 
       1047 
1018 
     | 
    
         
             
                      return smtp
         
     | 
| 
       1048 
1019 
     | 
    
         
             
                    end
         
     | 
| 
       1049 
1020 
     | 
    
         | 
| 
       1050 
     | 
    
         
            -
                    #  
     | 
| 
       1051 
     | 
    
         
            -
                    # @param email_template_default [String] default template, can be  
     | 
| 
      
 1021 
     | 
    
         
            +
                    # Send email using ERB template
         
     | 
| 
      
 1022 
     | 
    
         
            +
                    # @param email_template_default [String] default template, can be overridden by option
         
     | 
| 
       1052 
1023 
     | 
    
         
             
                    # @param values [Hash] values to be used in template, keys with default: to, from_name, from_email
         
     | 
| 
       1053 
1024 
     | 
    
         
             
                    def send_email_template(email_template_default: nil, values: {})
         
     | 
| 
       1054 
1025 
     | 
    
         
             
                      values[:to] ||= options.get_option(:notify_to, mandatory: true)
         
     | 
| 
         @@ -1061,14 +1032,14 @@ module Aspera 
     | 
|
| 
       1061 
1032 
     | 
    
         
             
                      end
         
     | 
| 
       1062 
1033 
     | 
    
         
             
                      start_options = [mail_conf[:domain]]
         
     | 
| 
       1063 
1034 
     | 
    
         
             
                      start_options.push(mail_conf[:username], mail_conf[:password], :login) if mail_conf.key?(:username) && mail_conf.key?(:password)
         
     | 
| 
       1064 
     | 
    
         
            -
                      #  
     | 
| 
      
 1035 
     | 
    
         
            +
                      # Create a binding with only variables defined in values
         
     | 
| 
       1065 
1036 
     | 
    
         
             
                      template_binding = Environment.empty_binding
         
     | 
| 
       1066 
     | 
    
         
            -
                      #  
     | 
| 
      
 1037 
     | 
    
         
            +
                      # Add variables to binding
         
     | 
| 
       1067 
1038 
     | 
    
         
             
                      values.each do |k, v|
         
     | 
| 
       1068 
1039 
     | 
    
         
             
                        Aspera.assert_type(k, Symbol)
         
     | 
| 
       1069 
1040 
     | 
    
         
             
                        template_binding.local_variable_set(k, v)
         
     | 
| 
       1070 
1041 
     | 
    
         
             
                      end
         
     | 
| 
       1071 
     | 
    
         
            -
                      #  
     | 
| 
      
 1042 
     | 
    
         
            +
                      # Execute template
         
     | 
| 
       1072 
1043 
     | 
    
         
             
                      msg_with_headers = ERB.new(notify_template).result(template_binding)
         
     | 
| 
       1073 
1044 
     | 
    
         
             
                      Log.dump(:msg_with_headers, msg_with_headers)
         
     | 
| 
       1074 
1045 
     | 
    
         
             
                      require 'net/smtp'
         
     | 
| 
         @@ -1082,7 +1053,7 @@ module Aspera 
     | 
|
| 
       1082 
1053 
     | 
    
         
             
                    end
         
     | 
| 
       1083 
1054 
     | 
    
         | 
| 
       1084 
1055 
     | 
    
         
             
                    # Save current configuration to config file
         
     | 
| 
       1085 
     | 
    
         
            -
                    # return true if file was saved
         
     | 
| 
      
 1056 
     | 
    
         
            +
                    # @return true if file was saved
         
     | 
| 
       1086 
1057 
     | 
    
         
             
                    def save_config_file_if_needed
         
     | 
| 
       1087 
1058 
     | 
    
         
             
                      raise Error, 'no configuration loaded' if @config_presets.nil?
         
     | 
| 
       1088 
1059 
     | 
    
         
             
                      current_checksum = config_checksum
         
     | 
| 
         @@ -1096,29 +1067,35 @@ module Aspera 
     | 
|
| 
       1096 
1067 
     | 
    
         
             
                      return true
         
     | 
| 
       1097 
1068 
     | 
    
         
             
                    end
         
     | 
| 
       1098 
1069 
     | 
    
         | 
| 
       1099 
     | 
    
         
            -
                    #  
     | 
| 
       1100 
     | 
    
         
            -
                    #  
     | 
| 
      
 1070 
     | 
    
         
            +
                    # @return [String] name if config_presets has default
         
     | 
| 
      
 1071 
     | 
    
         
            +
                    # @return nil if there is no config or bypass default params
         
     | 
| 
       1101 
1072 
     | 
    
         
             
                    def get_plugin_default_config_name(plugin_name_sym)
         
     | 
| 
       1102 
1073 
     | 
    
         
             
                      Aspera.assert(!@config_presets.nil?){'config_presets shall be defined'}
         
     | 
| 
       1103 
1074 
     | 
    
         
             
                      if !@use_plugin_defaults
         
     | 
| 
       1104 
1075 
     | 
    
         
             
                        Log.log.debug('skip default config')
         
     | 
| 
       1105 
1076 
     | 
    
         
             
                        return
         
     | 
| 
       1106 
1077 
     | 
    
         
             
                      end
         
     | 
| 
       1107 
     | 
    
         
            -
                      if  
     | 
| 
       1108 
     | 
    
         
            -
             
     | 
| 
       1109 
     | 
    
         
            -
                         
     | 
| 
       1110 
     | 
    
         
            -
             
     | 
| 
       1111 
     | 
    
         
            -
             
     | 
| 
       1112 
     | 
    
         
            -
             
     | 
| 
       1113 
     | 
    
         
            -
             
     | 
| 
       1114 
     | 
    
         
            -
             
     | 
| 
       1115 
     | 
    
         
            -
             
     | 
| 
       1116 
     | 
    
         
            -
             
     | 
| 
      
 1078 
     | 
    
         
            +
                      if !@config_presets.key?(CONF_PRESET_DEFAULTS)
         
     | 
| 
      
 1079 
     | 
    
         
            +
                        Log.log.debug('No default section')
         
     | 
| 
      
 1080 
     | 
    
         
            +
                        return
         
     | 
| 
      
 1081 
     | 
    
         
            +
                      end
         
     | 
| 
      
 1082 
     | 
    
         
            +
                      Aspera.assert_type(@config_presets[CONF_PRESET_DEFAULTS], Hash){'default section'}
         
     | 
| 
      
 1083 
     | 
    
         
            +
                      if !@config_presets[CONF_PRESET_DEFAULTS].key?(plugin_name_sym.to_s)
         
     | 
| 
      
 1084 
     | 
    
         
            +
                        Log.log.debug("No default for #{plugin_name_sym}")
         
     | 
| 
      
 1085 
     | 
    
         
            +
                        return
         
     | 
| 
      
 1086 
     | 
    
         
            +
                      end
         
     | 
| 
      
 1087 
     | 
    
         
            +
                      default_config_name = @config_presets[CONF_PRESET_DEFAULTS][plugin_name_sym.to_s]
         
     | 
| 
      
 1088 
     | 
    
         
            +
                      if !@config_presets.key?(default_config_name)
         
     | 
| 
      
 1089 
     | 
    
         
            +
                        Log.log.error do
         
     | 
| 
      
 1090 
     | 
    
         
            +
                          "Default config name [#{default_config_name}] specified for plugin [#{plugin_name_sym}], but it does not exist in config file.\n" \
         
     | 
| 
      
 1091 
     | 
    
         
            +
                            "Please fix the issue: either create preset with one parameter:\n" \
         
     | 
| 
      
 1092 
     | 
    
         
            +
                            "#{Info::CMD_NAME} config id #{default_config_name} init @json:'{}'\n" \
         
     | 
| 
      
 1093 
     | 
    
         
            +
                            "or remove default:\n#{Info::CMD_NAME} config id default remove #{plugin_name_sym}"
         
     | 
| 
       1117 
1094 
     | 
    
         
             
                        end
         
     | 
| 
       1118 
     | 
    
         
            -
                        raise Cli::Error, " 
     | 
| 
       1119 
     | 
    
         
            -
                        return default_config_name
         
     | 
| 
      
 1095 
     | 
    
         
            +
                        raise Cli::Error, "No such preset: #{default_config_name}"
         
     | 
| 
       1120 
1096 
     | 
    
         
             
                      end
         
     | 
| 
       1121 
     | 
    
         
            -
                       
     | 
| 
      
 1097 
     | 
    
         
            +
                      Aspera.assert_type(@config_presets[default_config_name], Hash, type: Cli::Error){'preset type'}
         
     | 
| 
      
 1098 
     | 
    
         
            +
                      return default_config_name
         
     | 
| 
       1122 
1099 
     | 
    
         
             
                    end
         
     | 
| 
       1123 
1100 
     | 
    
         | 
| 
       1124 
1101 
     | 
    
         
             
                    # @return [Hash] result of execution of vault command
         
     | 
| 
         @@ -1150,7 +1127,7 @@ module Aspera 
     | 
|
| 
       1150 
1127 
     | 
    
         
             
                    def vault_value(name)
         
     | 
| 
       1151 
1128 
     | 
    
         
             
                      m = name.split('.')
         
     | 
| 
       1152 
1129 
     | 
    
         
             
                      raise BadArgument, 'vault name shall match <name>.<param>' unless m.length.eql?(2)
         
     | 
| 
       1153 
     | 
    
         
            -
                      #  
     | 
| 
      
 1130 
     | 
    
         
            +
                      # This raise exception if label not found:
         
     | 
| 
       1154 
1131 
     | 
    
         
             
                      info = vault.get(label: m[0])
         
     | 
| 
       1155 
1132 
     | 
    
         
             
                      value = info[m[1].to_sym]
         
     | 
| 
       1156 
1133 
     | 
    
         
             
                      raise "no such entry value: #{m[1]}" if value.nil?
         
     | 
| 
         @@ -1171,12 +1148,12 @@ module Aspera 
     | 
|
| 
       1171 
1148 
     | 
    
         
             
                      )
         
     | 
| 
       1172 
1149 
     | 
    
         
             
                    end
         
     | 
| 
       1173 
1150 
     | 
    
         | 
| 
       1174 
     | 
    
         
            -
                    #  
     | 
| 
      
 1151 
     | 
    
         
            +
                    # Artificially raise an exception for tests
         
     | 
| 
       1175 
1152 
     | 
    
         
             
                    def execute_test
         
     | 
| 
       1176 
1153 
     | 
    
         
             
                      case options.get_next_command(%i[throw web])
         
     | 
| 
       1177 
1154 
     | 
    
         
             
                      when :throw
         
     | 
| 
       1178 
1155 
     | 
    
         
             
                        # :type [String]
         
     | 
| 
       1179 
     | 
    
         
            -
                        #  
     | 
| 
      
 1156 
     | 
    
         
            +
                        # Options
         
     | 
| 
       1180 
1157 
     | 
    
         
             
                        exception_class_name = options.get_next_argument('exception class name', mandatory: true)
         
     | 
| 
       1181 
1158 
     | 
    
         
             
                        exception_text = options.get_next_argument('exception text', mandatory: true)
         
     | 
| 
       1182 
1159 
     | 
    
         
             
                        type = Object.const_get(exception_class_name)
         
     | 
| 
         @@ -1186,7 +1163,7 @@ module Aspera 
     | 
|
| 
       1186 
1163 
     | 
    
         
             
                      end
         
     | 
| 
       1187 
1164 
     | 
    
         
             
                    end
         
     | 
| 
       1188 
1165 
     | 
    
         | 
| 
       1189 
     | 
    
         
            -
                    #  
     | 
| 
      
 1166 
     | 
    
         
            +
                    # Version of URL without trailing "/" and removing default port
         
     | 
| 
       1190 
1167 
     | 
    
         
             
                    def canonical_url(url)
         
     | 
| 
       1191 
1168 
     | 
    
         
             
                      url.chomp('/').sub(%r{^(https://[^/]+):443$}, '\1')
         
     | 
| 
       1192 
1169 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -1194,7 +1171,7 @@ module Aspera 
     | 
|
| 
       1194 
1171 
     | 
    
         
             
                    # Look for a preset that has the corresponding URL and username
         
     | 
| 
       1195 
1172 
     | 
    
         
             
                    # @return the first one matching
         
     | 
| 
       1196 
1173 
     | 
    
         
             
                    def lookup_preset(url:, username:)
         
     | 
| 
       1197 
     | 
    
         
            -
                      #  
     | 
| 
      
 1174 
     | 
    
         
            +
                      # Remove extra info to maximize match
         
     | 
| 
       1198 
1175 
     | 
    
         
             
                      url = canonical_url(url)
         
     | 
| 
       1199 
1176 
     | 
    
         
             
                      Log.log.debug{"Lookup preset for #{username}@#{url}"}
         
     | 
| 
       1200 
1177 
     | 
    
         
             
                      @config_presets.each_value do |v|
         
     | 
| 
         @@ -1219,6 +1196,71 @@ module Aspera 
     | 
|
| 
       1219 
1196 
     | 
    
         
             
                      end
         
     | 
| 
       1220 
1197 
     | 
    
         
             
                      return secret
         
     | 
| 
       1221 
1198 
     | 
    
         
             
                    end
         
     | 
| 
      
 1199 
     | 
    
         
            +
                    # Private
         
     | 
| 
      
 1200 
     | 
    
         
            +
                    # Folder in $HOME for application files (config, cache)
         
     | 
| 
      
 1201 
     | 
    
         
            +
                    ASPERA_HOME_FOLDER_NAME = '.aspera'
         
     | 
| 
      
 1202 
     | 
    
         
            +
                    # Default config file
         
     | 
| 
      
 1203 
     | 
    
         
            +
                    DEFAULT_CONFIG_FILENAME = 'config.yaml'
         
     | 
| 
      
 1204 
     | 
    
         
            +
                    # Reserved preset names
         
     | 
| 
      
 1205 
     | 
    
         
            +
                    CONF_PRESET_CONFIG = 'config'
         
     | 
| 
      
 1206 
     | 
    
         
            +
                    CONF_PRESET_VERSION = 'version'
         
     | 
| 
      
 1207 
     | 
    
         
            +
                    CONF_PRESET_DEFAULTS = 'default'
         
     | 
| 
      
 1208 
     | 
    
         
            +
                    CONF_PRESET_GLOBAL = 'global_common_defaults'
         
     | 
| 
      
 1209 
     | 
    
         
            +
                    # Special name to identify value of default
         
     | 
| 
      
 1210 
     | 
    
         
            +
                    GLOBAL_DEFAULT_KEYWORD = 'GLOBAL'
         
     | 
| 
      
 1211 
     | 
    
         
            +
                    CONF_GLOBAL_SYM = :config
         
     | 
| 
      
 1212 
     | 
    
         
            +
                    # Folder containing custom plugins in user's config folder
         
     | 
| 
      
 1213 
     | 
    
         
            +
                    ASPERA_PLUGINS_FOLDERNAME = 'plugins'
         
     | 
| 
      
 1214 
     | 
    
         
            +
                    PERSISTENCY_FOLDER = 'persist_store'
         
     | 
| 
      
 1215 
     | 
    
         
            +
                    ASPERA = 'aspera'
         
     | 
| 
      
 1216 
     | 
    
         
            +
                    SERVER_COMMAND = 'server'
         
     | 
| 
      
 1217 
     | 
    
         
            +
                    TRANSFERD_APP_NAME = 'sdk'
         
     | 
| 
      
 1218 
     | 
    
         
            +
                    DEMO_SERVER = 'demo'
         
     | 
| 
      
 1219 
     | 
    
         
            +
                    DEMO_PRESET = 'demoserver' # cspell: disable-line
         
     | 
| 
      
 1220 
     | 
    
         
            +
                    EMAIL_TEST_TEMPLATE = <<~END_OF_TEMPLATE
         
     | 
| 
      
 1221 
     | 
    
         
            +
                      From: <%=from_name%> <<%=from_email%>>
         
     | 
| 
      
 1222 
     | 
    
         
            +
                      To: <<%=to%>>
         
     | 
| 
      
 1223 
     | 
    
         
            +
                      Subject: #{Info::GEM_NAME} email test
         
     | 
| 
      
 1224 
     | 
    
         
            +
             
     | 
| 
      
 1225 
     | 
    
         
            +
                      This email was sent to test #{Info::CMD_NAME}.
         
     | 
| 
      
 1226 
     | 
    
         
            +
                    END_OF_TEMPLATE
         
     | 
| 
      
 1227 
     | 
    
         
            +
                    # Special extended values
         
     | 
| 
      
 1228 
     | 
    
         
            +
                    EXTEND_PRESET = :preset
         
     | 
| 
      
 1229 
     | 
    
         
            +
                    EXTEND_VAULT = :vault
         
     | 
| 
      
 1230 
     | 
    
         
            +
                    PRESET_DIG_SEPARATOR = '.'
         
     | 
| 
      
 1231 
     | 
    
         
            +
                    DEFAULT_CHECK_NEW_VERSION_DAYS = 7
         
     | 
| 
      
 1232 
     | 
    
         
            +
                    COFFEE_IMAGE_URL = 'https://enjoyjava.com/wp-content/uploads/2018/01/How-to-make-strong-coffee.jpg'
         
     | 
| 
      
 1233 
     | 
    
         
            +
                    GEM_CHECK_DATE_FMT = '%Y/%m/%d'
         
     | 
| 
      
 1234 
     | 
    
         
            +
                    # For testing only
         
     | 
| 
      
 1235 
     | 
    
         
            +
                    SELF_SIGNED_CERT = OpenSSL::SSL.const_get(:enon_yfirev.to_s.upcase.reverse) # cspell: disable-line
         
     | 
| 
      
 1236 
     | 
    
         
            +
                    CONF_OVERVIEW_KEYS = %w[preset parameter value].freeze
         
     | 
| 
      
 1237 
     | 
    
         
            +
                    SMTP_CONF_PARAMS = %i[server tls ssl port domain username password from_name from_email].freeze
         
     | 
| 
      
 1238 
     | 
    
         
            +
             
     | 
| 
      
 1239 
     | 
    
         
            +
                    private_constant :ASPERA_HOME_FOLDER_NAME,
         
     | 
| 
      
 1240 
     | 
    
         
            +
                      :DEFAULT_CONFIG_FILENAME,
         
     | 
| 
      
 1241 
     | 
    
         
            +
                      :CONF_PRESET_CONFIG,
         
     | 
| 
      
 1242 
     | 
    
         
            +
                      :CONF_PRESET_VERSION,
         
     | 
| 
      
 1243 
     | 
    
         
            +
                      :CONF_PRESET_DEFAULTS,
         
     | 
| 
      
 1244 
     | 
    
         
            +
                      :CONF_PRESET_GLOBAL,
         
     | 
| 
      
 1245 
     | 
    
         
            +
                      :ASPERA_PLUGINS_FOLDERNAME,
         
     | 
| 
      
 1246 
     | 
    
         
            +
                      :ASPERA,
         
     | 
| 
      
 1247 
     | 
    
         
            +
                      :DEMO_SERVER,
         
     | 
| 
      
 1248 
     | 
    
         
            +
                      :DEMO_PRESET,
         
     | 
| 
      
 1249 
     | 
    
         
            +
                      :EMAIL_TEST_TEMPLATE,
         
     | 
| 
      
 1250 
     | 
    
         
            +
                      :EXTEND_PRESET,
         
     | 
| 
      
 1251 
     | 
    
         
            +
                      :EXTEND_VAULT,
         
     | 
| 
      
 1252 
     | 
    
         
            +
                      :DEFAULT_CHECK_NEW_VERSION_DAYS,
         
     | 
| 
      
 1253 
     | 
    
         
            +
                      :SERVER_COMMAND,
         
     | 
| 
      
 1254 
     | 
    
         
            +
                      :PRESET_DIG_SEPARATOR,
         
     | 
| 
      
 1255 
     | 
    
         
            +
                      :COFFEE_IMAGE_URL,
         
     | 
| 
      
 1256 
     | 
    
         
            +
                      :SELF_SIGNED_CERT,
         
     | 
| 
      
 1257 
     | 
    
         
            +
                      :PERSISTENCY_FOLDER,
         
     | 
| 
      
 1258 
     | 
    
         
            +
                      :CONF_OVERVIEW_KEYS,
         
     | 
| 
      
 1259 
     | 
    
         
            +
                      :SMTP_CONF_PARAMS,
         
     | 
| 
      
 1260 
     | 
    
         
            +
                      :TRANSFERD_APP_NAME,
         
     | 
| 
      
 1261 
     | 
    
         
            +
                      :GLOBAL_DEFAULT_KEYWORD,
         
     | 
| 
      
 1262 
     | 
    
         
            +
                      :CONF_GLOBAL_SYM,
         
     | 
| 
      
 1263 
     | 
    
         
            +
                      :GEM_CHECK_DATE_FMT
         
     | 
| 
       1222 
1264 
     | 
    
         
             
                  end
         
     | 
| 
       1223 
1265 
     | 
    
         
             
                end
         
     | 
| 
       1224 
1266 
     | 
    
         
             
              end
         
     |