mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-19 09:38:19 +08:00
feat: validator decorator
This commit is contained in:
1 parent
ba03d7a7bf
commit
4e85b696c0
23 files changed
+313
-180
No files matched your search
@@ -1,66 +0,0 @@
|
||||
const description = 'Add blacklist by ip, uid';
|
||||
|
||||
// This code format is just for fun. DO NOT DO THIS IN YOUR CODE !
|
||||
/* eslint-disable */
|
||||
const { ObjectID } = require('mongodb');
|
||||
const document = require('../model/document');
|
||||
const discussion = require('../model/discussion');
|
||||
const user = require('../model/user');
|
||||
const blacklist = require('../model/blacklist');
|
||||
const db = require('../service/db');
|
||||
|
||||
async function _address(ip, bset, uset, dset, dryrun, report) {
|
||||
if (bset.has(ip))
|
||||
return
|
||||
bset.add(ip)
|
||||
report({ message: `ip ${ip}` })
|
||||
const users = await db.collection('user').find({ loginip: ip }).toArray()
|
||||
const tasks = []
|
||||
for (const udoc of users) {
|
||||
tasks.push(_user(udoc._id, bset, uset, dset, dryrun, report)) }
|
||||
await Promise.all(tasks)
|
||||
if (!dryrun)
|
||||
await blacklist.add(ip) }
|
||||
|
||||
async function _discussion(domainId, did, bset, uset, dset, dryrun, report) {
|
||||
if (dset.has(did))
|
||||
return
|
||||
dset.add(did)
|
||||
const ddoc = await discussion.get(domainId, did)
|
||||
if (!ddoc)
|
||||
return
|
||||
report({ message: `discussion ${ddoc['title']}` })
|
||||
await _user(ddoc['owner'], bset, uset, dset, dryrun, report)
|
||||
if (ddoc.ip)
|
||||
await _address(ddoc['ip'], bset, uset, dset, dryrun, report)
|
||||
if (!dryrun)
|
||||
await discussion.delete(domainId, ddoc['docId']) }
|
||||
|
||||
async function _user(uid, bset, uset, dset, dryrun, report) {
|
||||
if (uset.has(uid))
|
||||
return
|
||||
uset.add(uid)
|
||||
const udoc = await user.getById(uid)
|
||||
if (!udoc)
|
||||
return
|
||||
report({ message: `user ${udoc['_id']} ${udoc['uname']}` })
|
||||
await _address(udoc['loginip'], bset, uset, dset, dryrun, report)
|
||||
const ddocs = await db.collection('document')
|
||||
.find({ docType: document.TYPE_DISCUSSION }).sort({ domainId: 1, docId: 1 }).toArray()
|
||||
const tasks = []
|
||||
for (const ddoc of ddocs)
|
||||
tasks.push(_discussion(ddoc.domainId, ddoc.docId, bset, uset, dset, dryrun, report))
|
||||
await Promise.all(tasks)
|
||||
if (!dryrun)
|
||||
await user.ban(uid) }
|
||||
|
||||
async function run({address = null, discuss = null, user = null, dryrun = true}, report) {
|
||||
if (address)
|
||||
await _address(address, new Set(), new Set(), new Set(), dryrun, report)
|
||||
if (discuss)
|
||||
await _discussion(discuss.domainId, new ObjectID(discuss.did),
|
||||
new Set(), new Set(), new Set(), dryrun, report)
|
||||
if (user)
|
||||
await _user(user, new Set(), new Set(), new Set(), dryrun, report) }
|
||||
|
||||
global.Hydro.script.blacklist = module.exports = { run, description };
|
||||
@@ -0,0 +1,86 @@
|
||||
/* eslint-disable no-use-before-define */
|
||||
import { ObjectID } from 'mongodb';
|
||||
import * as document from '../model/document';
|
||||
import * as discussion from '../model/discussion';
|
||||
import * as user from '../model/user';
|
||||
import * as blacklist from '../model/blacklist';
|
||||
import * as db from '../service/db';
|
||||
|
||||
export const description = 'Add blacklist by ip, uid';
|
||||
|
||||
async function _address(
|
||||
ip: string,
|
||||
bset: Set<string>, uset: Set<number>, dset: Set<ObjectID>,
|
||||
dryrun: boolean, report: Function,
|
||||
) {
|
||||
if (bset.has(ip)) return;
|
||||
bset.add(ip);
|
||||
report({ message: `ip ${ip}` });
|
||||
const users = await db.collection('user').find({ loginip: ip }).toArray();
|
||||
const tasks = [];
|
||||
for (const udoc of users) {
|
||||
tasks.push(_user(udoc._id, bset, uset, dset, dryrun, report));
|
||||
}
|
||||
await Promise.all(tasks);
|
||||
if (!dryrun) await blacklist.add(ip);
|
||||
}
|
||||
|
||||
async function _discussion(
|
||||
domainId: string, did: ObjectID,
|
||||
bset: Set<string>, uset: Set<number>, dset: Set<ObjectID>,
|
||||
dryrun: boolean, report: Function,
|
||||
) {
|
||||
if (dset.has(did)) return;
|
||||
dset.add(did);
|
||||
const ddoc = await discussion.get(domainId, did);
|
||||
if (!ddoc) return;
|
||||
report({ message: `discussion ${ddoc.title}` });
|
||||
await _user(ddoc.owner, bset, uset, dset, dryrun, report);
|
||||
if (ddoc.ip) await _address(ddoc.ip, bset, uset, dset, dryrun, report);
|
||||
if (!dryrun) await discussion.del(domainId, ddoc.docId);
|
||||
}
|
||||
|
||||
async function _user(
|
||||
uid: number,
|
||||
bset: Set<string>, uset: Set<number>, dset: Set<ObjectID>,
|
||||
dryrun: boolean, report: Function,
|
||||
) {
|
||||
if (uset.has(uid)) return;
|
||||
uset.add(uid);
|
||||
const udoc = await user.getById('system', uid);
|
||||
if (!udoc) return;
|
||||
report({ message: `user ${udoc._id} ${udoc.uname}` });
|
||||
await _address(udoc.loginip(), bset, uset, dset, dryrun, report);
|
||||
const ddocs = await db.collection('document').find({ docType: document.TYPE_DISCUSSION })
|
||||
.sort({ domainId: 1, docId: 1 }).toArray();
|
||||
const tasks = [];
|
||||
for (const ddoc of ddocs) {
|
||||
tasks.push(_discussion(ddoc.domainId, ddoc.docId, bset, uset, dset, dryrun, report));
|
||||
}
|
||||
await Promise.all(tasks);
|
||||
if (!dryrun) await user.ban(uid);
|
||||
}
|
||||
|
||||
export async function run({
|
||||
address = null, discuss = null, user = null, dryrun = true,
|
||||
}, report) {
|
||||
if (address) await _address(address, new Set(), new Set(), new Set(), dryrun, report);
|
||||
if (discuss) {
|
||||
await _discussion(
|
||||
discuss.domainId, new ObjectID(discuss.did),
|
||||
new Set(), new Set(), new Set(), dryrun, report,
|
||||
);
|
||||
}
|
||||
if (user) await _user(user, new Set(), new Set(), new Set(), dryrun, report);
|
||||
}
|
||||
|
||||
export const validate = {
|
||||
$or: {
|
||||
address: 'string',
|
||||
discuss: ObjectID,
|
||||
user: 'number',
|
||||
},
|
||||
dryrun: 'boolean',
|
||||
};
|
||||
|
||||
global.Hydro.script.blacklist = { run, description, validate };
|
||||
@@ -1,12 +1,12 @@
|
||||
const description = 'Delete a user';
|
||||
|
||||
/* eslint-disable no-await-in-loop */
|
||||
const user = require('../model/user');
|
||||
const document = require('../model/document');
|
||||
const setting = require('../model/setting');
|
||||
const db = require('../service/db');
|
||||
const paginate = require('../lib/paginate');
|
||||
const { STATUS, PRIV } = require('../model/builtin');
|
||||
import * as user from '../model/user';
|
||||
import * as document from '../model/document';
|
||||
import * as setting from '../model/setting';
|
||||
import * as db from '../service/db';
|
||||
import paginate from '../lib/paginate';
|
||||
import { STATUS, PRIV } from '../model/builtin';
|
||||
|
||||
export const description = 'Delete a user';
|
||||
|
||||
const collDocument = db.collection('document');
|
||||
const collStatus = db.collection('document.status');
|
||||
@@ -19,7 +19,7 @@ for (const s of setting.PREFERENCE_SETTINGS) {
|
||||
$unset[s.key] = '';
|
||||
}
|
||||
|
||||
async function deleteRecord(uid) {
|
||||
async function deleteRecord(uid: number) {
|
||||
const [, pcount] = await paginate(
|
||||
collRecord.find(),
|
||||
1,
|
||||
@@ -45,7 +45,7 @@ async function deleteRecord(uid) {
|
||||
await collRecord.deleteMany({ uid });
|
||||
}
|
||||
|
||||
async function deleteDiscussion(uid) {
|
||||
async function deleteDiscussion(uid: number) {
|
||||
const [, pcount] = await paginate(
|
||||
collDocument.find({ docType: document.TYPE_DISCUSSION, owner: uid }),
|
||||
1,
|
||||
@@ -70,7 +70,7 @@ async function deleteDiscussion(uid) {
|
||||
// TODO delete replies
|
||||
}
|
||||
|
||||
async function run({
|
||||
export async function run({
|
||||
uid,
|
||||
}) {
|
||||
await deleteRecord(uid);
|
||||
@@ -87,4 +87,8 @@ async function run({
|
||||
return uid;
|
||||
}
|
||||
|
||||
global.Hydro.script.deleteUser = module.exports = { run, description };
|
||||
export const validate = {
|
||||
uid: 'number',
|
||||
};
|
||||
|
||||
global.Hydro.script.deleteUser = { run, description, validate };
|
||||
@@ -1,12 +1,12 @@
|
||||
const description = 'Install';
|
||||
import { PRIV } from '../model/builtin';
|
||||
import * as system from '../model/system';
|
||||
import * as user from '../model/user';
|
||||
import * as domain from '../model/domain';
|
||||
import pwhash from '../lib/hash.hydro';
|
||||
|
||||
const { PRIV_ALL } = require('../model/builtin').PRIV;
|
||||
const system = require('../model/system');
|
||||
const user = require('../model/user');
|
||||
const domain = require('../model/domain');
|
||||
const pwhash = require('../lib/hash.hydro');
|
||||
export const description = 'Install';
|
||||
|
||||
async function run({ username, password } = {}) {
|
||||
export async function run({ username = '', password = '' } = {}) {
|
||||
const def = {
|
||||
PROBLEM_PER_PAGE: 100,
|
||||
RECORD_PER_PAGE: 100,
|
||||
@@ -52,7 +52,7 @@ async function run({ username, password } = {}) {
|
||||
uname: username,
|
||||
password,
|
||||
regip: '127.0.0.1',
|
||||
priv: PRIV_ALL,
|
||||
priv: PRIV.PRIV_ALL,
|
||||
});
|
||||
} else {
|
||||
const salt = String.random();
|
||||
@@ -60,11 +60,18 @@ async function run({ username, password } = {}) {
|
||||
uname: username,
|
||||
unameLower: username.trim().toLowerCase(),
|
||||
salt,
|
||||
hash: pwhash.default(password, salt),
|
||||
hash: pwhash(password, salt),
|
||||
hashType: 'hydro',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
global.Hydro.script.install = module.exports = { run, description };
|
||||
export const validate = {
|
||||
$or: [
|
||||
{ username: 'string', password: 'string' },
|
||||
{ username: 'undefined', password: 'undefined' },
|
||||
],
|
||||
};
|
||||
|
||||
global.Hydro.script.install = { run, description, validate };
|
||||
@@ -1,10 +1,10 @@
|
||||
const description = 'Recalcuates nSubmit and nAccept in problem status.';
|
||||
import * as db from '../service/db';
|
||||
import { STATUS } from '../model/builtin';
|
||||
import * as document from '../model/document';
|
||||
|
||||
const db = require('../service/db');
|
||||
const { STATUS_ACCEPTED } = require('../model/builtin').STATUS;
|
||||
const document = require('../model/document');
|
||||
export const description = 'Recalcuates nSubmit and nAccept in problem status.';
|
||||
|
||||
async function run() {
|
||||
export async function run() {
|
||||
const pipeline = [
|
||||
{
|
||||
$match: { hidden: false, type: { $ne: 'run' } },
|
||||
@@ -15,7 +15,7 @@ async function run() {
|
||||
nSubmit: { $sum: 1 },
|
||||
nAccept: {
|
||||
$sum: {
|
||||
$cond: [{ $eq: ['$status', STATUS_ACCEPTED] }, 1, 0],
|
||||
$cond: [{ $eq: ['$status', STATUS.STATUS_ACCEPTED] }, 1, 0],
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -29,8 +29,8 @@ async function run() {
|
||||
},
|
||||
];
|
||||
const bulk = db.collection('document').initializeUnorderedBulkOp();
|
||||
db.collection('record').aggregate(pipeline).forEach(
|
||||
(adoc) => bulk.find({
|
||||
db.collection('record').aggregate(pipeline).each(
|
||||
(err, adoc: any) => bulk.find({
|
||||
domainId: adoc._id.domainId,
|
||||
docType: document.TYPE_PROBLEM,
|
||||
docId: adoc._id.pid,
|
||||
@@ -44,4 +44,6 @@ async function run() {
|
||||
await bulk.execute();
|
||||
}
|
||||
|
||||
global.Hydro.script.problemStat = module.exports = { run, description };
|
||||
export const validate = {};
|
||||
|
||||
global.Hydro.script.problemStat = { run, description, validate };
|
||||
@@ -1,11 +1,11 @@
|
||||
const description = 'Calculate the rating of a contest';
|
||||
import { ObjectID } from 'mongodb';
|
||||
import * as contest from '../model/contest';
|
||||
import * as user from '../model/user';
|
||||
import rating from '../lib/rating';
|
||||
|
||||
const { ObjectID } = require('mongodb');
|
||||
const contest = require('../model/contest');
|
||||
const user = require('../model/user');
|
||||
const rating = require('../lib/rating');
|
||||
export const description = 'Calculate the rating of a contest';
|
||||
|
||||
async function run({ domainId, contestId }) {
|
||||
export async function run({ domainId, contestId }) {
|
||||
contestId = new ObjectID(contestId);
|
||||
const tdoc = await contest.get(domainId, contestId);
|
||||
const tsdocs = await contest.getMultiStatus(domainId, { docId: contestId })
|
||||
@@ -20,4 +20,9 @@ async function run({ domainId, contestId }) {
|
||||
return rated;
|
||||
}
|
||||
|
||||
global.Hydro.script.rating = module.exports = { run, description };
|
||||
export const validate = {
|
||||
domainId: { $type: 'string' },
|
||||
contestId: { $type: ObjectID },
|
||||
};
|
||||
|
||||
global.Hydro.script.rating = { run, description, validate };
|
||||
@@ -1,13 +1,13 @@
|
||||
const description = 'Calculate rating of a domain, or all domains';
|
||||
|
||||
/* eslint-disable no-await-in-loop */
|
||||
const domain = require('../model/domain');
|
||||
const contest = require('../model/contest');
|
||||
const user = require('../model/user');
|
||||
const rating = require('../lib/rating');
|
||||
const { STATUS } = require('../model/builtin');
|
||||
import * as domain from '../model/domain';
|
||||
import * as contest from '../model/contest';
|
||||
import * as user from '../model/user';
|
||||
import rating from '../lib/rating';
|
||||
import { STATUS } from '../model/builtin';
|
||||
|
||||
async function run({ domainId, isSub = false }, report) {
|
||||
export const description = 'Calculate rating of a domain, or all domains';
|
||||
|
||||
export async function run({ domainId, isSub = false }, report) {
|
||||
if (!domainId) {
|
||||
const domains = await domain.getMulti().toArray();
|
||||
await report({ message: `Found ${domains.length} domains` });
|
||||
@@ -66,4 +66,11 @@ async function run({ domainId, isSub = false }, report) {
|
||||
return true;
|
||||
}
|
||||
|
||||
global.Hydro.script.recalcRating = module.exports = { run, description };
|
||||
export const validate = {
|
||||
$or: [
|
||||
{ domainId: 'string' },
|
||||
{ domainId: 'undefined' },
|
||||
],
|
||||
};
|
||||
|
||||
global.Hydro.script.recalcRating = { run, description, validate };
|
||||
@@ -1,18 +0,0 @@
|
||||
const description = 'Create a new user';
|
||||
|
||||
const user = require('../model/user');
|
||||
const system = require('../model/system');
|
||||
|
||||
async function run({
|
||||
uname, password, mail, uid,
|
||||
}) {
|
||||
if (!uid) uid = await system.inc('user');
|
||||
else uid = parseInt(uid, 10);
|
||||
if (Number.isNaN(uid)) throw new Error('uid');
|
||||
await user.create({
|
||||
uid, uname, password, mail, regip: '127.0.0.1',
|
||||
});
|
||||
return uid;
|
||||
}
|
||||
|
||||
global.Hydro.script.register = module.exports = { run, description };
|
||||
@@ -0,0 +1,24 @@
|
||||
import * as user from '../model/user';
|
||||
import * as system from '../model/system';
|
||||
|
||||
export const description = 'Create a new user';
|
||||
|
||||
export async function run({
|
||||
uname, password, mail, uid,
|
||||
}) {
|
||||
if (!uid) uid = await system.inc('user');
|
||||
else uid = parseInt(uid, 10);
|
||||
if (Number.isNaN(uid)) throw new Error('uid');
|
||||
await user.create({
|
||||
uid, uname, password, mail, regip: '127.0.0.1',
|
||||
});
|
||||
return uid;
|
||||
}
|
||||
|
||||
export const validate = {
|
||||
uname: { $type: 'string' },
|
||||
password: { $type: 'string' },
|
||||
mail: { $type: 'string' },
|
||||
};
|
||||
|
||||
global.Hydro.script.register = { run, description, validate };
|
||||
@@ -1,15 +0,0 @@
|
||||
const description = 'Set a user as superadmin.';
|
||||
|
||||
const user = require('../model/user');
|
||||
const { PRIV_ALL } = require('../model/builtin').PRIV;
|
||||
|
||||
async function run({
|
||||
uid,
|
||||
}) {
|
||||
uid = parseInt(uid, 10);
|
||||
if (Number.isNaN(uid)) throw new Error('uid');
|
||||
await user.setPriv(uid, PRIV_ALL);
|
||||
return uid;
|
||||
}
|
||||
|
||||
global.Hydro.script.setSuperadmin = module.exports = { run, description };
|
||||
@@ -0,0 +1,17 @@
|
||||
import * as user from '../model/user';
|
||||
import { PRIV } from '../model/builtin';
|
||||
|
||||
export const description = 'Set a user as superadmin.';
|
||||
|
||||
export async function run({ uid }) {
|
||||
uid = parseInt(uid, 10);
|
||||
if (Number.isNaN(uid)) throw new Error('uid');
|
||||
await user.setPriv(uid, PRIV.PRIV_ALL);
|
||||
return uid;
|
||||
}
|
||||
|
||||
export const validate = {
|
||||
uid: { $type: 'number' },
|
||||
};
|
||||
|
||||
global.Hydro.script.setSuperadmin = { run, description, validate };
|
||||
Reference in new issue
Block a user