From 77fc46c06938302e3011bf715f5375804b5aa4c2 Mon Sep 17 00:00:00 2001 From: undefined Date: Sat, 7 Aug 2021 02:47:21 +0800 Subject: [PATCH] core: limit ViewRecord --- packages/hydrooj/locales/ko.yaml | 1 - packages/hydrooj/locales/zh.yaml | 2 +- packages/hydrooj/locales/zh_TW.yaml | 2 +- packages/hydrooj/package.json | 2 +- packages/hydrooj/src/handler/contest.ts | 8 ++++---- packages/hydrooj/src/handler/homework.ts | 6 ++++-- packages/hydrooj/src/handler/record.ts | 13 +++++++++---- packages/hydrooj/src/lib/ui.ts | 10 ++++++---- packages/hydrooj/src/model/builtin.ts | 6 +++--- .../ui-default/components/zipDownloader/index.js | 2 +- packages/ui-default/locales/ko.yaml | 1 - packages/ui-default/locales/zh.yaml | 4 ++-- packages/ui-default/locales/zh_TW.yaml | 2 +- packages/ui-default/package.json | 2 +- .../templates/partials/contest_sidebar.html | 2 +- .../templates/partials/homework_sidebar.html | 2 +- packages/ui-default/templates/partials/nav.html | 2 +- 17 files changed, 37 insertions(+), 30 deletions(-) diff --git a/packages/hydrooj/locales/ko.yaml b/packages/hydrooj/locales/ko.yaml index 07d2cf394..5c0549beb 100644 --- a/packages/hydrooj/locales/ko.yaml +++ b/packages/hydrooj/locales/ko.yaml @@ -546,7 +546,6 @@ Rank: 순위 ranking: 순위 Read data of own problems: 자신의 문제 데이터 읽기 Read data of problem: 문제 데이터 읽기 -Read record codes: 점수 읽기 Ready (☆▽☆): 준비 완료! (☆▽☆) Ready: 준비됨 Recent {0} Records: 최근 {0} 점수 diff --git a/packages/hydrooj/locales/zh.yaml b/packages/hydrooj/locales/zh.yaml index 6f72c2649..16f6847f9 100644 --- a/packages/hydrooj/locales/zh.yaml +++ b/packages/hydrooj/locales/zh.yaml @@ -603,7 +603,7 @@ Recalculates nSubmit and nAccept in problem status.: 重新计算每道题目的 Recommended: 推荐 Record {0} not found.: 记录 {0} 不存在。 record_detail: 记录详情 -record_main: 评测队列 +record_main: 评测记录 Records per page: 每页展示的评测记录数量 Records: 评测记录 Refresh Records: 刷新评测记录 diff --git a/packages/hydrooj/locales/zh_TW.yaml b/packages/hydrooj/locales/zh_TW.yaml index 8219f7490..599a6eadd 100644 --- a/packages/hydrooj/locales/zh_TW.yaml +++ b/packages/hydrooj/locales/zh_TW.yaml @@ -351,9 +351,9 @@ QQ Group: QQ 群 QQ Visibility: QQ 可見性 Quit Scratchpad: 退出線上程式設計模式 Rank: 排名 +Read all records: 讀取記錄 Read data of own problems: 讀取自己題目的資料 Read data of problem: 讀取題目資料 -Read record codes: 讀取記錄的程式碼 Ready (☆▽☆): 馬上開始 (☆▽☆) Ready: 即將開始 Recent {0} Records: 最近 {0} 條記錄 diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index a46c8dd3e..97410d3eb 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.31.2", + "version": "2.32.0", "bin": "bin/hydrooj.js", "main": "src/loader", "module": "src/loader", diff --git a/packages/hydrooj/src/handler/contest.ts b/packages/hydrooj/src/handler/contest.ts index 54792609f..5f35e38f1 100644 --- a/packages/hydrooj/src/handler/contest.ts +++ b/packages/hydrooj/src/handler/contest.ts @@ -386,11 +386,11 @@ export class ContestDetailProblemSubmitHandler extends ContestProblemHandler { export class ContestCodeHandler extends Handler { @param('tid', Types.ObjectID) async get(domainId: string, tid: ObjectID) { - if (!this.user.hasPriv(PRIV.PRIV_READ_RECORD_CODE)) { - this.checkPerm(PERM.PERM_READ_RECORD_CODE); - } - await this.limitRate('homework_code', 3600, 60); + await this.limitRate('contest_code', 3600, 60); const [tdoc, tsdocs] = await contest.getAndListStatus(domainId, tid); + if (!this.user.own(tdoc) && !this.user.hasPriv(PRIV.PRIV_READ_RECORD)) { + this.checkPerm(PERM.PERM_READ_RECORD); + } if (!contest.canShowRecord.call(this, tdoc as any, true)) { throw new PermissionError(PERM.PERM_VIEW_CONTEST_HIDDEN_SCOREBOARD); } diff --git a/packages/hydrooj/src/handler/homework.ts b/packages/hydrooj/src/handler/homework.ts index c52149394..59b848a27 100644 --- a/packages/hydrooj/src/handler/homework.ts +++ b/packages/hydrooj/src/handler/homework.ts @@ -389,11 +389,13 @@ class HomeworkScoreboardDownloadHandler extends Handler { class HomeworkCodeHandler extends Handler { @param('tid', Types.ObjectID) async get(domainId: string, tid: ObjectID) { - if (!this.user.hasPriv(PRIV.PRIV_READ_RECORD_CODE)) this.checkPerm(PERM.PERM_READ_RECORD_CODE); - await this.limitRate('homework_code', 3600, 60); + await this.limitRate('contest_code', 3600, 60); const [tdoc, tsdocs] = await contest.getAndListStatus( domainId, tid, document.TYPE_HOMEWORK, ); + if (!this.user.own(tdoc) && !this.user.hasPriv(PRIV.PRIV_READ_RECORD)) { + this.checkPerm(PERM.PERM_READ_RECORD); + } const rnames = {}; for (const tsdoc of tsdocs) { for (const pid in tsdoc.detail || {}) { diff --git a/packages/hydrooj/src/handler/record.ts b/packages/hydrooj/src/handler/record.ts index a999390e2..593f0a733 100644 --- a/packages/hydrooj/src/handler/record.ts +++ b/packages/hydrooj/src/handler/record.ts @@ -104,8 +104,8 @@ class RecordDetailHandler extends Handler { throw new PermissionError(rid); } } - if (rdoc.uid !== this.user._id && !this.user.hasPriv(PRIV.PRIV_READ_RECORD_CODE)) { - if (!this.user.hasPerm(PERM.PERM_READ_RECORD_CODE)) rdoc.code = null; + if (rdoc.uid !== this.user._id && !this.user.hasPriv(PRIV.PRIV_READ_RECORD)) { + this.checkPerm(PERM.PERM_READ_RECORD); } // eslint-disable-next-line prefer-const let [pdoc, udoc] = await Promise.all([ @@ -188,7 +188,10 @@ class RecordMainConnectionHandler extends ConnectionHandler { if (pretest || contest.canShowScoreboard.call(this, tdoc, true)) this.tid = tid.toHexString(); else throw new PermissionError(PERM.PERM_VIEW_CONTEST_HIDDEN_SCOREBOARD); } - if (uidOrName) { + if (pretest) { + this.pretest = true; + this.uid = this.user._id; + } else if (uidOrName) { let udoc = await user.getById(domainId, +uidOrName); if (udoc) this.uid = udoc._id; else { @@ -207,7 +210,6 @@ class RecordMainConnectionHandler extends ConnectionHandler { } else throw new ProblemNotFoundError(domainId, pid); } if (status) this.status = status; - if (pretest) this.pretest = true; this.dispose = bus.on('record/change', this.onRecordChange.bind(this)); } @@ -261,6 +263,9 @@ class RecordDetailConnectionHandler extends ConnectionHandler { const tdoc = await contest.get(domainId, rdoc.contest.tid, -1); if (!contest.canShowRecord.call(this, tdoc)) throw new PermissionError(PERM.PERM_VIEW_CONTEST_HIDDEN_SCOREBOARD); } + if (rdoc.uid !== this.user._id && !this.user.hasPriv(PRIV.PRIV_READ_RECORD)) { + this.checkPerm(PERM.PERM_READ_RECORD); + } this.rid = rid.toString(); this.dispose = bus.on('record/change', this.onRecordChange.bind(this)); this.onRecordChange(rdoc); diff --git a/packages/hydrooj/src/lib/ui.ts b/packages/hydrooj/src/lib/ui.ts index 1bbe8c11a..329bb1cf0 100644 --- a/packages/hydrooj/src/lib/ui.ts +++ b/packages/hydrooj/src/lib/ui.ts @@ -34,16 +34,18 @@ const buildChecker = (...permPrivChecker: Array) => }; export const Nav = ( - name: string, args: Dictionary = {}, prefix: string, + name: string, args: ((handler: any) => Record) | Record = {}, prefix: string, ...permPrivChecker: Array ) => { + if (typeof args !== 'function') args = () => (args || {}); + const checker = buildChecker(...permPrivChecker); if (name.startsWith('@@')) { global.Hydro.ui.nodes.nav.splice(+name.split('@@')[1], 0, { - name: name.split('@@')[2], args: args || {}, prefix, checker: buildChecker(...permPrivChecker), + name: name.split('@@')[2], args, prefix, checker, }); } else { global.Hydro.ui.nodes.nav.push({ - name, args: args || {}, prefix, checker: buildChecker(...permPrivChecker), + name, args, prefix, checker, }); } }; @@ -70,7 +72,7 @@ Nav('training_main', {}, 'training', PERM.PERM_VIEW_TRAINING); Nav('homework_main', {}, 'homework', PERM.PERM_VIEW_HOMEWORK); Nav('discussion_main', {}, 'discussion', PERM.PERM_VIEW_DISCUSSION); Nav('contest_main', {}, 'contest', PERM.PERM_VIEW_CONTEST); -Nav('record_main', {}, 'record'); +Nav('record_main', (handler) => (handler.user.hasPriv(PRIV.PRIV_USER_PROFILE) ? { query: { uidOrName: handler.user._id } } : {}), 'record'); Nav('ranking', {}, 'ranking', PERM.PERM_VIEW_RANKING); Nav('domain_dashboard', {}, 'domain', PERM.PERM_EDIT_DOMAIN); Nav('manage_dashboard', {}, 'manage', PRIV.PRIV_EDIT_SYSTEM); diff --git a/packages/hydrooj/src/model/builtin.ts b/packages/hydrooj/src/model/builtin.ts index 08e32ff88..365b6cf13 100644 --- a/packages/hydrooj/src/model/builtin.ts +++ b/packages/hydrooj/src/model/builtin.ts @@ -30,7 +30,7 @@ export const PERM = { PERM_VIEW_PROBLEM_HIDDEN: 1n << 8n, PERM_SUBMIT_PROBLEM: 1n << 9n, PERM_READ_PROBLEM_DATA: 1n << 10n, - PERM_READ_RECORD_CODE: 1n << 12n, + PERM_READ_RECORD: 1n << 12n, PERM_REJUDGE_PROBLEM: 1n << 13n, PERM_REJUDGE: 1n << 14n, @@ -113,7 +113,7 @@ export const PERMS = [ Permission('perm_problem', PERM.PERM_VIEW_PROBLEM_HIDDEN, 'View hidden problems'), Permission('perm_problem', PERM.PERM_SUBMIT_PROBLEM, 'Submit problem'), Permission('perm_problem', PERM.PERM_READ_PROBLEM_DATA, 'Read data of problem'), - Permission('perm_record', PERM.PERM_READ_RECORD_CODE, 'Read record codes'), + Permission('perm_record', PERM.PERM_READ_RECORD, 'Read all records'), Permission('perm_record', PERM.PERM_REJUDGE_PROBLEM, 'Rejudge problems'), Permission('perm_record', PERM.PERM_REJUDGE, 'Rejudge records'), Permission('perm_problem_solution', PERM.PERM_VIEW_PROBLEM_SOLUTION, 'View problem solutions'), @@ -232,7 +232,7 @@ export const PRIV = { PRIV_USER_PROFILE: 1 << 2, PRIV_REGISTER_USER: 1 << 3, PRIV_READ_PROBLEM_DATA: 1 << 4, - PRIV_READ_RECORD_CODE: 1 << 7, + PRIV_READ_RECORD: 1 << 7, PRIV_VIEW_HIDDEN_RECORD: 1 << 8, PRIV_JUDGE: 1 << 9, // (renamed) PRIV_CREATE_DOMAIN: 1 << 10, diff --git a/packages/ui-default/components/zipDownloader/index.js b/packages/ui-default/components/zipDownloader/index.js index 10582e209..59ccab581 100644 --- a/packages/ui-default/components/zipDownloader/index.js +++ b/packages/ui-default/components/zipDownloader/index.js @@ -1,5 +1,5 @@ import { dump } from 'js-yaml'; -import * as streamsaver from 'streamsaver'; +import streamsaver from 'streamsaver'; import { createZipStream } from 'vj/utils/zip'; import pipeStream from 'vj/utils/pipeStream'; import i18n from 'vj/utils/i18n'; diff --git a/packages/ui-default/locales/ko.yaml b/packages/ui-default/locales/ko.yaml index 9dc90b1d4..074d85792 100644 --- a/packages/ui-default/locales/ko.yaml +++ b/packages/ui-default/locales/ko.yaml @@ -550,7 +550,6 @@ Rank: 순위 ranking: 순위 Read data of own problems: 자신의 문제 데이터 읽기 Read data of problem: 문제 데이터 읽기 -Read record codes: 점수 읽기 Ready (☆▽☆): 준비 완료! (☆▽☆) Ready: 준비됨 Recent {0} Records: 최근 {0} 점수 diff --git a/packages/ui-default/locales/zh.yaml b/packages/ui-default/locales/zh.yaml index 70bb59793..639ef7a5a 100644 --- a/packages/ui-default/locales/zh.yaml +++ b/packages/ui-default/locales/zh.yaml @@ -584,9 +584,9 @@ Quit Scratchpad: 退出在线编程模式 Quote: 引用 Rank: 排名 ranking: 排名 +Read all records: 读取所有提交记录 Read data of own problems: 读取自己题目的数据 Read data of problem: 读取题目数据 -Read record codes: 读取记录的代码 Ready (☆▽☆): 马上开始 (☆▽☆) Ready: 即将开始 Recent {0} Records: 最近 {0} 条记录 @@ -597,7 +597,7 @@ Recently Created Discussions: 最近创建的讨论 Recommended: 推荐 Record {0} not found.: 记录 {0} 不存在。 record_detail: 记录详情 -record_main: 评测队列 +record_main: 评测记录 Records: 评测记录 Refresh Records: 刷新评测记录 Refresh: 刷新 diff --git a/packages/ui-default/locales/zh_TW.yaml b/packages/ui-default/locales/zh_TW.yaml index b83bbd57c..4d139d9eb 100644 --- a/packages/ui-default/locales/zh_TW.yaml +++ b/packages/ui-default/locales/zh_TW.yaml @@ -353,9 +353,9 @@ QQ Group: QQ 群 QQ Visibility: QQ 可見性 Quit Scratchpad: 退出線上程式設計模式 Rank: 排名 +Read all records: 讀取記錄 Read data of own problems: 讀取自己題目的資料 Read data of problem: 讀取題目資料 -Read record codes: 讀取記錄的程式碼 Ready (☆▽☆): 馬上開始 (☆▽☆) Ready: 即將開始 Recent {0} Records: 最近 {0} 條記錄 diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index b3111b672..baeb42778 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.14.15", + "version": "4.15.0", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js", diff --git a/packages/ui-default/templates/partials/contest_sidebar.html b/packages/ui-default/templates/partials/contest_sidebar.html index 6065ae8ac..693cfd0fb 100644 --- a/packages/ui-default/templates/partials/contest_sidebar.html +++ b/packages/ui-default/templates/partials/contest_sidebar.html @@ -73,7 +73,7 @@ {{ _('Edit Contest') }} {% endif %} - {% if handler.user.hasPriv(PRIV.PRIV_READ_RECORD_CODE) or handler.user.hasPerm(perm.PERM_READ_RECORD_CODE) %} + {% if handler.user.own(tdoc) or handler.user.hasPriv(PRIV.PRIV_READ_RECORD) or handler.user.hasPerm(perm.PERM_READ_RECORD) %} {% if model.contest.canShowRecord.call(handler, tdoc, true) %} {% endif %} - {% if handler.user.hasPriv(PRIV.PRIV_READ_RECORD_CODE) or handler.user.hasPerm(perm.PERM_READ_RECORD_CODE) %} + {% if handler.user.own(tdoc) or handler.user.hasPriv(PRIV.PRIV_READ_RECORD) or handler.user.hasPerm(perm.PERM_READ_RECORD) %} diff --git a/packages/ui-default/templates/partials/nav.html b/packages/ui-default/templates/partials/nav.html index 3f54be978..aa88b6f5c 100644 --- a/packages/ui-default/templates/partials/nav.html +++ b/packages/ui-default/templates/partials/nav.html @@ -11,7 +11,7 @@