Skip to content
This repository has been archived by the owner on Jan 5, 2019. It is now read-only.

Commit

Permalink
Change azure artifacts to return putUrl (a write signed sas url)
Browse files Browse the repository at this point in the history
  • Loading branch information
lightsofapollo committed Jul 31, 2014
1 parent 6343a76 commit bcf1bd1
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 64 deletions.
13 changes: 5 additions & 8 deletions queue/blobstore.js
Expand Up @@ -3,7 +3,6 @@ var _ = require('lodash');
var Promise = require('promise');
var debug = require('debug')('queue:blobstore');
var assert = require('assert');
var urljoin = require('url-join');
var querystring = require('querystring');

/**
Expand Down Expand Up @@ -145,7 +144,8 @@ BlobStore.prototype.generateWriteSAS = function(key, options) {
Permissions: azure.Constants.BlobConstants.SharedAccessPermissions.WRITE
}
});
return _.pick(sas, 'baseUrl', 'path', 'queryString');

return sas.url();
};

/** Create signed GET url */
Expand All @@ -163,12 +163,9 @@ BlobStore.prototype.createSignedGetUrl = function(key, options) {
Permissions: azure.Constants.BlobConstants.SharedAccessPermissions.READ
}
});

// Generate URL
return urljoin(
sas.baseUrl,
sas.path,
'?' + querystring.stringify(sas.queryString)
);
return sas.url();
};

/** Delete a blob on azure blob storage */
Expand All @@ -184,4 +181,4 @@ BlobStore.prototype.deleteBlob = function(key, ignoreIfNotExists) {
return accept();
});
});
};
};
12 changes: 6 additions & 6 deletions routes/api/artifacts.js
Expand Up @@ -104,18 +104,18 @@ api.declare({
details.container = ctx.artifactStore.container;
details.path = path;
// Give 30 minutes before the signature expires
var sasExpiration = new Date();
sasExpiration.setMinutes(sasExpiration.getMinutes() + 30);
var writeExpiration = new Date();
writeExpiration.setMinutes(writeExpiration.getMinutes() + 30);
// Generate SAS
var sas = ctx.artifactStore.generateWriteSAS(path, {
expiry: sasExpiration
var putUrl = ctx.artifactStore.generateWriteSAS(path, {
expiry: writeExpiration
});
// Create reply
reply = Promise.resolve({
kind: 'azure',
contentType: input.contentType,
expires: sasExpiration.toJSON(),
sas: _.pick(sas, 'baseUrl', 'path', 'queryString')
expires: writeExpiration.toJSON(),
putUrl: putUrl
});

} else if (input.kind === 'redirect') {
Expand Down
2 changes: 1 addition & 1 deletion schemas/post-artifact-request.json
Expand Up @@ -125,4 +125,4 @@
]
}
]
}
}
32 changes: 6 additions & 26 deletions schemas/post-artifact-response.json
Expand Up @@ -55,38 +55,18 @@
"type": "string",
"maxLength": 255
},
"sas": {
"description": "Shared Access Signature (SAS), see Azure REST API reference for details on how to use this.",
"type": "object",
"properties": {
"baseUrl": {
"description": "Base URL for the azure blob storage account.",
"type": "string",
"format": "uri"
},
"path": {
"description": "Path to resource that you're granted write access to. This is typically on the form `<container>/<taskId>/<runId>/<name>`, but don't rely on that.",
"type": "string"
},
"queryString": {
"description": "Key-value pairs to provide as query-string parameters to authenticate requests. Typically, a few additional query-string parameters are also provided to identify operation and possibly block identifier, see Azure REST API reference for details.",
"type": "object"
}
},
"additionalProperties": false,
"required": [
"baseUrl",
"path",
"queryString"
]
"putUrl": {
"description": "Shared Access Signature (SAS) with write permissions, see [Azure REST API](http://msdn.microsoft.com/en-US/library/azure/dn140256.aspx) reference for details on how to use this.",
"type": "string",
"format": "uri"
}
},
"additionalProperties": false,
"required": [
"kind",
"expires",
"contentType",
"sas"
"putUrl"
]
}, {
"title": "Redirect Artifact Response",
Expand Down Expand Up @@ -118,4 +98,4 @@
]
}
]
}
}
4 changes: 2 additions & 2 deletions test/api/artifact_test.js
Expand Up @@ -209,7 +209,7 @@ suite('Post artifacts', function() {
var block2 = slugid.v4();

debug("### Uploading first block");
var uploader = new BlobUploader(result.sas);
var uploader = new BlobUploader(result.putUrl);
return Promise.all(
uploader.putBlock(block1, '{"block1_says": "Hello world",\n'),
uploader.putBlock(block2, '"block2_says": "Hello Again"}\n')
Expand Down Expand Up @@ -409,4 +409,4 @@ suite('Post artifacts', function() {
});
});

});
});
34 changes: 13 additions & 21 deletions test/queue/azure-blob-uploader-sas.js
@@ -1,52 +1,44 @@
var request = require('superagent-promise');
var url = require('url');
var debug = require('debug')('azure-blob-uploader-sas');
var assert = require('assert');
var urljoin = require('url-join');
var querystring = require('querystring');
var qs = require('querystring');
var _ = require('lodash');
var xmlbuilder = require('xmlbuilder');

/**
* Utility to upload block blobs using an azure Shared-Access-Signature
*
* Takes a input sas on the following form:
* {
* baseUrl: // Base url for azure blob storage account
* path: // Path to resources
* queryString: { // Query string parameters with SAS
* }
* @param {String} url fully constructed sas endpoint.
*/
var BlobUploader = function(sas) {
assert(sas.baseUrl, "Must have baseUrl");
assert(sas.path, "Must have path");
assert(sas.queryString, "Must have queryString with SAS");
this.sas = sas;
var BlobUploader = function(url) {
this.url = url;
};

// Export BlobUploader
module.exports = BlobUploader;

/** Construct URL for azure blob storage */
BlobUploader.prototype.buildUrl = function(queryString) {
// Merge querystring parameters
queryString = _.defaults(queryString || {}, this.sas.queryString);
// Build url
return urljoin(
this.sas.baseUrl,
this.sas.path,
'?' + querystring.stringify(queryString)
);
// Extend the query parameters if given....
var parsed = url.parse(this.url, true);
parsed.search = '?' + qs.stringify(
_.defaults(queryString || {}, parsed.query));

return url.format(parsed);
};

/** Upload a single block for commit later */
BlobUploader.prototype.putBlock = function(blockId, block) {
assert(blockId, "blockId must be given");
assert(block, "block must be given");

// Construct URL
var url = this.buildUrl({
comp: 'block',
blockid: new Buffer('' + blockId).toString('base64')
});

// Send request
return request
.put(url)
Expand Down

0 comments on commit bcf1bd1

Please sign in to comment.