groups: members cannot be set for external groups
This commit is contained in:
@@ -6,6 +6,7 @@ exports = module.exports = {
|
||||
get,
|
||||
getByName,
|
||||
|
||||
update,
|
||||
setName,
|
||||
|
||||
getWithMembers,
|
||||
@@ -27,13 +28,14 @@ const assert = require('assert'),
|
||||
BoxError = require('./boxerror.js'),
|
||||
constants = require('./constants.js'),
|
||||
database = require('./database.js'),
|
||||
externalLdap = require('./externalldap.js'),
|
||||
safe = require('safetydance'),
|
||||
uuid = require('uuid');
|
||||
|
||||
const GROUPS_FIELDS = [ 'id', 'name', 'source' ].join(',');
|
||||
|
||||
// keep this in sync with validateUsername
|
||||
function validateGroupname(name) {
|
||||
function validateName(name) {
|
||||
assert.strictEqual(typeof name, 'string');
|
||||
|
||||
if (name.length < 1) return new BoxError(BoxError.BAD_FIELD, 'name must be atleast 1 char');
|
||||
@@ -47,7 +49,7 @@ function validateGroupname(name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function validateGroupSource(source) {
|
||||
function validateSource(source) {
|
||||
assert.strictEqual(typeof source, 'string');
|
||||
|
||||
if (source !== '' && source !== 'ldap') return new BoxError(BoxError.BAD_FIELD, 'source must be "" or "ldap"');
|
||||
@@ -63,10 +65,10 @@ async function add(group) {
|
||||
name = name.toLowerCase(); // we store names in lowercase
|
||||
source = source || '';
|
||||
|
||||
let error = validateGroupname(name);
|
||||
let error = validateName(name);
|
||||
if (error) throw error;
|
||||
|
||||
error = validateGroupSource(source);
|
||||
error = validateSource(source);
|
||||
if (error) throw error;
|
||||
|
||||
const id = `gid-${uuid.v4()}`;
|
||||
@@ -154,14 +156,19 @@ async function getMembership(userId) {
|
||||
return result.map(function (r) { return r.groupId; });
|
||||
}
|
||||
|
||||
async function setMembership(userId, groupIds) {
|
||||
assert.strictEqual(typeof userId, 'string');
|
||||
async function setMembership(user, groupIds) {
|
||||
assert.strictEqual(typeof user, 'object');
|
||||
assert(Array.isArray(groupIds));
|
||||
|
||||
if (user.source === 'ldap') {
|
||||
const config = await externalLdap.getConfig();
|
||||
if (config.syncGroups) throw new BoxError(BoxError.BAD_STATE, 'Cannot set groups of external user when syncing groups');
|
||||
}
|
||||
|
||||
let queries = [ ];
|
||||
queries.push({ query: 'DELETE from groupMembers WHERE userId = ?', args: [ userId ] });
|
||||
queries.push({ query: 'DELETE from groupMembers WHERE userId = ?', args: [ user.id ] });
|
||||
groupIds.forEach(function (gid) {
|
||||
queries.push({ query: 'INSERT INTO groupMembers (groupId, userId) VALUES (? , ?)', args: [ gid, userId ] });
|
||||
queries.push({ query: 'INSERT INTO groupMembers (groupId, userId) VALUES (? , ?)', args: [ gid, user.id ] });
|
||||
});
|
||||
|
||||
const [error] = await safe(database.transaction(queries));
|
||||
@@ -170,14 +177,17 @@ async function setMembership(userId, groupIds) {
|
||||
if (error) throw error;
|
||||
}
|
||||
|
||||
async function setMembers(groupId, userIds) {
|
||||
assert.strictEqual(typeof groupId, 'string');
|
||||
async function setMembers(group, userIds, options) {
|
||||
assert.strictEqual(typeof group, 'object');
|
||||
assert(Array.isArray(userIds));
|
||||
assert.strictEqual(typeof options, 'object');
|
||||
|
||||
let queries = [];
|
||||
queries.push({ query: 'DELETE FROM groupMembers WHERE groupId = ?', args: [ groupId ] });
|
||||
if (!options.skipSourceCheck && group.source === 'ldap') throw new BoxError(BoxError.BAD_STATE, 'Cannot set members of external group');
|
||||
|
||||
const queries = [];
|
||||
queries.push({ query: 'DELETE FROM groupMembers WHERE groupId = ?', args: [ group.id ] });
|
||||
for (let i = 0; i < userIds.length; i++) {
|
||||
queries.push({ query: 'INSERT INTO groupMembers (groupId, userId) VALUES (?, ?)', args: [ groupId, userIds[i] ] });
|
||||
queries.push({ query: 'INSERT INTO groupMembers (groupId, userId) VALUES (?, ?)', args: [ group.id, userIds[i] ] });
|
||||
}
|
||||
|
||||
const [error] = await safe(database.transaction(queries));
|
||||
@@ -202,20 +212,46 @@ async function isMember(groupId, userId) {
|
||||
return result.length !== 0;
|
||||
}
|
||||
|
||||
async function update(id, data) {
|
||||
assert.strictEqual(typeof id, 'string');
|
||||
assert(data && typeof data === 'object');
|
||||
|
||||
if ('name' in data) {
|
||||
assert.strictEqual(typeof data.name, 'string');
|
||||
data.name = data.name.toLowerCase();
|
||||
const error = validateName(data.name);
|
||||
if (error) throw error;
|
||||
}
|
||||
|
||||
if ('source' in data) {
|
||||
assert.strictEqual(typeof data.source, 'string');
|
||||
const error = validateSource(data.source);
|
||||
if (error) throw error;
|
||||
}
|
||||
|
||||
const args = [];
|
||||
const fields = [];
|
||||
for (const k in data) {
|
||||
if (k === 'name' || k === 'source') {
|
||||
fields.push(k + ' = ?');
|
||||
args.push(data[k]);
|
||||
}
|
||||
}
|
||||
args.push(id);
|
||||
|
||||
const [updateError, result] = await safe(database.query('UPDATE userGroups SET ' + fields.join(', ') + ' WHERE id = ?', args));
|
||||
if (updateError && updateError.code === 'ER_DUP_ENTRY' && updateError.sqlMessage.indexOf('userGroups_name') !== -1) throw new BoxError(BoxError.ALREADY_EXISTS, 'name already exists');
|
||||
if (updateError) throw updateError;
|
||||
if (result.affectedRows !== 1) throw new BoxError(BoxError.NOT_FOUND, 'Group not found');
|
||||
}
|
||||
|
||||
async function setName(group, name) {
|
||||
assert.strictEqual(typeof group, 'object');
|
||||
assert.strictEqual(typeof name, 'string');
|
||||
|
||||
if (group.source === 'ldap') throw new BoxError(BoxError.BAD_STATE, 'Cannot set name of external group');
|
||||
|
||||
name = name.toLowerCase(); // we store names in lowercase
|
||||
const error = validateGroupname(name);
|
||||
if (error) throw error;
|
||||
|
||||
const [updateError, result] = await safe(database.query('UPDATE userGroups SET name = ? WHERE id = ?', [ name, group.id ]));
|
||||
if (updateError && updateError.code === 'ER_DUP_ENTRY' && updateError.sqlMessage.indexOf('userGroups_name') !== -1) throw new BoxError(BoxError.ALREADY_EXISTS, 'name already exists');
|
||||
if (updateError) throw updateError;
|
||||
if (result.affectedRows !== 1) throw new BoxError(BoxError.NOT_FOUND, 'Group not found');
|
||||
await update(group.id, { name });
|
||||
}
|
||||
|
||||
async function resetSource() {
|
||||
|
||||
Reference in New Issue
Block a user