167 lines
5.0 KiB
JavaScript
167 lines
5.0 KiB
JavaScript
|
|
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({
|
|
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);
|
|
}
|
|
}
|
|
});
|
|
};
|