function fixEncryptedItemEncoding()

in upgrades.js [117:231]


function fixEncryptedItemEncoding(err, s3Info, configPre, forwardCallback) {
    var willDoUpgrade = false;

    // convert the encrypted items from the previous native storage format to
    // base64 encoding
    loadClusters = [];

    var newMasterSymmetricKey;
    var newSecretKeyForS3;
    var updateExpressions = [];
    var expressionAttributeValues = {
        ":updateTime": {
            S: common.getFormattedDate()
        },
        ":version": {
            S: pjson.version
        }
    };

    if (configPre.masterSymmetricKey && configPre.masterSymmetricKey.S.indexOf('[') > -1) {
        willDoUpgrade = true;
        newMasterSymmetricKey = Buffer.from(JSON.parse(configPre.masterSymmetricKey.S)).toString('base64');
        updateExpressions.push("masterSymmetricKey = :masterSymmetricKey");
        expressionAttributeValues[":masterSymmetricKey"] = {
            S: newMasterSymmetricKey
        };
    }
    if (configPre.secretKeyForS3 && configPre.secretKeyForS3.S.indexOf('[') > -1) {
        willDoUpgrade = true;
        newSecretKeyForS3 = Buffer.from(JSON.parse(configPre.secretKeyForS3.S)).toString('base64');
        updateExpressions.push("secretKeyForS3 = :s3secretAccessKey");
        expressionAttributeValues[":s3secretAccessKey"] = {
            S: newSecretKeyForS3
        };
    }

    // upgrade each cluster entry's password for redshift
    if (configPre && configPre.loadClusters && configPre.loadClusters.L) {
        configPre.loadClusters.L.map(function (item) {
            if (item.M.connectPassword.S.indexOf('[') > -1) {
                willDoUpgrade = true;
                item.M.connectPassword.S = Buffer.from(JSON.parse(item.M.connectPassword.S)).toString('base64');
            }

            loadClusters.push(item);
        });
    }

    if (loadClusters.length > 0) {
        expressionAttributeValues[":newLoadClusters"] = {
            L: loadClusters
        };
    }

    if (willDoUpgrade) {
        var updateRequest = {
            Key: {
                s3Prefix: {
                    S: s3Info.prefix
                }
            },
            TableName: configTable,
            UpdateExpression: "SET #loadClusters = :newLoadClusters, lastUpdate = :updateTime, #ver = :version "
                + (updateExpressions.length > 0 ? "," + updateExpressions.join(',') : ""),
            ExpressionAttributeValues: expressionAttributeValues,
            ExpressionAttributeNames: {
                "#ver": 'version',
                "#loadClusters": 'loadClusters'
            },
            /*
             * current can't be the target version, or someone else has done an
             * upgrade
             */
            ConditionExpression: " #ver <> :version",
            // add the ALL_NEW return values so we have the
            // get the config after update
            ReturnValues: "ALL_NEW"
        };

        logger.info("Upgrading to 2.4.x Base64 encoded encryption values");
        logger.debug(JSON.stringify(updateRequest));

        dynamoClient.updateItem(updateRequest, function (err, data) {
            if (err) {
                if (err.code === conditionCheckFailed) {
                    // no problem - configuration was upgraded by someone else
                    // while we were running - requery and return
                    var dynamoLookup = {
                        Key: {
                            s3Prefix: {
                                S: s3Info.prefix
                            }
                        },
                        TableName: configTable,
                        ConsistentRead: true
                    };

                    dynamoClient.getItem(dynamoLookup, function (err, data) {
                        forwardCallback(null, s3Info, data.Item);
                    });
                } else {
                    // unknown error - return the original configuration with
                    // the error
                    forwardCallback(err, s3Info, configPre);
                }
            } else {
                // update was OK - go ahead with the new item returned by the
                // upgrade call
                forwardCallback(null, s3Info, data.Attributes);
            }
        });
    } else {
        forwardCallback(null, s3Info, configPre)
    }
}