aspera-cli 4.13.0 → 4.15.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|