Skip to content

Commit

Permalink
storage: getSigned*: clear up expiration format
Browse files Browse the repository at this point in the history
  • Loading branch information
stephenplusplus committed Aug 31, 2015
1 parent dc4fed8 commit 432777e
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 68 deletions.
43 changes: 25 additions & 18 deletions lib/storage/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -902,14 +902,14 @@ File.prototype.getMetadata = function(callback) {
* members.
*
* @param {object} options - Configuration object.
* @param {object} options.expiration - Timestamp (seconds since epoch) when
* this policy will expire.
* @param {array|array[]=} options.equals - Array of request parameters and
* their expected value (e.g. [['$<field>', '<value>']]). Values are
* translated into equality constraints in the conditions field of the
* policy document (e.g. ['eq', '$<field>', '<value>']). If only one
* equality condition is to be specified, options.equals can be a one-
* dimensional array (e.g. ['$<field>', '<value>']).
* @param {*} options.expires - A timestamp when this policy will expire. Any
* value given is passed to `new Date()`.
* @param {array|array[]=} options.startsWith - Array of request parameters and
* their expected prefixes (e.g. [['$<field>', '<value>']). Values are
* translated into starts-with constraints in the conditions field of the
Expand All @@ -932,22 +932,28 @@ File.prototype.getMetadata = function(callback) {
* @param {object} callback.policy - The document policy.
*
* @example
* file.getSignedPolicy({
* var options = {
* equals: ['$Content-Type', 'image/jpeg'],
* contentLengthRange: { min: 0, max: 1024 },
* expiration: Math.round(Date.now() / 1000) + (60 * 60 * 24 * 14) // 2 weeks.
* }, function(err, policy) {
* expires: '10-25-2022',
* contentLengthRange: {
* min: 0,
* max: 1024
* }
* };
*
* file.getSignedPolicy(options, function(err, policy) {
* // policy.string: the policy document in plain text.
* // policy.base64: the policy document in base64.
* // policy.signature: the policy signature in base64.
* });
*/
File.prototype.getSignedPolicy = function(options, callback) {
if (options.expiration < Math.floor(Date.now() / 1000)) {
var expires = new Date(options.expires);

if (expires < Date.now()) {
throw new Error('An expiration date cannot be in the past.');
}

var expirationString = new Date(options.expiration).toISOString();
var conditions = [
['eq', '$key', this.name],
{
Expand Down Expand Up @@ -1007,7 +1013,7 @@ File.prototype.getSignedPolicy = function(options, callback) {
}

var policy = {
expiration: expirationString,
expiration: expires.toISOString(),
conditions: conditions
};

Expand Down Expand Up @@ -1049,8 +1055,8 @@ File.prototype.getSignedPolicy = function(options, callback) {
* value in its request.
* @param {string=} options.contentType - If you provide this value, the client
* must provide this HTTP header set to the same value.
* @param {number} options.expires - Timestamp (seconds since epoch) when this
* link will expire.
* @param {*} options.expires - A timestamp when this link will expire. Any
* value given is passed to `new Date()`.
* @param {string=} options.extensionHeaders - If these headers are used, the
* server will check to make sure that the client provides matching values.
* @param {string=} options.promptSaveAs - The filename to prompt the user to
Expand All @@ -1066,16 +1072,14 @@ File.prototype.getSignedPolicy = function(options, callback) {
* @param {string} callback.url - The signed URL.
*
* @example
* var TWO_WEEKS_MS = Math.round(Date.now() / 1000) + (60 * 60 * 24 * 14);
*
* //-
* // Generate a URL that allows temporary access to download your file.
* //-
* var request = require('request');
*
* file.getSignedUrl({
* action: 'read',
* expires: TWO_WEEKS_MS
* expires: '03-17-2025'
* }, function(err, url) {
* if (err) {
* console.error(err);
Expand All @@ -1094,7 +1098,7 @@ File.prototype.getSignedPolicy = function(options, callback) {
* //-
* file.getSignedUrl({
* action: 'write',
* expires: TWO_WEEKS_MS
* expires: '03-17-2025'
* }, function(err, url) {
* if (err) {
* console.error(err);
Expand All @@ -1115,7 +1119,10 @@ File.prototype.getSignedPolicy = function(options, callback) {
* });
*/
File.prototype.getSignedUrl = function(options, callback) {
if (options.expires < Math.floor(Date.now() / 1000)) {
var expires = new Date(options.expires);
var expiresInSeconds = Math.round(expires / 1000); // The API expects seconds.

if (expires < Date.now()) {
throw new Error('An expiration date cannot be in the past.');
}

Expand All @@ -1142,7 +1149,7 @@ File.prototype.getSignedUrl = function(options, callback) {
options.action,
(options.contentMd5 || ''),
(options.contentType || ''),
options.expires,
expiresInSeconds,
(options.extensionHeaders || '') + options.resource
].join('\n'));
var signature = sign.sign(credentials.private_key, 'base64');
Expand All @@ -1169,7 +1176,7 @@ File.prototype.getSignedUrl = function(options, callback) {
callback(null, [
'https://storage.googleapis.com' + options.resource,
'?GoogleAccessId=' + credentials.client_email,
'&Expires=' + options.expires,
'&Expires=' + expiresInSeconds,
'&Signature=' + encodeURIComponent(signature),
responseContentType,
responseContentDisposition
Expand Down
50 changes: 48 additions & 2 deletions system-test/storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,7 @@ describe('storage', function() {
it('should create a signed read url', function(done) {
file.getSignedUrl({
action: 'read',
expires: Math.round(Date.now() / 1000) + 5
expires: Date.now() + 5,
}, function(err, signedReadUrl) {
assert.ifError(err);
request.get(signedReadUrl, function(err, resp, body) {
Expand All @@ -907,7 +907,7 @@ describe('storage', function() {
it('should create a signed delete url', function(done) {
file.getSignedUrl({
action: 'delete',
expires: Math.round(Date.now() / 1000) + 283473274
expires: Date.now() + 5,
}, function(err, signedDeleteUrl) {
assert.ifError(err);
request.del(signedDeleteUrl, function() {
Expand All @@ -919,4 +919,50 @@ describe('storage', function() {
});
});
});

describe('sign policy', function() {
var file;

before(function(done) {
file = bucket.file('LogoToSign.jpg');
fs.createReadStream(files.logo.path)
.pipe(file.createWriteStream())
.on('error', done)
.on('finish', done.bind(null, null));
});

after(function(done) {
file.delete(done);
});

it('should create a policy', function(done) {
var expires = new Date('10-25-2022');
var expectedExpiration = new Date(expires).toISOString();

var options = {
equals: ['$Content-Type', 'image/jpeg'],
expires: expires,
contentLengthRange: {
min: 0,
max: 1024
}
};

file.getSignedPolicy(options, function(err, policy) {
assert.ifError(err);

var policyJson;

try {
policyJson = JSON.parse(policy.string);
} catch (e) {
done(e);
return;
}

assert.strictEqual(policyJson.expiration, expectedExpiration);
done();
});
});
});
});
Loading

0 comments on commit 432777e

Please sign in to comment.