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

113 lines
4.3 KiB
JavaScript

module.exports = Self => {
Self.getSynchronizer = async function() {
let NODE_ENV = process.env.NODE_ENV;
if (!NODE_ENV || NODE_ENV == 'development')
return null;
return await Self.findOne({
fields: ['id', 'rolePrefix', 'userPrefix', 'userHost']
});
};
Object.assign(Self.prototype, {
async init() {
const [row] = await Self.rawSql('SELECT VERSION() AS `version`');
if (row.version.includes('MariaDB'))
this.dbType = 'MariaDB';
else
this.dbType = 'MySQL';
},
async syncUser(userName, info, password) {
let mysqlUser = userName;
if (this.dbType == 'MySQL')
mysqlUser = this.userPrefix + mysqlUser;
const [row] = await Self.rawSql(
`SELECT COUNT(*) AS nRows
FROM mysql.user
WHERE User = ? AND Host = ?`,
[mysqlUser, this.userHost]
);
let userExists = row.nRows > 0;
let isUpdatable = true;
if (this.dbType == 'MariaDB') {
const [row] = await Self.rawSql(
`SELECT Priv AS priv
FROM mysql.global_priv
WHERE User = ? AND Host = ?`,
[mysqlUser, this.userHost]
);
const priv = row && JSON.parse(row.priv);
isUpdatable = !row || (priv && priv.autogenerated);
}
if (!isUpdatable) {
console.warn(`RoleConfig.syncUser(): User '${userName}' cannot be updated, not managed by me`);
return;
}
if (info.hasAccount) {
if (password) {
if (!userExists) {
await Self.rawSql('CREATE USER ?@? IDENTIFIED BY ?',
[mysqlUser, this.userHost, password]);
await Self.rawSql(
`UPDATE mysql.global_priv
SET Priv = JSON_SET(Priv, '$.autogenerated' , TRUE)
WHERE User = ? AND Host = ?`,
[mysqlUser, this.userHost]
);
userExists = true;
} else {
switch (this.dbType) {
case 'MariaDB':
await Self.rawSql('ALTER USER ?@? IDENTIFIED BY ?',
[mysqlUser, this.userHost, password]);
break;
default:
await Self.rawSql('SET PASSWORD FOR ?@? = PASSWORD(?)',
[mysqlUser, this.userHost, password]);
}
}
}
if (userExists && this.dbType == 'MariaDB') {
let role = `${this.rolePrefix}${info.user.role().name}`;
try {
await Self.rawSql('REVOKE ALL, GRANT OPTION FROM ?@?',
[mysqlUser, this.userHost]);
} catch (err) {
if (err.code == 'ER_REVOKE_GRANTS')
console.warn(`${err.code}: ${err.sqlMessage}: ${err.sql}`);
else
throw err;
}
const [row] = await Self.rawSql(
`SELECT COUNT(*) AS nRows
FROM mysql.user
WHERE User = ? AND Host = ''`,
[role]
);
const roleExists = row.nRows > 0;
if (roleExists) {
await Self.rawSql('GRANT ? TO ?@?',
[role, mysqlUser, this.userHost]);
await Self.rawSql('SET DEFAULT ROLE ? FOR ?@?',
[role, mysqlUser, this.userHost]);
} else {
await Self.rawSql('SET DEFAULT ROLE NONE FOR ?@?',
[mysqlUser, this.userHost]);
}
}
} else if (userExists)
await Self.rawSql('DROP USER ?@?', [mysqlUser, this.userHost]);
}
});
};