diff --git a/lib/models/account.js b/lib/models/account.js index 6ed0105..45b6575 100644 --- a/lib/models/account.js +++ b/lib/models/account.js @@ -1,9 +1,50 @@ const Model = require('./model'); +const {getMysqlConnection} = require('../db'); +const listSqlSp = 'SELECT * from accounts WHERE service_provider_sid = ?'; +const listSqlAccount = 'SELECT * from accounts WHERE account_sid = ?'; +const retrieveSql = 'SELECT * from accounts WHERE WHERE service_provider_sid = ? AND account_sid = ?'; class Account extends Model { constructor() { super(); } + + /** + * list all accounts + */ + static retrieveAll(service_provider_sid, account_sid) { + if (!service_provider_sid && !account_sid) return super.retrieveAll(); + return new Promise((resolve, reject) => { + getMysqlConnection((err, conn) => { + if (err) return reject(err); + const sql = account_sid ? listSqlAccount : listSqlSp; + const args = account_sid ? [account_sid] : [service_provider_sid]; + conn.query(sql, args, (err, results, fields) => { + conn.release(); + if (err) return reject(err); + resolve(results); + }); + }); + }); + } + + /** + * retrieve an accounts + */ + static retrieve(sid, service_provider_sid) { + if (!service_provider_sid) return super.retrieve(sid); + return new Promise((resolve, reject) => { + getMysqlConnection((err, conn) => { + if (err) return reject(err); + conn.query(retrieveSql, [service_provider_sid, sid], (err, results, fields) => { + conn.release(); + if (err) return reject(err); + resolve(results); + }); + }); + }); + } + } Account.table = 'accounts'; diff --git a/lib/routes/api/accounts.js b/lib/routes/api/accounts.js index 8b29c29..a2200eb 100644 --- a/lib/routes/api/accounts.js +++ b/lib/routes/api/accounts.js @@ -3,6 +3,7 @@ const {DbErrorBadRequest, DbErrorUnprocessableRequest} = require('../../utils/er const Account = require('../../models/account'); const ServiceProvider = require('../../models/service-provider'); const decorate = require('./decorate'); +const sysError = require('./error'); const preconditions = { 'add': validateAdd, 'update': validateUpdate, @@ -52,6 +53,33 @@ async function validateDelete(req, sid) { } } -decorate(router, Account, ['*'], preconditions); +decorate(router, Account, ['add', 'update', 'delete'], preconditions); + +/* list */ +router.get('/', async(req, res) => { + const logger = req.app.locals.logger; + try { + const service_provider_sid = req.user.hasServiceProviderAuth ? req.user.service_provider_sid : null; + const account_sid = req.user.hasAccountAuth ? req.user.account_sid : null; + const results = await Account.retrieveAll(service_provider_sid, account_sid); + res.status(200).json(results); + } catch (err) { + sysError(logger, res, err); + } +}); + +/* retrieve */ +router.get('/:sid', async(req, res) => { + const logger = req.app.locals.logger; + try { + const service_provider_sid = req.user.hasServiceProviderAuth ? req.user.service_provider_sid : null; + const results = await Account.retrieve(req.params.sid, service_provider_sid); + if (results.length === 0) return res.status(404).end(); + return res.status(200).json(results[0]); + } + catch (err) { + sysError(logger, res, err); + } +}); module.exports = router; diff --git a/lib/routes/api/applications.js b/lib/routes/api/applications.js index 973a1d3..8c9bb4e 100644 --- a/lib/routes/api/applications.js +++ b/lib/routes/api/applications.js @@ -30,7 +30,7 @@ async function validateDelete(req, sid) { if (assignedPhoneNumbers > 0) throw new DbErrorUnprocessableRequest('cannot delete application with phone numbers'); } -decorate(router, Application, ['*'], preconditions); +decorate(router, Application, ['add', 'update', 'delete', 'retrieve'], preconditions); /** * if account-level privileges, retrieve only applications for that account @@ -40,11 +40,11 @@ router.get('/', async(req, res) => { const logger = req.app.locals.logger; try { let results; - if (req.user.account_sid) results = Application.retrieveAllForAccount(req.user.account_sid); - else if (req.user.service_provider_sid) { - results = Application.retrieveAllForServiceProvider(req.user.service_provider_sid); + if (req.user.hasAccountAuth) results = await Application.retrieveAllForAccount(req.user.account_sid); + else if (req.user.hasAccountAuth) { + results = await Application.retrieveAllForServiceProvider(req.user.service_provider_sid); } - else results = Application.Application.retrieveAll(); + else results = await Application.retrieveAll(); res.status(200).json(results); } catch (err) { sysError(logger, res, err); diff --git a/test/applications.js b/test/applications.js index 6943e07..846bdf2 100644 --- a/test/applications.js +++ b/test/applications.js @@ -44,6 +44,7 @@ test('application tests', async(t) => { auth: authAdmin, json: true, }); + //console.log(`result: ${JSON.stringify(result)}`); t.ok(result.length === 1 , 'successfully queried all applications'); /* query one applications */ diff --git a/test/auth.js b/test/auth.js index d64d560..3b368c6 100644 --- a/test/auth.js +++ b/test/auth.js @@ -94,6 +94,22 @@ test('authentication tests', async(t) => { t.ok(result.statusCode === 201, 'successfully created account B2 using service provider token B'); const accB2 = result.body.sid; + /* using auth token we see two accounts */ + result = await request.get('/Accounts', { + auth: authAdmin, + json: true + }); + //console.log(`result: ${JSON.stringify(result)}`); + t.ok(result.length === 4, 'using admin token we see all accounts'); + + /* using service provider token we see one account */ + result = await request.get('/Accounts', { + auth: {bearer: spA_token}, + json: true + }); + //console.log(`result: ${JSON.stringify(result)}`); + t.ok(result.length === 2, 'using service provider token we see all accounts'); + /* cannot update account from different service provider */ result = await request.put(`/Accounts/${accA1}`, { auth: {bearer: spB_token}, @@ -158,6 +174,14 @@ test('authentication tests', async(t) => { t.ok(result.statusCode === 422 && result.body.msg === 'insufficient permissions to create accounts', 'cannot create an account using an account-level token'); + /* using account token we see one account */ + result = await request.get('/Accounts', { + auth: {bearer: accA1_token}, + json: true + }); + //console.log(`result: ${JSON.stringify(result)}`); + t.ok(result.length === 1, 'using account token we see one account'); + /* cannot update account A2 using auth token for account A1*/ result = await request.put(`/Accounts/${accA2}`, { auth: {bearer: accA1_token},