feat: add components
This commit is contained in:
116
components/component-alibaba-cloud-sts.js
Normal file
116
components/component-alibaba-cloud-sts.js
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
var ALIBABA_CLOUD_PKCS7_URL = "http://100.100.100.200/2016-01-01/dynamic/instance-identity/pkcs7";
|
||||||
|
var ASSUME_ROLE_URL = "https://hatter.ink/cloud/alibaba_cloud/assume_role.json";
|
||||||
|
var ASSUME_ROLE_PKCS7_URL = "https://hatter.ink/cloud/alibaba_cloud/assume_role_pkcs7.json";
|
||||||
|
|
||||||
|
var localEncryption = require('https://hatter.ink/script/get/@1/component-local-encryption.js', null,
|
||||||
|
'f910156414a71339c87aec6f013f7ab504dfc2992e94d4d6e66fa7864a6f54a8');
|
||||||
|
|
||||||
|
function fetchAlibabaCloudStsAuto() {
|
||||||
|
var System = Packages.java.lang.System;
|
||||||
|
var alibabaCloudStsType = System.getenv('ALIBABA_CLOUD_STS_TYPE');
|
||||||
|
var alibabaCloudStsRoleArn = System.getenv('ALIBABA_CLOUD_STS_ROLE_ARN');
|
||||||
|
var alibabaCloutStsSlot = System.getenv('ALIBABA_CLOUD_STS_SLOT');
|
||||||
|
return fetchAlibabaCloudStsWithCache({
|
||||||
|
type: alibabaCloudStsType,
|
||||||
|
roleArn: alibabaCloudStsRoleArn,
|
||||||
|
slot: alibabaCloutStsSlot
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// var sts = fetchAlibabaCloudStsWithCache({
|
||||||
|
// type: 'piv',
|
||||||
|
// roleArn: 'acs:ram::1747527333918361:role/test-assertion-assume-role',
|
||||||
|
// slot: 'r3'
|
||||||
|
// });
|
||||||
|
// -----OR-----
|
||||||
|
// var sts = fetchAlibabaCloudStsWithCache({
|
||||||
|
// type: 'alibaba_cloud_instance',
|
||||||
|
// roleArn: 'acs:ram::1747527333918361:role/test-assertion-assume-role'
|
||||||
|
// });
|
||||||
|
function fetchAlibabaCloudStsWithCache(request) {
|
||||||
|
var cacheKey = (request.type || 'type-na')
|
||||||
|
+ '_' + (request.roleArn || 'role-na')
|
||||||
|
+ '_' + (request.slot || 'slot-na');
|
||||||
|
cacheKey = cacheKey.replace(/[^a-zA-Z0-9:-_]/g, '-');
|
||||||
|
|
||||||
|
var alibabaCloudStsDir = $$.rFile('~/.jssp/cache/.alibabacloudsts').newDirIfNotExists();
|
||||||
|
var stsFile = alibabaCloudStsDir.file(cacheKey);
|
||||||
|
var sts = null;
|
||||||
|
if (stsFile.exists()) {
|
||||||
|
try {
|
||||||
|
var tempSts = JSON.parse(localEncryption.decrypt(stsFile.string().trim()));
|
||||||
|
if (tempSts.expiration) {
|
||||||
|
var expireMillis = new Date(tempSts.expiration).getTime();
|
||||||
|
if (expireMillis > (new Date().getTime() + (60 * 1000))) {
|
||||||
|
sts = tempSts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO check validity
|
||||||
|
} catch (e) {
|
||||||
|
// IGNORE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sts == null) {
|
||||||
|
sts = fetchAlibabaCloudSts(request);
|
||||||
|
stsFile.write(localEncryption.encrypt(JSON.stringify(sts)));
|
||||||
|
}
|
||||||
|
return sts;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchAlibabaCloudSts(request) {
|
||||||
|
if (request.type == "alibaba_cloud_instance") {
|
||||||
|
return fetchAlibabaCloudStsByAlibabaCloudInstanceIdentity(request.roleArn);
|
||||||
|
}
|
||||||
|
if (request.type == "piv") {
|
||||||
|
return fetchAlibabaCloudStsByCardCliPiv(request.roleArn, request.slot);
|
||||||
|
}
|
||||||
|
throw 'Not supported request type: ' + request.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchAlibabaCloudStsByAlibabaCloudInstanceIdentity(roleArn) {
|
||||||
|
var curentMillis = $$.date().millis();
|
||||||
|
var uniqId = 'uid_' + curentMillis;
|
||||||
|
var aud = 'arn:hatter.ink:alibaba_cloud:action:assume_role';
|
||||||
|
var pkcs7Audience = aud + '|' + roleArn + '|' + uniqId + '|' + curentMillis;
|
||||||
|
|
||||||
|
var pkcs7 = $$.httpRequest()
|
||||||
|
.url(ALIBABA_CLOUD_PKCS7_URL + '?audience=' + encodeURIComponent(pkcs7Audience))
|
||||||
|
.addHeader('User-Agent', 'runjs-component/1.0')
|
||||||
|
.get().toString().trim();
|
||||||
|
|
||||||
|
var sts = $$.httpRequest()
|
||||||
|
.url(ASSUME_ROLE_PKCS7_URL + '?type=cli')
|
||||||
|
.addHeader('User-Agent', 'runjs-component/1.0')
|
||||||
|
.addHeader('Authorization', 'PKCS7 ' + pkcs7)
|
||||||
|
.get().toString().trim();
|
||||||
|
|
||||||
|
return JSON.parse(sts).data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchAlibabaCloudStsByCardCliPiv(roleArn, slot) {
|
||||||
|
var result = $$.shell().commands('card-cli', 'sign-jwt',
|
||||||
|
'-s', slot,
|
||||||
|
'-C', 'sub:' + roleArn,
|
||||||
|
'-C', 'aud:arn:hatter.ink:alibaba_cloud:action:assume_role',
|
||||||
|
'-K', slot,
|
||||||
|
'--jti', '--validity', '10m', '--json').start();
|
||||||
|
var out = result[0].string().trim();
|
||||||
|
var err = result[1].string().trim();
|
||||||
|
if ($STR(out.trim()) == '') {
|
||||||
|
throw 'Run card-cli error: ' + err;
|
||||||
|
}
|
||||||
|
var jwt_token = JSON.parse(out).token;
|
||||||
|
|
||||||
|
var sts = $$.httpRequest()
|
||||||
|
.url(ASSUME_ROLE_URL + '?type=cli&assertion=' + encodeURIComponent(jwt_token))
|
||||||
|
.addHeader('User-Agent', 'runjs-component/1.0')
|
||||||
|
.get().toString().trim();
|
||||||
|
|
||||||
|
return JSON.parse(sts).data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof exports == 'object') {
|
||||||
|
exports.fetchAlibabaCloudStsWithCache = fetchAlibabaCloudStsWithCache;
|
||||||
|
exports.fetchAlibabaCloudSts = fetchAlibabaCloudSts;
|
||||||
|
exports.fetchAlibabaCloudStsAuto = fetchAlibabaCloudStsAuto;
|
||||||
|
}
|
||||||
46
components/component-local-encryption.js
Normal file
46
components/component-local-encryption.js
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
var __SEED1 = __.bytes.fromBase64('tdYcsSYN6tkKAEylW0TBfqiiKwea6AA/WMEyyfnRYacR3+DmflIpupFWbVovSfXvculFc7XUjV71jkID1+JJKg==');
|
||||||
|
var __SEED2 = __readSeedFromFile(1024, '~/.jssp/.local-encryption-seed');
|
||||||
|
var __SEED3 = __readSeedFromFile(2048, '~/.jssp-local-encryption-seed');
|
||||||
|
|
||||||
|
function __readSeedFromFile(len, filename) {
|
||||||
|
var seed;
|
||||||
|
var seedFile = $$.rFile(filename);
|
||||||
|
if (seedFile.exists()) {
|
||||||
|
seed = seedFile.string().trim();
|
||||||
|
} else {
|
||||||
|
seed = $$.random().nextIoBytes(len).asBase64();
|
||||||
|
seedFile.write(seed);
|
||||||
|
}
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
var __SEED = __SEED1 + '|' + __SEED2 + '|' + __SEED3;
|
||||||
|
var Bytes = Packages.me.hatter.tools.commons.bytes.Bytes;
|
||||||
|
var AESCryptTool = Packages.me.hatter.tools.commons.security.crypt.AESCryptTool;
|
||||||
|
|
||||||
|
function encrypt(content) {
|
||||||
|
var key = $$.digests().sha256().digest(Bytes.from(__SEED).bytes());
|
||||||
|
var nonce = $$.random().nextIoBytes(12);
|
||||||
|
|
||||||
|
var cipher = AESCryptTool.gcmEncrypt(key.bytes(), nonce.bytes()).from(Bytes.from(content)).toBytes();
|
||||||
|
return 'LOCALENC-V1.' + nonce.asBase64URI() + '.' + cipher.asBase64URI();
|
||||||
|
}
|
||||||
|
|
||||||
|
function decrypt(localEncCiphertext) {
|
||||||
|
localEncCiphertext = $STR(localEncCiphertext);
|
||||||
|
if (localEncCiphertext.indexOf('LOCALENC-V1.') != 0) {
|
||||||
|
throw 'Invalid local encryption ciphertext: ' + localEncCiphertext;
|
||||||
|
}
|
||||||
|
var key = $$.digests().sha256().digest(Bytes.from(__SEED).bytes());
|
||||||
|
|
||||||
|
var ciphertextParts = localEncCiphertext.split('\.');
|
||||||
|
var nonce = Bytes.fromBase64URI(ciphertextParts[1]);
|
||||||
|
var ciphertext = Bytes.fromBase64URI(ciphertextParts[2]);
|
||||||
|
var plaintext = AESCryptTool.gcmDecrypt(key.bytes(), nonce.bytes()).from(ciphertext).toBytes();
|
||||||
|
return $STR(plaintext.string());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof exports == 'object') {
|
||||||
|
exports.encrypt = encrypt;
|
||||||
|
exports.decrypt = decrypt;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user