users: ensure all user objects have groupIds

this prevents ldap/sftp code from detecting user groups
and thus fails to detect membership of a user via operator groups.
This commit is contained in:
Girish Ramakrishnan
2025-08-07 12:28:55 +02:00
parent 063c272aea
commit e390a56f05

View File

@@ -546,12 +546,13 @@ async function isActivated() {
return result[0].total !== 0;
}
async function get(userId) {
assert.strictEqual(typeof userId, 'string');
async function internalGet(fieldName, fieldValue) {
assert.strictEqual(typeof fieldName, 'string');
assert.strictEqual(typeof fieldValue, 'string');
const results = await database.query(`SELECT ${USERS_FIELDS},GROUP_CONCAT(groupMembers.groupId) AS groupIds ` +
' FROM users LEFT OUTER JOIN groupMembers ON users.id = groupMembers.userId ' +
' GROUP BY users.id HAVING users.id = ?', [ userId ]);
' FROM users LEFT OUTER JOIN groupMembers ON users.id = groupMembers.userId ' +
` GROUP BY users.id HAVING users.${fieldName} = ?`, [ fieldValue ]);
if (results.length === 0) return null;
@@ -560,24 +561,14 @@ async function get(userId) {
return postProcess(results[0]);
}
async function getByEmail(email) {
assert.strictEqual(typeof email, 'string');
const result = await database.query(`SELECT ${USERS_FIELDS} FROM users WHERE email = ?`, [ email ]);
if (result.length === 0) return null;
return postProcess(result[0]);
async function get(userId) {
assert.strictEqual(typeof userId, 'string');
return await internalGet('id', userId);
}
async function getByRole(role) {
assert.strictEqual(typeof role, 'string');
// the mailer code relies on the first object being the 'owner' (thus the ORDER)
const results = await database.query(`SELECT ${USERS_FIELDS} FROM users WHERE role=? ORDER BY creationTime`, [ role ]);
results.forEach(postProcess);
return results;
async function getByEmail(email) {
assert.strictEqual(typeof email, 'string');
return await internalGet('email', email);
}
async function getByResetToken(resetToken) {
@@ -586,10 +577,7 @@ async function getByResetToken(resetToken) {
const error = validateToken(resetToken);
if (error) throw error;
const result = await database.query(`SELECT ${USERS_FIELDS} FROM users WHERE resetToken=?`, [ resetToken ]);
if (result.length === 0) return null;
return postProcess(result[0]);
return await internalGet('resetToken', resetToken);
}
async function getByInviteToken(inviteToken) {
@@ -598,19 +586,13 @@ async function getByInviteToken(inviteToken) {
const error = validateToken(inviteToken);
if (error) throw error;
const result = await database.query(`SELECT ${USERS_FIELDS} FROM users WHERE inviteToken=?`, [ inviteToken ]);
if (result.length === 0) return null;
return postProcess(result[0]);
return await internalGet('inviteToken', inviteToken);
}
async function getByUsername(username) {
assert.strictEqual(typeof username, 'string');
const result = await database.query(`SELECT ${USERS_FIELDS} FROM users WHERE username = ?`, [ username ]);
if (result.length === 0) return null;
return postProcess(result[0]);
return await internalGet('username', username);
}
async function update(user, data, auditSource) {
@@ -697,21 +679,38 @@ async function updateProfile(user, profile, auditSource) {
await update(user, profile, auditSource);
}
async function listByRole(role) {
assert.strictEqual(typeof role, 'string');
// the mailer code relies on the first object being the 'owner' (thus the ORDER)
const results = await database.query(`SELECT ${USERS_FIELDS},GROUP_CONCAT(groupMembers.groupId) AS groupIds ` +
' FROM users LEFT OUTER JOIN groupMembers ON users.id = groupMembers.userId ' +
' GROUP BY users.id HAVING role = ? ORDER BY users.creationTime', [ role ]);
results.forEach(function (result) {
result.groupIds = result.groupIds ? result.groupIds.split(',') : [ ];
});
results.forEach(postProcess);
return results;
}
async function getOwner() {
const owners = await getByRole(exports.ROLE_OWNER);
const owners = await listByRole(exports.ROLE_OWNER);
if (owners.length === 0) return null;
return owners[0];
}
async function getAdmins() {
const owners = await getByRole(exports.ROLE_OWNER);
const admins = await getByRole(exports.ROLE_ADMIN);
const owners = await listByRole(exports.ROLE_OWNER);
const admins = await listByRole(exports.ROLE_ADMIN);
return owners.concat(admins);
}
async function getSuperadmins() {
return await getByRole(exports.ROLE_OWNER);
return await listByRole(exports.ROLE_OWNER);
}
async function getPasswordResetLink(user, auditSource) {