115 lines
4.4 KiB
JavaScript
115 lines
4.4 KiB
JavaScript
|
|
module.exports = Self => {
|
|
Self.getLinker = 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) {
|
|
// eslint-disable-next-line no-console
|
|
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')
|
|
// eslint-disable-next-line no-console
|
|
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]);
|
|
}
|
|
});
|
|
};
|