Skip to content

Commit 47b18c6

Browse files
committed
core: contest: add feature whitelist for hidden contest fule
1 parent 24f5076 commit 47b18c6

3 files changed

Lines changed: 15 additions & 0 deletions

File tree

packages/hydrooj/src/handler/contest.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,11 @@ export class ContestPrintHandler extends ContestDetailBaseHandler {
273273
}
274274

275275
export class ContestProblemListHandler extends ContestDetailBaseHandler {
276+
@param('tid', Types.ObjectId)
277+
async prepare(domainId: string, tid: ObjectId) {
278+
if (contest.RULES[this.tdoc.rule].hidden) throw new ContestNotFoundError(domainId, tid);
279+
}
280+
276281
@param('tid', Types.ObjectId)
277282
async get(domainId: string, tid: ObjectId) {
278283
if (contest.isNotStarted(this.tdoc)) throw new ContestNotLiveError(domainId, tid);
@@ -663,6 +668,9 @@ export class ContestFileDownloadHandler extends ContestDetailBaseHandler {
663668
@param('noDisposition', Types.Boolean)
664669
@param('type', Types.Range(['public', 'private']), true)
665670
async get(domainId: string, tid: ObjectId, filename: string, noDisposition = false, type = 'private') {
671+
if (contest.RULES[this.tdoc.rule].hidden && !contest.RULES[this.tdoc.rule].features?.includes('download')) {
672+
throw new ContestNotFoundError(domainId, tid);
673+
}
666674
if (type === 'private' && !this.user.own(this.tdoc) && !this.user.hasPerm(PERM.PERM_EDIT_CONTEST)) {
667675
if (!this.tsdoc?.attend) throw new ContestNotAttendedError(domainId, tid);
668676
if (!contest.isOngoing(this.tdoc) && !contest.isDone(this.tdoc)) throw new ContestNotLiveError(domainId, tid);
@@ -785,6 +793,9 @@ export class ContestScoreboardHandler extends ContestDetailBaseHandler {
785793
@param('tid', Types.ObjectId)
786794
@param('view', Types.String, true)
787795
async get(domainId: string, tid: ObjectId, viewId = 'default') {
796+
if (contest.RULES[this.tdoc.rule].hidden && !contest.RULES[this.tdoc.rule].features?.includes('scoreboard')) {
797+
throw new ContestNotFoundError(domainId, tid);
798+
}
788799
if (!this.user.own(this.tdoc)) {
789800
if (!contest.canShowScoreboard.call(this, this.tdoc, true)) throw new ContestScoreboardHiddenError(tid);
790801
if (contest.isNotStarted(this.tdoc)) throw new ContestNotLiveError(domainId, tid);

packages/hydrooj/src/interface.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,10 +422,13 @@ export interface ScoreboardConfig {
422422
lockAt?: Date;
423423
}
424424

425+
export type Feature = 'scoreboard' | 'download';
426+
425427
export interface ContestRule<T = any> {
426428
_originalRule?: Partial<ContestRule<T>>;
427429
TEXT: string;
428430
hidden?: boolean;
431+
features?: Feature[];
429432
check: (args: any) => any;
430433
statusSort: Record<string, 1 | -1>;
431434
submitAfterAccept: boolean;

packages/hydrooj/src/model/contest.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,7 @@ const ledo = buildContestRule({
636636
const homework = buildContestRule({
637637
TEXT: 'Assignment',
638638
hidden: true,
639+
features: ['scoreboard', 'download'],
639640
check: () => { },
640641
submitAfterAccept: false,
641642
statusSort: { penaltyScore: -1, time: 1 },

0 commit comments

Comments
 (0)