diff --git a/packages/hydrooj/locales/zh.yaml b/packages/hydrooj/locales/zh.yaml index bf0b4010..3857b903 100644 --- a/packages/hydrooj/locales/zh.yaml +++ b/packages/hydrooj/locales/zh.yaml @@ -853,6 +853,8 @@ Valid for registered users who are not members of the domain: 对域外注册用 Valid for visitors: 对未登录的游客有效 Verify register email: 注册需邮件验证 Version: 版本 +View all contests: 查看所有比赛 +View all homework: 查看所有作业 View contest scoreboard: 查看比赛成绩表 View Contest: 查看比赛 View contests: 查看比赛 diff --git a/packages/hydrooj/src/handler/contest.ts b/packages/hydrooj/src/handler/contest.ts index 6d633b95..0bee65fa 100644 --- a/packages/hydrooj/src/handler/contest.ts +++ b/packages/hydrooj/src/handler/contest.ts @@ -74,12 +74,13 @@ ScheduleModel.Worker.addHandler('contest', async (doc) => { export class ContestListHandler extends Handler { @param('rule', Types.Range(contest.RULES), true) @param('page', Types.PositiveInt, true) - @param('all', Types.Boolean) - async get(domainId: string, rule = '', page = 1, all = false) { + async get(domainId: string, rule = '', page = 1) { if (rule && contest.RULES[rule].hidden) throw new BadRequestError(); const rules = Object.keys(contest.RULES).filter((i) => !contest.RULES[i].hidden); - if (all && !this.user.hasPerm(PERM.PERM_MOD_BADGE)) all = false; - const q = { ...all ? { assign: { $in: [...this.user.group, null] } } : {}, ...rule ? { rule } : { rule: { $in: rules } } }; + const q = { + ...this.user.hasPerm(PERM.PERM_VIEW_HIDDEN_CONTEST) ? {} : { $or: [{ assign: { $in: this.user.group } }, { assign: { $size: 0 } }] }, + ...rule ? { rule } : { rule: { $in: rules } }, + }; const cursor = contest.getMulti(domainId, q); const qs = rule ? `rule=${rule}` : ''; const [tdocs, tpcount] = await paginate(cursor, page, system.get('pagination.contest')); @@ -104,7 +105,7 @@ export class ContestDetailBaseHandler extends Handler { contest.get(domainId, tid), contest.getStatus(domainId, tid, this.user._id), ]); - if (this.tdoc.assign?.length && !this.user.own(this.tdoc)) { + if (this.tdoc.assign?.length && !this.user.own(this.tdoc) && !this.user.hasPerm(PERM.PERM_VIEW_HIDDEN_CONTEST)) { const groups = await user.listGroup(domainId, this.user._id); if (!Set.intersection(this.tdoc.assign, groups.map((i) => i.name)).size) { throw new NotAssignedError('contest', tid); @@ -163,7 +164,7 @@ export class ContestDetailHandler extends Handler { contest.getStatus(domainId, tid, this.user._id), ]); if (contest.RULES[this.tdoc.rule].hidden) throw new ContestNotFoundError(domainId, tid); - if (this.tdoc.assign?.length && !this.user.own(this.tdoc)) { + if (this.tdoc.assign?.length && !this.user.own(this.tdoc) && !this.user.hasPerm(PERM.PERM_VIEW_HIDDEN_CONTEST)) { const groups = await user.listGroup(domainId, this.user._id); if (!Set.intersection(this.tdoc.assign, groups.map((i) => i.name)).size) { throw new NotAssignedError('contest', tid); @@ -413,7 +414,7 @@ export class ContestEditHandler extends Handler { async postUpdate( domainId: string, tid: ObjectId, beginAtDate: string, beginAtTime: string, duration: number, title: string, content: string, rule: string, _pids: string, rated = false, - _code = '', autoHide = false, assign: string[] = null, lock: number = null, + _code = '', autoHide = false, assign: string[] = [], lock: number = null, contestDuration: number = null, maintainer: number[] = [], allowViewCode = false, ) { if (autoHide) this.checkPerm(PERM.PERM_EDIT_PROBLEM); diff --git a/packages/hydrooj/src/handler/homework.ts b/packages/hydrooj/src/handler/homework.ts index eeb7c8a5..74b6ea13 100644 --- a/packages/hydrooj/src/handler/homework.ts +++ b/packages/hydrooj/src/handler/homework.ts @@ -22,10 +22,11 @@ const convertPenaltyRules = validatePenaltyRules; class HomeworkMainHandler extends Handler { @param('page', Types.PositiveInt, true) - @param('all', Types.Boolean) - async get(domainId: string, page = 1, all = false) { - if (all && !this.user.hasPerm(PERM.PERM_MOD_BADGE)) all = false; - const cursor = contest.getMulti(domainId, { rule: 'homework', ...all ? { assign: { $in: [...this.user.group, null] } } : {} }); + async get(domainId: string, page = 1) { + const cursor = contest.getMulti(domainId, { + rule: 'homework', + ...this.user.hasPerm(PERM.PERM_VIEW_HIDDEN_HOMEWORK) ? {} : { $or: [{ assign: { $in: this.user.group } }, { assign: { $size: 0 } }] }, + }); const [tdocs, tpcount] = await paginate(cursor, page, system.get('pagination.contest')); const calendar = []; for (const tdoc of tdocs) { @@ -48,7 +49,7 @@ class HomeworkDetailHandler extends Handler { async prepare(domainId: string, tid: ObjectId) { const tdoc = await contest.get(domainId, tid); if (tdoc.rule !== 'homework') throw new ContestNotFoundError(domainId, tid); - if (tdoc.assign?.length && !this.user.own(tdoc)) { + if (tdoc.assign?.length && !this.user.own(tdoc) && !this.user.hasPerm(PERM.PERM_VIEW_HIDDEN_HOMEWORK)) { if (!Set.intersection(tdoc.assign, this.user.group).size) { throw new NotAssignedError('homework', tdoc.docId); } diff --git a/packages/hydrooj/src/model/builtin.ts b/packages/hydrooj/src/model/builtin.ts index 81509011..8066689b 100644 --- a/packages/hydrooj/src/model/builtin.ts +++ b/packages/hydrooj/src/model/builtin.ts @@ -69,6 +69,7 @@ export const PERM = { PERM_ATTEND_CONTEST: 1n << 45n, PERM_EDIT_CONTEST: 1n << 50n, PERM_EDIT_CONTEST_SELF: 1n << 51n, + PERM_VIEW_HIDDEN_CONTEST: 1n << 68n, // Homework PERM_VIEW_HOMEWORK: 1n << 52n, @@ -78,6 +79,7 @@ export const PERM = { PERM_ATTEND_HOMEWORK: 1n << 56n, PERM_EDIT_HOMEWORK: 1n << 57n, PERM_EDIT_HOMEWORK_SELF: 1n << 58n, + PERM_VIEW_HIDDEN_HOMEWORK: 1n << 69n, // Training PERM_VIEW_TRAINING: 1n << 46n, @@ -150,6 +152,7 @@ export const PERMS = [ Permission('perm_contest', PERM.PERM_ATTEND_CONTEST, 'Attend contests'), Permission('perm_contest', PERM.PERM_EDIT_CONTEST, 'Edit any contests'), Permission('perm_contest', PERM.PERM_EDIT_CONTEST_SELF, 'Edit own contests'), + Permission('perm_contest', PERM.PERM_VIEW_HIDDEN_CONTEST, 'View all contests'), Permission('perm_homework', PERM.PERM_VIEW_HOMEWORK, 'View homework'), Permission('perm_homework', PERM.PERM_VIEW_HOMEWORK_SCOREBOARD, 'View homework scoreboard'), Permission('perm_homework', PERM.PERM_VIEW_HOMEWORK_HIDDEN_SCOREBOARD, 'View hidden homework submission status and scoreboard'), @@ -157,6 +160,7 @@ export const PERMS = [ Permission('perm_homework', PERM.PERM_ATTEND_HOMEWORK, 'Claim homework'), Permission('perm_homework', PERM.PERM_EDIT_HOMEWORK, 'Edit any homework'), Permission('perm_homework', PERM.PERM_EDIT_HOMEWORK_SELF, 'Edit own homework'), + Permission('perm_homework', PERM.PERM_VIEW_HIDDEN_HOMEWORK, 'View all homework'), Permission('perm_training', PERM.PERM_VIEW_TRAINING, 'View training plans'), Permission('perm_training', PERM.PERM_CREATE_TRAINING, 'Create training plans'), Permission('perm_training', PERM.PERM_EDIT_TRAINING, 'Edit training plans'), diff --git a/packages/hydrooj/src/upgrade.ts b/packages/hydrooj/src/upgrade.ts index cd25871a..8a029d56 100644 --- a/packages/hydrooj/src/upgrade.ts +++ b/packages/hydrooj/src/upgrade.ts @@ -598,6 +598,10 @@ const scripts: UpgradeScript[] = [ await user.setById(udoc._id, { pinnedDomains: Array.from(pinnedDomains) }); }); }, + async function _82_83() { + await document.coll.updateMany({ docType: document.TYPE_CONTEST, assign: null }, { $set: { assign: [] } }); + return true; + }, ]; export default scripts;