From f54cf8a9bafbada111c395316f96603c4254caac Mon Sep 17 00:00:00 2001 From: undefined Date: Tue, 25 May 2021 00:22:59 +0800 Subject: [PATCH] core: remove problem_send --- packages/center/handler.ts | 24 +-- packages/center/package.json | 2 +- packages/hydrooj/package.json | 2 +- packages/hydrooj/src/entry/common.ts | 2 +- packages/hydrooj/src/entry/setup.ts | 108 +++++----- packages/hydrooj/src/handler/remote.ts | 190 ------------------ packages/hydrooj/src/model/setting.ts | 2 - packages/ui-default/package.json | 2 +- .../ui-default/templates/problem_detail.html | 1 - 9 files changed, 54 insertions(+), 279 deletions(-) delete mode 100644 packages/hydrooj/src/handler/remote.ts diff --git a/packages/center/handler.ts b/packages/center/handler.ts index 37aca75b5..47b875719 100644 --- a/packages/center/handler.ts +++ b/packages/center/handler.ts @@ -1,11 +1,9 @@ import db from 'hydrooj/dist/service/db'; import { - Handler, param, post, Route, Types, + Handler, post, Route, Types, } from 'hydrooj/dist/service/server'; -import { RemoteOnlineJudgeError } from 'hydrooj/dist/error'; import crypto from 'crypto'; import yaml from 'js-yaml'; -import superagent from 'superagent'; function decrypt(encrypted: string) { if (!encrypted) throw new Error(); @@ -53,28 +51,8 @@ class DataReportHandler extends Handler { } } -class ProxySendRequestHandler extends Handler { - @param('endpoint', Types.String) - @param('domainId', Types.String) - @param('url', Types.String) - @param('tokenId', Types.String) - @param('expire', Types.UnsignedInt) - async post(_d: string, endpoint: string, domainId: string, url: string, tokenId: string, expire: number) { - let res = await superagent.post(`${url}d/${domainId}/problem/send`) - .send({ operation: 'info', token: tokenId }) - .catch((e) => e); - if (res instanceof Error) throw new RemoteOnlineJudgeError(`[Post Target/Send/Info] ${res.message}`); - res = await superagent.post(`${endpoint}/problem/receive`).send({ - operation: 'request', url: `${url}d/${domainId}/problem/send`, tokenId, expire, - }).catch((e) => e); - if (res instanceof Error) throw new RemoteOnlineJudgeError(`[Post Target/Receive/Request] ${res.message}`); - this.response.body = { code: 0 }; - } -} - export function apply() { Route('data_report', '/center/report', DataReportHandler); - Route('proxy_send', '/center/send', ProxySendRequestHandler); } global.Hydro.handler.center = apply; diff --git a/packages/center/package.json b/packages/center/package.json index 2a4f38f2a..2a11d4af7 100644 --- a/packages/center/package.json +++ b/packages/center/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/center", - "version": "0.0.3", + "version": "0.0.4", "main": "package.json", "repository": "https://github.com/hydro-dev/Hydro.git", "author": "undefined ", diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 74a74fcdd..dc4b62fe7 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.26.29", + "version": "2.27.0", "bin": "bin/hydrooj.js", "main": "dist/loader.js", "typings": "dist/loader.d.ts", diff --git a/packages/hydrooj/src/entry/common.ts b/packages/hydrooj/src/entry/common.ts index 329b65ceb..5c61fe7eb 100644 --- a/packages/hydrooj/src/entry/common.ts +++ b/packages/hydrooj/src/entry/common.ts @@ -26,7 +26,7 @@ export const builtinModel = [ export const builtinHandler = [ 'home', 'problem', 'record', 'judge', 'user', 'contest', 'training', 'discussion', 'manage', 'import', - 'misc', 'homework', 'domain', 'remote', 'status', + 'misc', 'homework', 'domain', 'status', ]; export const builtinScript = [ diff --git a/packages/hydrooj/src/entry/setup.ts b/packages/hydrooj/src/entry/setup.ts index b71ed4b3f..3ce42606d 100644 --- a/packages/hydrooj/src/entry/setup.ts +++ b/packages/hydrooj/src/entry/setup.ts @@ -13,7 +13,7 @@ const logger = new Logger('setup'); const listenPort = argv.port || 8888; async function get(ctx: Context) { - ctx.body = ` + ctx.body = ` @@ -74,73 +74,63 @@ async function get(ctx: Context) { `; - ctx.response.type = 'text/html'; + ctx.response.type = 'text/html'; } async function post(ctx: Context) { - const { - host, port, name, username, password, - } = ctx.request.body; - let mongourl = 'mongodb://'; - if (username) mongourl += `${username}:${password}@`; - mongourl += `${host}:${port}/${name}`; - try { - const Database = await mongodb.MongoClient.connect(mongourl, { - useNewUrlParser: true, useUnifiedTopology: true, - }); - const db = Database.db(name); - const coll = db.collection('system'); - await Promise.all([ - coll.updateOne( - { _id: 'server.host' }, - { $set: { value: ctx.request.host } }, - { upsert: true }, - ), - coll.updateOne( - { _id: 'server.hostname' }, - { $set: { value: ctx.request.hostname } }, - { upsert: true }, - ), - coll.updateOne( - { _id: 'server.url' }, - { $set: { value: ctx.request.href } }, - { upsert: true }, - ), - coll.updateOne( - { _id: 'server.port' }, - { $set: { value: parseInt(listenPort as string, 10) } }, - { upsert: true }, - ), - ]); - fs.ensureDirSync(path.resolve(os.homedir(), '.hydro')); - fs.writeFileSync(path.resolve(os.homedir(), '.hydro', 'config.json'), JSON.stringify({ - host, port, name, username, password, - })); - ctx.body = `

