680: BlobService.getBlobUrl puts permissions in sas url even if parameter sharedAccessPolicy.Permission is left empty

This commit is contained in:
Andre Rodrigues 2013-04-30 16:03:10 +01:00
Родитель 1fbe3bc18a
Коммит ce1a03f193
8 изменённых файлов: 1347 добавлений и 1174 удалений

Просмотреть файл

@ -596,7 +596,7 @@ BlobService.prototype.getContainerAcl = function (container, optionsOrCallback,
if (!responseObject.error) {
responseObject.containerResult = new ContainerResult(container);
responseObject.containerResult.getPropertiesFromHeaders(responseObject.response.headers);
responseObject.containerResult.signedIdentifiers = ContainerAclResult.parse(responseObject.response.body.SignedIdentifiers.SignedIdentifier);
responseObject.containerResult.signedIdentifiers = ContainerAclResult.parse(responseObject.response.body);
}
var finalCallback = function (returnObject) {
@ -642,11 +642,17 @@ BlobService.prototype.setContainerAcl = function (container, publicAccessLevel,
var policies = null;
if (options && options.signedIdentifiers) {
if (!_.isArray(options.signedIdentifiers)) {
throw new Error('Signed identifiers need to be an array');
}
policies = ContainerAclResult.serialize(options.signedIdentifiers);
}
webResource.addOptionalHeader(HeaderConstants.CONTENT_LENGTH, !azureutil.objectIsNull(policies) ? Buffer.byteLength(policies) : 0);
if (publicAccessLevel) {
webResource.addOptionalHeader(HeaderConstants.BLOB_PUBLIC_ACCESS_HEADER, publicAccessLevel);
}
var processResponseCallback = function (responseObject, next) {
responseObject.containerResult = null;
@ -2311,10 +2317,7 @@ BlobService.prototype.generateSharedAccessSignature = function (container, blob,
resourceType = BlobConstants.ResourceTypes.BLOB;
}
if (azureutil.objectIsNull(sharedAccessPolicy.AccessPolicy.Permissions)) {
sharedAccessPolicy.AccessPolicy.Permissions = BlobConstants.SharedAccessPermissions.READ;
}
if (sharedAccessPolicy.AccessPolicy) {
if (!azureutil.objectIsNull(sharedAccessPolicy.AccessPolicy.Start)) {
if (!_.isDate(sharedAccessPolicy.AccessPolicy.Start)) {
sharedAccessPolicy.AccessPolicy.Start = new Date(sharedAccessPolicy.AccessPolicy.Start);
@ -2330,6 +2333,7 @@ BlobService.prototype.generateSharedAccessSignature = function (container, blob,
sharedAccessPolicy.AccessPolicy.Expiry = azureutil.truncatedISO8061Date(sharedAccessPolicy.AccessPolicy.Expiry);
}
}
var resourceName = createResourceName(container, blob);
var signedQueryString = this.sharedAccessSignatureCredentials.generateSignedQueryString(resourceName, {}, resourceType, sharedAccessPolicy);

Просмотреть файл

@ -52,13 +52,21 @@ function SharedAccessSignature(storageAccount, storageAccessKey, permissionSet)
* @return {object} The shared access signature query string.
*/
SharedAccessSignature.prototype.generateSignedQueryString = function (path, queryString, resourceType, sharedAccessPolicy) {
if (sharedAccessPolicy.AccessPolicy) {
if (sharedAccessPolicy.AccessPolicy.Start) {
queryString[QueryStringConstants.SIGNED_START] = sharedAccessPolicy.AccessPolicy.Start;
}
if (sharedAccessPolicy.AccessPolicy.Expiry) {
queryString[QueryStringConstants.SIGNED_EXPIRY] = sharedAccessPolicy.AccessPolicy.Expiry;
queryString[QueryStringConstants.SIGNED_RESOURCE] = resourceType;
}
if (sharedAccessPolicy.AccessPolicy.Permissions) {
queryString[QueryStringConstants.SIGNED_PERMISSIONS] = sharedAccessPolicy.AccessPolicy.Permissions;
}
}
queryString[QueryStringConstants.SIGNED_RESOURCE] = resourceType;
if (sharedAccessPolicy.Id) {
queryString[QueryStringConstants.SIGNED_IDENTIFIER] = sharedAccessPolicy.Id;
@ -138,9 +146,9 @@ SharedAccessSignature.prototype._generateSignature = function (path, resourceTyp
var canonicalizedResource = '/' + this.storageAccount + path;
var stringToSign =
getvalueToAppend(sharedAccessPolicy.AccessPolicy.Permissions) +
getvalueToAppend(sharedAccessPolicy.AccessPolicy.Start) +
getvalueToAppend(sharedAccessPolicy.AccessPolicy.Expiry) +
getvalueToAppend(sharedAccessPolicy.AccessPolicy ? sharedAccessPolicy.AccessPolicy.Permissions : '') +
getvalueToAppend(sharedAccessPolicy.AccessPolicy ? sharedAccessPolicy.AccessPolicy.Start : '') +
getvalueToAppend(sharedAccessPolicy.AccessPolicy ? sharedAccessPolicy.AccessPolicy.Expiry : '') +
getvalueToAppend(canonicalizedResource) +
getvalueToAppend(sharedAccessPolicy.Id, true);

Просмотреть файл

@ -17,6 +17,7 @@
var _ = require('underscore');
var xmlbuilder = require('xmlbuilder');
var azureutil = require('../../../util/util');
var Constants = require('../../../util/constants');
var ISO8061Date = require('../../../util/iso8061date');
@ -92,7 +93,12 @@ ContainerAclResult.serialize = function (signedIdentifiersJs) {
ContainerAclResult.parse = function (signedIdentifiersXml) {
var signedIdentifiers = [];
signedIdentifiersXml = azureutil.tryGetValueChain(signedIdentifiersXml, [ 'SignedIdentifiers', 'SignedIdentifier' ]);
if (signedIdentifiersXml) {
if (!_.isArray(signedIdentifiersXml)) {
signedIdentifiersXml = [ signedIdentifiersXml ];
}
signedIdentifiersXml.forEach(function (signedIdentifier) {
var si = {};
si.Id = signedIdentifier.Id;

Просмотреть файл

@ -264,6 +264,30 @@ exports.tryGetValueInsensitive = function (key, haystack, defaultValue) {
return defaultValue;
};
/**
* Returns the value in a chained object.
*
* @param {object} object The object with the values.
* @param {array} keys The keys.
* @param {mix} default The value to return if $key is not found in $array.
*
* @static
*
* @return mix
*/
exports.tryGetValueChain = function (object, keys, defaultValue) {
if (keys.length === 0) {
return object;
}
var currentKey = keys.shift();
if (object && object[currentKey]) {
return exports.tryGetValueChain(object[currentKey], keys, defaultValue);
}
return defaultValue;
};
/**
* Rounds a date off to seconds.
*

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -19,6 +19,9 @@ var fs = require('fs');
var path = require('path');
var util = require('util');
var sinon = require('sinon');
var url = require('url');
var request = require('request');
// Test includes
var testutil = require('../../util/util');
@ -1123,31 +1126,6 @@ describe('BlobService', function () {
});
});
it('GenerateSharedAccessSignature', function (done) {
var containerName = 'images';
var blobName = 'pic1.png';
var devStorageBlobService = azure.createBlobService(ServiceClient.DEVSTORE_STORAGE_ACCOUNT, ServiceClient.DEVSTORE_STORAGE_ACCESS_KEY);
var sharedAccessPolicy = {
AccessPolicy: {
Permissions: BlobConstants.SharedAccessPermissions.READ,
Start: new Date('October 11, 2011 11:03:40 am GMT'),
Expiry: new Date('October 12, 2011 11:53:40 am GMT')
}
};
var sharedAccessSignature = devStorageBlobService.generateSharedAccessSignature(containerName, blobName, sharedAccessPolicy);
assert.equal(sharedAccessSignature.queryString[QueryStringConstants.SIGNED_START], '2011-10-11T11:03:40Z');
assert.equal(sharedAccessSignature.queryString[QueryStringConstants.SIGNED_EXPIRY], '2011-10-12T11:53:40Z');
assert.equal(sharedAccessSignature.queryString[QueryStringConstants.SIGNED_RESOURCE], BlobConstants.ResourceTypes.BLOB);
assert.equal(sharedAccessSignature.queryString[QueryStringConstants.SIGNED_PERMISSIONS], BlobConstants.SharedAccessPermissions.READ);
assert.equal(sharedAccessSignature.queryString[QueryStringConstants.SIGNATURE], '7NIEip+VOrQ5ZV80pORPK1MOsJc62wwCNcbMvE+lQ0s=');
done();
});
it('CreateBlobWithBars', function (done) {
var containerName = testutil.generateId(containerNamesPrefix, containerNames, suiteUtil.isMocked);
var blobName = 'blobs/' + testutil.generateId(blobNamesPrefix, blobNames, suiteUtil.isMocked);
@ -1206,7 +1184,9 @@ describe('BlobService', function () {
});
});
it('GetBlobUrl', function (done) {
describe('shared access signature', function () {
describe('getBlobUrl', function () {
it('should work', function (done) {
var containerName = testutil.generateId(containerNamesPrefix, containerNames, suiteUtil.isMocked);
var blobName = testutil.generateId(blobNamesPrefix, blobNames, suiteUtil.isMocked);
@ -1221,7 +1201,7 @@ describe('BlobService', function () {
done();
});
it('GetBlobSharedUrl', function (done) {
it('should work with shared access policy', function (done) {
var containerName = 'container';
var blobName = 'blob';
@ -1234,12 +1214,57 @@ describe('BlobService', function () {
};
var blobUrl = blobServiceassert.getBlobUrl(containerName, blobName, sharedAccessPolicy);
assert.equal(blobUrl, 'https://host.com:80/' + containerName + '/' + blobName + '?se=2011-10-12T11%3A53%3A40Z&sr=b&sp=r&sig=eVkH%2BFxxShel2hcN50ZUmgPAHk%2FmqRVeaBfyry%2BVacw%3D');
assert.equal(blobUrl, 'https://host.com:80/' + containerName + '/' + blobName + '?se=2011-10-12T11%3A53%3A40Z&sr=b&sig=P5rp4qr5wWJdT3%2Fpys210lFcBzamGwjEYXaN2sf%2FHss%3D');
done();
});
it('GetBlobSharedUrlWithDuration', function (done) {
it('should work with container acl permissions', function (done) {
var containerName = testutil.generateId(containerNamesPrefix, containerNames, suiteUtil.isMocked);
var blobName = testutil.generateId(blobNamesPrefix, blobNames, suiteUtil.isMocked);
var fileNameSource = testutil.generateId('prefix') + '.bmp'; // fake bmp file with text...
var blobText = 'Hello World!';
blobService.createContainer(containerName, function (error) {
assert.equal(error, null);
var startTime = new Date('April 15, 2013 11:53:40 am GMT');
var readWriteSharedAccessPolicy = {
Id: 'readwrite',
AccessPolicy: {
Start: startTime,
Permissions: 'rwdl'
}
};
blobService.setContainerAcl(containerName, null, { signedIdentifiers: [ readWriteSharedAccessPolicy ] }, function (err) {
assert.equal(err, null);
blobService.createBlockBlobFromText(containerName, blobName, blobText, function (err) {
assert.equal(err, null);
var blobUrl = blobService.getBlobUrl(containerName, blobName, {
Id: 'readwrite',
AccessPolicy: {
Expiry: new Date('April 15, 2099 11:53:40 am GMT')
}
});
function responseCallback(err, rsp) {
assert.equal(rsp.statusCode, 200);
assert.equal(err, null);
fs.unlink(fileNameSource, done);
}
request.get(blobUrl, responseCallback).pipe(fs.createWriteStream(fileNameSource));
});
});
});
});
it('should work with duration', function (done) {
var containerName = 'container';
var blobName = 'blob';
@ -1257,10 +1282,37 @@ describe('BlobService', function () {
this.clock.restore();
var blobUrl = blobServiceassert.getBlobUrl(containerName, blobName, sharedAccessPolicy);
assert.equal(blobUrl, 'https://host.com:80/' + containerName + '/' + blobName + '?se=1970-01-01T00%3A10%3A00Z&sr=b&sp=r&sig=LofuDUzdHPpiteauMetANWzDpzd0Vw%2BVMOHyXYCipAM%3D');
assert.equal(blobUrl, 'https://host.com:80/' + containerName + '/' + blobName + '?se=1970-01-01T00%3A10%3A00Z&sr=b&sig=78rp23g%2FozomP%2FwwJHZ8BpyLIj0t%2B97oZgzFl1w3OAU%3D');
done();
});
});
it('GenerateSharedAccessSignature', function (done) {
var containerName = 'images';
var blobName = 'pic1.png';
var devStorageBlobService = azure.createBlobService(ServiceClient.DEVSTORE_STORAGE_ACCOUNT, ServiceClient.DEVSTORE_STORAGE_ACCESS_KEY);
var sharedAccessPolicy = {
AccessPolicy: {
Permissions: BlobConstants.SharedAccessPermissions.READ,
Start: new Date('October 11, 2011 11:03:40 am GMT'),
Expiry: new Date('October 12, 2011 11:53:40 am GMT')
}
};
var sharedAccessSignature = devStorageBlobService.generateSharedAccessSignature(containerName, blobName, sharedAccessPolicy);
assert.equal(sharedAccessSignature.queryString[QueryStringConstants.SIGNED_START], '2011-10-11T11:03:40Z');
assert.equal(sharedAccessSignature.queryString[QueryStringConstants.SIGNED_EXPIRY], '2011-10-12T11:53:40Z');
assert.equal(sharedAccessSignature.queryString[QueryStringConstants.SIGNED_RESOURCE], BlobConstants.ResourceTypes.BLOB);
assert.equal(sharedAccessSignature.queryString[QueryStringConstants.SIGNED_PERMISSIONS], BlobConstants.SharedAccessPermissions.READ);
assert.equal(sharedAccessSignature.queryString[QueryStringConstants.SIGNATURE], '7NIEip+VOrQ5ZV80pORPK1MOsJc62wwCNcbMvE+lQ0s=');
done();
});
});
it('responseEmits', function (done) {
var containerName = testutil.generateId(containerNamesPrefix, containerNames, suiteUtil.isMocked);
@ -1381,9 +1433,9 @@ describe('BlobService', function () {
});
function repeat(s, n) {
var ret = "";
var ret = '';
for (var i = 0; i < n; i++) {
ret += s;
}
return ret;
};
}

Просмотреть файл

@ -20,13 +20,7 @@ var testutil = require('../../util/util');
var blobtestutil = require('../../framework/blob-test-utils');
// Lib includes
var azureutil = testutil.libRequire('util/util');
var azure = testutil.libRequire('azure');
var BlobService = testutil.libRequire('services/blob/blobservice');
var Constants = testutil.libRequire('util/constants');
var BlobConstants = Constants.BlobConstants;
var testPrefix = 'filter-tests';
var blobService;

Просмотреть файл

@ -185,4 +185,13 @@ suite('util-tests', function() {
done();
});
test('Get property from object', function (done) {
// int positives
assert.equal(util.tryGetValueChain({a: { b: { c: 'd' }}}, [ 'a', 'b', 'c' ]), 'd');
assert.equal(util.tryGetValueChain({a: { b: { c: 'd' }}}, [ 'a', 'b', 'k' ]), null);
assert.equal(util.tryGetValueChain(null, [ 'a', 'b', 'k' ]), null);
done();
});
});