diff --git a/lib/routes/api/service-providers.js b/lib/routes/api/service-providers.js index 1ad3a2c..74dd09b 100644 --- a/lib/routes/api/service-providers.js +++ b/lib/routes/api/service-providers.js @@ -28,13 +28,28 @@ WHERE voip_carrier_sid IN ( )`; /* only admin users can add a service provider */ -async function validateAdd(req) { +function validateAdd(req) { if (!req.user.hasAdminAuth) { throw new DbErrorForbidden('only admin users can add a service provider'); } } -async function validateUpdate(req) { +async function validateRetrieve(req) { + const service_provider_sid = parseServiceProviderSid(req); + if (req.user.hasScope('admin')) return ; + if (req.user.hasScope('service_provider')) { + if (service_provider_sid === req.user.service_provider_sid) return ; + } + if (req.user.hasScope('account')) { + /* allow account users to retrieve service provider data from parent SP */ + const sid = req.user.account_sid; + const [r] = await promisePool.execute('SELECT service_provider_sid from accounts WHERE account_sid = ?', [sid]); + if (r.length === 1 && r[0].service_provider_sid === req.user.service_provider_sid) return; + } + throw new DbErrorForbidden('insufficient permissions to update service provider'); +} + +function validateUpdate(req) { if (req.user.hasScope('admin')) return ; if (req.user.hasScope('service_provider')) { const service_provider_sid = parseServiceProviderSid(req); @@ -68,8 +83,12 @@ router.use('/:sid/PredefinedCarriers', hasServiceProviderPermissions, require('. router.get('/:sid/Accounts', async(req, res) => { const logger = req.app.locals.logger; try { + await validateRetrieve(req); const service_provider_sid = parseServiceProviderSid(req); - const results = await Account.retrieveAll(service_provider_sid); + let results = await Account.retrieveAll(service_provider_sid); + if (req.user.hasScope('account')) { + results = results.filter((r) => r.account_sid === req.user.account_sid); + } res.status(200).json(results); } catch (err) { sysError(logger, res, err); @@ -78,8 +97,12 @@ router.get('/:sid/Accounts', async(req, res) => { router.get('/:sid/Applications', async(req, res) => { const logger = req.app.locals.logger; try { + await validateRetrieve(req); const service_provider_sid = parseServiceProviderSid(req); - const results = await Application.retrieveAll(service_provider_sid); + let results = await Application.retrieveAll(service_provider_sid); + if (req.user.hasScope('account')) { + results = results.filter((r) => r.account_sid === req.user.account_sid); + } res.status(200).json(results); } catch (err) { sysError(logger, res, err); @@ -88,8 +111,12 @@ router.get('/:sid/Applications', async(req, res) => { router.get('/:sid/PhoneNumbers', async(req, res) => { const logger = req.app.locals.logger; try { + await validateRetrieve(req); const service_provider_sid = parseServiceProviderSid(req); - const results = await PhoneNumber.retrieveAllForSP(service_provider_sid); + let results = await PhoneNumber.retrieveAllForSP(service_provider_sid); + if (req.user.hasScope('account')) { + results = results.filter((r) => r.account_sid === req.user.account_sid); + } res.status(200).json(results); } catch (err) { sysError(logger, res, err); @@ -98,6 +125,7 @@ router.get('/:sid/PhoneNumbers', async(req, res) => { router.get('/:sid/VoipCarriers', async(req, res) => { const logger = req.app.locals.logger; try { + await validateRetrieve(req); const service_provider_sid = parseServiceProviderSid(req); const results = await VoipCarrier.retrieveAllForSP(service_provider_sid); res.status(200).json(results); @@ -108,6 +136,7 @@ router.get('/:sid/VoipCarriers', async(req, res) => { router.post('/:sid/VoipCarriers', async(req, res) => { const logger = req.app.locals.logger; try { + validateUpdate(req); const service_provider_sid = parseServiceProviderSid(req); const uuid = await VoipCarrier.make({...req.body, service_provider_sid}); res.status(201).json({sid: uuid}); @@ -118,6 +147,7 @@ router.post('/:sid/VoipCarriers', async(req, res) => { router.put('/:sid/VoipCarriers/:voip_carrier_sid', async(req, res) => { const logger = req.app.locals.logger; try { + validateUpdate(req); const rowsAffected = await VoipCarrier.update(req.params.voip_carrier_sid, req.body); if (rowsAffected === 0) { return res.sendStatus(404); @@ -127,21 +157,15 @@ router.put('/:sid/VoipCarriers/:voip_carrier_sid', async(req, res) => { sysError(logger, res, err); } }); -router.get(':sid/Acccounts', async(req, res) => { - const logger = req.app.locals.logger; - try { - const service_provider_sid = parseServiceProviderSid(req); - const results = await Account.retrieveAll(service_provider_sid); - res.status(200).json(results); - } catch (err) { - sysError(logger, res, err); - } -}); router.get('/:sid/ApiKeys', async(req, res) => { const logger = req.app.locals.logger; const {sid} = req.params; try { - const results = await ApiKey.retrieveAllForSP(sid); + await validateRetrieve(req); + let results = await ApiKey.retrieveAllForSP(sid); + if (req.user.hasScope('account')) { + results = results.filter((r) => r.account_sid === req.user.account_sid); + } res.status(200).json(results); await ApiKey.updateLastUsed(sid); } catch (err) { @@ -153,7 +177,7 @@ router.get('/:sid/ApiKeys', async(req, res) => { router.post('/', async(req, res) => { const logger = req.app.locals.logger; try { - await validateAdd(req); + validateAdd(req); // create webhooks if provided const obj = Object.assign({}, req.body); @@ -208,7 +232,7 @@ router.put('/:sid', async(req, res) => { const sid = req.params.sid; const logger = req.app.locals.logger; try { - await validateUpdate(req); + validateUpdate(req); // create webhooks if provided const obj = Object.assign({}, req.body);