This page will reload in 3 secs.

+ const { + host, port, name, username, password, + } = ctx.request.body; + let mongourl = 'mongodb://'; + if (username) mongourl += `${username}:${password}@`; + mongourl += `${host}:${port}/${name}`; + try { + const Database = await mongodb.MongoClient.connect(mongourl, { + useNewUrlParser: true, useUnifiedTopology: true, + }); + const db = Database.db(name); + const coll = db.collection('system'); + await Promise.all([ + coll.updateOne( + { _id: 'server.url' }, + { $set: { value: ctx.request.href } }, + { upsert: true }, + ), + coll.updateOne( + { _id: 'server.port' }, + { $set: { value: parseInt(listenPort as string, 10) } }, + { upsert: true }, + ), + ]); + fs.ensureDirSync(path.resolve(os.homedir(), '.hydro')); + fs.writeFileSync(path.resolve(os.homedir(), '.hydro', 'config.json'), JSON.stringify({ + host, port, name, username, password, + })); + ctx.body = `

This page will reload in 3 secs.

`; - setTimeout(() => process.exit(0), 500); - } catch (e) { - ctx.body = `Error connecting to database: ${e.message}\n${e.stack}`; - } + setTimeout(() => process.exit(0), 500); + } catch (e) { + ctx.body = `Error connecting to database: ${e.message}\n${e.stack}`; + } } export function load() { - const app = new Koa(); - const server = http.createServer(app.callback()); - app.keys = ['Hydro']; - app - .use(cache(path.join(os.tmpdir(), 'hydro', 'public'), { - maxAge: 365 * 24 * 60 * 60, - })) - .use(Body()) - .use((ctx) => { - if (ctx.request.method.toLowerCase() === 'post') return post(ctx); - return get(ctx); - }); - server.listen(listenPort); - logger.success('Server listening at: %d', listenPort); + const app = new Koa(); + const server = http.createServer(app.callback()); + app.keys = ['Hydro']; + app + .use(cache(path.join(os.tmpdir(), 'hydro', 'public'), { + maxAge: 365 * 24 * 60 * 60, + })) + .use(Body()) + .use((ctx) => { + if (ctx.request.method.toLowerCase() === 'post') return post(ctx); + return get(ctx); + }); + server.listen(listenPort); + logger.success('Server listening at: %d', listenPort); } diff --git a/packages/hydrooj/src/handler/remote.ts b/packages/hydrooj/src/handler/remote.ts deleted file mode 100644 index 364c7787b..000000000 --- a/packages/hydrooj/src/handler/remote.ts +++ /dev/null @@ -1,190 +0,0 @@ -/* eslint-disable no-await-in-loop */ -import superagent from 'superagent'; -import { PassThrough } from 'stream'; -import { argv } from 'yargs'; -import { PermissionError, InvalidTokenError, RemoteOnlineJudgeError } from '../error'; -import { Logger } from '../logger'; -import { logAndReturn } from '../utils'; -import { ProblemAdd } from '../lib/ui'; -import { PERM, PRIV } from '../model/builtin'; -import token from '../model/token'; -import problem from '../model/problem'; -import * as system from '../model/system'; -import storage from '../model/storage'; -import { - Handler, Types, Route, post, -} from '../service/server'; - -const logger = new Logger('remote'); - -export class ProblemSendHandler extends Handler { - async get() { - this.checkPerm(PERM.PERM_VIEW_PROBLEM); - this.response.template = 'problem_send.html'; - } - - @post('target', Types.String) - @post('pids', Types.Array) - async postSend(domainId: string, _target: string, _pids: (number | string)[]) { - this.checkPerm(PERM.PERM_VIEW_PROBLEM); - const target = _target.split('@'); - if (target[1].endsWith('/')) target[1] = target[1].substr(0, target[1].length - 1); - const getHidden = this.user.hasPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN); - const getData = this.user.hasPriv(PRIV.PRIV_READ_PROBLEM_DATA) || this.user.hasPerm(PERM.PERM_READ_PROBLEM_DATA); - const pdocs = await problem.getList(domainId, _pids, true, true, ['docId', 'owner', 'hidden']); - const pids = new Set(); - for (const key in pdocs) { - pids.add(pdocs[key].docId); - if (pdocs[key].hidden && !getHidden && !this.user.own(pdocs[key])) { - throw new PermissionError(PERM.PERM_VIEW_PROBLEM_HIDDEN); - } - if (!getData && !this.user.own(pdocs[key]) && !this.user.hasPriv(PRIV.PRIV_READ_PROBLEM_DATA)) { - throw new PermissionError(PERM.PERM_READ_PROBLEM_DATA); - } - } - const [url, expire] = system.getMany(['server.url', 'session.saved_expire_seconds']); - const tokenId = await token.createOrUpdate(token.TYPE_EXPORT, expire, { creator: this.user._id, domainId, pids: Array.from(pids) }); - const res = system.get('server.proxy') - ? await superagent.post(`${system.get('server.center')}/send`) - .send({ - endpoint: `${target[1]}/d/${target[0]}`, - domainId, - url, - tokenId, - expire, - }).catch(logAndReturn(logger)) - : await superagent.post(`${target[1]}/d/${target[0]}/problem/receive`) - .send({ - operation: 'request', url: `${url}d/${domainId}/problem/send`, tokenId, expire, - }).catch(logAndReturn(logger)); - if (res instanceof Error) throw new RemoteOnlineJudgeError(`[Post Target/Request] ${res.message}`); - this.back(); - } - - @post('token', Types.Content) - async postInfo(domainId: string, tokenId: string) { - const data = await token.get(tokenId, token.TYPE_EXPORT); - if (!data) throw new InvalidTokenError(tokenId); - const r = {}; - const pdocs = await problem.getMulti(domainId, { docId: { $in: data.pids } }, ['title', 'docId']).toArray(); - for (const pdoc of pdocs) r[pdoc.docId] = pdoc.title; - this.response.body = { pdocs: r, pids: data.pids }; - } - - @post('token', Types.Content, true) - @post('pids', Types.Array) - async postFetch(domainId: string, tokenId: string, pids: number[]) { - pids = pids.map((i) => (+i ? +i : i)); - const pdocs = await problem.getMulti(domainId, { docId: { $in: pids } }, problem.PROJECTION_PUBLIC).toArray(); - const data = await token.get(tokenId, token.TYPE_EXPORT); - if (!data) throw new InvalidTokenError(tokenId); - if (pids.filter((pid) => !data.pids.includes(pid)).length) throw new InvalidTokenError(tokenId); - const links = []; - for (const pdoc of pdocs) { - const files = await storage.list(`problem/${domainId}/${pdoc.docId}/`, true); - const l = []; - for (const file of files) { - l.push([ - file.name, - await storage.signDownloadLink(file.prefix + file.name, file.name, false, 'user'), - ]); - } - links.push(l); - } - this.response.body = { pdocs, links }; - } -} - -export class ProblemReceiveHandler extends Handler { - noCheckPermView = true; - - async get({ domainId }) { - this.checkPerm(PERM.PERM_CREATE_PROBLEM); - let requests = await token.getMulti(token.TYPE_IMPORT, { domainId }).toArray(); - requests = requests.map((request) => { - const url = new URL(request.source); - request.display = `${url.host}/${url.pathname.split('/')[2]}/`; - request.url = `${url.origin}/d/${url.pathname.split('/')[2]}/p/`; - return request; - }); - this.response.template = 'problem_receive.html'; - this.response.body = { requests }; - this.response.body.path = [ - ['Hydro', 'homepage'], - ['problem_main', 'problem_main'], - ['problem_receive', null], - ]; - } - - @post('url', Types.String) - @post('tokenId', Types.String) - @post('expire', Types.UnsignedInt) - async postRequest(domainId: string, url: string, tokenId: string, expire: number) { - const res = await superagent.post(url) - .send({ operation: 'info', token: tokenId }) - .catch(logAndReturn(logger)); - if (res instanceof Error) throw new RemoteOnlineJudgeError(`[Post Origin/Info] ${res.message}`); - const [id] = await token.add(token.TYPE_IMPORT, expire, { - domainId, tokenId, source: url, pdocs: res.body.pdocs, pids: res.body.pids, - }); - this.response.body = { token: id }; - } - - // eslint-disable-next-line class-methods-use-this - async syncFiles(domainId: string, baseUrl: string, pid: number, files: [string, string][]) { - for (const file of files) { - const content = new PassThrough(); - superagent.get(file[1].startsWith('/') ? baseUrl + file[1] : file[1]).pipe(content); - if (file[0].startsWith('testdata/')) { - await problem.addTestdata(domainId, pid, file[0].split('testdata/')[1], content); - } else if (file[0].startsWith('additional_file/')) { - await problem.addAdditionalFile(domainId, pid, file[0].split('additional_file/')[1], content); - } - } - } - - @post('tokenId', Types.String) - @post('pids', Types.Array, true) - async postConfirm(domainId: string, tokenId: string, filterPid?: number[]) { - this.checkPerm(PERM.PERM_CREATE_PROBLEM); - const data = await token.get(tokenId, token.TYPE_IMPORT); - if (!data) throw new InvalidTokenError(tokenId); - const res = await superagent.post(data.source).send({ - operation: 'fetch', - token: data.tokenId, - pids: filterPid.length ? filterPid.map((i) => (+i ? +i : i)) : data.pids, - }).catch(logAndReturn(logger)); - if (res instanceof Error) throw new RemoteOnlineJudgeError(`[Post Origin/Fetch] ${res.message}`); - const pids = []; - const { pdocs } = res.body; - const files = res.body.links; - const source = new URL(data.source); - const baseUrl = `${source.protocol}//${source.host}`; - const exportToken = await token.get(data.tokenId, token.TYPE_EXPORT); - for (let i = 0; i < pdocs.length; i++) { - const pdoc = pdocs[i]; - if (pdoc.pid) { - const exist = await problem.get(domainId, pdoc.pid); - if (exist) pdoc.pid = undefined; - } - const pid = await problem.add(domainId, pdoc.pid, pdoc.title, pdoc.content, exportToken?.creator || this.user._id, pdoc.tag); - pids.push(pid); - this.syncFiles( - domainId, - exportToken ? baseUrl : `http://127.0.0.1:${argv.port || system.get('server.port')}`, - pid, files[i], - ).catch(logAndReturn(logger)); - await problem.edit(domainId, pid, { html: pdoc.html }); - } - this.back(); - this.response.body = { pids }; - } -} - -export async function apply() { - ProblemAdd('problem_receive', {}, 'copy', 'Receive From Hydro'); - Route('problem_receive', '/problem/receive', ProblemReceiveHandler); - Route('problem_send', '/problem/send', ProblemSendHandler); -} - -global.Hydro.handler.remote = apply; diff --git a/packages/hydrooj/src/model/setting.ts b/packages/hydrooj/src/model/setting.ts index f0fa5d186..375f4988f 100644 --- a/packages/hydrooj/src/model/setting.ts +++ b/packages/hydrooj/src/model/setting.ts @@ -173,8 +173,6 @@ SystemSetting( Setting('setting_server', 'server.name', 'Hydro', 'text', 'server.name', 'Server Name'), Setting('setting_server', 'server.displayName', 'Hydro', 'text', 'server.name', 'Server Name (Global Display)', FLAG_PRO), Setting('setting_server', 'server.worker', 1, 'number', 'server.worker', 'Server Workers Number', FLAG_PRO), - Setting('setting_server', 'server.hostname', 'oj.undefined.moe', 'text', 'server.hostname', 'Server Hostname'), - Setting('setting_server', 'server.host', 'oj.undefined.moe', 'text', 'server.host', 'Server Host'), Setting('setting_server', 'server.url', '/', 'text', 'server.url', 'Server BaseURL'), Setting('setting_server', 'server.cdn', '/', 'text', 'server.cdn', 'CDN Prefix'), Setting('setting_server', 'server.port', 8888, 'number', 'server.port', 'Server Port'), diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index ee16d9197..74fad88cd 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.8.46", + "version": "4.9.0", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js", diff --git a/packages/ui-default/templates/problem_detail.html b/packages/ui-default/templates/problem_detail.html index 66ccd31ca..3bafcfb65 100644 --- a/packages/ui-default/templates/problem_detail.html +++ b/packages/ui-default/templates/problem_detail.html @@ -5,7 +5,6 @@ {{ set(UiContext, { problemId: pdoc.pid|default(pdoc.docId), problemNumId: pdoc.docId, - postCopyUrl: url('problem_send'), postPretestUrl: url('problem_pretest', pid=pdoc.docId), codeLang: handler.user.codeLang, codeTemplate: handler.user.codeTemplate,