203 lines
6.0 KiB
JavaScript
203 lines
6.0 KiB
JavaScript
|
|
const app = require('vn-loopback/server/server');
|
|
|
|
module.exports = Self => {
|
|
Object.assign(Self, {
|
|
synchronizers: [],
|
|
|
|
addSynchronizer(synchronizer) {
|
|
this.synchronizers.push(synchronizer);
|
|
},
|
|
|
|
async getInstance() {
|
|
let instance = await Self.findOne({
|
|
fields: ['homedir', 'shell', 'idBase']
|
|
});
|
|
await instance.synchronizerInit();
|
|
return instance;
|
|
},
|
|
|
|
async syncUsers() {
|
|
let instance = await Self.getInstance();
|
|
|
|
let usersToSync = await instance.synchronizerGetUsers();
|
|
usersToSync = Array.from(usersToSync.values())
|
|
.sort((a, b) => a.localeCompare(b));
|
|
|
|
for (let userName of usersToSync) {
|
|
try {
|
|
console.log(`Synchronizing user '${userName}'`);
|
|
await instance.synchronizerSyncUser(userName);
|
|
console.log(` -> User '${userName}' sinchronized`);
|
|
} catch (err) {
|
|
console.error(` -> User '${userName}' synchronization error:`, err.message);
|
|
}
|
|
}
|
|
|
|
await instance.synchronizerDeinit();
|
|
await Self.syncRoles();
|
|
},
|
|
|
|
async syncUser(userName, password) {
|
|
let instance = await Self.getInstance();
|
|
try {
|
|
await instance.synchronizerSyncUser(userName, password, true);
|
|
} finally {
|
|
await instance.synchronizerDeinit();
|
|
}
|
|
},
|
|
|
|
async syncRoles() {
|
|
let instance = await Self.getInstance();
|
|
try {
|
|
await instance.synchronizerSyncRoles();
|
|
} finally {
|
|
await instance.synchronizerDeinit();
|
|
}
|
|
},
|
|
|
|
async getSynchronizer() {
|
|
return await Self.findOne();
|
|
}
|
|
});
|
|
|
|
Object.assign(Self.prototype, {
|
|
async synchronizerInit() {
|
|
let mailConfig = await app.models.MailConfig.findOne({
|
|
fields: ['domain']
|
|
});
|
|
|
|
let synchronizers = [];
|
|
|
|
for (let Synchronizer of Self.synchronizers) {
|
|
let synchronizer = await Synchronizer.getSynchronizer();
|
|
if (!synchronizer) continue;
|
|
Object.assign(synchronizer, {
|
|
accountConfig: this
|
|
});
|
|
await synchronizer.init();
|
|
synchronizers.push(synchronizer);
|
|
}
|
|
|
|
Object.assign(this, {
|
|
synchronizers,
|
|
domain: mailConfig.domain
|
|
});
|
|
},
|
|
|
|
async synchronizerDeinit() {
|
|
for (let synchronizer of this.synchronizers)
|
|
await synchronizer.deinit();
|
|
},
|
|
|
|
async synchronizerSyncUser(userName, password, syncGroups) {
|
|
let $ = app.models;
|
|
|
|
if (!userName) return;
|
|
userName = userName.toLowerCase();
|
|
|
|
// Skip conflicting users
|
|
if (['administrator', 'root'].indexOf(userName) >= 0)
|
|
return;
|
|
|
|
let user = await $.Account.findOne({
|
|
where: {name: userName},
|
|
fields: [
|
|
'id',
|
|
'nickname',
|
|
'email',
|
|
'lang',
|
|
'roleFk',
|
|
'sync',
|
|
'active',
|
|
'created',
|
|
'bcryptPassword',
|
|
'updated'
|
|
],
|
|
include: [
|
|
{
|
|
relation: 'roles',
|
|
scope: {
|
|
include: {
|
|
relation: 'inherits',
|
|
scope: {
|
|
fields: ['name']
|
|
}
|
|
}
|
|
}
|
|
}, {
|
|
relation: 'role',
|
|
fields: ['name']
|
|
}
|
|
]
|
|
});
|
|
|
|
let info = {
|
|
user,
|
|
hasAccount: false
|
|
};
|
|
|
|
if (user) {
|
|
let exists = await $.UserAccount.exists(user.id);
|
|
Object.assign(info, {
|
|
hasAccount: user.active && exists,
|
|
corporateMail: `${userName}@${this.domain}`,
|
|
uidNumber: this.idBase + user.id
|
|
});
|
|
}
|
|
|
|
let errs = [];
|
|
|
|
for (let synchronizer of this.synchronizers) {
|
|
try {
|
|
await synchronizer.syncUser(userName, info, password);
|
|
if (syncGroups)
|
|
await synchronizer.syncUserGroups(userName, info);
|
|
} catch (err) {
|
|
errs.push(err);
|
|
}
|
|
}
|
|
|
|
if (errs.length) throw errs[0];
|
|
},
|
|
|
|
async synchronizerGetUsers() {
|
|
let usersToSync = new Set();
|
|
|
|
for (let synchronizer of this.synchronizers)
|
|
await synchronizer.getUsers(usersToSync);
|
|
|
|
return usersToSync;
|
|
},
|
|
|
|
async synchronizerSyncRoles() {
|
|
for (let synchronizer of this.synchronizers)
|
|
await synchronizer.syncRoles();
|
|
},
|
|
|
|
async syncUser(userName, info, password) {
|
|
if (info.user && password)
|
|
await app.models.user.setPassword(info.user.id, password);
|
|
},
|
|
|
|
async getUsers(usersToSync) {
|
|
let accounts = await app.models.UserAccount.find({
|
|
fields: ['id'],
|
|
include: {
|
|
relation: 'user',
|
|
scope: {
|
|
fields: ['name'],
|
|
where: {active: true}
|
|
}
|
|
}
|
|
});
|
|
|
|
for (let account of accounts) {
|
|
let user = account.user();
|
|
if (!user) continue;
|
|
usersToSync.add(user.name);
|
|
}
|
|
}
|
|
});
|
|
};
|