aspera-cli 4.13.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +81 -7
- data/CONTRIBUTING.md +22 -6
- data/README.md +2038 -1080
- data/bin/ascli +18 -9
- data/bin/asession +12 -14
- data/examples/dascli +1 -1
- data/examples/proxy.pac +1 -1
- data/examples/rubyc +24 -0
- data/lib/aspera/aoc.rb +219 -159
- data/lib/aspera/ascmd.rb +25 -14
- data/lib/aspera/cli/basic_auth_plugin.rb +12 -9
- data/lib/aspera/cli/error.rb +17 -0
- data/lib/aspera/cli/extended_value.rb +47 -12
- data/lib/aspera/cli/formatter.rb +260 -179
- data/lib/aspera/cli/hints.rb +80 -0
- data/lib/aspera/cli/main.rb +104 -156
- data/lib/aspera/cli/manager.rb +259 -209
- data/lib/aspera/cli/plugin.rb +123 -63
- data/lib/aspera/cli/plugins/alee.rb +2 -3
- data/lib/aspera/cli/plugins/aoc.rb +341 -261
- data/lib/aspera/cli/plugins/ats.rb +22 -21
- data/lib/aspera/cli/plugins/bss.rb +5 -5
- data/lib/aspera/cli/plugins/config.rb +578 -627
- data/lib/aspera/cli/plugins/console.rb +44 -6
- data/lib/aspera/cli/plugins/cos.rb +15 -17
- data/lib/aspera/cli/plugins/faspex.rb +114 -100
- data/lib/aspera/cli/plugins/faspex5.rb +411 -264
- data/lib/aspera/cli/plugins/node.rb +354 -259
- data/lib/aspera/cli/plugins/orchestrator.rb +61 -29
- data/lib/aspera/cli/plugins/preview.rb +82 -90
- data/lib/aspera/cli/plugins/server.rb +79 -32
- data/lib/aspera/cli/plugins/shares.rb +55 -42
- data/lib/aspera/cli/sync_actions.rb +68 -0
- data/lib/aspera/cli/transfer_agent.rb +66 -73
- data/lib/aspera/cli/transfer_progress.rb +74 -0
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/colors.rb +12 -8
- data/lib/aspera/command_line_builder.rb +14 -11
- data/lib/aspera/cos_node.rb +3 -2
- data/lib/aspera/data/6 +0 -0
- data/lib/aspera/environment.rb +24 -9
- data/lib/aspera/fasp/agent_aspera.rb +126 -0
- data/lib/aspera/fasp/agent_base.rb +31 -77
- data/lib/aspera/fasp/agent_connect.rb +25 -21
- data/lib/aspera/fasp/agent_direct.rb +89 -103
- data/lib/aspera/fasp/agent_httpgw.rb +231 -149
- data/lib/aspera/fasp/agent_node.rb +41 -34
- data/lib/aspera/fasp/agent_trsdk.rb +75 -32
- data/lib/aspera/fasp/error_info.rb +4 -2
- data/lib/aspera/fasp/faux_file.rb +52 -0
- data/lib/aspera/fasp/installation.rb +53 -195
- data/lib/aspera/fasp/management.rb +244 -0
- data/lib/aspera/fasp/parameters.rb +71 -37
- data/lib/aspera/fasp/parameters.yaml +76 -8
- data/lib/aspera/fasp/products.rb +162 -0
- data/lib/aspera/fasp/resume_policy.rb +3 -3
- data/lib/aspera/fasp/transfer_spec.rb +7 -6
- data/lib/aspera/fasp/uri.rb +26 -24
- data/lib/aspera/faspex_gw.rb +2 -2
- data/lib/aspera/faspex_postproc.rb +2 -2
- data/lib/aspera/hash_ext.rb +14 -4
- data/lib/aspera/json_rpc.rb +49 -0
- data/lib/aspera/keychain/macos_security.rb +13 -13
- data/lib/aspera/line_logger.rb +23 -0
- data/lib/aspera/log.rb +58 -16
- data/lib/aspera/node.rb +157 -92
- data/lib/aspera/oauth.rb +37 -19
- data/lib/aspera/open_application.rb +4 -4
- data/lib/aspera/persistency_action_once.rb +1 -1
- data/lib/aspera/persistency_folder.rb +2 -2
- data/lib/aspera/preview/file_types.rb +4 -2
- data/lib/aspera/preview/generator.rb +22 -35
- data/lib/aspera/preview/options.rb +2 -0
- data/lib/aspera/preview/terminal.rb +73 -16
- data/lib/aspera/preview/utils.rb +21 -28
- data/lib/aspera/proxy_auto_config.js +2 -2
- data/lib/aspera/rest.rb +136 -68
- data/lib/aspera/rest_call_error.rb +1 -1
- data/lib/aspera/rest_error_analyzer.rb +15 -14
- data/lib/aspera/rest_errors_aspera.rb +37 -34
- data/lib/aspera/secret_hider.rb +18 -15
- data/lib/aspera/ssh.rb +5 -2
- data/lib/aspera/sync.rb +127 -119
- data/lib/aspera/temp_file_manager.rb +10 -3
- data/lib/aspera/web_auth.rb +10 -7
- data/lib/aspera/web_server_simple.rb +9 -4
- data.tar.gz.sig +0 -0
- metadata +34 -17
- metadata.gz.sig +0 -0
- data/docs/test_env.conf +0 -186
- data/lib/aspera/cli/listener/line_dump.rb +0 -19
- data/lib/aspera/cli/listener/logger.rb +0 -22
- data/lib/aspera/cli/listener/progress.rb +0 -50
- data/lib/aspera/cli/listener/progress_multi.rb +0 -84
- data/lib/aspera/cli/plugins/sync.rb +0 -44
- data/lib/aspera/data/7 +0 -0
- data/lib/aspera/fasp/listener.rb +0 -13
@@ -17,15 +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
|
-
|
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
|
-
|
25
|
-
|
26
|
-
|
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']
|
71
|
+
return {
|
72
|
+
preset_value: preset_value,
|
73
|
+
test_args: 'organization'
|
74
|
+
}
|
75
|
+
end
|
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?
|
27
139
|
end
|
28
|
-
return
|
140
|
+
return {
|
141
|
+
preset_value: preset_result,
|
142
|
+
test_args: 'user profile show'
|
143
|
+
}
|
29
144
|
end
|
30
145
|
end
|
31
146
|
# special value for package id
|
@@ -50,7 +165,6 @@ module Aspera
|
|
50
165
|
client_registration_token
|
51
166
|
client_access_key
|
52
167
|
kms_profile].freeze
|
53
|
-
ENTITY_NAME_SPECIFIER = 'name'
|
54
168
|
PACKAGE_QUERY_DEFAULT = {'archived' => false, 'exclude_dropbox_packages' => true, 'has_content' => true, 'received' => true}.freeze
|
55
169
|
|
56
170
|
def initialize(env)
|
@@ -58,130 +172,52 @@ module Aspera
|
|
58
172
|
@cache_workspace_info = nil
|
59
173
|
@cache_home_node_file = nil
|
60
174
|
@cache_api_aoc = nil
|
61
|
-
options.
|
62
|
-
options.
|
63
|
-
options.
|
64
|
-
options.
|
65
|
-
options.
|
66
|
-
options.
|
67
|
-
options.
|
68
|
-
options.
|
69
|
-
options.
|
70
|
-
options.
|
71
|
-
options.add_opt_simple(:link, 'Public link to shared resource')
|
72
|
-
options.add_opt_simple(:new_user_option, 'New user creation option for unknown package recipients')
|
73
|
-
options.add_opt_simple(:from_folder, 'Source folder for Folder-to-Folder transfer')
|
74
|
-
options.add_opt_boolean(:validate_metadata, 'Validate shared inbox metadata')
|
75
|
-
options.set_option(:validate_metadata, :yes)
|
76
|
-
options.set_option(:operation, :push)
|
77
|
-
options.set_option(:auth, :jwt)
|
78
|
-
options.set_option(:scope, AoC::SCOPE_FILES_USER)
|
79
|
-
options.set_option(:private_key, '@file:' + env[:private_key_path]) if env[:private_key_path].is_a?(String)
|
80
|
-
options.set_option(:workspace, :default)
|
175
|
+
options.declare(:auth, 'OAuth type of authentication', values: Oauth::STD_AUTH_TYPES, default: :jwt)
|
176
|
+
options.declare(:client_id, 'OAuth API client identifier')
|
177
|
+
options.declare(:client_secret, 'OAuth API client secret')
|
178
|
+
options.declare(:scope, 'OAuth scope for AoC API calls', default: AoC::SCOPE_FILES_USER)
|
179
|
+
options.declare(:redirect_uri, 'OAuth API client redirect URI')
|
180
|
+
options.declare(:private_key, 'OAuth JWT RSA private key PEM value (prefix file path with @file:)')
|
181
|
+
options.declare(:passphrase, 'RSA private key passphrase')
|
182
|
+
options.declare(:workspace, 'Name of workspace', types: [String, NilClass], default: Aspera::AoC::DEFAULT_WORKSPACE)
|
183
|
+
options.declare(:new_user_option, 'New user creation option for unknown package recipients')
|
184
|
+
options.declare(:validate_metadata, 'Validate shared inbox metadata', values: :bool, default: true)
|
81
185
|
options.parse_options!
|
82
|
-
# add node plugin options
|
83
|
-
Node.
|
84
|
-
end
|
85
|
-
|
86
|
-
# build list of options for AoC API, based on options of CLI
|
87
|
-
def aoc_params(subpath)
|
88
|
-
# copy command line options to args
|
89
|
-
return Aspera::AoC::OPTIONS_NEW.each_with_object({subpath: subpath}){|i, m|m[i] = options.get_option(i)}
|
186
|
+
# add node plugin options (for manual)
|
187
|
+
Node.declare_options(options)
|
90
188
|
end
|
91
189
|
|
92
|
-
|
93
|
-
if @cache_api_aoc.nil?
|
94
|
-
@cache_api_aoc = AoC.new(aoc_params(AoC::API_V1))
|
95
|
-
# add keychain for access key secrets
|
96
|
-
@cache_api_aoc.secret_finder = @agents[:config]
|
97
|
-
end
|
98
|
-
return @cache_api_aoc
|
99
|
-
end
|
190
|
+
OPTIONS_NEW = %i[url auth client_id client_secret scope redirect_uri private_key passphrase username password workspace].freeze
|
100
191
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
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]}"
|
108
199
|
end
|
109
|
-
|
110
|
-
ws_name = options.get_option(:workspace)
|
111
|
-
ws_id =
|
112
|
-
case ws_name
|
113
|
-
when :default
|
114
|
-
Log.log.debug('Using default workspace'.green)
|
115
|
-
raise CliError, 'No default workspace defined for user, please specify workspace' if default_workspace_id.nil?
|
116
|
-
default_workspace_id
|
117
|
-
when String then aoc_api.lookup_entity_by_name('workspaces', ws_name)['id']
|
118
|
-
when NilClass then nil
|
119
|
-
else raise CliError, 'unexpected value type for workspace'
|
120
|
-
end
|
121
|
-
@cache_workspace_info =
|
122
|
-
begin
|
123
|
-
aoc_api.read("workspaces/#{ws_id}")[:data]
|
124
|
-
rescue Aspera::RestCallError => e
|
125
|
-
Log.log.debug(e.message)
|
126
|
-
{ 'id' => :undefined, 'name' => :undefined }
|
127
|
-
end
|
128
|
-
Log.dump(:current_workspace_info, @cache_workspace_info)
|
129
|
-
# display workspace
|
130
|
-
default_flag = @cache_workspace_info['id'] == default_workspace_id ? ' (default)' : ''
|
131
|
-
formatter.display_status("Current Workspace: #{@cache_workspace_info['name'].to_s.red}#{default_flag}")
|
132
|
-
return @cache_workspace_info
|
200
|
+
raise
|
133
201
|
end
|
134
202
|
|
135
|
-
|
136
|
-
|
137
|
-
return @
|
138
|
-
if !aoc_api.url_token_data.nil?
|
139
|
-
assert_public_link_types(['view_shared_file'])
|
140
|
-
home_node_id = aoc_api.url_token_data['data']['node_id']
|
141
|
-
home_file_id = aoc_api.url_token_data['data']['file_id']
|
142
|
-
end
|
143
|
-
home_node_id ||= current_workspace_info['home_node_id'] || current_workspace_info['node_id']
|
144
|
-
home_file_id ||= current_workspace_info['home_file_id']
|
145
|
-
if home_node_id.to_s.empty?
|
146
|
-
# not part of any workspace, but has some folder shared
|
147
|
-
user_info = aoc_api.current_user_info(exception: true)
|
148
|
-
home_node_id = user_info['read_only_home_node_id']
|
149
|
-
home_file_id = user_info['read_only_home_file_id']
|
150
|
-
end
|
151
|
-
|
152
|
-
raise "Cannot get user's home node id, check your default workspace or specify one" if home_node_id.to_s.empty?
|
153
|
-
@cache_home_node_file = {
|
154
|
-
node_id: home_node_id,
|
155
|
-
file_id: home_file_id
|
156
|
-
}
|
157
|
-
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
|
158
206
|
end
|
159
207
|
|
160
208
|
# get identifier or name from command line
|
161
209
|
# @return identifier
|
162
210
|
def get_resource_id_from_args(resource_class_path)
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
# try to find item by name (single partial match or exact match)
|
167
|
-
l_res_id = aoc_api.lookup_entity_by_name(resource_class_path, l_res_name)['id'] unless l_res_name.nil?
|
168
|
-
# if no name or id option, taken on command line (after command)
|
169
|
-
if l_res_id.nil?
|
170
|
-
l_res_id = options.get_next_argument('identifier')
|
171
|
-
l_res_id = aoc_api.lookup_entity_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']
|
172
214
|
end
|
173
|
-
return l_res_id
|
174
215
|
end
|
175
216
|
|
176
217
|
def get_resource_path_from_args(resource_class_path)
|
177
218
|
return "#{resource_class_path}/#{get_resource_id_from_args(resource_class_path)}"
|
178
219
|
end
|
179
220
|
|
180
|
-
def assert_public_link_types(expected)
|
181
|
-
raise CliBadArgument, "public link type is #{aoc_api.url_token_data['purpose']} but action requires one of #{expected.join(',')}" \
|
182
|
-
unless expected.include?(aoc_api.url_token_data['purpose'])
|
183
|
-
end
|
184
|
-
|
185
221
|
# Call aoc_api.read with same parameters.
|
186
222
|
# Use paging if necessary to get all results
|
187
223
|
# @return [Hash] {list: , total: }
|
@@ -189,10 +225,8 @@ module Aspera
|
|
189
225
|
raise 'Query must be Hash' unless base_query.is_a?(Hash)
|
190
226
|
# set default large page if user does not specify own parameters. AoC Caps to 1000 anyway
|
191
227
|
base_query['per_page'] = 1000 unless base_query.key?('per_page')
|
192
|
-
max_items = base_query
|
193
|
-
base_query.delete(
|
194
|
-
max_pages = base_query[MAX_PAGES]
|
195
|
-
base_query.delete(MAX_PAGES)
|
228
|
+
max_items = base_query.delete(MAX_ITEMS)
|
229
|
+
max_pages = base_query.delete(MAX_PAGES)
|
196
230
|
item_list = []
|
197
231
|
total_count = nil
|
198
232
|
current_page = base_query['page']
|
@@ -209,9 +243,10 @@ module Aspera
|
|
209
243
|
break if add_items.empty?
|
210
244
|
# append new items to full list
|
211
245
|
item_list += add_items
|
212
|
-
break if !
|
213
|
-
break if !
|
246
|
+
break if !max_items.nil? && item_list.count >= max_items
|
247
|
+
break if !max_pages.nil? && page_count >= max_pages
|
214
248
|
end
|
249
|
+
item_list = item_list[0..max_items - 1] if !max_items.nil? && item_list.count > max_items
|
215
250
|
return {list: item_list, total: total_count}
|
216
251
|
end
|
217
252
|
|
@@ -222,33 +257,32 @@ module Aspera
|
|
222
257
|
# @param scope [String] node scope, or nil (admin)
|
223
258
|
def execute_nodegen4_command(command_repo, node_id, file_id: nil, scope: nil)
|
224
259
|
top_node_api = aoc_api.node_api_from(
|
225
|
-
node_id:
|
226
|
-
workspace_id:
|
227
|
-
workspace_name:
|
228
|
-
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
|
229
264
|
)
|
230
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?
|
231
|
-
node_plugin = Node.new(@agents
|
232
|
-
skip_basic_auth_options: true,
|
233
|
-
skip_node_options: true,
|
234
|
-
node_api: top_node_api))
|
266
|
+
node_plugin = Node.new(@agents, api: top_node_api)
|
235
267
|
case command_repo
|
236
268
|
when *Node::COMMANDS_GEN4
|
237
269
|
return node_plugin.execute_command_gen4(command_repo, file_id)
|
238
270
|
when :transfer
|
239
271
|
# client side is agent
|
240
|
-
# server side is
|
272
|
+
# server side is transfer server
|
241
273
|
# in same workspace
|
242
|
-
|
243
|
-
|
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
|
244
277
|
when :push
|
245
278
|
client_direction = Fasp::TransferSpec::DIRECTION_SEND
|
246
|
-
client_folder =
|
279
|
+
client_folder = source_folder
|
247
280
|
server_folder = transfer.destination_folder(client_direction)
|
248
281
|
when :pull
|
249
282
|
client_direction = Fasp::TransferSpec::DIRECTION_RECEIVE
|
250
283
|
client_folder = transfer.destination_folder(client_direction)
|
251
|
-
server_folder =
|
284
|
+
server_folder = source_folder
|
285
|
+
else raise 'internal error'
|
252
286
|
end
|
253
287
|
client_apfid = top_node_api.resolve_api_fid(file_id, client_folder)
|
254
288
|
server_apfid = top_node_api.resolve_api_fid(file_id, server_folder)
|
@@ -290,7 +324,8 @@ module Aspera
|
|
290
324
|
end
|
291
325
|
when :subscription
|
292
326
|
org = aoc_api.read('organization')[:data]
|
293
|
-
bss_api =
|
327
|
+
bss_api = api_from_options('bss/platform')
|
328
|
+
# cspell:disable
|
294
329
|
graphql_query = "
|
295
330
|
query ($organization_id: ID!) {
|
296
331
|
aoc (organization_id: $organization_id) {
|
@@ -339,17 +374,18 @@ module Aspera
|
|
339
374
|
}
|
340
375
|
}
|
341
376
|
"
|
377
|
+
# cspell:enable
|
342
378
|
result = bss_api.create('graphql', {'variables' => {'organization_id' => org['id']}, 'query' => graphql_query})[:data]['data']
|
343
379
|
return {type: :single_object, data: result['aoc']['bssSubscription']}
|
344
380
|
when :ats
|
345
381
|
ats_api = Rest.new(aoc_api.params.deep_merge({
|
346
|
-
base_url: aoc_api.params[:base_url]
|
382
|
+
base_url: "#{aoc_api.params[:base_url]}/admin/ats/pub/v1",
|
347
383
|
auth: {scope: AoC::SCOPE_FILES_ADMIN_USER}
|
348
384
|
}))
|
349
|
-
return Ats.new(@agents
|
385
|
+
return Ats.new(@agents).execute_action_gen(ats_api)
|
350
386
|
when :analytics
|
351
387
|
analytics_api = Rest.new(aoc_api.params.deep_merge({
|
352
|
-
base_url: aoc_api.params[:base_url].gsub('/api/v1', '')
|
388
|
+
base_url: "#{aoc_api.params[:base_url].gsub('/api/v1', '')}/analytics/v2",
|
353
389
|
auth: {scope: AoC::SCOPE_FILES_ADMIN_USER}
|
354
390
|
}))
|
355
391
|
command_analytics = options.get_next_command(%i[application_events transfers])
|
@@ -360,24 +396,23 @@ module Aspera
|
|
360
396
|
return {type: :object_list, data: events}
|
361
397
|
when :transfers
|
362
398
|
event_type = command_analytics.to_s
|
363
|
-
filter_resource = options.
|
364
|
-
filter_id = options.
|
399
|
+
filter_resource = options.get_next_argument('resource', expected: %i[organizations users nodes])
|
400
|
+
filter_id = options.get_next_argument('identifier', mandatory: false) ||
|
365
401
|
case filter_resource
|
366
|
-
when
|
367
|
-
when
|
368
|
-
when
|
369
|
-
else raise '
|
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'
|
370
406
|
end
|
371
407
|
filter = options.get_option(:query) || {}
|
372
|
-
raise 'query must be Hash' unless filter.is_a?(Hash)
|
373
408
|
filter['limit'] ||= 100
|
374
|
-
if options.get_option(:once_only,
|
409
|
+
if options.get_option(:once_only, mandatory: true)
|
375
410
|
saved_date = []
|
376
411
|
start_date_persistency = PersistencyActionOnce.new(
|
377
412
|
manager: @agents[:persistency],
|
378
413
|
data: saved_date,
|
379
|
-
ids: IdGenerator.from_list(['aoc_ana_date', options.get_option(:url,
|
380
|
-
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,
|
381
416
|
filter_id)))
|
382
417
|
start_date_time = saved_date.first
|
383
418
|
stop_date_time = Time.now.utc.strftime('%FT%T.%LZ')
|
@@ -387,9 +422,9 @@ module Aspera
|
|
387
422
|
filter['start_time'] = start_date_time unless start_date_time.nil?
|
388
423
|
filter['stop_time'] = stop_date_time
|
389
424
|
end
|
390
|
-
events = analytics_api.read("#{filter_resource}/#{filter_id}/#{event_type}",
|
425
|
+
events = analytics_api.read("#{filter_resource}/#{filter_id}/#{event_type}", query_read_delete(default: filter))[:data][event_type]
|
391
426
|
start_date_persistency&.save
|
392
|
-
if !options.get_option(:
|
427
|
+
if !options.get_option(:notify_to).nil?
|
393
428
|
events.each do |tr_event|
|
394
429
|
config.send_email_template(values: {ev: tr_event})
|
395
430
|
end
|
@@ -405,7 +440,7 @@ module Aspera
|
|
405
440
|
when :self, :organization then resource_type
|
406
441
|
when :client_registration_token, :client_access_key then "admin/#{resource_type}s"
|
407
442
|
when :application then 'admin/apps_new'
|
408
|
-
when :dropbox then resource_type
|
443
|
+
when :dropbox then "#{resource_type}es"
|
409
444
|
when :kms_profile then "integrations/#{resource_type}s"
|
410
445
|
else "#{resource_type}s"
|
411
446
|
end
|
@@ -429,9 +464,7 @@ module Aspera
|
|
429
464
|
id_result = 'token' if resource_class_path.eql?('admin/client_registration_tokens')
|
430
465
|
# TODO: report inconsistency: creation url is !=, and does not return id.
|
431
466
|
resource_class_path = 'admin/client_registration/token' if resource_class_path.eql?('admin/client_registration_tokens')
|
432
|
-
|
433
|
-
return do_bulk_operation(list_or_one, 'created', id_result: id_result) do |params|
|
434
|
-
raise 'expecting Hash' unless params.is_a?(Hash)
|
467
|
+
return do_bulk_operation(command: command, descr: 'creation data', id_result: id_result) do |params|
|
435
468
|
aoc_api.create(resource_class_path, params)[:data]
|
436
469
|
end
|
437
470
|
when :list
|
@@ -451,35 +484,39 @@ module Aspera
|
|
451
484
|
when :group_membership then default_fields.push(*%w[group_id member_type member_id])
|
452
485
|
when :workspace_membership then default_fields.push(*%w[workspace_id member_type member_id])
|
453
486
|
end
|
454
|
-
items = read_with_paging(resource_class_path,
|
487
|
+
items = read_with_paging(resource_class_path, query_read_delete(default: default_query))
|
455
488
|
formatter.display_item_count(items[:list].length, items[:total])
|
456
489
|
return {type: :object_list, data: items[:list], fields: default_fields}
|
457
490
|
when :show
|
458
491
|
object = aoc_api.read(resource_instance_path)[:data]
|
492
|
+
# default: show all, but certificate
|
459
493
|
fields = object.keys.reject{|k|k.eql?('certificate')}
|
460
494
|
return { type: :single_object, data: object, fields: fields }
|
461
495
|
when :modify
|
462
|
-
changes = options.get_next_argument('
|
463
|
-
|
464
|
-
|
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
|
465
501
|
when :delete
|
466
|
-
return do_bulk_operation(
|
502
|
+
return do_bulk_operation(command: command, descr: 'identifier', values: res_id) do |one_id|
|
467
503
|
aoc_api.delete("#{resource_class_path}/#{one_id}")
|
468
504
|
{'id' => one_id}
|
469
505
|
end
|
470
506
|
when :set_pub_key
|
471
507
|
# special : reads private and generate public
|
472
|
-
the_private_key = options.get_next_argument('private_key')
|
508
|
+
the_private_key = options.get_next_argument('private_key PEM value', type: String)
|
473
509
|
the_public_key = OpenSSL::PKey::RSA.new(the_private_key).public_key.to_s
|
474
510
|
aoc_api.update(resource_instance_path, {jwt_grant_enabled: true, public_key: the_public_key})
|
475
511
|
return Main.result_success
|
476
512
|
when :do
|
477
513
|
command_repo = options.get_next_command(NODE4_EXT_COMMANDS)
|
514
|
+
aoc_api.context(:none)
|
478
515
|
return execute_nodegen4_command(command_repo, res_id)
|
479
516
|
else raise 'unknown command'
|
480
517
|
end
|
481
518
|
when :usage_reports
|
482
|
-
return {type: :object_list, data: aoc_api.read('usage_reports', {workspace_id:
|
519
|
+
return {type: :object_list, data: aoc_api.read('usage_reports', {workspace_id: aoc_api.context(:none)[:workspace_id]})[:data]}
|
483
520
|
end
|
484
521
|
end
|
485
522
|
|
@@ -488,10 +525,19 @@ module Aspera
|
|
488
525
|
|
489
526
|
def execute_action
|
490
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
|
491
537
|
case command
|
492
538
|
when :reminder
|
493
539
|
# send an email reminder with list of orgs
|
494
|
-
user_email = options.get_option(:username,
|
540
|
+
user_email = options.get_option(:username, mandatory: true)
|
495
541
|
Rest.new(base_url: "#{AoC.api_base_url}/#{AoC::API_V1}").create('organization_reminders', {email: user_email})[:data]
|
496
542
|
return Main.result_status("List of organizations user is member of, has been sent by e-mail to #{user_email}")
|
497
543
|
when :servers
|
@@ -511,14 +557,14 @@ module Aspera
|
|
511
557
|
when :list
|
512
558
|
return {type: :object_list, data: aoc_api.read('workspaces')[:data], fields: %w[id name]}
|
513
559
|
when :current
|
514
|
-
return { type: :single_object, data:
|
560
|
+
return { type: :single_object, data: aoc_api.read("workspaces/#{aoc_api.context(:none)[:workspace_id]}")[:data] }
|
515
561
|
end
|
516
562
|
when :profile
|
517
563
|
case options.get_next_command(%i[show modify])
|
518
564
|
when :show
|
519
565
|
return { type: :single_object, data: aoc_api.current_user_info(exception: true) }
|
520
566
|
when :modify
|
521
|
-
aoc_api.update("users/#{aoc_api.current_user_info(exception: true)['id']}", options.get_next_argument('
|
567
|
+
aoc_api.update("users/#{aoc_api.current_user_info(exception: true)['id']}", options.get_next_argument('properties', type: Hash))
|
522
568
|
return Main.result_status('modified')
|
523
569
|
end
|
524
570
|
end
|
@@ -528,29 +574,28 @@ module Aspera
|
|
528
574
|
when :shared_inboxes
|
529
575
|
case options.get_next_command(%i[list show])
|
530
576
|
when :list
|
531
|
-
query =
|
577
|
+
query = query_read_delete
|
532
578
|
if query.nil?
|
533
579
|
query = {'embed[]' => 'dropbox', 'aggregate_permissions_by_dropbox' => true, 'sort' => 'dropbox_name'}
|
534
|
-
query['workspace_id'] =
|
580
|
+
query['workspace_id'] = aoc_api.context[:workspace_id] unless aoc_api.context[:workspace_id].eql?(:undefined)
|
535
581
|
end
|
536
582
|
return {type: :object_list, data: aoc_api.read('dropbox_memberships', query)[:data], fields: ['dropbox_id', 'dropbox.name']}
|
537
583
|
when :show
|
538
584
|
return {type: :single_object, data: aoc_api.read(get_resource_path_from_args('dropboxes'), query)[:data]}
|
539
585
|
end
|
540
586
|
when :send
|
541
|
-
package_data =
|
542
|
-
raise CliBadArgument, 'value must be hash, refer to doc' unless package_data.is_a?(Hash)
|
587
|
+
package_data = value_create_modify(command: package_command)
|
543
588
|
new_user_option = options.get_option(:new_user_option)
|
544
589
|
option_validate = options.get_option(:validate_metadata)
|
545
590
|
# works for both normal usr auth and link auth
|
546
|
-
package_data['workspace_id'] ||=
|
591
|
+
package_data['workspace_id'] ||= aoc_api.context[:workspace_id]
|
547
592
|
|
548
|
-
if !aoc_api.
|
549
|
-
assert_public_link_types(%w[send_package_to_user send_package_to_dropbox])
|
550
|
-
box_type = aoc_api.
|
551
|
-
package_data['recipients'] = [{'id' => aoc_api.
|
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}]
|
552
597
|
# enforce workspace id from link (should be already ok, but in case user wanted to override)
|
553
|
-
package_data['workspace_id'] = aoc_api.
|
598
|
+
package_data['workspace_id'] = aoc_api.public_link['data']['workspace_id']
|
554
599
|
end
|
555
600
|
|
556
601
|
# transfer may raise an error
|
@@ -559,38 +604,43 @@ module Aspera
|
|
559
604
|
# return all info on package (especially package id)
|
560
605
|
return { type: :single_object, data: created_package[:info]}
|
561
606
|
when :recv
|
562
|
-
|
563
|
-
|
564
|
-
|
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']
|
565
612
|
end
|
566
|
-
#
|
567
|
-
ids_to_download
|
613
|
+
# get from command line unless it was a public link
|
614
|
+
ids_to_download ||= instance_identifier
|
568
615
|
skip_ids_data = []
|
569
616
|
skip_ids_persistency = nil
|
570
|
-
if options.get_option(:once_only,
|
617
|
+
if options.get_option(:once_only, mandatory: true)
|
571
618
|
skip_ids_persistency = PersistencyActionOnce.new(
|
572
619
|
manager: @agents[:persistency],
|
573
620
|
data: skip_ids_data,
|
574
|
-
id: IdGenerator.from_list(
|
575
|
-
|
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)))
|
576
626
|
end
|
577
|
-
if
|
578
|
-
query =
|
627
|
+
if ExtendedValue::ALL.eql?(ids_to_download)
|
628
|
+
query = query_read_delete(default: PACKAGE_QUERY_DEFAULT)
|
579
629
|
raise 'option query must be Hash' unless query.is_a?(Hash)
|
580
630
|
if query.key?('dropbox_name')
|
581
631
|
# convenience: specify name instead of id
|
582
632
|
raise 'not both dropbox_name and dropbox_id' if query.key?('dropbox_id')
|
583
|
-
query['dropbox_id'] = aoc_api.
|
633
|
+
query['dropbox_id'] = aoc_api.lookup_by_name('dropboxes', query['dropbox_name'])['id']
|
584
634
|
query.delete('dropbox_name')
|
585
635
|
end
|
586
|
-
query['workspace_id'] ||=
|
636
|
+
query['workspace_id'] ||= aoc_api.context[:workspace_id] unless aoc_api.context[:workspace_id].eql?(:undefined)
|
587
637
|
# get list of packages in inbox
|
588
638
|
package_info = aoc_api.read('packages', query)[:data]
|
589
639
|
# remove from list the ones already downloaded
|
590
640
|
ids_to_download = package_info.map{|e|e['id']}
|
591
641
|
# array here
|
592
642
|
ids_to_download.reject!{|id|skip_ids_data.include?(id)}
|
593
|
-
end #
|
643
|
+
end # ExtendedValue::ALL
|
594
644
|
# list here
|
595
645
|
ids_to_download = [ids_to_download] unless ids_to_download.is_a?(Array)
|
596
646
|
result_transfer = []
|
@@ -600,8 +650,8 @@ module Aspera
|
|
600
650
|
formatter.display_status("downloading package: #{package_info['name']}")
|
601
651
|
package_node_api = aoc_api.node_api_from(
|
602
652
|
node_id: package_info['node_id'],
|
603
|
-
workspace_id:
|
604
|
-
workspace_name:
|
653
|
+
workspace_id: aoc_api.context[:workspace_id],
|
654
|
+
workspace_name: aoc_api.context[:workspace_name],
|
605
655
|
package_info: package_info)
|
606
656
|
statuses = transfer.start(
|
607
657
|
package_node_api.transfer_spec_gen4(
|
@@ -618,112 +668,145 @@ module Aspera
|
|
618
668
|
end
|
619
669
|
return Main.result_transfer_multiple(result_transfer)
|
620
670
|
when :show
|
621
|
-
package_id =
|
671
|
+
package_id = instance_identifier
|
622
672
|
package_info = aoc_api.read("packages/#{package_id}")[:data]
|
623
673
|
return { type: :single_object, data: package_info }
|
624
674
|
when :list
|
625
675
|
display_fields = %w[id name bytes_transferred]
|
626
|
-
query =
|
676
|
+
query = query_read_delete(default: PACKAGE_QUERY_DEFAULT)
|
627
677
|
raise 'option query must be Hash' unless query.is_a?(Hash)
|
628
678
|
if query.key?('dropbox_name')
|
629
679
|
# convenience: specify name instead of id
|
630
680
|
raise 'not both dropbox_name and dropbox_id' if query.key?('dropbox_id')
|
631
|
-
query['dropbox_id'] = aoc_api.
|
681
|
+
query['dropbox_id'] = aoc_api.lookup_by_name('dropboxes', query['dropbox_name'])['id']
|
632
682
|
query.delete('dropbox_name')
|
633
683
|
end
|
634
|
-
if
|
684
|
+
if aoc_api.context[:workspace_id].eql?(:undefined)
|
635
685
|
display_fields.push('workspace_id')
|
636
686
|
else
|
637
|
-
query['workspace_id'] ||=
|
687
|
+
query['workspace_id'] ||= aoc_api.context[:workspace_id]
|
638
688
|
end
|
639
689
|
packages = aoc_api.read('packages', query)[:data]
|
640
690
|
return {type: :object_list, data: packages, fields: display_fields}
|
641
691
|
when :delete
|
642
|
-
|
643
|
-
return do_bulk_operation(list_or_one, 'deleted') do |id|
|
692
|
+
return do_bulk_operation(command: package_command, descr: 'identifier', values: identifier) do |id|
|
644
693
|
raise 'expecting String identifier' unless id.is_a?(String) || id.is_a?(Integer)
|
645
694
|
aoc_api.delete("packages/#{id}")[:data]
|
646
695
|
end
|
647
696
|
when *Node::NODE4_READ_ACTIONS
|
648
|
-
package_id =
|
697
|
+
package_id = instance_identifier
|
649
698
|
package_info = aoc_api.read("packages/#{package_id}")[:data]
|
650
|
-
return execute_nodegen4_command(package_command, package_info['node_id'], file_id: package_info['file_id'], scope:
|
699
|
+
return execute_nodegen4_command(package_command, package_info['node_id'], file_id: package_info['file_id'], scope: Aspera::Node::SCOPE_USER)
|
651
700
|
end
|
652
701
|
when :files
|
653
702
|
command_repo = options.get_next_command([:short_link].concat(NODE4_EXT_COMMANDS))
|
654
703
|
case command_repo
|
655
704
|
when *NODE4_EXT_COMMANDS
|
656
|
-
return execute_nodegen4_command(command_repo,
|
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)
|
657
706
|
when :short_link
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
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)
|
710
|
+
home_node_api = aoc_api.node_api_from(
|
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)
|
715
|
+
folder_info = {
|
716
|
+
node_id: shared_apfid[:api].app_info[:node_info]['id'],
|
717
|
+
file_id: shared_apfid[:file_id],
|
718
|
+
workspace_id: aoc_api.context[:workspace_id]
|
719
|
+
}
|
720
|
+
purpose = case link_type
|
721
|
+
when :public then 'token_auth_redirection'
|
722
|
+
when :private then 'shared_folder_auth_link'
|
723
|
+
else raise 'internal error'
|
666
724
|
end
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
shared_apfid = home_node_api.resolve_api_fid(home_info[:file_id], folder_dest)
|
675
|
-
create_params = {
|
676
|
-
file_id: shared_apfid[:file_id],
|
677
|
-
node_id: shared_apfid[:api].app_info[:node_info]['id'],
|
678
|
-
workspace_id: current_workspace_info['id']
|
725
|
+
case short_link_command
|
726
|
+
when :delete
|
727
|
+
one_id = instance_identifier
|
728
|
+
folder_info.delete(:workspace_id)
|
729
|
+
delete_params = {
|
730
|
+
edit_access: true,
|
731
|
+
json_query: folder_info.to_json
|
679
732
|
}
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
733
|
+
aoc_api.delete("short_links/#{one_id}", delete_params)
|
734
|
+
if link_type.eql?(:public)
|
735
|
+
# TODO: get permission id..
|
736
|
+
# shared_apfid[:api].delete('permissions', {ids: })[:data]
|
737
|
+
end
|
738
|
+
return Main.result_status('deleted')
|
739
|
+
when :list
|
740
|
+
query = if link_type.eql?(:private)
|
741
|
+
folder_info
|
742
|
+
else
|
743
|
+
{
|
744
|
+
url_token_data: {
|
745
|
+
data: folder_info,
|
746
|
+
purpose: 'view_shared_file'
|
747
|
+
}
|
748
|
+
}
|
749
|
+
end
|
750
|
+
list_params = {
|
751
|
+
json_query: query.to_json,
|
752
|
+
purpose: purpose,
|
753
|
+
edit_access: true,
|
754
|
+
# embed: 'updated_by_user',
|
755
|
+
sort: '-created_at'
|
756
|
+
}
|
757
|
+
result = aoc_api.read('short_links', list_params)[:data]
|
758
|
+
return {type: :object_list, data: result, fields: Formatter.all_but('data')}
|
759
|
+
when :create
|
760
|
+
creation_params = {
|
761
|
+
purpose: purpose,
|
762
|
+
user_selected_name: nil
|
763
|
+
}
|
764
|
+
case link_type
|
765
|
+
when :private
|
766
|
+
creation_params[:data] = folder_info
|
767
|
+
when :public
|
768
|
+
creation_params[:expires_at] = nil
|
769
|
+
creation_params[:password_enabled] = false
|
770
|
+
folder_info[:name] = ''
|
771
|
+
creation_params[:data] = {
|
689
772
|
aoc: true,
|
690
773
|
url_token_data: {
|
691
|
-
data:
|
774
|
+
data: folder_info,
|
692
775
|
purpose: 'view_shared_file'
|
693
776
|
}
|
694
777
|
}
|
695
|
-
value_option['user_selected_name'] = nil
|
696
|
-
else
|
697
|
-
raise 'purpose must be one of: token_auth_redirection or shared_folder_auth_link'
|
698
778
|
end
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
'
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
779
|
+
result_create_short_link = aoc_api.create('short_links', creation_params)[:data]
|
780
|
+
# public: Creation: permission on node
|
781
|
+
if link_type.eql?(:public)
|
782
|
+
# TODO: merge with node permissions ?
|
783
|
+
# TODO: access level as arg
|
784
|
+
access_levels = Aspera::Node::ACCESS_LEVELS # ['delete','list','mkdir','preview','read','rename','write']
|
785
|
+
folder_name = File.basename(folder_dest)
|
786
|
+
perm_data = {
|
787
|
+
'file_id' => shared_apfid[:file_id],
|
788
|
+
'access_id' => result_create_short_link['resource_id'],
|
789
|
+
'access_type' => 'user',
|
790
|
+
'access_levels' => access_levels,
|
791
|
+
'tags' => {
|
792
|
+
'url_token' => true,
|
793
|
+
'workspace_id' => aoc_api.context[:workspace_id],
|
794
|
+
'workspace_name' => aoc_api.context[:workspace_name],
|
795
|
+
'folder_name' => folder_name,
|
796
|
+
'created_by_name' => aoc_api.current_user_info['name'],
|
797
|
+
'created_by_email' => aoc_api.current_user_info['email'],
|
798
|
+
'access_key' => shared_apfid[:api].app_info[:node_info]['access_key'],
|
799
|
+
'node' => shared_apfid[:api].app_info[:node_info]['host']
|
800
|
+
}
|
719
801
|
}
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
802
|
+
created_data = shared_apfid[:api].create('permissions', perm_data)[:data]
|
803
|
+
aoc_api.permissions_send_event(created_data: created_data, app_info: shared_apfid[:api].app_info)
|
804
|
+
# TODO: event ?
|
805
|
+
end
|
806
|
+
return {type: :single_object, data: result_create_short_link}
|
807
|
+
end # short_link command
|
725
808
|
end # files command
|
726
|
-
|
809
|
+
raise 'Error: shall not reach this line'
|
727
810
|
when :automation
|
728
811
|
Log.log.warn('BETA: work under progress')
|
729
812
|
# automation api is not in the same place
|
@@ -738,7 +821,7 @@ module Aspera
|
|
738
821
|
wf_command = options.get_next_command(%i[action launch].concat(Plugin::ALL_OPS))
|
739
822
|
case wf_command
|
740
823
|
when *Plugin::ALL_OPS
|
741
|
-
return entity_command(wf_command, automation_api, 'workflows'
|
824
|
+
return entity_command(wf_command, automation_api, 'workflows')
|
742
825
|
when :launch
|
743
826
|
wf_id = instance_identifier
|
744
827
|
data = automation_api.create("workflows/#{wf_id}/launch", {})[:data]
|
@@ -760,10 +843,10 @@ module Aspera
|
|
760
843
|
return execute_admin_action
|
761
844
|
when :gateway
|
762
845
|
require 'aspera/faspex_gw'
|
763
|
-
url =
|
846
|
+
url = value_create_modify(command: command, type: String)
|
764
847
|
uri = URI.parse(url)
|
765
848
|
server = WebServerSimple.new(uri)
|
766
|
-
server.mount(uri.path, Faspex4GWServlet, aoc_api,
|
849
|
+
server.mount(uri.path, Faspex4GWServlet, aoc_api, aoc_api.context(:none)[:workspace_id])
|
767
850
|
trap('INT') { server.shutdown }
|
768
851
|
formatter.display_status("Faspex 4 gateway listening on #{url}")
|
769
852
|
Log.log.info("Listening on #{url}")
|
@@ -776,10 +859,7 @@ module Aspera
|
|
776
859
|
raise 'internal error: command shall return'
|
777
860
|
end
|
778
861
|
|
779
|
-
private :
|
780
|
-
:home_info,
|
781
|
-
:assert_public_link_types,
|
782
|
-
:execute_admin_action
|
862
|
+
private :execute_admin_action
|
783
863
|
end # AoC
|
784
864
|
end # Plugins
|
785
865
|
end # Cli
|