judge: add secret config key

This commit is contained in:
undefined committed 2021-06-24 12:45:19 +08:00
1 parent 37ce0a4f66
commit e334c5e56b
11 files changed
+34 -11

No files matched your search

+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@hydrooj/hydrojudge", "name": "@hydrooj/hydrojudge",
"bin": "bin/hydrojudge.js", "bin": "bin/hydrojudge.js",
"version": "2.8.11", "version": "2.8.12",
"main": "package.json", "main": "package.json",
"author": "undefined <i@undefined.moe>", "author": "undefined <i@undefined.moe>",
"repository": "https://github.com/hydro-dev/Hydro.git", "repository": "https://github.com/hydro-dev/Hydro.git",
+5
View File
@@ -64,3 +64,8 @@ env:
default: | default: |
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOME=/w HOME=/w
secret:
type: text
name: secret
desc: Judge Token Secret
default: Hydro-Judge-Secret
+1 -1
View File
@@ -229,6 +229,6 @@ export default async function readCases(folder: string, cfg: Record<string, any>
result.subtasks = c.subtasks; result.subtasks = c.subtasks;
result.count = c.count; result.count = c.count;
} }
isValidConfig(result); if ((!args.key) || args.key !== result.key) isValidConfig(result);
return result; return result;
} }
+1
View File
@@ -25,6 +25,7 @@ let config = {
env: `\ env: `\
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOME=/w`, HOME=/w`,
secret: String.random(32),
}; };
export function getConfig(key: string) { export function getConfig(key: string) {
+2 -2
View File
@@ -9,7 +9,7 @@ import { ObjectID } from 'mongodb';
import { LangConfig } from '@hydrooj/utils/lib/lang'; import { LangConfig } from '@hydrooj/utils/lib/lang';
import * as tmpfs from '../tmpfs'; import * as tmpfs from '../tmpfs';
import log from '../log'; import log from '../log';
import { compilerText, Queue } from '../utils'; import { compilerText, md5, Queue } from '../utils';
import { getConfig } from '../config'; import { getConfig } from '../config';
import { FormatError, CompileError, SystemError } from '../error'; import { FormatError, CompileError, SystemError } from '../error';
import { STATUS_COMPILE_ERROR, STATUS_SYSTEM_ERROR } from '../status'; import { STATUS_COMPILE_ERROR, STATUS_SYSTEM_ERROR } from '../status';
@@ -111,7 +111,7 @@ class JudgeTask {
this.config = await readCases( this.config = await readCases(
this.folder, this.folder,
{ ...this.config, detail: this.session.config.detail }, { ...this.config, detail: this.session.config.detail },
{ next: this.next }, { next: this.next, key: md5(`${this.domainId}${this.pid}${getConfig('secret')}`) },
); );
this.stat.judge = new Date(); this.stat.judge = new Date();
await judge[this.config.type || 'default'].judge(this); await judge[this.config.type || 'default'].judge(this);
+2 -2
View File
@@ -11,7 +11,7 @@ import * as sysinfo from './sysinfo';
import * as tmpfs from './tmpfs'; import * as tmpfs from './tmpfs';
import { FormatError, CompileError, SystemError } from './error'; import { FormatError, CompileError, SystemError } from './error';
import { STATUS_COMPILE_ERROR, STATUS_SYSTEM_ERROR } from './status'; import { STATUS_COMPILE_ERROR, STATUS_SYSTEM_ERROR } from './status';
import { compilerText } from './utils'; import { compilerText, md5 } from './utils';
import readCases from './cases'; import readCases from './cases';
import { getConfig } from './config'; import { getConfig } from './config';
@@ -233,7 +233,7 @@ async function postInit() {
this.config = await readCases( this.config = await readCases(
this.folder, this.folder,
this.config, this.config,
{ next: this.next }, { next: this.next, key: md5(`${this.domainId}${this.pid}${getConfig('secret')}`) },
); );
this.stat.judge = new Date(); this.stat.judge = new Date();
await judge[this.config.type || 'default'].judge(this); await judge[this.config.type || 'default'].judge(this);
+10
View File
@@ -1,4 +1,5 @@
import fs from 'fs-extra'; import fs from 'fs-extra';
import crypto from 'crypto';
import path from 'path'; import path from 'path';
import { parse } from 'shell-quote'; import { parse } from 'shell-quote';
import _ from 'lodash'; import _ from 'lodash';
@@ -14,6 +15,15 @@ export function parseFilename(filePath: string) {
return t[t.length - 1]; return t[t.length - 1];
} }
const encrypt = (algorithm, content) => {
const hash = crypto.createHash(algorithm);
hash.update(content);
return hash.digest('hex');
};
export const sha1 = (content: string) => encrypt('sha1', content);
export const md5 = (content: string) => encrypt('md5', content);
export class Queue<T> extends EventEmitter { export class Queue<T> extends EventEmitter {
queue: T[] = []; queue: T[] = [];
waiting: any[] = []; waiting: any[] = [];
+1 -1
View File
@@ -12,7 +12,7 @@
}, },
"preferUnplugged": true, "preferUnplugged": true,
"dependencies": { "dependencies": {
"@hydrooj/utils": "workspace:packages/utils", "@hydrooj/utils": "workspace:*",
"adm-zip": "^0.5.5", "adm-zip": "^0.5.5",
"ansi_up": "^5.0.1", "ansi_up": "^5.0.1",
"cac": "^6.7.3", "cac": "^6.7.3",
@@ -53,6 +53,7 @@ const problemConfigSchema = {
type: 'object', type: 'object',
def: problemConfigSchemaDef, def: problemConfigSchemaDef,
properties: { properties: {
key: { type: 'string', pattern: '[0-9a-f]{32}' },
type: { enum: ['default', 'interactive', 'submit_answer', 'subjective'] }, type: { enum: ['default', 'interactive', 'submit_answer', 'subjective'] },
checker_type: { enum: ['default', 'lemon', 'syzoj', 'testlib', 'strict', 'qduoj'] }, checker_type: { enum: ['default', 'lemon', 'syzoj', 'testlib', 'strict', 'qduoj'] },
checker: { type: 'string', pattern: '\\.' }, checker: { type: 'string', pattern: '\\.' },
@@ -36,7 +36,10 @@ export default class SubjectiveContainer extends React.PureComponent {
Textbox(args, name) { Textbox(args, name) {
return ( return (
<label htmlFor={`textbox${name}`}> <label htmlFor={`textbox${name}`}>
{name}. {args.desc} {name}. {args.desc.split('\n').map((i, index) => {
if (index) return <><br />{i}</>;
return i;
})}
<div name={`form_item_${name}`} className="textbox-container"> <div name={`form_item_${name}`} className="textbox-container">
<input type="text" name={name} id={`textbox${name}`} className="textbox" onChange={this.onChange}></input> <input type="text" name={name} id={`textbox${name}`} className="textbox" onChange={this.onChange}></input>
</div> </div>
@@ -47,7 +50,10 @@ export default class SubjectiveContainer extends React.PureComponent {
Radio(args, name) { Radio(args, name) {
return ( return (
<> <>
{name}. {args.desc} {name}. {args.desc.split('\n').map((i, index) => {
if (index) return <><br />{i}</>;
return i;
})}
{args.choices.map((i) => ( {args.choices.map((i) => (
<label className="radiobox" htmlFor={`radio${name}${i}`} key={i}> <label className="radiobox" htmlFor={`radio${name}${i}`} key={i}>
<input type="radio" name={name} id={`radio${name}${i}`} value={i} onChange={this.onChange} /> {i} <br /> <input type="radio" name={name} id={`radio${name}${i}`} value={i} onChange={this.onChange} /> {i} <br />
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "@hydrooj/ui-default", "name": "@hydrooj/ui-default",
"version": "4.11.36", "version": "4.11.37",
"author": "undefined <i@undefined.moe>", "author": "undefined <i@undefined.moe>",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"main": "hydro.js", "main": "hydro.js",
@@ -26,7 +26,7 @@
"@blueprintjs/core": "^3.45.0", "@blueprintjs/core": "^3.45.0",
"@blueprintjs/icons": "^3.26.1", "@blueprintjs/icons": "^3.26.1",
"@blueprintjs/select": "^3.16.4", "@blueprintjs/select": "^3.16.4",
"@hydrooj/utils": "workspace:packages/utils", "@hydrooj/utils": "workspace:*",
"@types/json-schema": "^7.0.7", "@types/json-schema": "^7.0.7",
"@types/katex": "^0.11.0", "@types/katex": "^0.11.0",
"@undefined-moe/monaco-yaml": "^2.5.0", "@undefined-moe/monaco-yaml": "^2.5.0",