Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions lib/storage/bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -942,10 +942,10 @@ Bucket.prototype.makePublic = function(options, callback) {
* will be uploaded to the File object's bucket and under the File object's
* name. Lastly, when this argument is omitted, the file is uploaded to your
* bucket using the name of the local file.
* @param {string} options.encryptionKey - A custom encryption key. See
* [Customer-supplied Encryption Keys](https://cloud.google.com/storage/docs/encryption#customer-supplied).
* @param {boolean} options.gzip - Automatically gzip the file. This will set
* `options.metadata.contentEncoding` to `gzip`.
* @param {string} options.key - A custom encryption key. See
* [Customer-supplied Encryption Keys](https://cloud.google.com/storage/docs/encryption#customer-supplied).
* @param {object} options.metadata - See an
* [Objects: insert request body](https://cloud.google.com/storage/docs/json_api/v1/objects/insert#request_properties_JSON).
* @param {string} options.offset - The starting byte of the upload stream, for
Expand Down Expand Up @@ -1050,14 +1050,15 @@ Bucket.prototype.makePublic = function(options, callback) {
* });
*
* //-
* // To use [Customer-supplied Encryption Keys](https://cloud.google.com/storage/docs/encryption#customer-supplied),
* // provide the `key` option.
* // To use
* // <a href="https://cloud.google.com/storage/docs/encryption#customer-supplied">
* // Customer-supplied Encryption Keys</a>, provide the `encryptionKey` option.
* //-
* var crypto = require('crypto');
* var encryptionKey = crypto.randomBytes(32);
*
* bucket.upload('img.png', {
* key: encryptionKey
* encryptionKey: encryptionKey
* }, function(err, newFile) {
* // `img.png` was uploaded with your custom encryption key.
*
Expand All @@ -1067,12 +1068,12 @@ Bucket.prototype.makePublic = function(options, callback) {
* // However, to use your encryption key later, you must create a `File`
* // instance with the `key` supplied:
* var file = bucket.file('img.png', {
* key: encryptionKey
* encryptionKey: encryptionKey
* });
*
* // Or with `file#setKey`:
* // Or with `file#setEncryptionKey`:
* var file = bucket.file('img.png');
* file.setKey(encryptionKey);
* file.setEncryptionKey(encryptionKey);
* });
*/
Bucket.prototype.upload = function(localPath, options, callback) {
Expand All @@ -1091,12 +1092,12 @@ Bucket.prototype.upload = function(localPath, options, callback) {
} else if (is.string(options.destination)) {
// Use the string as the name of the file.
newFile = this.file(options.destination, {
key: options.key
encryptionKey: options.encryptionKey
});
} else {
// Resort to using the name of the incoming file.
newFile = this.file(path.basename(localPath), {
key: options.key
encryptionKey: options.encryptionKey
});
}

Expand Down
31 changes: 16 additions & 15 deletions lib/storage/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ var STORAGE_UPLOAD_BASE_URL = 'https://www.googleapis.com/upload/storage/v1/b';
* attached to.
* @param {string} name - The name of the remote file.
* @param {object=} options - Configuration object.
* @param {string} options.encryptionKey - A custom encryption key.
* @param {number} options.generation - Generation to scope the file to.
* @param {string} options.key - A custom encryption key.
*/
/**
* A File object is created from your Bucket object using
Expand Down Expand Up @@ -242,8 +242,8 @@ function File(bucket, name, options) {
methods: methods
});

if (options.key) {
this.setKey(options.key);
if (options.encryptionKey) {
this.setEncryptionKey(options.encryptionKey);
}

/**
Expand Down Expand Up @@ -997,47 +997,48 @@ File.prototype.download = function(options, callback) {

/**
* The Storage API allows you to use a custom key for server-side encryption.
* Supply this method with a passphrase and the correct key (AES-256) will be
* generated and used for you.
*
* @resource [Customer-supplied Encryption Keys]{@link https://cloud.google.com/storage/docs/encryption#customer-supplied}
*
* @param {string|buffer} key - An AES-256 encryption key.
* @param {string|buffer} encryptionKey - An AES-256 encryption key.
* @return {module:storage/file}
*
* @example
* var crypto = require('crypto');
* var encryptionKey = crypto.randomBytes(32);
*
* var fileWithCustomEncryption = myBucket.file('my-file');
* fileWithCustomEncryption.setKey(encryptionKey);
* fileWithCustomEncryption.setEncryptionKey(encryptionKey);
*
* var fileWithoutCustomEncryption = myBucket.file('my-file');
*
* fileWithCustomEncryption.save('data', function(err) {
* // Try to download with the File object that hasn't had `setKey()` called:
* // Try to download with the File object that hasn't had
* // `setEncryptionKey()` called:
* fileWithoutCustomEncryption.download(function(err) {
* // We will receive an error:
* // err.message === 'Bad Request'
*
* // Try again with the File object we called `setKey()` on:
* // Try again with the File object we called `setEncryptionKey()` on:
* fileWithCustomEncryption.download(function(err, contents) {
* // contents.toString() === 'data'
* });
* });
* });
*/
File.prototype.setKey = function(key) {
this.key = key;
File.prototype.setEncryptionKey = function(encryptionKey) {
this.encryptionKey = encryptionKey;

key = new Buffer(key).toString('base64');
var hash = crypto.createHash('sha256').update(key, 'base64').digest('base64');
encryptionKey = new Buffer(encryptionKey).toString('base64');
var hash = crypto.createHash('sha256')
.update(encryptionKey, 'base64')
.digest('base64');

this.interceptors.push({
request: function(reqOpts) {
reqOpts.headers = reqOpts.headers || {};
reqOpts.headers['x-goog-encryption-algorithm'] = 'AES256';
reqOpts.headers['x-goog-encryption-key'] = key;
reqOpts.headers['x-goog-encryption-key'] = encryptionKey;
reqOpts.headers['x-goog-encryption-key-sha256'] = hash;
return reqOpts;
}
Expand Down Expand Up @@ -1613,7 +1614,7 @@ File.prototype.startResumableUpload_ = function(dup, options) {
bucket: this.bucket.name,
file: this.name,
generation: this.generation,
key: this.key,
key: this.encryptionKey,
metadata: options.metadata,
offset: options.offset,
predefinedAcl: options.predefinedAcl,
Expand Down
8 changes: 5 additions & 3 deletions system-test/storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ describe('storage', function() {
var key = crypto.randomBytes(32);

bucket.upload(FILES.big.path, {
key: key,
encryptionKey: key,
resumable: false
}, function(err, file) {
assert.ifError(err);
Expand All @@ -403,7 +403,7 @@ describe('storage', function() {
var key = crypto.randomBytes(32);

bucket.upload(FILES.big.path, {
key: key,
encryptionKey: key,
resumable: true
}, function(err, file) {
assert.ifError(err);
Expand Down Expand Up @@ -802,7 +802,9 @@ describe('storage', function() {
describe('customer-supplied encryption keys', function() {
var encryptionKey = crypto.randomBytes(32);

var file = bucket.file('encrypted-file', { key: encryptionKey });
var file = bucket.file('encrypted-file', {
encryptionKey: encryptionKey
});
var unencryptedFile = bucket.file(file.name);

before(function(done) {
Expand Down
12 changes: 6 additions & 6 deletions test/storage/bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -911,13 +911,13 @@ describe('Bucket', function() {
it('should accept a path, metadata, & cb', function(done) {
var options = {
metadata: metadata,
key: 'key'
encryptionKey: 'key'
};
bucket.upload(filepath, options, function(err, file) {
assert.ifError(err);
assert.equal(file.bucket.name, bucket.name);
assert.deepEqual(file.metadata, metadata);
assert.strictEqual(file.options.key, options.key);
assert.strictEqual(file.options.encryptionKey, options.encryptionKey);
done();
});
});
Expand All @@ -926,13 +926,13 @@ describe('Bucket', function() {
var newFileName = 'new-file-name.png';
var options = {
destination: newFileName,
key: 'key'
encryptionKey: 'key'
};
bucket.upload(filepath, options, function(err, file) {
assert.ifError(err);
assert.equal(file.bucket.name, bucket.name);
assert.equal(file.name, newFileName);
assert.strictEqual(file.options.key, options.key);
assert.strictEqual(file.options.encryptionKey, options.encryptionKey);
done();
});
});
Expand All @@ -942,14 +942,14 @@ describe('Bucket', function() {
var options = {
destination: newFileName,
metadata: metadata,
key: 'key'
encryptionKey: 'key'
};
bucket.upload(filepath, options, function(err, file) {
assert.ifError(err);
assert.equal(file.bucket.name, bucket.name);
assert.equal(file.name, newFileName);
assert.deepEqual(file.metadata, metadata);
assert.strictEqual(file.options.key, options.key);
assert.strictEqual(file.options.encryptionKey, options.encryptionKey);
done();
});
});
Expand Down
18 changes: 9 additions & 9 deletions test/storage/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,14 +228,14 @@ describe('File', function() {
it('should set a custom encryption key', function(done) {
var key = 'key';

var setKey = File.prototype.setKey;
File.prototype.setKey = function(key_) {
File.prototype.setKey = setKey;
var setEncryptionKey = File.prototype.setEncryptionKey;
File.prototype.setEncryptionKey = function(key_) {
File.prototype.setEncryptionKey = setEncryptionKey;
assert.strictEqual(key_, key);
done();
};

new File(BUCKET, FILE_NAME, { key: key });
new File(BUCKET, FILE_NAME, { encryptionKey: key });
});
});

Expand Down Expand Up @@ -2191,15 +2191,15 @@ describe('File', function() {
});
});

describe('setKey', function() {
describe('setEncryptionKey', function() {
var KEY = crypto.randomBytes(32);

beforeEach(function() {
file.setKey(KEY);
file.setEncryptionKey(KEY);
});

it('should localize the key', function() {
assert.strictEqual(file.key, KEY);
assert.strictEqual(file.encryptionKey, KEY);
});

it('should push the correct request interceptor', function(done) {
Expand Down Expand Up @@ -2232,7 +2232,7 @@ describe('File', function() {
};

file.generation = 3;
file.key = 'key';
file.encryptionKey = 'key';

resumableUploadOverride = function(opts) {
var bucket = file.bucket;
Expand All @@ -2243,7 +2243,7 @@ describe('File', function() {
assert.strictEqual(opts.bucket, bucket.name);
assert.strictEqual(opts.file, file.name);
assert.strictEqual(opts.generation, file.generation);
assert.strictEqual(opts.key, file.key);
assert.strictEqual(opts.key, file.encryptionKey);
assert.strictEqual(opts.metadata, options.metadata);
assert.strictEqual(opts.offset, options.offset);
assert.strictEqual(opts.predefinedAcl, options.predefinedAcl);
Expand Down