258 lines
11 KiB
JavaScript
258 lines
11 KiB
JavaScript
#! /usr/bin/env runjs
|
|
|
|
requireJAR('aliyun-sdk-oss-2.4.1-SNAPSHOT.jar');
|
|
requireJAR('commons-beanutils-1.8.0.jar');
|
|
requireJAR('commons-codec-1.9.jar');
|
|
requireJAR('commons-collections-3.2.1.jar');
|
|
requireJAR('commons-lang-2.5.jar');
|
|
requireJAR('commons-logging-1.2.jar');
|
|
requireJAR('ezmorph-1.0.6.jar');
|
|
requireJAR('hamcrest-core-1.1.jar');
|
|
requireJAR('httpclient-4.4.1.jar');
|
|
requireJAR('httpcore-4.4.1.jar');
|
|
requireJAR('jdom-1.1.jar');
|
|
requireJAR('json-lib-2.4-jdk15.jar');
|
|
|
|
requireJAR('maven:external.jose4j:jose4j:0.5.5');
|
|
requireJAR('maven:org.slf4j:slf4j-api:1.7.21');
|
|
|
|
var oss = require('component-oss.js');
|
|
var args = require('component-args.js');
|
|
var bytes = require('component-bytes.js');
|
|
var counter = require('component-counter.js');
|
|
var gpg = require('component-gpg-ex.js');
|
|
|
|
var File = java.io.File;
|
|
var System = java.lang.System;
|
|
var FileInputStream = java.io.FileInputStream;
|
|
var FileOutputStream = java.io.FileOutputStream;
|
|
|
|
var JsonWebKey = Packages.org.jose4j.jwk.JsonWebKey;
|
|
var JsonWebEncryption = Packages.org.jose4j.jwe.JsonWebEncryption;
|
|
var KeyManagementAlgorithmIdentifiers = Packages.org.jose4j.jwe.KeyManagementAlgorithmIdentifiers;
|
|
var ContentEncryptionAlgorithmIdentifiers = Packages.org.jose4j.jwe.ContentEncryptionAlgorithmIdentifiers;
|
|
var CounterInputStream = Packages.me.hatter.tools.commons.io.CounterInputStream;
|
|
var RFile = Packages.me.hatter.tools.commons.io.RFile;
|
|
var IOUtil = Packages.me.hatter.tools.commons.io.IOUtil;
|
|
var KeyValue = Packages.me.hatter.tools.commons.network.HttpRequest.KeyValue;
|
|
var ListObjectsRequest = Packages.com.aliyun.oss.model.ListObjectsRequest;
|
|
var AESCryptTool = Packages.me.hatter.tools.commons.security.crypt.AESCryptTool;
|
|
var DefaultRollCounter = Packages.me.hatter.tools.commons.io.DefaultRollCounter;
|
|
|
|
var main = () => {
|
|
var start = $$.date().millis();
|
|
|
|
var parsedArgs = args.parseARGS(['noenc', 'removesourcefile']);
|
|
|
|
if ((parsedArgs.args.length != 1) && (parsedArgs.args.length != 3)) {
|
|
println('osssendfile.js -- upload file to play.hatter.me');
|
|
println();
|
|
println('osssendfile.js [--config config.json] list');
|
|
println('osssendfile.js [--config config.json] clear');
|
|
println('osssendfile.js [--config config.json] [--noenc] [--removesourcefile] [--jwk \'x\'] file.ext title keywords');
|
|
println('osssendfile.js [--config config.json] [--noenc] [--removesourcefile] [--jwk \'{JWK}\'] file.ext title keywords');
|
|
return;
|
|
}
|
|
|
|
var configJSON = null;
|
|
try {
|
|
var config = RFile.from(parsedArgs.values['config'] || '~/.jssp/config/osssendfile.json').string();
|
|
configJSON = JSON.parse(config);
|
|
} catch (e) {
|
|
println('Parse config error: ' + e);
|
|
}
|
|
|
|
var hasNoAccessKey = !configJSON.accessKey || !configJSON.secretKey;
|
|
var hasNoOidc = !configJSON.oidc;
|
|
if (!configJSON || !configJSON.bucket || !configJSON.endpoint || !configJSON.token || (hasNoAccessKey && hasNoOidc)) {
|
|
println('----- Config format -----');
|
|
println('{');
|
|
println(' \"endpoint\": \"<ENDPOINT>\",');
|
|
println(' \"accessKey\": \"<AK>\",');
|
|
println(' \"secretKey\": \"<SK>\",');
|
|
println(' \"bucket\": \"<BUCKET>\",');
|
|
println(' \"token\": \"<TOKEN>\",');
|
|
println(' \"deleteSourceFile\": false');
|
|
println('}');
|
|
println('----- OR -----');
|
|
println('{');
|
|
println(' \"endpoint\": \"<ENDPOINT>\",');
|
|
println(' \"bucket\": \"<BUCKET>\",');
|
|
println(' \"token\": \"<TOKEN>\",');
|
|
println(' \"oidc\": {');
|
|
println(' \"sub\": \"<SUB>\",');
|
|
println(' \"client_id\": \"<CLIENT_ID>\",');
|
|
println(' \"client_secret\": \"<CLIENT_SECRET>\"');
|
|
println(' },');
|
|
println(' \"deleteSourceFile\": false');
|
|
println('}');
|
|
return;
|
|
}
|
|
|
|
var stsCredential = null;
|
|
if (configJSON.oidc) {
|
|
var params = $$.list();
|
|
params.add(new KeyValue('client_id', configJSON.oidc.clientId));
|
|
params.add(new KeyValue('client_secret', configJSON.oidc.clientSecret));
|
|
params.add(new KeyValue('sub', configJSON.oidc.sub));
|
|
var createStsUrl = 'https://hatter.ink/oidc/create_sts.json';
|
|
var sts = $$.httpRequest().readTimeout(5 * 60 * 1000).url(createStsUrl).post(params);
|
|
|
|
var stsJSON = JSON.parse(sts.toString());
|
|
if (stsJSON.status != 200) {
|
|
println('Get STS failed: ' + stsJSON.message);
|
|
return;
|
|
}
|
|
stsCredential= stsJSON.data;
|
|
}
|
|
|
|
var OSSClient = Packages.com.aliyun.oss.OSSClient;
|
|
var client;
|
|
if (stsCredential) {
|
|
client = new OSSClient(configJSON.endpoint, stsCredential.accessKeyId, stsCredential.accessKeySecret, stsCredential.securityToken);
|
|
} else {
|
|
client = new OSSClient(configJSON.endpoint, configJSON.accessKey, configJSON.secretKey);
|
|
}
|
|
try {
|
|
if (parsedArgs.args.length == 1) {
|
|
var getSums = () => {
|
|
var objectListing = client.listObjects(
|
|
new ListObjectsRequest(configJSON.bucket)
|
|
.withMaxKeys(100)
|
|
.withPrefix('tempfiles/temp_transfer_')
|
|
);
|
|
return $ARRAY(objectListing.getObjectSummaries());
|
|
};
|
|
|
|
var commandMap = {
|
|
'list': () => {
|
|
var sums = getSums();
|
|
println('Find ' + sums.length + ' object(s).')
|
|
sums.forEach((s) => {
|
|
println("Object: " + $$.asList(s.getKey(), s.getSize(), s.getLastModified()));
|
|
});
|
|
println('DONE @' + new Date());
|
|
},
|
|
'clear': () => {
|
|
var sums = getSums();
|
|
println('Find ' + sums.length + ' object(s).')
|
|
sums.forEach((s) => {
|
|
println("Delete object: " + $$.asList(s.getKey(), s.getSize(), s.getLastModified()));
|
|
client.deleteObject(configJSON.bucket, s.getKey());
|
|
});
|
|
println('DONE @' + new Date());
|
|
},
|
|
'null': (cmd) => {
|
|
println('[ERROR] Unknown command: ' + cmd);
|
|
}
|
|
};
|
|
|
|
(commandMap[parsedArgs.args[0]] || commandMap['null'])(parsedArgs.args[0]);
|
|
return;
|
|
}
|
|
|
|
var file = parsedArgs.args[0];
|
|
var title = parsedArgs.args[1];
|
|
var keywords = parsedArgs.args[2];
|
|
|
|
var ext = (file.lastIndexOf('.') > 0) ? file.substring(file.lastIndexOf('.') + 1) : null;
|
|
var sendFile = $$.file(file);
|
|
if (!(sendFile.exists())) {
|
|
println("File not exists: " + sendFile);
|
|
return;
|
|
}
|
|
|
|
if (!client.doesBucketExist(configJSON.bucket)) {
|
|
println("Bucket NOT exists: " + configJSON.bucket);
|
|
return;
|
|
}
|
|
|
|
var isSecure = false;
|
|
var tempKey = $$.random().nextIoBytes(16);
|
|
var pJwk = parsedArgs.values['jwk'];
|
|
if (pJwk) {
|
|
var pJwkContent = pJwk[0];
|
|
if ((pJwk[0].length == 0) || ($STR(pJwk[0]) == 'x')) {
|
|
pJwkContent = gpg.decrypt('~/jwk.json.asc');
|
|
}
|
|
var jwk = JsonWebKey.Factory.newJwk(pJwkContent);
|
|
var senderJwe = new JsonWebEncryption();
|
|
senderJwe.setPlaintext(title);
|
|
senderJwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.DIRECT);
|
|
senderJwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_128_GCM);
|
|
senderJwe.setKey(jwk.getKey());
|
|
var encTitle = 'JWE:' + senderJwe.getCompactSerialization();
|
|
println('Encrypt JWE title: ' + title + ' --> ' + encTitle);
|
|
title = encTitle;
|
|
|
|
isSecure = true;
|
|
tempKey = __.bytes.from(jwk.getKey().getEncoded());
|
|
}
|
|
|
|
var isDoDefaultEnc = !parsedArgs.flags['noenc'];
|
|
var sendFileTemp = sendFile;
|
|
if (isDoDefaultEnc) {
|
|
sendFileTemp = $$.file(file + '.tmp');
|
|
println('Encryption local file: ' + sendFile + ' --> ' + sendFileTemp + (isSecure ? ' [secure]': ' [normal]'));
|
|
AESCryptTool.gcmEncrypt(tempKey.bytes()).counter(new DefaultRollCounter(sendFile.length()).prefix('Encrypting: ')).from(sendFile).to(sendFileTemp);
|
|
}
|
|
|
|
var newFile = 'tempfiles/temp_transfer_' + $$.date().millis() + (ext ? ('.' + ext) : '');
|
|
println('Uploading object: ' + sendFileTemp + ' --> ' + newFile + ', file size: ' + bytes.showBytes(sendFileTemp.length()));
|
|
var databaseDbGpg = new FileInputStream(sendFileTemp);
|
|
var counterIS = new CounterInputStream(databaseDbGpg, counter.getCounterBar(sendFileTemp.length()));
|
|
client.putObject(configJSON.bucket, newFile, counterIS);
|
|
println();
|
|
|
|
// var ossURL = oss.generateSignedURL(configJSON.endpoint, configJSON.accessKey, configJSON.secretKey, configJSON.bucket, newFile, 600 * 1000);
|
|
var ossURL = client.generatePresignedUrl(configJSON.bucket, newFile, new java.util.Date(new java.util.Date().getTime() + 600 * 1000)).toString();
|
|
println('Object URL: ' + ossURL);
|
|
|
|
println('Sending document ....');
|
|
var params = $$.list();
|
|
params.add(new KeyValue('jsonp', '1'));
|
|
params.add(new KeyValue('token', configJSON.token));
|
|
params.add(new KeyValue('url', ossURL));
|
|
params.add(new KeyValue('title', title));
|
|
params.add(new KeyValue('keywords', keywords));
|
|
if (isDoDefaultEnc) {
|
|
if (isSecure) {
|
|
params.add(new KeyValue('jwe_secure', "true"));
|
|
params.add(new KeyValue('real_length', sendFile.length()));
|
|
params.add(new KeyValue('real_sha256', __.rfile.from(sendFile).digest(__.digests.sha256()).asHex()));
|
|
} else {
|
|
params.add(new KeyValue('encryption', tempKey.asBase64()));
|
|
}
|
|
}
|
|
var res = $$.httpRequest().readTimeout(5 * 60 * 1000).url('https://play.hatter.me/doc/addDoc.jsonp').post(params);
|
|
println('Add doc result: ' + res);
|
|
|
|
var resJSON = JSON.parse(res.toString());
|
|
|
|
if (resJSON.status == 200) {
|
|
println("Deleteing object: " + newFile);
|
|
client.deleteObject(configJSON.bucket, newFile);
|
|
} else {
|
|
println("Object is not deleted: " + newFile);
|
|
}
|
|
|
|
if (isDoDefaultEnc) {
|
|
sendFileTemp.delete();
|
|
}
|
|
var deleteSourceFile = configJSON.deleteSourceFile || parsedArgs.flags['removesourcefile'] || false;
|
|
if (deleteSourceFile) {
|
|
println('Delete file: ' + sendFile);
|
|
sendFile.delete();
|
|
}
|
|
|
|
println('DONE @' + new Date());
|
|
} catch (e) {
|
|
println('OSS Error: ' + e);
|
|
} finally {
|
|
client.shutdown();
|
|
}
|
|
};
|
|
|
|
main();
|
|
|