拆分域管理与系统管理

This commit is contained in:
masnn committed 2020-06-04 13:27:44 +08:00
1 parent 385e46ae42
commit faec4744d7
24 files changed
+249 -168

No files matched your search

+147
View File
@@ -0,0 +1,147 @@
const user = require('../model/user');
const domain = require('../model/domain');
const { Route, Handler } = require('../service/server');
const { PERM_MANAGE } = require('../permission');
const { RoleAlreadyExistError, ValidationError } = require('../error');
class ManageHandler extends Handler {
async prepare({ domainId }) {
this.checkPerm(PERM_MANAGE);
this.domain = await domain.get(domainId);
}
}
class DomainEditHandler extends ManageHandler {
async get() {
const path = [
['Hydro', '/'],
['domain', '/domain'],
['domain_edit', null],
];
this.response.template = 'domain_edit.html';
this.response.body = { domain: this.domain, path };
}
async post({
domainId, name, gravatar, bulletin,
}) {
await domain.edit(domainId, { name, gravatar, bulletin });
this.response.redirect = '/domain/dashboard';
}
}
class DomainDashboardHandler extends ManageHandler {
async get() {
const path = [
['Hydro', '/'],
['domain', '/domain'],
['domain_dashboard', null],
];
this.response.template = 'domain_dashboard.html';
this.response.body = { domain: this.domain, path };
}
}
class DomainUserHandler extends ManageHandler {
async get({ domainId }) {
const uids = [];
const rudocs = {};
const [udocs, roles] = await Promise.all([
user.getInDomain(domainId),
user.getRoles(domainId),
]);
for (const role of roles) rudocs[role._id] = [];
for (const udoc of udocs) {
uids.push(udoc.uid);
// TODO Improve here
// eslint-disable-next-line no-await-in-loop
const ud = await user.getById(domainId, udoc.uid);
rudocs[udoc.role].push({ ...ud, role: udoc.role });
}
const rolesSelect = roles.map((role) => [role._id, role._id]);
const udict = await user.getList(domainId, uids);
const path = [
['Hydro', '/'],
['domain', '/domain'],
['domain_user', null],
];
this.response.template = 'domain_user.html';
this.response.body = {
roles, rolesSelect, rudocs, udict, path, domain: this.domain,
};
}
async postSetUser({ domainId, uid, role }) {
await user.setRole(domainId, uid, role);
this.back();
}
}
class DomainPermissionHandler extends ManageHandler {
async get({ domainId }) {
const roles = await user.getRoles(domainId);
const path = [
['Hydro', '/'],
['domain', '/domain'],
['domain_permission', null],
];
this.response.template = 'domain_permission.html';
this.response.body = { roles, domain: this.domain, path };
}
async post({ domainId }) {
const roles = {};
for (const role in this.request.body) {
if (this.request.body[role] instanceof Array) {
roles[role] = this.request.body[role].join('');
}
}
await user.setRoles(domainId, roles);
this.back();
}
}
class DomainRoleHandler extends ManageHandler {
async get({ domainId }) {
const roles = await user.getRoles(domainId);
const path = [
['Hydro', '/'],
['domain', '/domain'],
['domain_role', null],
];
this.response.template = 'domain_role.html';
this.response.body = { roles, domain: this.domain, path };
}
async postAdd({ domainId, role }) {
const [r, u] = await Promise.all([
user.getRole(domainId, role),
user.getRole(domainId, 'default'),
]);
if (r) throw new RoleAlreadyExistError(role);
await user.addRole(domainId, role, u.perm);
this.back();
}
async postDelete({ roles }) {
for (const role of roles) {
if (['root', 'default', 'guest'].includes(role)) {
throw new ValidationError('role');
}
}
await user.deleteRoles(roles);
this.back();
}
}
async function apply() {
Route('/domain/dashboard', DomainDashboardHandler);
Route('/domain/edit', DomainEditHandler);
Route('/domain/user', DomainUserHandler);
Route('/domain/permission', DomainPermissionHandler);
Route('/domain/role', DomainRoleHandler);
}
global.Hydro.handler.domain = module.exports = {
apply,
};
+1 -128
View File
@@ -1,4 +1,3 @@
const user = require('../model/user');
const domain = require('../model/domain');
const setting = require('../model/setting');
const system = require('../model/system');
@@ -6,7 +5,7 @@ const { Route, Handler } = require('../service/server');
const { PERM_MANAGE } = require('../permission');
const hpm = require('../lib/hpm');
const loader = require('../loader');
const { RoleAlreadyExistError, ValidationError, PermissionError } = require('../error');
const { PermissionError } = require('../error');
class ManageHandler extends Handler {
async prepare({ domainId }) {
@@ -33,124 +32,6 @@ class ManageDashboardHandler extends ManageHandler {
}
}
class ManageEditHandler extends ManageHandler {
async get() {
const path = [
['Hydro', '/'],
['manage', '/manage'],
['manage_edit', null],
];
this.response.template = 'manage_edit.html';
this.response.body = { domain: this.domain, path };
}
async post({
domainId, name, gravatar, bulletin,
}) {
await domain.edit(domainId, { name, gravatar, bulletin });
this.response.redirect = '/manage/dashboard';
}
}
class ManageUserHandler extends ManageHandler {
async get({ domainId }) {
// FIXME(masnn) UPDATE CODE
const uids = [];
const rudocs = {};
const [udocs, roles] = await Promise.all([
user.getInDomain(domainId),
user.getRoles(domainId),
]);
for (const role of roles) rudocs[role._id] = [];
for (const udoc of udocs) {
uids.push(udoc.uid);
// TODO Improve here
// eslint-disable-next-line no-await-in-loop
const ud = await user.getById(domainId, udoc.uid);
rudocs[udoc.role].push({ ...ud, role: udoc.role });
}
const rolesSelect = roles.map((role) => [role._id, role._id]);
const udict = await user.getList(domainId, uids);
const path = [
['Hydro', '/'],
['manage', '/manage'],
['manage_user', null],
];
this.response.template = 'manage_user.html';
this.response.body = {
roles, rolesSelect, rudocs, udict, path,
};
}
async postSetUser({ domainId, uid, role }) {
await user.setRole(domainId, uid, role);
this.back();
}
}
class ManagePermissionHandler extends ManageHandler {
async get({ domainId }) {
const [roles, d] = await Promise.all([
user.getRoles(domainId),
domain.get(domainId),
]);
const path = [
['Hydro', '/'],
['manage', '/manage'],
['manage_permission', null],
];
this.response.template = 'manage_permission.html';
this.response.body = { roles, domain: d, path };
}
async post({ domainId }) {
const roles = {};
for (const role in this.request.body) {
if (this.request.body[role] instanceof Array) {
roles[role] = this.request.body[role].join('');
}
}
await user.setRoles(domainId, roles);
this.back();
}
}
class ManageRoleHandler extends ManageHandler {
async get({ domainId }) {
const [roles, d] = await Promise.all([
user.getRoles(domainId),
domain.get(domainId),
]);
const path = [
['Hydro', '/'],
['manage', '/manage'],
['manage_role', null],
];
this.response.template = 'manage_role.html';
this.response.body = { roles, domain: d, path };
}
async postAdd({ domainId, role }) {
const [r, u] = await Promise.all([
user.getRole(domainId, role),
user.getRole(domainId, 'default'),
]);
if (r) throw new RoleAlreadyExistError(role);
await user.addRole(domainId, role, u.perm);
this.back();
}
async postDelete({ roles }) {
for (const role of roles) {
if (['root', 'default', 'guest'].includes(role)) {
throw new ValidationError('role');
}
}
await user.deleteRoles(roles);
this.back();
}
}
class SystemHandler extends Handler {
async prepare() {
if (!this.user.priv) throw new PermissionError('???');
@@ -210,10 +91,6 @@ class SystemSettingHandler extends SystemHandler {
async function apply() {
Route('/manage', module.exports.ManageMainHandler);
Route('/manage/dashboard', module.exports.ManageDashboardHandler);
Route('/manage/edit', module.exports.ManageEditHandler);
Route('/manage/user', module.exports.ManageUserHandler);
Route('/manage/permission', module.exports.ManagePermissionHandler);
Route('/manage/role', module.exports.ManageRoleHandler);
Route('/manage/module', SystemModuleHandler);
Route('/manage/setting', SystemSettingHandler);
}
@@ -221,10 +98,6 @@ async function apply() {
global.Hydro.handler.manage = module.exports = {
ManageMainHandler,
ManageDashboardHandler,
ManageEditHandler,
ManageUserHandler,
ManagePermissionHandler,
ManageRoleHandler,
SystemModuleHandler,
SystemSettingHandler,
apply,
+8 -1
View File
@@ -32,7 +32,13 @@ class StatusHandler extends Handler {
class StatusUpdateHandler extends Handler {
async post(args) {
this.checkPerm(PERM_JUDGE);
await coll.updateOne({ _id: args._id }, { $set: args }, { upsert: true });
await coll.updateOne({ _id: args._id }, { $set: { ...args, type: 'judger' } }, { upsert: true });
}
}
class SwitchLanguageHandler extends Handler {
async get({ lang }) {
this.session.language = lang;
}
}
@@ -41,6 +47,7 @@ async function apply() {
Route('/fs/:id/:name/:secret', FileDownloadHandler);
Route('/status', StatusHandler);
Route('/status/update', StatusUpdateHandler);
Route('/language/:lang', SwitchLanguageHandler);
}
global.Hydro.handler.misc = module.exports = {
+4 -2
View File
@@ -54,7 +54,7 @@ class UserRegisterHandler extends Handler {
}
async post({ mail }) {
if (await user.getByEmail(mail, true)) throw new UserAlreadyExistError(mail);
if (await user.getByEmail('system', mail, true)) throw new UserAlreadyExistError(mail);
this.limitRate('send_mail', 3600, 30);
const t = await token.add(
token.TYPE_REGISTRATION,
@@ -62,7 +62,9 @@ class UserRegisterHandler extends Handler {
{ mail },
);
if (await system.get('smtp.user')) {
const m = await this.renderHTML('user_register_mail', { url: `/register/${t[0]}` });
const m = await this.renderHTML('user_register_mail.html', {
url: `${await system.get('baseurl')}/register/${t[0]}`,
});
await sendMail(mail, 'Sign Up', 'user_register_mail', m);
this.response.template = 'user_register_mail_sent.html';
} else {
+1 -1
View File
@@ -14,6 +14,6 @@ Item('/t', 'training_main', 'training', permission.PERM_VIEW_TRAINING);
Item('/homework', 'homework_main', 'homework', permission.PERM_VIEW_HOMEWORK);
Item('/discuss', 'discussion_main', 'discussion', permission.PERM_VIEW_DISCUSSION);
Item('/c', 'contest_main', 'contest', permission.PERM_VIEW_CONTEST);
Item('/manage', 'manage', 'manage', permission.PERM_MANAGE);
Item('/domain', 'domain_dashboard', 'domain', permission.PERM_MANAGE);
global.Hydro.lib.nav = module.exports = Item;
+1 -1
View File
@@ -252,7 +252,7 @@ async function load() {
const builtinHandler = [
'home', 'problem', 'record', 'judge', 'user',
'contest', 'training', 'discussion', 'manage', 'import',
'misc', 'homework',
'misc', 'homework', 'domain',
];
for (const i of builtinHandler) require(`./handler/${i}`);
await model();
+1
View File
@@ -44,6 +44,7 @@ const SETTINGS_BY_KEY = {};
for (const setting in SETTINGS) SETTINGS_BY_KEY[setting.key] = setting;
const SYSTEM_SETTINGS = [
Setting('setting_basic', 'user.register', null, false, 'checkbox', 'Allow register'),
Setting('setting_smtp', 'smtp.user', null, null, 'text', 'SMTP Username'),
Setting('setting_smtp', 'smtp.pass', null, null, 'password', 'SMTP Password'),
Setting('setting_smtp', 'smtp.host', null, null, 'text', 'SMTP Server Host'),
+1 -1
View File
@@ -16,7 +16,7 @@ async function postInit() {
const info = await sysinfo.get();
await coll.updateOne(
{ _id: info._id },
{ $set: { ...info, updateAt: new Date() } },
{ $set: { ...info, updateAt: new Date(), type: 'server' } },
{ upsert: true },
);
setInterval(update, 3 * 60 * 1000);