aspera-cli 4.14.0 → 4.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +54 -3
  4. data/CONTRIBUTING.md +7 -7
  5. data/README.md +1457 -880
  6. data/bin/ascli +18 -9
  7. data/bin/asession +12 -14
  8. data/examples/proxy.pac +1 -1
  9. data/lib/aspera/aoc.rb +198 -127
  10. data/lib/aspera/ascmd.rb +24 -14
  11. data/lib/aspera/cli/basic_auth_plugin.rb +9 -6
  12. data/lib/aspera/cli/error.rb +17 -0
  13. data/lib/aspera/cli/extended_value.rb +47 -12
  14. data/lib/aspera/cli/formatter.rb +260 -171
  15. data/lib/aspera/cli/hints.rb +80 -0
  16. data/lib/aspera/cli/main.rb +101 -147
  17. data/lib/aspera/cli/manager.rb +160 -124
  18. data/lib/aspera/cli/plugin.rb +70 -59
  19. data/lib/aspera/cli/plugins/alee.rb +0 -1
  20. data/lib/aspera/cli/plugins/aoc.rb +239 -273
  21. data/lib/aspera/cli/plugins/ats.rb +8 -5
  22. data/lib/aspera/cli/plugins/bss.rb +2 -2
  23. data/lib/aspera/cli/plugins/config.rb +516 -375
  24. data/lib/aspera/cli/plugins/console.rb +40 -0
  25. data/lib/aspera/cli/plugins/cos.rb +4 -5
  26. data/lib/aspera/cli/plugins/faspex.rb +99 -84
  27. data/lib/aspera/cli/plugins/faspex5.rb +179 -148
  28. data/lib/aspera/cli/plugins/node.rb +219 -153
  29. data/lib/aspera/cli/plugins/orchestrator.rb +52 -17
  30. data/lib/aspera/cli/plugins/preview.rb +46 -32
  31. data/lib/aspera/cli/plugins/server.rb +57 -17
  32. data/lib/aspera/cli/plugins/shares.rb +34 -12
  33. data/lib/aspera/cli/sync_actions.rb +68 -0
  34. data/lib/aspera/cli/transfer_agent.rb +45 -55
  35. data/lib/aspera/cli/transfer_progress.rb +74 -0
  36. data/lib/aspera/cli/version.rb +1 -1
  37. data/lib/aspera/colors.rb +3 -1
  38. data/lib/aspera/command_line_builder.rb +14 -11
  39. data/lib/aspera/cos_node.rb +3 -2
  40. data/lib/aspera/environment.rb +17 -6
  41. data/lib/aspera/fasp/agent_aspera.rb +126 -0
  42. data/lib/aspera/fasp/agent_base.rb +31 -77
  43. data/lib/aspera/fasp/agent_connect.rb +21 -22
  44. data/lib/aspera/fasp/agent_direct.rb +88 -102
  45. data/lib/aspera/fasp/agent_httpgw.rb +196 -192
  46. data/lib/aspera/fasp/agent_node.rb +41 -34
  47. data/lib/aspera/fasp/agent_trsdk.rb +75 -34
  48. data/lib/aspera/fasp/error_info.rb +2 -2
  49. data/lib/aspera/fasp/faux_file.rb +52 -0
  50. data/lib/aspera/fasp/installation.rb +43 -184
  51. data/lib/aspera/fasp/management.rb +244 -0
  52. data/lib/aspera/fasp/parameters.rb +59 -26
  53. data/lib/aspera/fasp/parameters.yaml +75 -8
  54. data/lib/aspera/fasp/products.rb +162 -0
  55. data/lib/aspera/fasp/transfer_spec.rb +1 -1
  56. data/lib/aspera/fasp/uri.rb +4 -4
  57. data/lib/aspera/faspex_gw.rb +2 -2
  58. data/lib/aspera/faspex_postproc.rb +2 -2
  59. data/lib/aspera/hash_ext.rb +2 -2
  60. data/lib/aspera/json_rpc.rb +49 -0
  61. data/lib/aspera/line_logger.rb +23 -0
  62. data/lib/aspera/log.rb +57 -16
  63. data/lib/aspera/node.rb +97 -14
  64. data/lib/aspera/oauth.rb +36 -18
  65. data/lib/aspera/open_application.rb +4 -4
  66. data/lib/aspera/persistency_folder.rb +2 -2
  67. data/lib/aspera/preview/file_types.rb +4 -2
  68. data/lib/aspera/preview/generator.rb +22 -35
  69. data/lib/aspera/preview/options.rb +2 -0
  70. data/lib/aspera/preview/terminal.rb +24 -13
  71. data/lib/aspera/preview/utils.rb +19 -26
  72. data/lib/aspera/rest.rb +103 -72
  73. data/lib/aspera/rest_call_error.rb +1 -1
  74. data/lib/aspera/rest_error_analyzer.rb +15 -14
  75. data/lib/aspera/rest_errors_aspera.rb +37 -34
  76. data/lib/aspera/secret_hider.rb +14 -16
  77. data/lib/aspera/ssh.rb +4 -1
  78. data/lib/aspera/sync.rb +128 -122
  79. data/lib/aspera/temp_file_manager.rb +10 -3
  80. data/lib/aspera/web_auth.rb +10 -7
  81. data/lib/aspera/web_server_simple.rb +9 -4
  82. data.tar.gz.sig +0 -0
  83. metadata +33 -15
  84. metadata.gz.sig +0 -0
  85. data/lib/aspera/cli/listener/line_dump.rb +0 -19
  86. data/lib/aspera/cli/listener/logger.rb +0 -22
  87. data/lib/aspera/cli/listener/progress.rb +0 -50
  88. data/lib/aspera/cli/listener/progress_multi.rb +0 -84
  89. data/lib/aspera/cli/plugins/sync.rb +0 -44
  90. data/lib/aspera/fasp/listener.rb +0 -13
@@ -17,18 +17,130 @@ module Aspera
17
17
  module Cli
18
18
  module Plugins
19
19
  class Aoc < Aspera::Cli::BasicAuthPlugin
20
+ AOC_PATH_API_CLIENTS = 'admin/api-clients'
21
+ # default redirect for AoC web auth
22
+ DEFAULT_REDIRECT = 'http://localhost:12345'
23
+ private_constant :AOC_PATH_API_CLIENTS, :DEFAULT_REDIRECT
20
24
  class << self
25
+ def application_name
26
+ 'Aspera on Cloud'
27
+ end
28
+
21
29
  def detect(base_url)
