diff --git a/lib/routes/api/api-keys.js b/lib/routes/api/api-keys.js index ccd9bbf..1a2e935 100644 --- a/lib/routes/api/api-keys.js +++ b/lib/routes/api/api-keys.js @@ -1,6 +1,7 @@ const router = require('express').Router(); const {DbErrorBadRequest} = require('../../utils/errors'); const ApiKey = require('../../models/api-key'); +const Account = require('../../models/account'); const decorate = require('./decorate'); const uuidv4 = require('uuid/v4'); const assert = require('assert'); @@ -10,17 +11,32 @@ const preconditions = { 'delete': validateDeleteToken }; -function validateAddToken(req) { +async function validateAddToken(req) { req.body.token = uuidv4(); if (req.user.hasAdminAuth) return; if (req.user.hasServiceProviderAuth) { + if (!req.body.service_provider_sid && !req.body.account_sid) { + throw new DbErrorBadRequest('service provider token may not be used to create admin token'); + } + else if (req.body.service_provider_sid && req.body.service_provider_sid !== req.user.service_provider_sid) { + throw new DbErrorBadRequest( + 'a service provider token can only be used to create tokens for the same service provider'); + } + else if (req.body.account_sid) { + const result = await Account.retrieve(req.body.account_sid); + if (result.length === 1 && result[0].service_provider_sid != req.user.service_provider_sid) { + throw new DbErrorBadRequest( + 'a service provider token can only be used to create tokens for the same service provider'); + } + } if (req.body.account_sid) delete req.body.service_provider_sid; else req.body.service_provider_sid = req.user.service_provider_sid; } if (req.user.hasAccountAuth) { if (req.body.account_sid !== req.user.account_sid) { - throw new DbErrorBadRequest('an account level token may not be used to create a token for a different account'); + throw new DbErrorBadRequest( + 'an account level token can only be used to create account level tokens for the same account'); } delete req.body['service_provider_sid']; req.body['account_sid'] = req.user.account_sid; diff --git a/test/auth.js b/test/auth.js index 7b7e6e9..d64d560 100644 --- a/test/auth.js +++ b/test/auth.js @@ -222,9 +222,75 @@ test('authentication tests', async(t) => { } }); //console.log(`result: ${JSON.stringify(result)}`); - t.ok(result.statusCode === 400 && result.body.msg === 'an account level token may not be used to create a token for a different account', + t.ok(result.statusCode === 400 && result.body.msg === 'an account level token can only be used to create account level tokens for the same account', 'an account level token may not be used to create a token for a different account'); + /* account level token can not create service provider token */ + result = await request.post('/ApiKeys', { + resolveWithFullResponse: true, + simple: false, + auth: {bearer: accA1_token}, + json: true, + body: { + service_provider_sid: spA_sid + } + }); + t.ok(result.statusCode === 400 && result.body.msg === 'an account level token can only be used to create account level tokens for the same account', + 'account level token can not create service provider token'); + + /* account level token can not create admin token */ + result = await request.post('/ApiKeys', { + resolveWithFullResponse: true, + simple: false, + auth: {bearer: accA1_token}, + json: true, + body: { + } + }); + t.ok(result.statusCode === 400 && result.body.msg === 'an account level token can only be used to create account level tokens for the same account', + 'account level token can not create admin token'); + + /* service provider token can not create admin token */ + result = await request.post('/ApiKeys', { + resolveWithFullResponse: true, + simple: false, + auth: {bearer: spA_token}, + json: true, + body: { + } + }); + //console.log(`result: ${JSON.stringify(result)}`); + t.ok(result.statusCode === 400 && result.body.msg === 'service provider token may not be used to create admin token', + 'service provider token can not create admin token'); + + /* service provider token can not create token for different service provider */ + result = await request.post('/ApiKeys', { + resolveWithFullResponse: true, + simple: false, + auth: {bearer: spA_token}, + json: true, + body: { + service_provider_sid: spB_sid + } + }); + //console.log(`result: ${JSON.stringify(result)}`); + t.ok(result.statusCode === 400 && result.body.msg === 'a service provider token can only be used to create tokens for the same service provider', + 'service provider token can not create token for different service provider'); + + /* service provider token can not create token for account under different service provider */ + result = await request.post('/ApiKeys', { + resolveWithFullResponse: true, + simple: false, + auth: {bearer: spA_token}, + json: true, + body: { + account_sid: accB1 + } + }); + //console.log(`result: ${JSON.stringify(result)}`); + t.ok(result.statusCode === 400 && result.body.msg === 'a service provider token can only be used to create tokens for the same service provider', + 'service provider token can not create token for account under a different service provider'); + /* account level token can create token for the same account */ result = await request.post('/ApiKeys', { resolveWithFullResponse: true,