From bee99cc9034c9a5cb9a8d8773f44968253f4a71f Mon Sep 17 00:00:00 2001 From: elenasolomon Date: Thu, 9 Feb 2017 14:28:41 +0200 Subject: [PATCH 01/12] Add an API endpoint for getting a SAS string for use with a specific Azure Blob Storage container --- schemas/azure-blob-access-response.yml | 22 ++++++++ src/azure.js | 73 ++++++++++++++++++++++++++ test/azure_test.js | 53 ++++++++++++++++++- 3 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 schemas/azure-blob-access-response.yml diff --git a/schemas/azure-blob-access-response.yml b/schemas/azure-blob-access-response.yml new file mode 100644 index 0000000..0cb7730 --- /dev/null +++ b/schemas/azure-blob-access-response.yml @@ -0,0 +1,22 @@ +$schema: http://json-schema.org/draft-04/schema# +title: "Azure Shared-Access-Signature Response" +description: | + Response to a request for an Shared-Access-Signature to access and Azure + Blob Storage container. +type: object +properties: + sas: + description: | + Shared-Access-Signature string. This is the querystring parameters to + be appened after `?` or `&` depending on whether or not a querystring is + already present in the URL. + type: string + expiry: + description: | + Date and time of when the Shared-Access-Signature expires. + type: string + format: date-time +additionalProperties: false +required: + - sas + - expiry \ No newline at end of file diff --git a/src/azure.js b/src/azure.js index 0cf00df..00bafcd 100644 --- a/src/azure.js +++ b/src/azure.js @@ -131,3 +131,76 @@ api.declare({ expiry: expiry.toJSON() }); }); + +api.declare({ + method: 'get', + route: '/azure/:account/blob/:container/read-write', + name: 'azureBlobSAS', + input: undefined, + output: 'azure-blob-access-response.json#', + deferAuth: true, + stability: 'stable', + scopes: [['auth:azure-blob-access:/']], + title: "Get Shared-Access-Signature for Azure Blob", + description: [ + "Get a shared access signature (SAS) string for use with a specific Azure", + "Blob Storage container. Note, this will create the container, if it doesn't", + "already exist." + ].join('\n') +}, async function(req, res){ + // Get parameters + var account = req.params.account; + var containerName = req.params.container; + + // Check that the client is authorized to access given account and table + if (!req.satisfies({ + account: account, + container: containerName + })) { + return; + } + + // Check that the account exists + if (!this.azureAccounts[account]) { + return res.status(404).json({ + message: "Account '" + account + "' not found, can't delegate access" + }); + } + + // Construct client + var blob = new azure.Blob({ + accountId: account, + accessKey: this.azureAccounts[account] + }); + + // Create container ignore error, if it already exists + try { + await blob.createContainer(containerName); + } catch (err) { + if (err.code !== 'ContainerAlreadyExists') { + throw err; + } + } + + // Construct SAS + var expiry = new Date(Date.now() + 25 * 60 * 1000); + var sas = blob.sas(containerName, null, { + start: new Date(Date.now() - 15 * 60 * 1000), + expiry: expiry, + resourceType: 'container', + permissions: { + read: true, + add: true, + create: true, + write: true, + delete: true, + list: true + } + }); + + // Return the generated SAS + return res.reply({ + sas: sas, + expiry: expiry.toJSON() + }); +}); \ No newline at end of file diff --git a/test/azure_test.js b/test/azure_test.js index 500443f..a476829 100644 --- a/test/azure_test.js +++ b/test/azure_test.js @@ -1,4 +1,4 @@ -suite('azure table (sas)', function() { +suite.only('azure table (sas)', function() { var Promise = require('promise'); var assert = require('assert'); var debug = require('debug')('auth:test:azure'); @@ -181,4 +181,53 @@ suite('azure table (sas)', function() { assert(err.statusCode == 403, "Expected authorization error!"); }); }); -}); + + test('azureBlobSAS', function() { + return helper.auth.azureBlobSAS( + helper.testaccount, + 'container-test' + ).then(function(result) { + assert(typeof(result.sas) === 'string', "Expected some form of string"); + assert(new Date(result.expiry).getTime() > new Date().getTime(), + "Expected expiry to be in the future"); + }); + }); + + test('azureBlobSAS (allowed container)', function() { + // Restrict access a bit + var auth = new helper.Auth({ + baseUrl: helper.baseUrl, + credentials: rootCredentials, + authorizedScopes: [ + 'auth:azure-blob-access:' + helper.testaccount + '/allowed-container' + ] + }); + return auth.azureBlobSAS( + helper.testaccount, + 'allowed-container' + ).then(function(result) { + assert(typeof(result.sas) === 'string', "Expected some form of string"); + assert(new Date(result.expiry).getTime() > new Date().getTime(), + "Expected expiry to be in the future"); + }); + }); + + test('azureBlobSAS (unauthorized container)', function() { + // Restrict access a bit + var auth = new helper.Auth({ + baseUrl: helper.baseUrl, + credentials: rootCredentials, + authorizedScopes: [ + 'auth:azure-blob-access:' + helper.testaccount + '/allowed-container' + ] + }); + return auth.azureBlobSAS( + helper.testaccount, + 'unauthorized-container' + ).then(function(result) { + assert(false, "Expected an authentication error!"); + }, function(err) { + assert(err.statusCode == 403, "Expected authorization error!"); + }); + }); +}); \ No newline at end of file From 619a8c1805119edd6b54906dfd32ec12da98bb10 Mon Sep 17 00:00:00 2001 From: elenasolomon Date: Thu, 9 Feb 2017 14:40:22 +0200 Subject: [PATCH 02/12] small correction to a schema description --- schemas/azure-blob-access-response.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/azure-blob-access-response.yml b/schemas/azure-blob-access-response.yml index 0cb7730..b686085 100644 --- a/schemas/azure-blob-access-response.yml +++ b/schemas/azure-blob-access-response.yml @@ -1,7 +1,7 @@ $schema: http://json-schema.org/draft-04/schema# title: "Azure Shared-Access-Signature Response" description: | - Response to a request for an Shared-Access-Signature to access and Azure + Response to a request for an Shared-Access-Signature to access an Azure Blob Storage container. type: object properties: From 10c4478b5f3789f864b1784e5dd6792484843798 Mon Sep 17 00:00:00 2001 From: elenasolomon Date: Fri, 10 Feb 2017 10:59:22 +0200 Subject: [PATCH 03/12] removes '.only' from azure test suite --- test/azure_test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/azure_test.js b/test/azure_test.js index a476829..cfabe32 100644 --- a/test/azure_test.js +++ b/test/azure_test.js @@ -1,4 +1,4 @@ -suite.only('azure table (sas)', function() { +suite('azure table (sas)', function() { var Promise = require('promise'); var assert = require('assert'); var debug = require('debug')('auth:test:azure'); From 931d0a50eeee70dc01474be9a7f4a490bdb71f7e Mon Sep 17 00:00:00 2001 From: elenasolomon Date: Mon, 20 Feb 2017 17:45:29 +0200 Subject: [PATCH 04/12] changes the scope to: auth:azure-blob::/ --- ...s-response.yml => azure-blob-response.yml} | 0 src/azure.js | 56 +++++--- test/azure_test.js | 126 +++++++++++++----- 3 files changed, 127 insertions(+), 55 deletions(-) rename schemas/{azure-blob-access-response.yml => azure-blob-response.yml} (100%) diff --git a/schemas/azure-blob-access-response.yml b/schemas/azure-blob-response.yml similarity index 100% rename from schemas/azure-blob-access-response.yml rename to schemas/azure-blob-response.yml diff --git a/src/azure.js b/src/azure.js index 00bafcd..ee45366 100644 --- a/src/azure.js +++ b/src/azure.js @@ -134,28 +134,36 @@ api.declare({ api.declare({ method: 'get', - route: '/azure/:account/blob/:container/read-write', + route: '/azure/:account/blob/:container/:level', name: 'azureBlobSAS', input: undefined, - output: 'azure-blob-access-response.json#', + output: 'azure-blob-response.json#', deferAuth: true, stability: 'stable', - scopes: [['auth:azure-blob-access:/']], + scopes: [['auth:azure-blob::/']], title: "Get Shared-Access-Signature for Azure Blob", description: [ "Get a shared access signature (SAS) string for use with a specific Azure", - "Blob Storage container. Note, this will create the container, if it doesn't", - "already exist." + "Blob Storage container. If the level is read-write, the container will be created, " + + "if it doesn't already exists." ].join('\n') }, async function(req, res){ // Get parameters - var account = req.params.account; - var containerName = req.params.container; + let account = req.params.account; + let containerName = req.params.container; + let level = req.params.level; + + if (['read-write', 'read-only'].indexOf(level) < 0) { + return res.status(404).json({ + message: "Level '" + level + "' is not valid. Must be one of ['read-write', 'read-only']." + }); + } - // Check that the client is authorized to access given account and table + // Check that the client is authorized to access given account and container if (!req.satisfies({ account: account, - container: containerName + container: containerName, + level: level, })) { return; } @@ -168,33 +176,37 @@ api.declare({ } // Construct client - var blob = new azure.Blob({ + let blob = new azure.Blob({ accountId: account, accessKey: this.azureAccounts[account] }); // Create container ignore error, if it already exists - try { - await blob.createContainer(containerName); - } catch (err) { - if (err.code !== 'ContainerAlreadyExists') { - throw err; + if (level === 'read-write') { + try { + await blob.createContainer(containerName); + } catch (err) { + if (err.code !== 'ContainerAlreadyExists') { + throw err; + } } } + let perm = level === 'read-write'; + // Construct SAS - var expiry = new Date(Date.now() + 25 * 60 * 1000); - var sas = blob.sas(containerName, null, { + let expiry = new Date(Date.now() + 25 * 60 * 1000); + let sas = blob.sas(containerName, null, { start: new Date(Date.now() - 15 * 60 * 1000), expiry: expiry, resourceType: 'container', permissions: { read: true, - add: true, - create: true, - write: true, - delete: true, - list: true + add: perm, + create: perm, + write: perm, + delete: perm, + list: perm } }); diff --git a/test/azure_test.js b/test/azure_test.js index cfabe32..995e309 100644 --- a/test/azure_test.js +++ b/test/azure_test.js @@ -1,4 +1,4 @@ -suite('azure table (sas)', function() { +suite.only('azure table (sas)', function() { var Promise = require('promise'); var assert = require('assert'); var debug = require('debug')('auth:test:azure'); @@ -101,8 +101,7 @@ suite('azure table (sas)', function() { accessToken: helper.rootAccessToken }; - - test('azureTableSAS (allowed table)', function() { + test('azureTableSAS (allowed table)', () => { // Restrict access a bit var auth = new helper.Auth({ baseUrl: helper.baseUrl, @@ -182,52 +181,113 @@ suite('azure table (sas)', function() { }); }); - test('azureBlobSAS', function() { - return helper.auth.azureBlobSAS( + test('azureBlobSAS', async () => { + let result = await helper.auth.azureBlobSAS( helper.testaccount, - 'container-test' - ).then(function(result) { - assert(typeof(result.sas) === 'string', "Expected some form of string"); - assert(new Date(result.expiry).getTime() > new Date().getTime(), - "Expected expiry to be in the future"); + 'container-test', + 'read-write' + ); + + assert(typeof(result.sas) === 'string', "Expected some form of string"); + assert(new Date(result.expiry).getTime() > new Date().getTime(), + "Expected expiry to be in the future"); + }); + + test('azureBlobSAS (read-write)', async () => { + let result = await helper.auth.azureBlobSAS( + helper.testaccount, + 'container-test', + 'read-write', + ); + assert(typeof(result.sas) === 'string', "Expected some form of string"); + assert(new Date(result.expiry).getTime() > new Date().getTime(), + "Expected expiry to be in the future"); + + let blob = new azure.Blob({ + accountId: helper.testaccount, + sas: result.sas }); + + result = await blob.putBlob('container-test', 'blobTest', {type: 'BlockBlob'}); + assert(result); }); - test('azureBlobSAS (allowed container)', function() { - // Restrict access a bit - var auth = new helper.Auth({ + test('azureBlobSAS (read-only)', async () => { + let result = await helper.auth.azureBlobSAS( + helper.testaccount, + 'container-test', + 'read-only', + ); + assert(typeof(result.sas) === 'string', "Expected some form of string"); + assert(new Date(result.expiry).getTime() > new Date().getTime(), + "Expected expiry to be in the future"); + + let blob = new azure.Blob({ + accountId: helper.testaccount, + sas: result.sas + }); + + try { + await blob.putBlob('container-test', 'blobTest', {type: 'BlockBlob'}); + } catch (error) { + assert.equal(error.code, 'AuthorizationPermissionMismatch'); + return; + } + assert(false, 'This should have thrown an error because the write is not allowed.'); + }); + + test('azureBlobSAS (invalid level)', async () => { + try { + await helper.auth.azureBlobSAS( + helper.testaccount, + 'container-test', + 'foo-bar-baz', + ); + } catch (error) { + assert.equal(error.message, "Level 'foo-bar-baz' is not valid. Must be one of ['read-write', 'read-only']."); + return; + } + assert(false, "This should have thrown an error"); + }); + + test('azureBlobSAS (allowed container)', async () => { + let auth = new helper.Auth({ baseUrl: helper.baseUrl, credentials: rootCredentials, authorizedScopes: [ - 'auth:azure-blob-access:' + helper.testaccount + '/allowed-container' + 'auth:azure-blob:read-write:' + helper.testaccount + '/allowed-container' ] }); - return auth.azureBlobSAS( + + let result = await auth.azureBlobSAS( helper.testaccount, - 'allowed-container' - ).then(function(result) { - assert(typeof(result.sas) === 'string', "Expected some form of string"); - assert(new Date(result.expiry).getTime() > new Date().getTime(), - "Expected expiry to be in the future"); - }); + 'allowed-container', + 'read-write' + ); + + assert(typeof(result.sas) === 'string', "Expected some form of string"); + assert(new Date(result.expiry).getTime() > new Date().getTime(), + "Expected expiry to be in the future"); }); - test('azureBlobSAS (unauthorized container)', function() { - // Restrict access a bit - var auth = new helper.Auth({ + test('azureBlobSAS (unauthorized container)', async () => { + let auth = new helper.Auth({ baseUrl: helper.baseUrl, credentials: rootCredentials, authorizedScopes: [ - 'auth:azure-blob-access:' + helper.testaccount + '/allowed-container' + 'auth:azure-blob:read-write:' + helper.testaccount + '/allowed-container' ] }); - return auth.azureBlobSAS( - helper.testaccount, - 'unauthorized-container' - ).then(function(result) { - assert(false, "Expected an authentication error!"); - }, function(err) { - assert(err.statusCode == 403, "Expected authorization error!"); - }); + try { + await auth.azureBlobSAS( + helper.testaccount, + 'unauthorized-container', + 'read-write' + ); + } catch (error) { + assert(error.statusCode == 403, "Expected authorization error!"); + return; + } + assert(false, "Expected an authentication error!"); }); }); \ No newline at end of file From 5a2a074ac7a2f9fabc77ed9b0f5ffd540f146307 Mon Sep 17 00:00:00 2001 From: elenasolomon Date: Tue, 21 Feb 2017 10:39:49 +0200 Subject: [PATCH 05/12] Integrate the changes requested in the code review --- src/azure.js | 12 +++++------- test/azure_test.js | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/azure.js b/src/azure.js index ee45366..e05b2e7 100644 --- a/src/azure.js +++ b/src/azure.js @@ -88,9 +88,8 @@ api.declare({ // Check that the account exists if (!this.azureAccounts[account]) { - return res.status(404).json({ - message: "Account '" + account + "' not found, can't delegate access" - }); + return res.reportError('InvalidRequestArguments', + `Account '${account}' not found, can't delegate access`); } // Construct client @@ -154,9 +153,8 @@ api.declare({ let level = req.params.level; if (['read-write', 'read-only'].indexOf(level) < 0) { - return res.status(404).json({ - message: "Level '" + level + "' is not valid. Must be one of ['read-write', 'read-only']." - }); + return res.reportError('InvalidRequestArguments', + `Level '${level}' is not valid. Must be one of ['read-write', 'read-only'].`); } // Check that the client is authorized to access given account and container @@ -206,7 +204,7 @@ api.declare({ create: perm, write: perm, delete: perm, - list: perm + list: true, } }); diff --git a/test/azure_test.js b/test/azure_test.js index 995e309..fa3d1ad 100644 --- a/test/azure_test.js +++ b/test/azure_test.js @@ -244,7 +244,7 @@ suite.only('azure table (sas)', function() { 'foo-bar-baz', ); } catch (error) { - assert.equal(error.message, "Level 'foo-bar-baz' is not valid. Must be one of ['read-write', 'read-only']."); + assert.equal(error.code, 'InvalidRequestArguments'); return; } assert(false, "This should have thrown an error"); From 93921d254234b18e3d49b2bb0c3323deb851c369 Mon Sep 17 00:00:00 2001 From: elenasolomon Date: Tue, 21 Feb 2017 10:41:34 +0200 Subject: [PATCH 06/12] removes .only from azure tests --- test/azure_test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/azure_test.js b/test/azure_test.js index fa3d1ad..e567512 100644 --- a/test/azure_test.js +++ b/test/azure_test.js @@ -1,4 +1,4 @@ -suite.only('azure table (sas)', function() { +suite('azure table (sas)', function() { var Promise = require('promise'); var assert = require('assert'); var debug = require('debug')('auth:test:azure'); From b52858d5b858541ddaf266f8a4470683cdae7d6d Mon Sep 17 00:00:00 2001 From: elenasolomon Date: Wed, 22 Feb 2017 16:34:39 +0200 Subject: [PATCH 07/12] changed the version of the fast-azure-storage library --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e0eb164..932f111 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "babel-runtime": "^6.6.1", "cryptiles": "^2.0.4", "debug": "^2.2.0", - "fast-azure-storage": "^0.3.5", + "fast-azure-storage": "^1.0.0", "hawk": "2.3.0", "hoek": "^2.16.3", "lodash": "^3.9.3", From 356eb99fb88012afb5a263015a204f2c99c118b1 Mon Sep 17 00:00:00 2001 From: elenasolomon Date: Fri, 24 Feb 2017 15:12:47 +0200 Subject: [PATCH 08/12] integrate changes requested in code review --- schemas/azure-blob-response.yml | 4 ++-- schemas/azure-table-access-response.yml | 2 +- src/azure.js | 16 +++++++--------- src/v1.js | 2 ++ test/azure_test.js | 21 ++++++++++++++++++++- 5 files changed, 32 insertions(+), 13 deletions(-) diff --git a/schemas/azure-blob-response.yml b/schemas/azure-blob-response.yml index b686085..2a60afc 100644 --- a/schemas/azure-blob-response.yml +++ b/schemas/azure-blob-response.yml @@ -1,5 +1,5 @@ $schema: http://json-schema.org/draft-04/schema# -title: "Azure Shared-Access-Signature Response" +title: "Azure Blob Shared-Access-Signature Response" description: | Response to a request for an Shared-Access-Signature to access an Azure Blob Storage container. @@ -19,4 +19,4 @@ properties: additionalProperties: false required: - sas - - expiry \ No newline at end of file + - expiry diff --git a/schemas/azure-table-access-response.yml b/schemas/azure-table-access-response.yml index eee69f1..ce27665 100644 --- a/schemas/azure-table-access-response.yml +++ b/schemas/azure-table-access-response.yml @@ -1,5 +1,5 @@ $schema: http://json-schema.org/draft-04/schema# -title: "Azure Shared-Access-Signature Response" +title: "Azure Table Shared-Access-Signature Response" description: | Response to a request for an Shared-Access-Signature to access and Azure Table Storage table. diff --git a/src/azure.js b/src/azure.js index e05b2e7..8249871 100644 --- a/src/azure.js +++ b/src/azure.js @@ -133,7 +133,7 @@ api.declare({ api.declare({ method: 'get', - route: '/azure/:account/blob/:container/:level', + route: '/azure/:account/containers/:container/:level', name: 'azureBlobSAS', input: undefined, output: 'azure-blob-response.json#', @@ -149,7 +149,7 @@ api.declare({ }, async function(req, res){ // Get parameters let account = req.params.account; - let containerName = req.params.container; + let container = req.params.container; let level = req.params.level; if (['read-write', 'read-only'].indexOf(level) < 0) { @@ -158,11 +158,9 @@ api.declare({ } // Check that the client is authorized to access given account and container - if (!req.satisfies({ - account: account, - container: containerName, - level: level, - })) { + if (!(level === 'read-only' && + req.satisfies({account, container, level: 'read-write'}, true)) && + !req.satisfies({account, container, level})) { return; } @@ -182,7 +180,7 @@ api.declare({ // Create container ignore error, if it already exists if (level === 'read-write') { try { - await blob.createContainer(containerName); + await blob.createContainer(container); } catch (err) { if (err.code !== 'ContainerAlreadyExists') { throw err; @@ -194,7 +192,7 @@ api.declare({ // Construct SAS let expiry = new Date(Date.now() + 25 * 60 * 1000); - let sas = blob.sas(containerName, null, { + let sas = blob.sas(container, null, { start: new Date(Date.now() - 15 * 60 * 1000), expiry: expiry, resourceType: 'container', diff --git a/src/v1.js b/src/v1.js index 8c6bb6f..86e6b53 100644 --- a/src/v1.js +++ b/src/v1.js @@ -55,6 +55,8 @@ var api = new API({ // Patterns for Azure account: /^[a-z0-9]{3,24}$/, table: /^[A-Za-z][A-Za-z0-9]{2,62}$/, + container: /^[a-z0-9](?!.*([-])\1)[a-z0-9-]{2,62}$/, + level: /^(read-write|read-only)$/, // Patterns for AWS bucket: /^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$/, diff --git a/test/azure_test.js b/test/azure_test.js index e567512..b6a06c4 100644 --- a/test/azure_test.js +++ b/test/azure_test.js @@ -1,4 +1,4 @@ -suite('azure table (sas)', function() { +suite.only('azure table (sas)', function() { var Promise = require('promise'); var assert = require('assert'); var debug = require('debug')('auth:test:azure'); @@ -270,6 +270,25 @@ suite('azure table (sas)', function() { "Expected expiry to be in the future"); }); + test('azureBlobSAS (allowed read-write -> read-only)', async () => { + var auth = new helper.Auth({ + baseUrl: helper.baseUrl, + credentials: rootCredentials, + authorizedScopes: [ + 'auth:azure-blob:read-write:' + helper.testaccount + '/allowed-container' + ] + }); + + let result = await auth.azureBlobSAS( + helper.testaccount, + 'allowed-container', + 'read-only', + ); + assert(typeof(result.sas) === 'string', "Expected some form of string"); + assert(new Date(result.expiry).getTime() > new Date().getTime(), + "Expected expiry to be in the future"); + }); + test('azureBlobSAS (unauthorized container)', async () => { let auth = new helper.Auth({ baseUrl: helper.baseUrl, From 3c836152cab479fa467c1adbecb593119ebfa5f6 Mon Sep 17 00:00:00 2001 From: elenasolomon Date: Fri, 24 Feb 2017 18:06:53 +0200 Subject: [PATCH 09/12] fixes the container regex pattern --- src/v1.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v1.js b/src/v1.js index 86e6b53..8ee9a76 100644 --- a/src/v1.js +++ b/src/v1.js @@ -55,7 +55,7 @@ var api = new API({ // Patterns for Azure account: /^[a-z0-9]{3,24}$/, table: /^[A-Za-z][A-Za-z0-9]{2,62}$/, - container: /^[a-z0-9](?!.*([-])\1)[a-z0-9-]{2,62}$/, + container: /^(?!.*[-]{2})[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/, level: /^(read-write|read-only)$/, // Patterns for AWS From 9a598b1ed62752fee762460d08eb78423b11eadb Mon Sep 17 00:00:00 2001 From: elenasolomon Date: Fri, 24 Feb 2017 18:16:57 +0200 Subject: [PATCH 10/12] res.reportError insteadof res.status --- src/azure.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/azure.js b/src/azure.js index 8249871..98fc482 100644 --- a/src/azure.js +++ b/src/azure.js @@ -166,9 +166,8 @@ api.declare({ // Check that the account exists if (!this.azureAccounts[account]) { - return res.status(404).json({ - message: "Account '" + account + "' not found, can't delegate access" - }); + return res.reportError('InvalidRequestArguments', + `Account '${level}' not found, can't delegate access.`); } // Construct client From 91811dce210aa342388a27b6fce653658cfe5f5b Mon Sep 17 00:00:00 2001 From: elenasolomon Date: Mon, 27 Feb 2017 12:00:44 +0200 Subject: [PATCH 11/12] - changed the error from InvalidRequestArguments in ResourceNotFound - corrects some unit tests --- src/azure.js | 15 ++------------- test/azure_test.js | 7 +++---- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/azure.js b/src/azure.js index 98fc482..e78f121 100644 --- a/src/azure.js +++ b/src/azure.js @@ -73,12 +73,6 @@ api.declare({ var tableName = req.params.table; var level = req.params.level; - if (!['read-write', 'read-only'].includes(level)) { - return res.status(404).json({ - message: "Level '" + level + "' is not valid. Must be one of ['read-write', 'read-only']." - }); - } - // We have a complicated scope situation for read-only since we want // read-write to grant read-only permissions as well if (!(level === 'read-only' && req.satisfies({account, table: tableName, level: 'read-write'}, true)) && @@ -88,7 +82,7 @@ api.declare({ // Check that the account exists if (!this.azureAccounts[account]) { - return res.reportError('InvalidRequestArguments', + return res.reportError('ResourceNotFound', `Account '${account}' not found, can't delegate access`); } @@ -152,11 +146,6 @@ api.declare({ let container = req.params.container; let level = req.params.level; - if (['read-write', 'read-only'].indexOf(level) < 0) { - return res.reportError('InvalidRequestArguments', - `Level '${level}' is not valid. Must be one of ['read-write', 'read-only'].`); - } - // Check that the client is authorized to access given account and container if (!(level === 'read-only' && req.satisfies({account, container, level: 'read-write'}, true)) && @@ -166,7 +155,7 @@ api.declare({ // Check that the account exists if (!this.azureAccounts[account]) { - return res.reportError('InvalidRequestArguments', + return res.reportError('ResourceNotFound', `Account '${level}' not found, can't delegate access.`); } diff --git a/test/azure_test.js b/test/azure_test.js index b6a06c4..4d63fc1 100644 --- a/test/azure_test.js +++ b/test/azure_test.js @@ -1,5 +1,4 @@ -suite.only('azure table (sas)', function() { - var Promise = require('promise'); +suite('azure table and blob (sas)', function() { var assert = require('assert'); var debug = require('debug')('auth:test:azure'); var helper = require('./helper'); @@ -92,7 +91,7 @@ suite.only('azure table (sas)', function() { ).then(function(result) { assert(false, "This should have thrown an error"); }).catch(function(err) { - assert.equal(err.message, "Level 'foo-bar-baz' is not valid. Must be one of ['read-write', 'read-only']."); + assert.equal(err.code, "InvalidRequestArguments"); }); }); @@ -271,7 +270,7 @@ suite.only('azure table (sas)', function() { }); test('azureBlobSAS (allowed read-write -> read-only)', async () => { - var auth = new helper.Auth({ + let auth = new helper.Auth({ baseUrl: helper.baseUrl, credentials: rootCredentials, authorizedScopes: [ From e647e301e3e1b8cd92673503b8e297eaa7a0a25a Mon Sep 17 00:00:00 2001 From: elenasolomon Date: Mon, 27 Feb 2017 22:03:00 +0200 Subject: [PATCH 12/12] creates a helper method to set authorized scopes --- test/azure_test.js | 72 ++++++++++++++-------------------------------- test/helper.js | 11 +++++++ 2 files changed, 33 insertions(+), 50 deletions(-) diff --git a/test/azure_test.js b/test/azure_test.js index 4d63fc1..71b2fe1 100644 --- a/test/azure_test.js +++ b/test/azure_test.js @@ -1,4 +1,4 @@ -suite('azure table and blob (sas)', function() { +suite.only('azure table and blob (sas)', function() { var assert = require('assert'); var debug = require('debug')('auth:test:azure'); var helper = require('./helper'); @@ -102,13 +102,9 @@ suite('azure table and blob (sas)', function() { test('azureTableSAS (allowed table)', () => { // Restrict access a bit - var auth = new helper.Auth({ - baseUrl: helper.baseUrl, - credentials: rootCredentials, - authorizedScopes: [ - 'auth:azure-table:read-write:' + helper.testaccount + '/allowedTable' - ] - }); + let auth = helper.scopes([ + 'auth:azure-table:read-write:' + helper.testaccount + '/allowedTable' + ]); return auth.azureTableSAS( helper.testaccount, 'allowedTable', @@ -122,13 +118,9 @@ suite('azure table and blob (sas)', function() { test('azureTableSAS (allowed table rw -> ro)', function() { // Restrict access a bit - var auth = new helper.Auth({ - baseUrl: helper.baseUrl, - credentials: rootCredentials, - authorizedScopes: [ - 'auth:azure-table:read-write:' + helper.testaccount + '/allowedTable' - ] - }); + let auth = helper.scopes([ + 'auth:azure-table:read-write:' + helper.testaccount + '/allowedTable' + ]); return auth.azureTableSAS( helper.testaccount, 'allowedTable', @@ -142,13 +134,9 @@ suite('azure table and blob (sas)', function() { test('azureTableSAS (too high permission)', function() { // Restrict access a bit - var auth = new helper.Auth({ - baseUrl: helper.baseUrl, - credentials: rootCredentials, - authorizedScopes: [ - 'auth:azure-table:read-only:' + helper.testaccount + '/allowedTable' - ] - }); + let auth = helper.scopes([ + 'auth:azure-table:read-only:' + helper.testaccount + '/allowedTable' + ]); return auth.azureTableSAS( helper.testaccount, 'allowedTable', @@ -162,13 +150,9 @@ suite('azure table and blob (sas)', function() { test('azureTableSAS (unauthorized table)', function() { // Restrict access a bit - var auth = new helper.Auth({ - baseUrl: helper.baseUrl, - credentials: rootCredentials, - authorizedScopes: [ - 'auth:azure-table:read-write:' + helper.testaccount + '/allowedTable' - ] - }); + let auth = helper.scopes([ + 'auth:azure-table:read-write:' + helper.testaccount + '/allowedTable' + ]); return auth.azureTableSAS( helper.testaccount, 'unauthorizedTable', @@ -250,13 +234,9 @@ suite('azure table and blob (sas)', function() { }); test('azureBlobSAS (allowed container)', async () => { - let auth = new helper.Auth({ - baseUrl: helper.baseUrl, - credentials: rootCredentials, - authorizedScopes: [ - 'auth:azure-blob:read-write:' + helper.testaccount + '/allowed-container' - ] - }); + let auth = helper.scopes([ + 'auth:azure-blob:read-write:' + helper.testaccount + '/allowed-container' + ]); let result = await auth.azureBlobSAS( helper.testaccount, @@ -270,13 +250,9 @@ suite('azure table and blob (sas)', function() { }); test('azureBlobSAS (allowed read-write -> read-only)', async () => { - let auth = new helper.Auth({ - baseUrl: helper.baseUrl, - credentials: rootCredentials, - authorizedScopes: [ - 'auth:azure-blob:read-write:' + helper.testaccount + '/allowed-container' - ] - }); + let auth = helper.scopes([ + 'auth:azure-blob:read-write:' + helper.testaccount + '/allowed-container' + ]); let result = await auth.azureBlobSAS( helper.testaccount, @@ -289,13 +265,9 @@ suite('azure table and blob (sas)', function() { }); test('azureBlobSAS (unauthorized container)', async () => { - let auth = new helper.Auth({ - baseUrl: helper.baseUrl, - credentials: rootCredentials, - authorizedScopes: [ - 'auth:azure-blob:read-write:' + helper.testaccount + '/allowed-container' - ] - }); + let auth = helper.scopes([ + 'auth:azure-blob:read-write:' + helper.testaccount + '/allowed-container' + ]); try { await auth.azureBlobSAS( helper.testaccount, diff --git a/test/helper.js b/test/helper.js index 415289e..3f0d91e 100644 --- a/test/helper.js +++ b/test/helper.js @@ -81,6 +81,17 @@ mocha.before(async () => { } }); + helper.scopes = (scopes) => { + return new helper.Auth({ + baseUrl: helper.baseUrl, + credentials: { + clientId: 'root', + accessToken: cfg.app.rootAccessToken, + }, + authorizedScopes: scopes, + }); + } + // Create test server let { server: testServer_,