@aws-cdk/aws-iam
Version:
CDK routines for easily assigning correct and minimal IAM permissions
94 lines • 14.7 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.external = void 0;
const tls = require("tls");
const url = require("url");
// eslint-disable-next-line import/no-extraneous-dependencies
const aws = require("aws-sdk");
let client;
function iam() {
if (!client) {
client = new aws.IAM();
}
return client;
}
function defaultLogger(fmt, ...args) {
// eslint-disable-next-line no-console
console.log(fmt, ...args);
}
/**
* Downloads the CA thumbprint from the issuer URL
*/
async function downloadThumbprint(issuerUrl) {
return new Promise((ok, ko) => {
const purl = url.parse(issuerUrl);
const port = purl.port ? parseInt(purl.port, 10) : 443;
if (!purl.host) {
return ko(new Error(`unable to determine host from issuer url ${issuerUrl}`));
}
exports.external.log(`Fetching x509 certificate chain from issuer ${issuerUrl}`);
const socket = tls.connect(port, purl.host, { rejectUnauthorized: false, servername: purl.host });
socket.once('error', ko);
socket.once('secureConnect', () => {
let cert = socket.getPeerX509Certificate();
if (!cert) {
throw new Error(`Unable to retrieve X509 certificate from host ${purl.host}`);
}
while (cert.issuerCertificate) {
printCertificate(cert);
cert = cert.issuerCertificate;
}
const validTo = new Date(cert.validTo);
const certificateValidity = getCertificateValidity(validTo);
if (certificateValidity < 0) {
return ko(new Error(`The certificate has already expired on: ${validTo.toUTCString()}`));
}
// Warning user if certificate validity is expiring within 6 months
if (certificateValidity < 180) {
/* eslint-disable-next-line no-console */
console.warn(`The root certificate obtained would expire in ${certificateValidity} days!`);
}
socket.end();
const thumbprint = extractThumbprint(cert);
exports.external.log(`Certificate Authority thumbprint for ${issuerUrl} is ${thumbprint}`);
ok(thumbprint);
});
});
}
function extractThumbprint(cert) {
return cert.fingerprint.split(':').join('');
}
function printCertificate(cert) {
exports.external.log('-------------BEGIN CERT----------------');
exports.external.log(`Thumbprint: ${extractThumbprint(cert)}`);
exports.external.log(`Valid To: ${cert.validTo}`);
if (cert.issuerCertificate) {
exports.external.log(`Issuer Thumbprint: ${extractThumbprint(cert.issuerCertificate)}`);
}
exports.external.log(`Issuer: ${cert.issuer}`);
exports.external.log(`Subject: ${cert.subject}`);
exports.external.log('-------------END CERT------------------');
}
/**
* To get the validity timeline for the certificate
* @param certDate The valid to date for the certificate
* @returns The number of days the certificate is valid wrt current date
*/
function getCertificateValidity(certDate) {
const millisecondsInDay = 24 * 60 * 60 * 1000;
const currentDate = new Date();
const validity = Math.round((certDate.getTime() - currentDate.getTime()) / millisecondsInDay);
return validity;
}
// allows unit test to replace with mocks
/* eslint-disable max-len */
exports.external = {
downloadThumbprint,
log: defaultLogger,
createOpenIDConnectProvider: (req) => iam().createOpenIDConnectProvider(req).promise(),
deleteOpenIDConnectProvider: (req) => iam().deleteOpenIDConnectProvider(req).promise(),
updateOpenIDConnectProviderThumbprint: (req) => iam().updateOpenIDConnectProviderThumbprint(req).promise(),
addClientIDToOpenIDConnectProvider: (req) => iam().addClientIDToOpenIDConnectProvider(req).promise(),
removeClientIDFromOpenIDConnectProvider: (req) => iam().removeClientIDFromOpenIDConnectProvider(req).promise(),
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0ZXJuYWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJleHRlcm5hbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFTQSwyQkFBMkI7QUFDM0IsMkJBQTJCO0FBQzNCLDZEQUE2RDtBQUM3RCwrQkFBK0I7QUFFL0IsSUFBSSxNQUFlLENBQUM7QUFFcEIsU0FBUyxHQUFHO0lBQ1YsSUFBSSxDQUFDLE1BQU0sRUFBRTtRQUFFLE1BQU0sR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztLQUFFO0lBQ3hDLE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRCxTQUFTLGFBQWEsQ0FBQyxHQUFXLEVBQUUsR0FBRyxJQUFXO0lBQ2hELHNDQUFzQztJQUN0QyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDO0FBQzVCLENBQUM7QUFFRDs7R0FFRztBQUNILEtBQUssVUFBVSxrQkFBa0IsQ0FBQyxTQUFpQjtJQUVqRCxPQUFPLElBQUksT0FBTyxDQUFTLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFO1FBQ3BDLE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbEMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztRQUV2RCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRTtZQUNkLE9BQU8sRUFBRSxDQUFDLElBQUksS0FBSyxDQUFDLDRDQUE0QyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUM7U0FDL0U7UUFFRCxnQkFBUSxDQUFDLEdBQUcsQ0FBQywrQ0FBK0MsU0FBUyxFQUFFLENBQUMsQ0FBQztRQUV6RSxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksRUFB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R0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxHQUFHLFdBQVcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLGlCQUFpQixDQUFDLENBQUM7SUFFOUYsT0FBTyxRQUFRLENBQUM7QUFDbEIsQ0FBQztBQUVELHlDQUF5QztBQUN6Qyw0QkFBNEI7QUFDZixRQUFBLFFBQVEsR0FBRztJQUN0QixrQkFBa0I7SUFDbEIsR0FBRyxFQUFFLGFBQWE7SUFDbEIsMkJBQTJCLEVBQUUsQ0FBQyxHQUErQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQywyQkFBMkIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUU7SUFDbEksMkJBQTJCLEVBQUUsQ0FBQyxHQUErQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQywyQkFBMkIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUU7SUFDbEkscUNBQXFDLEVBQUUsQ0FBQyxHQUF5RCxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxxQ0FBcUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUU7SUFDaEssa0NBQWtDLEVBQUUsQ0FBQyxHQUFzRCxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxrQ0FBa0MsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUU7SUFDdkosdUNBQXVDLEVBQUUsQ0FBQyxHQUEyRCxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyx1Q0FBdUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUU7Q0FDdkssQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGlzdGFuYnVsIGlnbm9yZSBmaWxlICovXG4vLyB0aGUgWDUwOSBjZXJ0aWZpY2F0ZSBBUEkgaXMgYXZhaWxhYmxlIG9ubHkgaW4gbm9kZTE2LlxuLy8gc2luY2Ugd2UgY29tcGlsZSB0aGUgcmVwbyBhZ2FpbnN0IG5vZGUgMTQsIHR5cGVjaGVja2luZyBpdCB3aWxsIGZhaWwuXG4vLyBpdHMgY3VycmVudGx5IHRvbyBjb21wbGV4IHRvIGNvbmZpZ3VyZSBub2RlMTYgb25seSBvbiB0aGlzXG4vLyBmaWxlIChqc2lpIGRvZXNuJ3Qgc3VwcG9ydCBjdXN0b20gdHNjb25maWcpXG4vLyBzbyB3ZSBkaXNhYmxlIHR5cGVjaGVja2luZy4gZG9uJ3Qgd29ycnksIHdlIGhhdmUgc3VmZmljaWVudCBpbnRlZyB0ZXN0cyB0aGF0XG4vLyB2YWxpZGF0ZSB0aGlzIGNvZGUgZG9lc24ndCBicmVhay5cbi8vIEB0cy1ub2NoZWNrXG5pbXBvcnQgeyBYNTA5Q2VydGlmaWNhdGUgfSBmcm9tICdub2RlOmNyeXB0byc7XG5pbXBvcnQgKiBhcyB0bHMgZnJvbSAndGxzJztcbmltcG9ydCAqIGFzIHVybCBmcm9tICd1cmwnO1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llc1xuaW1wb3J0ICogYXMgYXdzIGZyb20gJ2F3cy1zZGsnO1xuXG5sZXQgY2xpZW50OiBhd3MuSUFNO1xuXG5mdW5jdGlvbiBpYW0oKSB7XG4gIGlmICghY2xpZW50KSB7IGNsaWVudCA9IG5ldyBhd3MuSUFNKCk7IH1cbiAgcmV0dXJuIGNsaWVudDtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdExvZ2dlcihmbXQ6IHN0cmluZywgLi4uYXJnczogYW55W10pIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgY29uc29sZS5sb2coZm10LCAuLi5hcmdzKTtcbn1cblxuLyoqXG4gKiBEb3dubG9hZHMgdGhlIENBIHRodW1icHJpbnQgZnJvbSB0aGUgaXNzdWVyIFVSTFxuICovXG5hc3luYyBmdW5jdGlvbiBkb3dubG9hZFRodW1icHJpbnQoaXNzdWVyVXJsOiBzdHJpbmcpIHtcblxuICByZXR1cm4gbmV3IFByb21pc2U8c3RyaW5nPigob2ssIGtvKSA9PiB7XG4gICAgY29uc3QgcHVybCA9IHVybC5wYXJzZShpc3N1ZXJVcmwpO1xuICAgIGNvbnN0IHBvcnQgPSBwdXJsLnBvcnQgPyBwYXJzZUludChwdXJsLnBvcnQsIDEwKSA6IDQ0MztcblxuICAgIGlmICghcHVybC5ob3N0KSB7XG4gICAgICByZXR1cm4ga28obmV3IEVycm9yKGB1bmFibGUgdG8gZGV0ZXJtaW5lIGhvc3QgZnJvbSBpc3N1ZXIgdXJsICR7aXNzdWVyVXJsfWApKTtcbiAgICB9XG5cbiAgICBleHRlcm5hbC5sb2coYEZldGNoaW5nIHg1MDkgY2VydGlmaWNhdGUgY2hhaW4gZnJvbSBpc3N1ZXIgJHtpc3N1ZXJVcmx9YCk7XG5cbiAgICBjb25zdCBzb2NrZXQgPSB0bHMuY29ubmVjdChwb3J0LCBwdXJsLmhvc3QsIHsgcmVqZWN0VW5hdXRob3JpemVkOiBmYWxzZSwgc2VydmVybmFtZTogcHVybC5ob3N0IH0pO1xuICAgIHNvY2tldC5vbmNlKCdlcnJvcicsIGtvKTtcblxuICAgIHNvY2tldC5vbmNlKCdzZWN1cmVDb25uZWN0JywgKCkgPT4ge1xuICAgICAgbGV0IGNlcnQgPSBzb2NrZXQuZ2V0UGVlclg1MDlDZXJ0aWZpY2F0ZSgpO1xuICAgICAgaWYgKCFjZXJ0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIHJldHJpZXZlIFg1MDkgY2VydGlmaWNhdGUgZnJvbSBob3N0ICR7cHVybC5ob3N0fWApO1xuICAgICAgfVxuICAgICAgd2hpbGUgKGNlcnQuaXNzdWVyQ2VydGlmaWNhdGUpIHtcbiAgICAgICAgcHJpbnRDZXJ0aWZpY2F0ZShjZXJ0KTtcbiAgICAgICAgY2VydCA9IGNlcnQuaXNzdWVyQ2VydGlmaWNhdGU7XG4gICAgICB9XG4gICAgICBjb25zdCB2YWxpZFRvID0gbmV3IERhdGUoY2VydC52YWxpZFRvKTtcbiAgICAgIGNvbnN0IGNlcnRpZmljYXRlVmFsaWRpdHkgPSBnZXRDZXJ0aWZpY2F0ZVZhbGlkaXR5KHZhbGlkVG8pO1xuXG4gICAgICBpZiAoY2VydGlmaWNhdGVWYWxpZGl0eSA8IDApIHtcbiAgICAgICAgcmV0dXJuIGtvKG5ldyBFcnJvcihgVGhlIGNlcnRpZmljYXRlIGhhcyBhbHJlYWR5IGV4cGlyZWQgb246ICR7dmFsaWRUby50b1VUQ1N0cmluZygpfWApKTtcbiAgICAgIH1cblxuICAgICAgLy8gV2FybmluZyB1c2VyIGlmIGNlcnRpZmljYXRlIHZhbGlkaXR5IGlzIGV4cGlyaW5nIHdpdGhpbiA2IG1vbnRoc1xuICAgICAgaWYgKGNlcnRpZmljYXRlVmFsaWRpdHkgPCAxODApIHtcbiAgICAgICAgLyogZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGUgKi9cbiAgICAgICAgY29uc29sZS53YXJuKGBUaGUgcm9vdCBjZXJ0aWZpY2F0ZSBvYnRhaW5lZCB3b3VsZCBleHBpcmUgaW4gJHtjZXJ0aWZpY2F0ZVZhbGlkaXR5fSBkYXlzIWApO1xuICAgICAgfVxuXG4gICAgICBzb2NrZXQuZW5kKCk7XG5cbiAgICAgIGNvbnN0IHRodW1icHJpbnQgPSBleHRyYWN0VGh1bWJwcmludChjZXJ0KTtcbiAgICAgIGV4dGVybmFsLmxvZyhgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IHRodW1icHJpbnQgZm9yICR7aXNzdWVyVXJsfSBpcyAke3RodW1icHJpbnR9YCk7XG5cbiAgICAgIG9rKHRodW1icHJpbnQpO1xuICAgIH0pO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gZXh0cmFjdFRodW1icHJpbnQoY2VydDogWDUwOUNlcnRpZmljYXRlKSB7XG4gIHJldHVybiBjZXJ0LmZpbmdlcnByaW50LnNwbGl0KCc6Jykuam9pbignJyk7XG59XG5cbmZ1bmN0aW9uIHByaW50Q2VydGlmaWNhdGUoY2VydDogWDUwOUNlcnRpZmljYXRlKSB7XG4gIGV4dGVybmFsLmxvZygnLS0tLS0tLS0tLS0tLUJFR0lOIENFUlQtLS0tLS0tLS0tLS0tLS0tJyk7XG4gIGV4dGVybmFsLmxvZyhgVGh1bWJwcmludDogJHtleHRyYWN0VGh1bWJwcmludChjZXJ0KX1gKTtcbiAgZXh0ZXJuYWwubG9nKGBWYWxpZCBUbzogJHtjZXJ0LnZhbGlkVG99YCk7XG4gIGlmIChjZXJ0Lmlzc3VlckNlcnRpZmljYXRlKSB7XG4gICAgZXh0ZXJuYWwubG9nKGBJc3N1ZXIgVGh1bWJwcmludDogJHtleHRyYWN0VGh1bWJwcmludChjZXJ0Lmlzc3VlckNlcnRpZmljYXRlKX1gKTtcbiAgfVxuICBleHRlcm5hbC5sb2coYElzc3VlcjogJHtjZXJ0Lmlzc3Vlcn1gKTtcbiAgZXh0ZXJuYWwubG9nKGBTdWJqZWN0OiAke2NlcnQuc3ViamVjdH1gKTtcbiAgZXh0ZXJuYWwubG9nKCctLS0tLS0tLS0tLS0tRU5EIENFUlQtLS0tLS0tLS0tLS0tLS0tLS0nKTtcbn1cblxuLyoqXG4gKiBUbyBnZXQgdGhlIHZhbGlkaXR5IHRpbWVsaW5lIGZvciB0aGUgY2VydGlmaWNhdGVcbiAqIEBwYXJhbSBjZXJ0RGF0ZSBUaGUgdmFsaWQgdG8gZGF0ZSBmb3IgdGhlIGNlcnRpZmljYXRlXG4gKiBAcmV0dXJucyBUaGUgbnVtYmVyIG9mIGRheXMgdGhlIGNlcnRpZmljYXRlIGlzIHZhbGlkIHdydCBjdXJyZW50IGRhdGVcbiAqL1xuZnVuY3Rpb24gZ2V0Q2VydGlmaWNhdGVWYWxpZGl0eShjZXJ0RGF0ZTogRGF0ZSk6IE51bWJlciB7XG4gIGNvbnN0IG1pbGxpc2Vjb25kc0luRGF5ID0gMjQgKiA2MCAqIDYwICogMTAwMDtcbiAgY29uc3QgY3VycmVudERhdGUgPSBuZXcgRGF0ZSgpO1xuXG4gIGNvbnN0IHZhbGlkaXR5ID0gTWF0aC5yb3VuZCgoY2VydERhdGUuZ2V0VGltZSgpIC0gY3VycmVudERhdGUuZ2V0VGltZSgpKSAvIG1pbGxpc2Vjb25kc0luRGF5KTtcblxuICByZXR1cm4gdmFsaWRpdHk7XG59XG5cbi8vIGFsbG93cyB1bml0IHRlc3QgdG8gcmVwbGFjZSB3aXRoIG1vY2tzXG4vKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG5leHBvcnQgY29uc3QgZXh0ZXJuYWwgPSB7XG4gIGRvd25sb2FkVGh1bWJwcmludCxcbiAgbG9nOiBkZWZhdWx0TG9nZ2VyLFxuICBjcmVhdGVPcGVuSURDb25uZWN0UHJvdmlkZXI6IChyZXE6IGF3cy5JQU0uQ3JlYXRlT3BlbklEQ29ubmVjdFByb3ZpZGVyUmVxdWVzdCkgPT4gaWFtKCkuY3JlYXRlT3BlbklEQ29ubmVjdFByb3ZpZGVyKHJlcSkucHJvbWlzZSgpLFxuICBkZWxldGVPcGVuSURDb25uZWN0UHJvdmlkZXI6IChyZXE6IGF3cy5JQU0uRGVsZXRlT3BlbklEQ29ubmVjdFByb3ZpZGVyUmVxdWVzdCkgPT4gaWFtKCkuZGVsZXRlT3BlbklEQ29ubmVjdFByb3ZpZGVyKHJlcSkucHJvbWlzZSgpLFxuICB1cGRhdGVPcGVuSURDb25uZWN0UHJvdmlkZXJUaHVtYnByaW50OiAocmVxOiBhd3MuSUFNLlVwZGF0ZU9wZW5JRENvbm5lY3RQcm92aWRlclRodW1icHJpbnRSZXF1ZXN0KSA9PiBpYW0oKS51cGRhdGVPcGVuSURDb25uZWN0UHJvdmlkZXJUaHVtYnByaW50KHJlcSkucHJvbWlzZSgpLFxuICBhZGRDbGllbnRJRFRvT3BlbklEQ29ubmVjdFByb3ZpZGVyOiAocmVxOiBhd3MuSUFNLkFkZENsaWVudElEVG9PcGVuSURDb25uZWN0UHJvdmlkZXJSZXF1ZXN0KSA9PiBpYW0oKS5hZGRDbGllbnRJRFRvT3BlbklEQ29ubmVjdFByb3ZpZGVyKHJlcSkucHJvbWlzZSgpLFxuICByZW1vdmVDbGllbnRJREZyb21PcGVuSURDb25uZWN0UHJvdmlkZXI6IChyZXE6IGF3cy5JQU0uUmVtb3ZlQ2xpZW50SURGcm9tT3BlbklEQ29ubmVjdFByb3ZpZGVyUmVxdWVzdCkgPT4gaWFtKCkucmVtb3ZlQ2xpZW50SURGcm9tT3BlbklEQ29ubmVjdFByb3ZpZGVyKHJlcSkucHJvbWlzZSgpLFxufTsiXX0=
;