core&ui: add PERM_VIEW_HIDDEN_CONTEST and PERM_VIEW_HIDDEN_HOMEWORK (#571)

Co-authored-by: panda <panda_dtdyy@outlook.com>
pull/553/head
Rei 1 year ago committed by GitHub
parent 4dcc2a2e78
commit 6cbb5ccfc9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -853,6 +853,8 @@ Valid for registered users who are not members of the domain: 对域外注册用
Valid for visitors: 对未登录的游客有效 Valid for visitors: 对未登录的游客有效
Verify register email: 注册需邮件验证 Verify register email: 注册需邮件验证
Version: 版本 Version: 版本
View all contests: 查看所有比赛
View all homework: 查看所有作业
View contest scoreboard: 查看比赛成绩表 View contest scoreboard: 查看比赛成绩表
View Contest: 查看比赛 View Contest: 查看比赛
View contests: 查看比赛 View contests: 查看比赛

@ -74,12 +74,13 @@ ScheduleModel.Worker.addHandler('contest', async (doc) => {
export class ContestListHandler extends Handler { export class ContestListHandler extends Handler {
@param('rule', Types.Range(contest.RULES), true) @param('rule', Types.Range(contest.RULES), true)
@param('page', Types.PositiveInt, true) @param('page', Types.PositiveInt, true)
@param('all', Types.Boolean) async get(domainId: string, rule = '', page = 1) {
async get(domainId: string, rule = '', page = 1, all = false) {
if (rule && contest.RULES[rule].hidden) throw new BadRequestError(); if (rule && contest.RULES[rule].hidden) throw new BadRequestError();
const rules = Object.keys(contest.RULES).filter((i) => !contest.RULES[i].hidden); 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 = {
const q = { ...all ? { assign: { $in: [...this.user.group, null] } } : {}, ...rule ? { rule } : { rule: { $in: rules } } }; ...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 cursor = contest.getMulti(domainId, q);
const qs = rule ? `rule=${rule}` : ''; const qs = rule ? `rule=${rule}` : '';
const [tdocs, tpcount] = await paginate<Tdoc>(cursor, page, system.get('pagination.contest')); const [tdocs, tpcount] = await paginate<Tdoc>(cursor, page, system.get('pagination.contest'));
@ -104,7 +105,7 @@ export class ContestDetailBaseHandler extends Handler {
contest.get(domainId, tid), contest.get(domainId, tid),
contest.getStatus(domainId, tid, this.user._id), 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); const groups = await user.listGroup(domainId, this.user._id);
if (!Set.intersection(this.tdoc.assign, groups.map((i) => i.name)).size) { if (!Set.intersection(this.tdoc.assign, groups.map((i) => i.name)).size) {
throw new NotAssignedError('contest', tid); throw new NotAssignedError('contest', tid);
@ -163,7 +164,7 @@ export class ContestDetailHandler extends Handler {
contest.getStatus(domainId, tid, this.user._id), contest.getStatus(domainId, tid, this.user._id),
]); ]);
if (contest.RULES[this.tdoc.rule].hidden) throw new ContestNotFoundError(domainId, tid); 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); const groups = await user.listGroup(domainId, this.user._id);
if (!Set.intersection(this.tdoc.assign, groups.map((i) => i.name)).size) { if (!Set.intersection(this.tdoc.assign, groups.map((i) => i.name)).size) {
throw new NotAssignedError('contest', tid); throw new NotAssignedError('contest', tid);
@ -413,7 +414,7 @@ export class ContestEditHandler extends Handler {
async postUpdate( async postUpdate(
domainId: string, tid: ObjectId, beginAtDate: string, beginAtTime: string, duration: number, domainId: string, tid: ObjectId, beginAtDate: string, beginAtTime: string, duration: number,
title: string, content: string, rule: string, _pids: string, rated = false, 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, contestDuration: number = null, maintainer: number[] = [], allowViewCode = false,
) { ) {
if (autoHide) this.checkPerm(PERM.PERM_EDIT_PROBLEM); if (autoHide) this.checkPerm(PERM.PERM_EDIT_PROBLEM);

@ -22,10 +22,11 @@ const convertPenaltyRules = validatePenaltyRules;
class HomeworkMainHandler extends Handler { class HomeworkMainHandler extends Handler {
@param('page', Types.PositiveInt, true) @param('page', Types.PositiveInt, true)
@param('all', Types.Boolean) async get(domainId: string, page = 1) {
async get(domainId: string, page = 1, all = false) { const cursor = contest.getMulti(domainId, {
if (all && !this.user.hasPerm(PERM.PERM_MOD_BADGE)) all = false; rule: 'homework',
const cursor = contest.getMulti(domainId, { rule: 'homework', ...all ? { assign: { $in: [...this.user.group, null] } } : {} }); ...this.user.hasPerm(PERM.PERM_VIEW_HIDDEN_HOMEWORK) ? {} : { $or: [{ assign: { $in: this.user.group } }, { assign: { $size: 0 } }] },
});
const [tdocs, tpcount] = await paginate<Tdoc>(cursor, page, system.get('pagination.contest')); const [tdocs, tpcount] = await paginate<Tdoc>(cursor, page, system.get('pagination.contest'));
const calendar = []; const calendar = [];
for (const tdoc of tdocs) { for (const tdoc of tdocs) {
@ -48,7 +49,7 @@ class HomeworkDetailHandler extends Handler {
async prepare(domainId: string, tid: ObjectId) { async prepare(domainId: string, tid: ObjectId) {
const tdoc = await contest.get(domainId, tid); const tdoc = await contest.get(domainId, tid);
if (tdoc.rule !== 'homework') throw new ContestNotFoundError(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) { if (!Set.intersection(tdoc.assign, this.user.group).size) {
throw new NotAssignedError('homework', tdoc.docId); throw new NotAssignedError('homework', tdoc.docId);
} }

@ -69,6 +69,7 @@ export const PERM = {
PERM_ATTEND_CONTEST: 1n << 45n, PERM_ATTEND_CONTEST: 1n << 45n,
PERM_EDIT_CONTEST: 1n << 50n, PERM_EDIT_CONTEST: 1n << 50n,
PERM_EDIT_CONTEST_SELF: 1n << 51n, PERM_EDIT_CONTEST_SELF: 1n << 51n,
PERM_VIEW_HIDDEN_CONTEST: 1n << 68n,
// Homework // Homework
PERM_VIEW_HOMEWORK: 1n << 52n, PERM_VIEW_HOMEWORK: 1n << 52n,
@ -78,6 +79,7 @@ export const PERM = {
PERM_ATTEND_HOMEWORK: 1n << 56n, PERM_ATTEND_HOMEWORK: 1n << 56n,
PERM_EDIT_HOMEWORK: 1n << 57n, PERM_EDIT_HOMEWORK: 1n << 57n,
PERM_EDIT_HOMEWORK_SELF: 1n << 58n, PERM_EDIT_HOMEWORK_SELF: 1n << 58n,
PERM_VIEW_HIDDEN_HOMEWORK: 1n << 69n,
// Training // Training
PERM_VIEW_TRAINING: 1n << 46n, 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_ATTEND_CONTEST, 'Attend contests'),
Permission('perm_contest', PERM.PERM_EDIT_CONTEST, 'Edit any 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_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, 'View homework'),
Permission('perm_homework', PERM.PERM_VIEW_HOMEWORK_SCOREBOARD, 'View homework scoreboard'), 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'), 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_ATTEND_HOMEWORK, 'Claim homework'),
Permission('perm_homework', PERM.PERM_EDIT_HOMEWORK, 'Edit any 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_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_VIEW_TRAINING, 'View training plans'),
Permission('perm_training', PERM.PERM_CREATE_TRAINING, 'Create training plans'), Permission('perm_training', PERM.PERM_CREATE_TRAINING, 'Create training plans'),
Permission('perm_training', PERM.PERM_EDIT_TRAINING, 'Edit training plans'), Permission('perm_training', PERM.PERM_EDIT_TRAINING, 'Edit training plans'),

@ -598,6 +598,10 @@ const scripts: UpgradeScript[] = [
await user.setById(udoc._id, { pinnedDomains: Array.from(pinnedDomains) }); 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; export default scripts;

Loading…
Cancel
Save