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

198 lines
5.8 KiB
JavaScript
Raw Normal View History

const app = require('vn-loopback/server/server');
module.exports = Self => {
Object.assign(Self, {
synchronizers: [],
addSynchronizer(synchronizer) {
this.synchronizers.push(synchronizer);
},
2020-11-13 09:33:34 +00:00
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 = instance.getUsers();
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(` -> '${userName}' sinchronized`);
} catch (err) {
console.error(` -> '${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']
}
}
}
}
});
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) {
2020-11-13 09:33:34 +00:00
if (info.user)
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);
}
}
});
};