async'ify the groups code
This commit is contained in:
+113
-123
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
exports = module.exports = {
|
||||
create,
|
||||
add,
|
||||
remove,
|
||||
get,
|
||||
getByName,
|
||||
@@ -18,16 +18,16 @@ exports = module.exports = {
|
||||
|
||||
setMembership,
|
||||
getMembership,
|
||||
|
||||
count
|
||||
};
|
||||
|
||||
var assert = require('assert'),
|
||||
const assert = require('assert'),
|
||||
BoxError = require('./boxerror.js'),
|
||||
constants = require('./constants.js'),
|
||||
groupdb = require('./groupdb.js'),
|
||||
uuid = require('uuid'),
|
||||
_ = require('underscore');
|
||||
database = require('./database.js'),
|
||||
safe = require('safetydance'),
|
||||
uuid = require('uuid');
|
||||
|
||||
const GROUPS_FIELDS = [ 'id', 'name', 'source' ].join(',');
|
||||
|
||||
// keep this in sync with validateUsername
|
||||
function validateGroupname(name) {
|
||||
@@ -52,199 +52,189 @@ function validateGroupSource(source) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function create(name, source, callback) {
|
||||
assert.strictEqual(typeof name, 'string');
|
||||
assert.strictEqual(typeof source, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
async function add(group) {
|
||||
assert.strictEqual(typeof group, 'object');
|
||||
|
||||
// we store names in lowercase
|
||||
name = name.toLowerCase();
|
||||
let { name, source } = group;
|
||||
|
||||
var error = validateGroupname(name);
|
||||
if (error) return callback(error);
|
||||
name = name.toLowerCase(); // we store names in lowercase
|
||||
source = source || '';
|
||||
|
||||
let error = validateGroupname(name);
|
||||
if (error) throw error;
|
||||
|
||||
error = validateGroupSource(source);
|
||||
if (error) return callback(error);
|
||||
if (error) throw error;
|
||||
|
||||
var id = 'gid-' + uuid.v4();
|
||||
groupdb.add(id, name, source, function (error) {
|
||||
if (error) return callback(error);
|
||||
const id = `gid-${uuid.v4()}`;
|
||||
|
||||
callback(null, { id: id, name: name });
|
||||
});
|
||||
[error] = await safe(database.query('INSERT INTO userGroups (id, name, source) VALUES (?, ?, ?)', [ id, name, source ]));
|
||||
if (error && error.code === 'ER_DUP_ENTRY') throw new BoxError(BoxError.ALREADY_EXISTS, error);
|
||||
if (error) throw error;
|
||||
|
||||
return { id, name };
|
||||
}
|
||||
|
||||
function remove(id, callback) {
|
||||
async function remove(id) {
|
||||
assert.strictEqual(typeof id, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
groupdb.del(id, function (error) {
|
||||
if (error) return callback(error);
|
||||
// also cleanup the groupMembers table
|
||||
let queries = [];
|
||||
queries.push({ query: 'DELETE FROM groupMembers WHERE groupId = ?', args: [ id ] });
|
||||
queries.push({ query: 'DELETE FROM userGroups WHERE id = ?', args: [ id ] });
|
||||
|
||||
callback(null);
|
||||
});
|
||||
const result = await database.transaction(queries);
|
||||
if (result[1].affectedRows !== 1) throw new BoxError(BoxError.NOT_FOUND, 'Group not found');
|
||||
}
|
||||
|
||||
function get(id, callback) {
|
||||
async function get(id) {
|
||||
assert.strictEqual(typeof id, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
groupdb.get(id, function (error, result) {
|
||||
if (error) return callback(error);
|
||||
const result = await database.query(`SELECT ${GROUPS_FIELDS} FROM userGroups WHERE id = ? ORDER BY name`, [ id ]);
|
||||
if (result.length === 0) return null;
|
||||
|
||||
return callback(null, result);
|
||||
});
|
||||
return result[0];
|
||||
}
|
||||
|
||||
function getByName(name, callback) {
|
||||
async function getByName(name) {
|
||||
assert.strictEqual(typeof name, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
groupdb.getByName(name, function (error, result) {
|
||||
if (error) return callback(error);
|
||||
const result = await database.query(`SELECT ${GROUPS_FIELDS} FROM userGroups WHERE name = ?`, [ name ]);
|
||||
if (result.length === 0) return null;
|
||||
|
||||
return callback(null, result);
|
||||
});
|
||||
return result[0];
|
||||
}
|
||||
|
||||
function getWithMembers(id, callback) {
|
||||
async function getWithMembers(id) {
|
||||
assert.strictEqual(typeof id, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
groupdb.getWithMembers(id, function (error, result) {
|
||||
if (error) return callback(error);
|
||||
const results = await database.query('SELECT ' + GROUPS_FIELDS + ',GROUP_CONCAT(groupMembers.userId) AS userIds ' +
|
||||
' FROM userGroups LEFT OUTER JOIN groupMembers ON userGroups.id = groupMembers.groupId ' +
|
||||
' WHERE userGroups.id = ? ' +
|
||||
' GROUP BY userGroups.id', [ id ]);
|
||||
|
||||
return callback(null, result);
|
||||
});
|
||||
if (results.length === 0) return null;
|
||||
|
||||
const result = results[0];
|
||||
result.userIds = result.userIds ? result.userIds.split(',') : [ ];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function getAll(callback) {
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
groupdb.getAll(function (error, result) {
|
||||
if (error) return callback(error);
|
||||
|
||||
return callback(null, result);
|
||||
});
|
||||
async function getAll() {
|
||||
const results = await database.query('SELECT ' + GROUPS_FIELDS + ' FROM userGroups ORDER BY name');
|
||||
return results;
|
||||
}
|
||||
|
||||
function getAllWithMembers(callback) {
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
async function getAllWithMembers() {
|
||||
const results = await database.query('SELECT ' + GROUPS_FIELDS + ',GROUP_CONCAT(groupMembers.userId) AS userIds ' +
|
||||
' FROM userGroups LEFT OUTER JOIN groupMembers ON userGroups.id = groupMembers.groupId ' +
|
||||
' GROUP BY userGroups.id ORDER BY name');
|
||||
|
||||
groupdb.getAllWithMembers(function (error, result) {
|
||||
if (error) return callback(error);
|
||||
|
||||
return callback(null, result);
|
||||
});
|
||||
results.forEach(function (result) { result.userIds = result.userIds ? result.userIds.split(',') : [ ]; });
|
||||
return results;
|
||||
}
|
||||
|
||||
function getMembers(groupId, callback) {
|
||||
async function getMembers(groupId) {
|
||||
assert.strictEqual(typeof groupId, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
groupdb.getMembers(groupId, function (error, result) {
|
||||
if (error) return callback(error);
|
||||
const result = await database.query('SELECT userId FROM groupMembers WHERE groupId=?', [ groupId ]);
|
||||
|
||||
return callback(null, result);
|
||||
});
|
||||
return result.map(function (r) { return r.userId; });
|
||||
}
|
||||
|
||||
function getMembership(userId, callback) {
|
||||
async function getMembership(userId) {
|
||||
assert.strictEqual(typeof userId, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
groupdb.getMembership(userId, function (error, result) {
|
||||
if (error) return callback(error);
|
||||
const result = await database.query('SELECT groupId FROM groupMembers WHERE userId=? ORDER BY groupId', [ userId ]);
|
||||
|
||||
return callback(null, result);
|
||||
});
|
||||
return result.map(function (r) { return r.groupId; });
|
||||
}
|
||||
|
||||
function setMembership(userId, groupIds, callback) {
|
||||
async function setMembership(userId, groupIds) {
|
||||
assert.strictEqual(typeof userId, 'string');
|
||||
assert(Array.isArray(groupIds));
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
groupdb.setMembership(userId, groupIds, function (error) {
|
||||
if (error) return callback(error);
|
||||
|
||||
return callback(null);
|
||||
let queries = [ ];
|
||||
queries.push({ query: 'DELETE from groupMembers WHERE userId = ?', args: [ userId ] });
|
||||
groupIds.forEach(function (gid) {
|
||||
queries.push({ query: 'INSERT INTO groupMembers (groupId, userId) VALUES (? , ?)', args: [ gid, userId ] });
|
||||
});
|
||||
|
||||
const [error] = await safe(database.transaction(queries));
|
||||
if (error && error.code === 'ER_NO_REFERENCED_ROW_2') throw new BoxError(BoxError.NOT_FOUND, error.message);
|
||||
if (error && error.code === 'ER_DUP_ENTRY') throw new BoxError(BoxError.CONFLICT, 'Already member');
|
||||
if (error) throw error;
|
||||
}
|
||||
|
||||
function addMember(groupId, userId, callback) {
|
||||
async function addMember(groupId, userId) {
|
||||
assert.strictEqual(typeof groupId, 'string');
|
||||
assert.strictEqual(typeof userId, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
groupdb.addMember(groupId, userId, function (error) {
|
||||
if (error) return callback(error);
|
||||
|
||||
return callback(null);
|
||||
});
|
||||
const [error] = await safe(database.query('INSERT INTO groupMembers (groupId, userId) VALUES (?, ?)', [ groupId, userId ]));
|
||||
if (error && error.code === 'ER_DUP_ENTRY') throw new BoxError(BoxError.ALREADY_EXISTS, error);
|
||||
if (error && error.code === 'ER_NO_REFERENCED_ROW_2' && error.sqlMessage.includes('userId')) throw new BoxError(BoxError.NOT_FOUND, 'User not found');
|
||||
if (error && error.code === 'ER_NO_REFERENCED_ROW_2') throw new BoxError(BoxError.NOT_FOUND, 'Group not found');
|
||||
if (error) throw error;
|
||||
}
|
||||
|
||||
function setMembers(groupId, userIds, callback) {
|
||||
async function setMembers(groupId, userIds) {
|
||||
assert.strictEqual(typeof groupId, 'string');
|
||||
assert(Array.isArray(userIds));
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
groupdb.setMembers(groupId, userIds, function (error) {
|
||||
if (error) return callback(error);
|
||||
let queries = [];
|
||||
queries.push({ query: 'DELETE FROM groupMembers WHERE groupId = ?', args: [ groupId ] });
|
||||
for (let i = 0; i < userIds.length; i++) {
|
||||
queries.push({ query: 'INSERT INTO groupMembers (groupId, userId) VALUES (?, ?)', args: [ groupId, userIds[i] ] });
|
||||
}
|
||||
|
||||
return callback(null);
|
||||
});
|
||||
const [error] = await safe(database.transaction(queries));
|
||||
if (error && error.code === 'ER_NO_REFERENCED_ROW_2') throw new BoxError(BoxError.NOT_FOUND, 'Group not found');
|
||||
if (error && error.code === 'ER_DUP_ENTRY') throw new BoxError(BoxError.CONFLICT, 'Duplicate member in list');
|
||||
if (error) throw error;
|
||||
}
|
||||
|
||||
function removeMember(groupId, userId, callback) {
|
||||
async function removeMember(groupId, userId) {
|
||||
assert.strictEqual(typeof groupId, 'string');
|
||||
assert.strictEqual(typeof userId, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
groupdb.removeMember(groupId, userId, function (error) {
|
||||
if (error) return callback(error);
|
||||
|
||||
return callback(null);
|
||||
});
|
||||
const result = await database.query('DELETE FROM groupMembers WHERE groupId = ? AND userId = ?', [ groupId, userId ]);
|
||||
if (result.affectedRows !== 1) throw new BoxError(BoxError.NOT_FOUND, 'Group not found');
|
||||
}
|
||||
|
||||
function isMember(groupId, userId, callback) {
|
||||
async function isMember(groupId, userId) {
|
||||
assert.strictEqual(typeof groupId, 'string');
|
||||
assert.strictEqual(typeof userId, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
groupdb.isMember(groupId, userId, function (error, result) {
|
||||
if (error) return callback(error);
|
||||
|
||||
return callback(null, result);
|
||||
});
|
||||
const result = await database.query('SELECT 1 FROM groupMembers WHERE groupId=? AND userId=?', [ groupId, userId ]);
|
||||
return result.length !== 0;
|
||||
}
|
||||
|
||||
function update(groupId, data, callback) {
|
||||
assert.strictEqual(typeof groupId, 'string');
|
||||
async function update(id, data) {
|
||||
assert.strictEqual(typeof id, 'string');
|
||||
assert(data && typeof data === 'object');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
let error;
|
||||
if ('name' in data) {
|
||||
assert.strictEqual(typeof data.name, 'string');
|
||||
error = validateGroupname(data.name);
|
||||
if (error) return callback(error);
|
||||
if (error) throw error;
|
||||
}
|
||||
|
||||
groupdb.update(groupId, _.pick(data, 'name'), function (error) {
|
||||
if (error) return callback(error);
|
||||
let args = [ ];
|
||||
let fields = [ ];
|
||||
for (let k in data) {
|
||||
if (k === 'name') {
|
||||
assert.strictEqual(typeof data.name, 'string');
|
||||
fields.push(k + ' = ?');
|
||||
args.push(data.name);
|
||||
}
|
||||
}
|
||||
args.push(id);
|
||||
|
||||
callback(null);
|
||||
});
|
||||
}
|
||||
|
||||
function count(callback) {
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
groupdb.count(function (error, count) {
|
||||
if (error) return callback(error);
|
||||
|
||||
callback(null, count);
|
||||
});
|
||||
let result;
|
||||
[error, result] = safe(database.query('UPDATE userGroups SET ' + fields.join(', ') + ' WHERE id = ?', args));
|
||||
if (error && error.code === 'ER_DUP_ENTRY' && error.sqlMessage.indexOf('userGroups_name') !== -1) throw new BoxError(BoxError.ALREADY_EXISTS, 'name already exists');
|
||||
if (error) throw error;
|
||||
if (result.affectedRows !== 1) throw new BoxError(BoxError.NOT_FOUND, 'Group not found');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user