22
- api = Rest.new({base_url: base_url})
30
+ # no protocol ?
31
+ base_url = "https://#{base_url}" unless base_url.match?(%r{^[a-z]{1,6}://})
32
+ # only org provided ?
33
+ base_url = "#{base_url}.#{Aspera::AoC::PROD_DOMAIN}" unless base_url.include?('.')
34
+ # AoC is only https
35
+ return nil unless base_url.start_with?('https://')
36
+ result = Rest.new({base_url: base_url, redirect_max: 10}).read('')
37
+ # Any AoC is on this domain
38
+ return nil unless result[:http].uri.host.end_with?(Aspera::AoC::PROD_DOMAIN)
39
+ Log.log.debug{'AoC Main page: #{result[:http].body.include?(Aspera::AoC::PRODUCT_NAME)}'}
40
+ base_url = result[:http].uri.to_s if result[:http].uri.path.include?('/public')
23
41
  # either in standard domain, or product name in page
24
- if URI.parse(base_url).host.end_with?(Aspera::AoC::PROD_DOMAIN) ||
25
- api.call({operation: 'GET', redirect_max: 1, headers: {'Accept' => 'text/html'}})[:http].body.include?(Aspera::AoC::PRODUCT_NAME)
42
+ return {
43
+ version: 'SaaS',
44
+ url: base_url
45
+ }
46
+ end
47
+
48
+ def private_key_required?(url)
49
+ # pub link do not need private key
50
+ return AoC.link_info(url)[:token].nil?
51
+ end
52
+
53
+ # @param [Hash] env : options, formatter
54
+ # @param [Hash] params : plugin_sym, instance_url
55
+ # @return [Hash] :preset_value, :test_args
56
+ def wizard(object:, private_key_path: nil, pub_key_pem: nil)
57
+ # set vars to look like object
58
+ options = object.options
59
+ formatter = object.formatter
60
+ options.declare(:use_generic_client, 'Wizard: AoC: use global or org specific jwt client id', values: :bool, default: true)
61
+ options.parse_options!
62
+ instance_url = options.get_option(:url, mandatory: true)
63
+ pub_link_info = AoC.link_info(instance_url)
64
+ if !pub_link_info[:token].nil?
65
+ pub_api = Rest.new({base_url: "https://#{URI.parse(pub_link_info[:url]).host}/api/v1"})
66
+ pub_info = pub_api.read('env/url_token_check', {token: pub_link_info[:token]})[:data]
67
+ preset_value = {
68
+ link: instance_url
69
+ }
70
+ preset_value[:password] = options.get_option(:password, mandatory: true) if pub_info['password_protected']
26
71
  return {
27
- version: 'SaaS',
28
- name: 'Aspera on Cloud'
72
+ preset_value: preset_value,
73
+ test_args: 'organization'
29
74
  }
30
75
  end
31
- return nil
76
+ # make username mandatory for jwt, this triggers interactive input
77
+ wiz_username = options.get_option(:username, mandatory: true)
78
+ raise "Username shall be an email in AoC: #{wiz_username}" if !(wiz_username =~ /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i)
79
+ # Set the pub key and jwt tag in the user's profile automatically
80
+ auto_set_pub_key = false
81
+ auto_set_jwt = false
82
+ # use browser authentication to bootstrap
83
+ use_browser_authentication = false
84
+ if options.get_option(:use_generic_client)
85
+ formatter.display_status('Using global client_id.')
86
+ formatter.display_status('Please Login to your Aspera on Cloud instance.')
87
+ formatter.display_status('Navigate to: 👤 → Account Settings → Profile → Public Key')
88
+ formatter.display_status('Check or update the value to:'.red.blink)
89
+ formatter.display_status(pub_key_pem)
90
+ if !options.get_option(:test_mode)
91
+ formatter.display_status('Once updated or validated, press enter.')
92
+ OpenApplication.instance.uri(instance_url)
93
+ $stdin.gets
94
+ end
95
+ else
96
+ formatter.display_status('Using organization specific client_id.')
97
+ if options.get_option(:client_id).nil? || options.get_option(:client_secret).nil?
98
+ formatter.display_status('Please login to your Aspera on Cloud instance.'.red)
99
+ formatter.display_status('Navigate to: 𓃑 → Admin → Integrations → API Clients')
100
+ formatter.display_status('Check or create in integration:')
101
+ formatter.display_status("- name: #{@info[:name]}")
102
+ formatter.display_status("- redirect uri: #{DEFAULT_REDIRECT}")
103
+ formatter.display_status('- origin: localhost')
104
+ formatter.display_status('Use the generated client id and secret in the following prompts.'.red)
105
+ end
106
+ OpenApplication.instance.uri("#{instance_url}/#{AOC_PATH_API_CLIENTS}")
107
+ options.get_option(:client_id, mandatory: true)
108
+ options.get_option(:client_secret, mandatory: true)
109
+ use_browser_authentication = true
110
+ end
111
+ if use_browser_authentication
112
+ formatter.display_status('We will use web authentication to bootstrap.')
113
+ auto_set_pub_key = true
114
+ auto_set_jwt = true
115
+ aoc_api.oauth.generic_parameters[:grant_method] = :web
116
+ aoc_api.oauth.generic_parameters[:scope] = AoC::SCOPE_FILES_ADMIN
117
+ aoc_api.oauth.specific_parameters[:redirect_uri] = DEFAULT_REDIRECT
118
+ end
119
+ myself = object.aoc_api.read('self')[:data]
120
+ if auto_set_pub_key
121
+ raise Cli::Error, 'Public key is already set in profile (use --override=yes)' unless myself['public_key'].empty? || option_override
122
+ formatter.display_status('Updating profile with the public key.')
123
+ aoc_api.update("users/#{myself['id']}", {'public_key' => pub_key_pem})
124
+ end
125
+ if auto_set_jwt
126
+ formatter.display_status('Enabling JWT for client')
127
+ aoc_api.update("clients/#{options.get_option(:client_id)}", {'jwt_grant_enabled' => true, 'explicit_authorization_required' => false})
128
+ end
129
+ preset_result = {
130
+ url: instance_url,
131
+ username: myself['email'],
132
+ auth: :jwt.to_s,
133
+ private_key: "@file:#{private_key_path}"
134
+ }
135
+ # set only if non nil
136
+ %i[client_id client_secret].each do |s|
137
+ o = options.get_option(s)
138
+ preset_result[s.to_s] = o unless o.nil?
139
+ end
140
+ return {
141
+ preset_value: preset_result,
142
+ test_args: 'user profile show'
143
+ }
32
144
  end
33
145
  end
34
146
  # special value for package id
@@ -53,8 +165,6 @@ module Aspera
53
165
  client_registration_token
54
166
  client_access_key
55
167
  kms_profile].freeze
56
- # TODO: remove this and use %name: instead
57
- ENTITY_NAME_SPECIFIER = 'name'
58
168
  PACKAGE_QUERY_DEFAULT = {'archived' => false, 'exclude_dropbox_packages' => true, 'has_content' => true, 'received' => true}.freeze
59
169
 
60
170
  def initialize(env)
@@ -63,124 +173,51 @@ module Aspera
63
173
  @cache_home_node_file = nil
64
174
  @cache_api_aoc = nil
65
175
  options.declare(:auth, 'OAuth type of authentication', values: Oauth::STD_AUTH_TYPES, default: :jwt)
66
- options.declare(:operation, 'Client operation for transfers', values: %i[push pull], default: :push)
67
176
  options.declare(:client_id, 'OAuth API client identifier')
68
177
  options.declare(:client_secret, 'OAuth API client secret')
178
+ options.declare(:scope, 'OAuth scope for AoC API calls', default: AoC::SCOPE_FILES_USER)
69
179
  options.declare(:redirect_uri, 'OAuth API client redirect URI')
70
180
  options.declare(:private_key, 'OAuth JWT RSA private key PEM value (prefix file path with @file:)')
71
- options.declare(:scope, 'OAuth scope for AoC API calls', default: AoC::SCOPE_FILES_USER)
72
181
  options.declare(:passphrase, 'RSA private key passphrase')
73
- options.declare(:workspace, 'Name of workspace', default: :default)
74
- # TODO: remove this and use %name: instead
75
- options.declare(:name, "Resource name (prefer to use keyword #{ENTITY_NAME_SPECIFIER})")
76
- options.declare(:link, 'Public link to shared resource')
182
+ options.declare(:workspace, 'Name of workspace', types: [String, NilClass], default: Aspera::AoC::DEFAULT_WORKSPACE)
77
183
  options.declare(:new_user_option, 'New user creation option for unknown package recipients')
78
- options.declare(:from_folder, 'Source folder for Folder-to-Folder transfer')
79
184
  options.declare(:validate_metadata, 'Validate shared inbox metadata', values: :bool, default: true)
80
185
  options.parse_options!
81
- # add node plugin options (TODO: check needed ? if yes, tell why)
82
- Node.new(env.merge({man_only: true, skip_basic_auth_options: true}))
186
+ # add node plugin options (for manual)
187
+ Node.declare_options(options)
83
188
  end
84
189
 
85
- # build list of options for AoC API, based on options of CLI
86
- def aoc_params(subpath)
87
- # copy command line options to args
88
- return Aspera::AoC::OPTIONS_NEW.each_with_object({subpath: subpath}){|i, m|m[i] = options.get_option(i)}
89
- end
90
-
91
- def aoc_api
92
- if @cache_api_aoc.nil?
93
- @cache_api_aoc = AoC.new(aoc_params(AoC::API_V1))
94
- # add keychain for access key secrets
95
- @cache_api_aoc.secret_finder = @agents[:config]
96
- end
97
- return @cache_api_aoc
98
- end
190
+ OPTIONS_NEW = %i[url auth client_id client_secret scope redirect_uri private_key passphrase username password workspace].freeze
99
191
 
100
- # @return [Hash] current workspace information,
101
- def current_workspace_info
102
- return @cache_workspace_info unless @cache_workspace_info.nil?
103
- default_workspace_id = if aoc_api.url_token_data.nil?
104
- aoc_api.current_user_info['default_workspace_id']
105
- else
106
- aoc_api.url_token_data['data']['workspace_id']
192
+ def api_from_options(new_base_path)
193
+ create_values = {subpath: new_base_path, secret_finder: @agents[:config]}
194
+ # create an API object with the same options, but with a different subpath
195
+ return Aspera::AoC.new(**OPTIONS_NEW.each_with_object(create_values) { |i, m|m[i] = options.get_option(i) unless options.get_option(i).nil?})
196
+ rescue ArgumentError => e
197
+ if (m = e.message.match(/missing keyword: :(.*)$/))
198
+ raise Cli::Error, "Missing option: #{m[1]}"
107
199
  end
108
-
109
- ws_name = options.get_option(:workspace)
110
- ws_id =
111
- case ws_name
112
- when :default
113
- Log.log.debug('Using default workspace'.green)
114
- raise CliError, 'No default workspace defined for user, please specify workspace' if default_workspace_id.nil?
115
- default_workspace_id
116
- when String then aoc_api.lookup_by_name('workspaces', ws_name)['id']
117
- when NilClass then nil
118
- else raise CliError, 'unexpected value type for workspace'
119
- end
120
- @cache_workspace_info =
121
- begin
122
- aoc_api.read("workspaces/#{ws_id}")[:data]
123
- rescue Aspera::RestCallError => e
124
- Log.log.debug(e.message)
125
- { 'id' => :undefined, 'name' => :undefined }
126
- end
127
- Log.dump(:current_workspace_info, @cache_workspace_info)
128
- # display workspace
129
- default_flag = @cache_workspace_info['id'] == default_workspace_id ? ' (default)' : ''
130
- formatter.display_status("Current Workspace: #{@cache_workspace_info['name'].to_s.red}#{default_flag}")
131
- return @cache_workspace_info
200
+ raise
132
201
  end
133
202
 
134
- # @return [Hash] with :node_id and :file_id
135
- def home_info
136
- return @cache_home_node_file unless @cache_home_node_file.nil?
137
- if !aoc_api.url_token_data.nil?
138
- assert_public_link_types(['view_shared_file'])
139
- home_node_id = aoc_api.url_token_data['data']['node_id']
140
- home_file_id = aoc_api.url_token_data['data']['file_id']
141
- end
142
- home_node_id ||= current_workspace_info['home_node_id'] || current_workspace_info['node_id']
143
- home_file_id ||= current_workspace_info['home_file_id']
144
- if home_node_id.to_s.empty?
145
- # not part of any workspace, but has some folder shared
146
- user_info = aoc_api.current_user_info(exception: true)
147
- home_node_id = user_info['read_only_home_node_id']
148
- home_file_id = user_info['read_only_home_file_id']
149
- end
150
-
151
- raise "Cannot get user's home node id, check your default workspace or specify one" if home_node_id.to_s.empty?
152
- @cache_home_node_file = {
153
- node_id: home_node_id,
154
- file_id: home_file_id
155
- }
156
- return @cache_home_node_file
203
+ def aoc_api
204
+ @cache_api_aoc = api_from_options(AoC::API_V1) if @cache_api_aoc.nil?
205
+ return @cache_api_aoc
157
206
  end
158
207
 
159
208
  # get identifier or name from command line
160
209
  # @return identifier
161
210
  def get_resource_id_from_args(resource_class_path)
162
- l_res_id = options.get_option(:id)
163
- l_res_name = options.get_option(:name)
164
- raise 'Provide either option id or name, not both' unless l_res_id.nil? || l_res_name.nil?
165
- # try to find item by name (single partial match or exact match)
166
- l_res_id = aoc_api.lookup_by_name(resource_class_path, l_res_name)['id'] unless l_res_name.nil?
167
- # if no name or id option, taken on command line (after command)
168
- if l_res_id.nil?
169
- l_res_id = options.get_next_argument('identifier')
170
- l_res_id = aoc_api.lookup_by_name(resource_class_path, options.get_next_argument('identifier'))['id'] if l_res_id.eql?(ENTITY_NAME_SPECIFIER)
211
+ return instance_identifier do |field, value|
212
+ raise Cli::BadArgument, 'only selection by name is supported' unless field.eql?('name')
213
+ aoc_api.lookup_by_name(resource_class_path, value)['id']
171
214
  end
172
- return l_res_id
173
215
  end
174
216
 
175
217
  def get_resource_path_from_args(resource_class_path)
176
218
  return "#{resource_class_path}/#{get_resource_id_from_args(resource_class_path)}"
177
219
  end
178
220
 
179
- def assert_public_link_types(expected)
180
- raise CliBadArgument, "public link type is #{aoc_api.url_token_data['purpose']} but action requires one of #{expected.join(',')}" \
181
- unless expected.include?(aoc_api.url_token_data['purpose'])
182
- end
183
-
184
221
  # Call aoc_api.read with same parameters.
185
222
  # Use paging if necessary to get all results
186
223
  # @return [Hash] {list: , total: }
@@ -188,10 +225,8 @@ module Aspera
188
225
  raise 'Query must be Hash' unless base_query.is_a?(Hash)
189
226
  # set default large page if user does not specify own parameters. AoC Caps to 1000 anyway
190
227
  base_query['per_page'] = 1000 unless base_query.key?('per_page')
191
- max_items = base_query[MAX_ITEMS]
192
- base_query.delete(MAX_ITEMS)
193
- max_pages = base_query[MAX_PAGES]
194
- base_query.delete(MAX_PAGES)
228
+ max_items = base_query.delete(MAX_ITEMS)
229
+ max_pages = base_query.delete(MAX_PAGES)
195
230
  item_list = []
196
231
  total_count = nil
197
232
  current_page = base_query['page']
@@ -208,9 +243,10 @@ module Aspera
208
243
  break if add_items.empty?
209
244
  # append new items to full list
210
245
  item_list += add_items
211
- break if !max_pages.nil? && page_count > max_pages
212
- break if !max_items.nil? && item_list.count > max_items
246
+ break if !max_items.nil? && item_list.count >= max_items
247
+ break if !max_pages.nil? && page_count >= max_pages
213
248
  end
249
+ item_list = item_list[0..max_items - 1] if !max_items.nil? && item_list.count > max_items
214
250
  return {list: item_list, total: total_count}
215
251
  end
216
252
 
@@ -221,33 +257,32 @@ module Aspera
221
257
  # @param scope [String] node scope, or nil (admin)
222
258
  def execute_nodegen4_command(command_repo, node_id, file_id: nil, scope: nil)
223
259
  top_node_api = aoc_api.node_api_from(
224
- node_id: node_id,
225
- workspace_id: current_workspace_info['id'],
226
- workspace_name: current_workspace_info['name'],
227
- scope: scope
260
+ node_id: node_id,
261
+ workspace_id: aoc_api.context[:workspace_id],
262
+ workspace_name: aoc_api.context[:workspace_name],
263
+ scope: scope
228
264
  )
229
265
  file_id = top_node_api.read("access_keys/#{top_node_api.app_info[:node_info]['access_key']}")[:data]['root_file_id'] if file_id.nil?
230
- node_plugin = Node.new(@agents.merge(
231
- skip_basic_auth_options: true,
232
- skip_node_options: true,
233
- node_api: top_node_api))
266
+ node_plugin = Node.new(@agents, api: top_node_api)
234
267
  case command_repo
235
268
  when *Node::COMMANDS_GEN4
236
269
  return node_plugin.execute_command_gen4(command_repo, file_id)
237
270
  when :transfer
238
271
  # client side is agent
239
- # server side is protocol server
272
+ # server side is transfer server
240
273
  # in same workspace
241
- # default is push
242
- case options.get_option(:operation, mandatory: true)
274
+ push_pull = options.get_next_argument('direction', expected: %i[push pull])
275
+ source_folder = options.get_next_argument('folder of source files', type: String)
276
+ case push_pull
243
277
  when :push
244
278
  client_direction = Fasp::TransferSpec::DIRECTION_SEND
245
- client_folder = options.get_option(:from_folder, mandatory: true)
279
+ client_folder = source_folder
246
280
  server_folder = transfer.destination_folder(client_direction)
247
281
  when :pull
248
282
  client_direction = Fasp::TransferSpec::DIRECTION_RECEIVE
249
283
  client_folder = transfer.destination_folder(client_direction)
250
- server_folder = options.get_option(:from_folder, mandatory: true)
284
+ server_folder = source_folder
285
+ else raise 'internal error'
251
286
  end
252
287
  client_apfid = top_node_api.resolve_api_fid(file_id, client_folder)
253
288
  server_apfid = top_node_api.resolve_api_fid(file_id, server_folder)
@@ -289,7 +324,8 @@ module Aspera
289
324
  end
290
325
  when :subscription
291
326
  org = aoc_api.read('organization')[:data]
292
- bss_api = AoC.new(aoc_params('bss/platform'))
327
+ bss_api = api_from_options('bss/platform')
328
+ # cspell:disable
293
329
  graphql_query = "
294
330
  query ($organization_id: ID!) {
295
331
  aoc (organization_id: $organization_id) {
@@ -338,17 +374,18 @@ module Aspera
338
374
  }
339
375
  }
340
376
  "
377
+ # cspell:enable
341
378
  result = bss_api.create('graphql', {'variables' => {'organization_id' => org['id']}, 'query' => graphql_query})[:data]['data']
342
379
  return {type: :single_object, data: result['aoc']['bssSubscription']}
343
380
  when :ats
344
381
  ats_api = Rest.new(aoc_api.params.deep_merge({
345
- base_url: aoc_api.params[:base_url] + '/admin/ats/pub/v1',
382
+ base_url: "#{aoc_api.params[:base_url]}/admin/ats/pub/v1",
346
383
  auth: {scope: AoC::SCOPE_FILES_ADMIN_USER}
347
384
  }))
348
- return Ats.new(@agents.merge(skip_node_options: true)).execute_action_gen(ats_api)
385
+ return Ats.new(@agents).execute_action_gen(ats_api)
349
386
  when :analytics
350
387
  analytics_api = Rest.new(aoc_api.params.deep_merge({
351
- base_url: aoc_api.params[:base_url].gsub('/api/v1', '') + '/analytics/v2',
388
+ base_url: "#{aoc_api.params[:base_url].gsub('/api/v1', '')}/analytics/v2",
352
389
  auth: {scope: AoC::SCOPE_FILES_ADMIN_USER}
353
390
  }))
354
391
  command_analytics = options.get_next_command(%i[application_events transfers])
@@ -359,24 +396,23 @@ module Aspera
359
396
  return {type: :object_list, data: events}
360
397
  when :transfers
361
398
  event_type = command_analytics.to_s
362
- filter_resource = options.get_option(:name) || 'organizations'
363
- filter_id = options.get_option(:id) ||
399
+ filter_resource = options.get_next_argument('resource', expected: %i[organizations users nodes])
400
+ filter_id = options.get_next_argument('identifier', mandatory: false) ||
364
401
  case filter_resource
365
- when 'organizations' then aoc_api.current_user_info['organization_id']
366
- when 'users' then aoc_api.current_user_info['id']
367
- when 'nodes' then aoc_api.current_user_info['id'] # TODO: consistent ? # rubocop:disable Lint/DuplicateBranch
368
- else raise 'organizations or users for option --name'
402
+ when :organizations then aoc_api.current_user_info['organization_id']
403
+ when :users then aoc_api.current_user_info['id']
404
+ when :nodes then aoc_api.current_user_info['id'] # TODO: consistent ? # rubocop:disable Lint/DuplicateBranch
405
+ else raise 'Internal error'
369
406
  end
370
407
  filter = options.get_option(:query) || {}
371
- raise 'query must be Hash' unless filter.is_a?(Hash)
372
408
  filter['limit'] ||= 100
373
409
  if options.get_option(:once_only, mandatory: true)
374
410
  saved_date = []
375
411
  start_date_persistency = PersistencyActionOnce.new(
376
412
  manager: @agents[:persistency],
377
413
  data: saved_date,
378
- ids: IdGenerator.from_list(['aoc_ana_date', options.get_option(:url, mandatory: true), current_workspace_info['name']].push(
379
- filter_resource,
414
+ ids: IdGenerator.from_list(['aoc_ana_date', options.get_option(:url, mandatory: true), aoc_api.context[:workspace_name]].push(
415
+ filter_resource.to_s,
380
416
  filter_id)))
381
417
  start_date_time = saved_date.first
382
418
  stop_date_time = Time.now.utc.strftime('%FT%T.%LZ')
@@ -388,7 +424,7 @@ module Aspera
388
424
  end
389
425
  events = analytics_api.read("#{filter_resource}/#{filter_id}/#{event_type}", query_read_delete(default: filter))[:data][event_type]
390
426
  start_date_persistency&.save
391
- if !options.get_option(:notif_to).nil?
427
+ if !options.get_option(:notify_to).nil?
392
428
  events.each do |tr_event|
393
429
  config.send_email_template(values: {ev: tr_event})
394
430
  end
@@ -404,7 +440,7 @@ module Aspera
404
440
  when :self, :organization then resource_type
405
441
  when :client_registration_token, :client_access_key then "admin/#{resource_type}s"
406
442
  when :application then 'admin/apps_new'
407
- when :dropbox then resource_type.to_s + 'es'
443
+ when :dropbox then "#{resource_type}es"
408
444
  when :kms_profile then "integrations/#{resource_type}s"
409
445
  else "#{resource_type}s"
410
446
  end
@@ -428,9 +464,7 @@ module Aspera
428
464
  id_result = 'token' if resource_class_path.eql?('admin/client_registration_tokens')
429
465
  # TODO: report inconsistency: creation url is !=, and does not return id.
430
466
  resource_class_path = 'admin/client_registration/token' if resource_class_path.eql?('admin/client_registration_tokens')
431
- list_or_one = options.get_next_argument('creation data', type: Hash)
432
- return do_bulk_operation(list_or_one, 'created', id_result: id_result) do |params|
433
- raise 'expecting Hash' unless params.is_a?(Hash)
467
+ return do_bulk_operation(command: command, descr: 'creation data', id_result: id_result) do |params|
434
468
  aoc_api.create(resource_class_path, params)[:data]
435
469
  end
436
470
  when :list
@@ -455,30 +489,34 @@ module Aspera
455
489
  return {type: :object_list, data: items[:list], fields: default_fields}
456
490
  when :show
457
491
  object = aoc_api.read(resource_instance_path)[:data]
492
+ # default: show all, but certificate
458
493
  fields = object.keys.reject{|k|k.eql?('certificate')}
459
494
  return { type: :single_object, data: object, fields: fields }
460
495
  when :modify
461
- changes = options.get_next_argument('modified parameters (hash)')
462
- aoc_api.update(resource_instance_path, changes)
463
- return Main.result_status('modified')
496
+ changes = options.get_next_argument('properties', type: Hash)
497
+ return do_bulk_operation(command: command, descr: 'identifier', values: res_id) do |one_id|
498
+ aoc_api.update("#{resource_class_path}/#{one_id}", changes)
499
+ {'id' => one_id}
500
+ end
464
501
  when :delete
465
- return do_bulk_operation(res_id, 'deleted') do |one_id|
502
+ return do_bulk_operation(command: command, descr: 'identifier', values: res_id) do |one_id|
466
503
  aoc_api.delete("#{resource_class_path}/#{one_id}")
467
504
  {'id' => one_id}
468
505
  end
469
506
  when :set_pub_key
470
507
  # special : reads private and generate public
471
- the_private_key = options.get_next_argument('private_key')
508
+ the_private_key = options.get_next_argument('private_key PEM value', type: String)
472
509
  the_public_key = OpenSSL::PKey::RSA.new(the_private_key).public_key.to_s
473
510
  aoc_api.update(resource_instance_path, {jwt_grant_enabled: true, public_key: the_public_key})
474
511
  return Main.result_success
475
512
  when :do
476
513
  command_repo = options.get_next_command(NODE4_EXT_COMMANDS)
514
+ aoc_api.context(:none)
477
515
  return execute_nodegen4_command(command_repo, res_id)
478
516
  else raise 'unknown command'
479
517
  end
480
518
  when :usage_reports
481
- return {type: :object_list, data: aoc_api.read('usage_reports', {workspace_id: current_workspace_info['id']})[:data]}
519
+ return {type: :object_list, data: aoc_api.read('usage_reports', {workspace_id: aoc_api.context(:none)[:workspace_id]})[:data]}
482
520
  end
483
521
  end
484
522
 
@@ -487,6 +525,15 @@ module Aspera
487
525
 
488
526
  def execute_action
489
527
  command = options.get_next_command(ACTIONS)
528
+ if %i[files packages].include?(command)
529
+ default_flag = ' (default)' if options.get_option(:workspace).eql?(:default)
530
+ app_context = aoc_api.context(command)
531
+ formatter.display_status("Workspace: #{app_context[:workspace_name].to_s.red}#{default_flag}")
532
+ if !aoc_api.private_link.nil?
533
+ folder_name = aoc_api.node_api_from(node_id: app_context[:home_node_id]).read("files/#{app_context[:home_file_id]}")[:data]['name']
534
+ formatter.display_status("Private Folder: #{folder_name}")
535
+ end
536
+ end
490
537
  case command
491
538
  when :reminder
492
539
  # send an email reminder with list of orgs
@@ -510,14 +557,14 @@ module Aspera
510
557
  when :list
511
558
  return {type: :object_list, data: aoc_api.read('workspaces')[:data], fields: %w[id name]}
512
559
  when :current
513
- return { type: :single_object, data: current_workspace_info }
560
+ return { type: :single_object, data: aoc_api.read("workspaces/#{aoc_api.context(:none)[:workspace_id]}")[:data] }
514
561
  end
515
562
  when :profile
516
563
  case options.get_next_command(%i[show modify])
517
564
  when :show
518
565
  return { type: :single_object, data: aoc_api.current_user_info(exception: true) }
519
566
  when :modify
520
- aoc_api.update("users/#{aoc_api.current_user_info(exception: true)['id']}", options.get_next_argument('modified parameters (hash)'))
567
+ aoc_api.update("users/#{aoc_api.current_user_info(exception: true)['id']}", options.get_next_argument('properties', type: Hash))
521
568
  return Main.result_status('modified')
522
569
  end
523
570
  end
@@ -530,25 +577,25 @@ module Aspera
530
577
  query = query_read_delete
531
578
  if query.nil?
532
579
  query = {'embed[]' => 'dropbox', 'aggregate_permissions_by_dropbox' => true, 'sort' => 'dropbox_name'}
533
- query['workspace_id'] = current_workspace_info['id'] unless current_workspace_info['id'].eql?(:undefined)
580
+ query['workspace_id'] = aoc_api.context[:workspace_id] unless aoc_api.context[:workspace_id].eql?(:undefined)
534
581
  end
535
582
  return {type: :object_list, data: aoc_api.read('dropbox_memberships', query)[:data], fields: ['dropbox_id', 'dropbox.name']}
536
583
  when :show
537
584
  return {type: :single_object, data: aoc_api.read(get_resource_path_from_args('dropboxes'), query)[:data]}
538
585
  end
539
586
  when :send
540
- package_data = value_create_modify(command: package_command, type: Hash)
587
+ package_data = value_create_modify(command: package_command)
541
588
  new_user_option = options.get_option(:new_user_option)
542
589
  option_validate = options.get_option(:validate_metadata)
543
590
  # works for both normal usr auth and link auth
544
- package_data['workspace_id'] ||= current_workspace_info['id']
591
+ package_data['workspace_id'] ||= aoc_api.context[:workspace_id]
545
592
 
546
- if !aoc_api.url_token_data.nil?
547
- assert_public_link_types(%w[send_package_to_user send_package_to_dropbox])
548
- box_type = aoc_api.url_token_data['purpose'].split('_').last
549
- package_data['recipients'] = [{'id' => aoc_api.url_token_data['data']["#{box_type}_id"], 'type' => box_type}]
593
+ if !aoc_api.public_link.nil?
594
+ aoc_api.assert_public_link_types(%w[send_package_to_user send_package_to_dropbox])
595
+ box_type = aoc_api.public_link['purpose'].split('_').last
596
+ package_data['recipients'] = [{'id' => aoc_api.public_link['data']["#{box_type}_id"], 'type' => box_type}]
550
597
  # enforce workspace id from link (should be already ok, but in case user wanted to override)
551
- package_data['workspace_id'] = aoc_api.url_token_data['data']['workspace_id']
598
+ package_data['workspace_id'] = aoc_api.public_link['data']['workspace_id']
552
599
  end
553
600
 
554
601
  # transfer may raise an error
@@ -557,22 +604,27 @@ module Aspera
557
604
  # return all info on package (especially package id)
558
605
  return { type: :single_object, data: created_package[:info]}
559
606
  when :recv
560
- if !aoc_api.url_token_data.nil?
561
- assert_public_link_types(['view_received_package'])
562
- options.set_option(:id, aoc_api.url_token_data['data']['package_id'])
607
+ ids_to_download = nil
608
+ if !aoc_api.public_link.nil?
609
+ aoc_api.assert_public_link_types(['view_received_package'])
610
+ # set the package id, it will
611
+ ids_to_download = aoc_api.public_link['data']['package_id']
563
612
  end
564
- # scalar here
565
- ids_to_download = instance_identifier
613
+ # get from command line unless it was a public link
614
+ ids_to_download ||= instance_identifier
566
615
  skip_ids_data = []
567
616
  skip_ids_persistency = nil
568
617
  if options.get_option(:once_only, mandatory: true)
569
618
  skip_ids_persistency = PersistencyActionOnce.new(
570
619
  manager: @agents[:persistency],
571
620
  data: skip_ids_data,
572
- id: IdGenerator.from_list(['aoc_recv', options.get_option(:url, mandatory: true),
573
- current_workspace_info['id']].concat(aoc_api.additional_persistence_ids)))
621
+ id: IdGenerator.from_list(
622
+ ['aoc_recv',
623
+ options.get_option(:url, mandatory: true),
624
+ aoc_api.context[:workspace_id]
625
+ ].concat(aoc_api.additional_persistence_ids)))
574
626
  end
575
- if VAL_ALL.eql?(ids_to_download)
627
+ if ExtendedValue::ALL.eql?(ids_to_download)
576
628
  query = query_read_delete(default: PACKAGE_QUERY_DEFAULT)
577
629
  raise 'option query must be Hash' unless query.is_a?(Hash)
578
630
  if query.key?('dropbox_name')
@@ -581,14 +633,14 @@ module Aspera
581
633
  query['dropbox_id'] = aoc_api.lookup_by_name('dropboxes', query['dropbox_name'])['id']
582
634
  query.delete('dropbox_name')
583
635
  end
584
- query['workspace_id'] ||= current_workspace_info['id'] unless current_workspace_info['id'].eql?(:undefined)
636
+ query['workspace_id'] ||= aoc_api.context[:workspace_id] unless aoc_api.context[:workspace_id].eql?(:undefined)
585
637
  # get list of packages in inbox
586
638
  package_info = aoc_api.read('packages', query)[:data]
587
639
  # remove from list the ones already downloaded
588
640
  ids_to_download = package_info.map{|e|e['id']}
589
641
  # array here
590
642
  ids_to_download.reject!{|id|skip_ids_data.include?(id)}
591
- end # VAL_ALL
643
+ end # ExtendedValue::ALL
592
644
  # list here
593
645
  ids_to_download = [ids_to_download] unless ids_to_download.is_a?(Array)
594
646
  result_transfer = []
@@ -598,8 +650,8 @@ module Aspera
598
650
  formatter.display_status("downloading package: #{package_info['name']}")
599
651
  package_node_api = aoc_api.node_api_from(
600
652
  node_id: package_info['node_id'],
601
- workspace_id: current_workspace_info['id'],
602
- workspace_name: current_workspace_info['name'],
653
+ workspace_id: aoc_api.context[:workspace_id],
654
+ workspace_name: aoc_api.context[:workspace_name],
603
655
  package_info: package_info)
604
656
  statuses = transfer.start(
605
657
  package_node_api.transfer_spec_gen4(
@@ -616,7 +668,7 @@ module Aspera
616
668
  end
617
669
  return Main.result_transfer_multiple(result_transfer)
618
670
  when :show
619
- package_id = options.get_next_argument('package ID')
671
+ package_id = instance_identifier
620
672
  package_info = aoc_api.read("packages/#{package_id}")[:data]
621
673
  return { type: :single_object, data: package_info }
622
674
  when :list
@@ -629,43 +681,41 @@ module Aspera
629
681
  query['dropbox_id'] = aoc_api.lookup_by_name('dropboxes', query['dropbox_name'])['id']
630
682
  query.delete('dropbox_name')
631
683
  end
632
- if current_workspace_info['id'].eql?(:undefined)
684
+ if aoc_api.context[:workspace_id].eql?(:undefined)
633
685
  display_fields.push('workspace_id')
634
686
  else
635
- query['workspace_id'] ||= current_workspace_info['id']
687
+ query['workspace_id'] ||= aoc_api.context[:workspace_id]
636
688
  end
637
689
  packages = aoc_api.read('packages', query)[:data]
638
690
  return {type: :object_list, data: packages, fields: display_fields}
639
691
  when :delete
640
- list_or_one = instance_identifier
641
- return do_bulk_operation(list_or_one, 'deleted') do |id|
692
+ return do_bulk_operation(command: package_command, descr: 'identifier', values: identifier) do |id|
642
693
  raise 'expecting String identifier' unless id.is_a?(String) || id.is_a?(Integer)
643
694
  aoc_api.delete("packages/#{id}")[:data]
644
695
  end
645
696
  when *Node::NODE4_READ_ACTIONS
646
- package_id = options.get_next_argument('package ID')
697
+ package_id = instance_identifier
647
698
  package_info = aoc_api.read("packages/#{package_id}")[:data]
648
- return execute_nodegen4_command(package_command, package_info['node_id'], file_id: package_info['file_id'], scope: AoC::SCOPE_NODE_USER)
699
+ return execute_nodegen4_command(package_command, package_info['node_id'], file_id: package_info['file_id'], scope: Aspera::Node::SCOPE_USER)
649
700
  end
650
701
  when :files
651
702
  command_repo = options.get_next_command([:short_link].concat(NODE4_EXT_COMMANDS))
652
703
  case command_repo
653
704
  when *NODE4_EXT_COMMANDS
654
- return execute_nodegen4_command(command_repo, home_info[:node_id], file_id: home_info[:file_id], scope: AoC::SCOPE_NODE_USER)
705
+ return execute_nodegen4_command(command_repo, aoc_api.context[:home_node_id], file_id: aoc_api.context[:home_file_id], scope: Aspera::Node::SCOPE_USER)
655
706
  when :short_link
656
- # execute action on AoC API
657
- short_link_command = options.get_next_command(%i[create delete list])
658
- folder_dest = options.get_next_argument('path')
659
707
  link_type = options.get_next_argument('link type', expected: %i[public private])
708
+ short_link_command = options.get_next_command(%i[create delete list])
709
+ folder_dest = options.get_next_argument('path', type: String)
660
710
  home_node_api = aoc_api.node_api_from(
661
- node_id: home_info[:node_id],
662
- workspace_id: current_workspace_info['id'],
663
- workspace_name: current_workspace_info['name'])
664
- shared_apfid = home_node_api.resolve_api_fid(home_info[:file_id], folder_dest)
711
+ node_id: aoc_api.context[:home_node_id],
712
+ workspace_id: aoc_api.context[:workspace_id],
713
+ workspace_name: aoc_api.context[:workspace_name])
714
+ shared_apfid = home_node_api.resolve_api_fid(aoc_api.context[:home_file_id], folder_dest)
665
715
  folder_info = {
666
716
  node_id: shared_apfid[:api].app_info[:node_info]['id'],
667
717
  file_id: shared_apfid[:file_id],
668
- workspace_id: current_workspace_info['id']
718
+ workspace_id: aoc_api.context[:workspace_id]
669
719
  }
670
720
  purpose = case link_type
671
721
  when :public then 'token_auth_redirection'
@@ -699,14 +749,13 @@ module Aspera
699
749
  end
700
750
  list_params = {
701
751
  json_query: query.to_json,
702
- edit_access: true,
703
752
  purpose: purpose,
753
+ edit_access: true,
704
754
  # embed: 'updated_by_user',
705
755
  sort: '-created_at'
706
756
  }
707
757
  result = aoc_api.read('short_links', list_params)[:data]
708
- result.each{|i|i.delete('data')}
709
- return {type: :object_list, data: result}
758
+ return {type: :object_list, data: result, fields: Formatter.all_but('data')}
710
759
  when :create
711
760
  creation_params = {
712
761
  purpose: purpose,
@@ -741,8 +790,8 @@ module Aspera
741
790
  'access_levels' => access_levels,
742
791
  'tags' => {
743
792
  'url_token' => true,
744
- 'workspace_id' => current_workspace_info['id'],
745
- 'workspace_name' => current_workspace_info['name'],
793
+ 'workspace_id' => aoc_api.context[:workspace_id],
794
+ 'workspace_name' => aoc_api.context[:workspace_name],
746
795
  'folder_name' => folder_name,
747
796
  'created_by_name' => aoc_api.current_user_info['name'],
748
797
  'created_by_email' => aoc_api.current_user_info['email'],
@@ -772,7 +821,7 @@ module Aspera
772
821
  wf_command = options.get_next_command(%i[action launch].concat(Plugin::ALL_OPS))
773
822
  case wf_command
774
823
  when *Plugin::ALL_OPS
775
- return entity_command(wf_command, automation_api, 'workflows', id_default: :id)
824
+ return entity_command(wf_command, automation_api, 'workflows')
776
825
  when :launch
777
826
  wf_id = instance_identifier
778
827
  data = automation_api.create("workflows/#{wf_id}/launch", {})[:data]
@@ -794,10 +843,10 @@ module Aspera
794
843
  return execute_admin_action
795
844
  when :gateway
796
845
  require 'aspera/faspex_gw'
797
- url = value_create_modify(type: String)
846
+ url = value_create_modify(command: command, type: String)
798
847
  uri = URI.parse(url)
799
848
  server = WebServerSimple.new(uri)
800
- server.mount(uri.path, Faspex4GWServlet, aoc_api, current_workspace_info['id'])
849
+ server.mount(uri.path, Faspex4GWServlet, aoc_api, aoc_api.context(:none)[:workspace_id])
801
850
  trap('INT') { server.shutdown }
802
851
  formatter.display_status("Faspex 4 gateway listening on #{url}")
803
852
  Log.log.info("Listening on #{url}")
@@ -810,90 +859,7 @@ module Aspera
810
859
  raise 'internal error: command shall return'
811
860
  end
812
861
 
813
- # @param [Hash] params : plugin_sym, instance_url
814
- # @return [Hash] :preset_value, :test_args
815
- def wizard(params)
816
- if params[:prepare]
817
- organization = AoC.parse_url(params[:instance_url]).first
818
- # if not defined by user, generate name
819
- params[:preset_name] ||= [params[:plugin_sym], organization].join('_')
820
- params[:need_private_key] = true
821
- return
822
- end
823
- options.set_option(:private_key, '@file:' + params[:private_key_path])
824
- # make username mandatory for jwt, this triggers interactive input
825
- options.get_option(:username, mandatory: true)
826
- auto_set_pub_key = false
827
- auto_set_jwt = false
828
- use_browser_authentication = false
829
- if options.get_option(:use_generic_client)
830
- formatter.display_status('Using global client_id.')
831
- formatter.display_status('Please Login to your Aspera on Cloud instance.'.red)
832
- formatter.display_status('Navigate to your "Account Settings"'.red)
833
- formatter.display_status('Check or update the value of "Public Key" to be:'.red.blink)
834
- formatter.display_status(params[:pub_key_pem])
835
- if !options.get_option(:test_mode)
836
- formatter.display_status('Once updated or validated, press enter.')
837
- OpenApplication.instance.uri(params[:instance_url])
838
- $stdin.gets
839
- end
840
- else
841
- formatter.display_status('Using organization specific client_id.')
842
- if options.get_option(:client_id).nil? || options.get_option(:client_secret).nil?
843
- formatter.display_status('Please login to your Aspera on Cloud instance.'.red)
844
- formatter.display_status('Go to: Apps->Admin->Organization->Integrations')
845
- formatter.display_status('Create or check if there is an existing integration named:')
846
- formatter.display_status("- name: #{@info[:name]}")
847
- formatter.display_status("- redirect uri: #{DEFAULT_REDIRECT}")
848
- formatter.display_status('- origin: localhost')
849
- formatter.display_status('Once created or identified,')
850
- formatter.display_status('Please enter:'.red)
851
- end
852
- OpenApplication.instance.uri("#{params[:instance_url]}/#{AOC_PATH_API_CLIENTS}")
853
- options.get_option(:client_id, mandatory: true)
854
- options.get_option(:client_secret, mandatory: true)
855
- use_browser_authentication = true
856
- end
857
- if use_browser_authentication
858
- formatter.display_status('We will use web authentication to bootstrap.')
859
- auto_set_pub_key = true
860
- auto_set_jwt = true
861
- aoc_api.oauth.generic_parameters[:grant_method] = :web
862
- aoc_api.oauth.generic_parameters[:scope] = AoC::SCOPE_FILES_ADMIN
863
- aoc_api.oauth.specific_parameters[:redirect_uri] = DEFAULT_REDIRECT
864
- end
865
- myself = aoc_api.read('self')[:data]
866
- if auto_set_pub_key
867
- raise CliError, 'Public key is already set in profile (use --override=yes)' unless myself['public_key'].empty? || option_override
868
- formatter.display_status('Updating profile with new key')
869
- aoc_api.update("users/#{myself['id']}", {'public_key' => params[:pub_key_pem]})
870
- end
871
- if auto_set_jwt
872
- formatter.display_status('Enabling JWT for client')
873
- aoc_api.update("clients/#{options.get_option(:client_id)}", {'jwt_grant_enabled' => true, 'explicit_authorization_required' => false})
874
- end
875
- formatter.display_status("Creating new config preset: #{params[:preset_name]}")
876
- preset_result = {
877
- url: params[:instance_url],
878
- username: myself['email'],
879
- auth: :jwt.to_s,
880
- private_key: '@file:' + params[:private_key_path]
881
- }.stringify_keys
882
- # set only if non nil
883
- %i[client_id client_secret].each do |s|
884
- o = options.get_option(s)
885
- preset_result[s.to_s] = o unless o.nil?
886
- end
887
- return {
888
- preset_value: preset_result,
889
- test_args: "#{params[:plugin_sym]} user profile show"
890
- }
891
- end
892
-
893
- private :aoc_params,
894
- :home_info,
895
- :assert_public_link_types,
896
- :execute_admin_action
862
+ private :execute_admin_action
897
863
  end # AoC
898
864
  end # Plugins
899
865
  end # Cli