salix/modules/account/back/models/account-config.js

167 lines
5.0 KiB
JavaScript
Raw Normal View History

const models = require('vn-loopback/server/server').models;
module.exports = Self => {
Object.assign(Self, {
linkers: [],
addLinker(linker) {
this.linkers.push(linker);
},
async initEngine() {
const accountConfig = await Self.findOne({
2020-11-13 09:33:34 +00:00
fields: ['homedir', 'shell', 'idBase']
});
const mailConfig = await models.MailConfig.findOne({
fields: ['domain']
});
const linkers = [];
for (const Linker of Self.linkers) {
const linker = await Linker.getLinker();
if (!linker) continue;
Object.assign(linker, {accountConfig});
await linker.init();
linkers.push(linker);
}
Object.assign(accountConfig, {
linkers,
domain: mailConfig.domain
});
return {
accountConfig,
linkers
};
},
async deinitEngine(engine) {
for (const linker of engine.linkers)
await linker.deinit();
},
async syncUser(userName, password) {
const engine = await Self.initEngine();
try {
await Self.syncUserBase(engine, userName, password, true);
} finally {
await Self.deinitEngine(engine);
}
},
async syncUsers() {
const engine = await Self.initEngine();
let usersToSync = new Set();
for (const linker of engine.linkers)
await linker.getUsers(usersToSync);
usersToSync = Array.from(usersToSync.values())
.sort((a, b) => a.localeCompare(b));
for (let userName of usersToSync) {
try {
// eslint-disable-next-line no-console
console.log(`Synchronizing user '${userName}'`);
await Self.syncUserBase(engine, userName);
// eslint-disable-next-line no-console
console.log(` -> User '${userName}' sinchronized`);
} catch (err) {
// eslint-disable-next-line no-console
console.error(` -> User '${userName}' synchronization error:`, err.message);
}
}
await Self.deinitEngine(engine);
await Self.syncRoles();
},
async syncUserBase(engine, userName, password, syncGroups) {
if (!userName) return;
userName = userName.toLowerCase();
// Skip conflicting users
if (['administrator', 'root'].indexOf(userName) >= 0)
return;
const user = await models.VnUser.findOne({
where: {name: userName},
fields: [
'id',
'nickname',
'email',
'lang',
'roleFk',
'sync',
'active',
'created',
'password',
'updated'
],
include: [
{
relation: 'roles',
scope: {
include: {
relation: 'inherits',
scope: {
fields: ['name']
}
}
}
}, {
relation: 'role',
fields: ['name']
}
]
});
const info = {
user,
hasAccount: false
};
if (user) {
const exists = await models.Account.exists(user.id);
const {accountConfig} = engine;
Object.assign(info, {
hasAccount: user.active && exists,
corporateMail: `${userName}@${accountConfig.domain}`,
uidNumber: accountConfig.idBase + user.id
});
}
const errs = [];
for (const linker of engine.linkers) {
try {
await linker.syncUser(userName, info, password);
if (syncGroups)
await linker.syncUserGroups(userName, info);
} catch (err) {
errs.push(err);
}
}
if (errs.length) throw errs[0];
},
async syncRoles() {
const engine = await Self.initEngine();
try {
await Self.rawSql(`CALL account.role_sync`);
for (const linker of engine.linkers)
await linker.syncRoles();
} finally {
await Self.deinitEngine(engine);
}
}
});
};