core: fix contest permission check

pull/546/head
undefined 2 years ago
parent 78b6c6b913
commit dde46c6e7f
No known key found for this signature in database

@ -331,11 +331,9 @@ export class ContestScoreboardHandler extends ContestDetailBaseHandler {
async exportScoreboard(domainId: string, tid: ObjectId, ext: string) {
await this.limitRate('scoreboard_download', 60, 3);
if (ext === 'ghost') {
if ((contest.isDone(this.tdoc) || contest.isLocked(this.tdoc)) && !this.tdoc.unlocked) {
if (!this.user.own(this.tdoc)) {
if (contest.isLocked(this.tdoc) && !this.user.own(this.tdoc)) {
this.checkPerm(PERM.PERM_VIEW_CONTEST_HIDDEN_SCOREBOARD);
}
}
await this.exportGhost(domainId, tid);
return;
}

@ -51,13 +51,14 @@ class RecordListHandler extends ContestDetailBaseHandler {
this.tdoc = tdoc;
if (!tdoc) throw new ContestNotFoundError(domainId, pid);
if (!contest.canShowScoreboard.call(this, tdoc, true)) throw new PermissionError(PERM.PERM_VIEW_CONTEST_HIDDEN_SCOREBOARD);
if (!contest.canShowRecord.call(this, tdoc, true)) {
throw new PermissionError(PERM.PERM_VIEW_CONTEST_HIDDEN_SCOREBOARD);
}
if (!(await contest.getStatus(domainId, tid, this.user._id))?.attend) {
if (contest.canShowRecord.call(this, tdoc, true)) {
const name = tdoc.rule === 'homework'
? "You haven't claimed this homework yet."
: "You haven't attended this contest yet.";
notification.push({ name, args: { type: 'note' }, checker: () => true });
} else throw new ContestNotAttendedError(domainId, tid);
}
}
if (uidOrName) {
@ -250,7 +251,7 @@ class RecordMainConnectionHandler extends ConnectionHandler {
if (tid) {
this.tdoc = await contest.get(domainId, tid);
if (!this.tdoc) throw new ContestNotFoundError(domainId, tid);
if (pretest || contest.canShowScoreboard.call(this, this.tdoc, true)) this.tid = tid.toHexString();
if (pretest || contest.canShowScoreboard.call(this, this.tdoc, true, true)) this.tid = tid.toHexString();
else throw new PermissionError(PERM.PERM_VIEW_CONTEST_HIDDEN_SCOREBOARD);
}
if (pretest) {

@ -53,7 +53,8 @@ const acm = buildContestRule({
submitAfterAccept: false,
showScoreboard: (tdoc, now) => now > tdoc.beginAt,
showSelfRecord: () => true,
showRecord: (tdoc, now) => now > tdoc.endAt,
// eslint-disable-next-line @typescript-eslint/no-use-before-define
showRecord: (tdoc, now) => now > tdoc.endAt && !isLocked(tdoc),
stat(tdoc, journal: AcmJournal[]) {
const naccept = Counter<number>();
const npending = Counter<number>();
@ -245,7 +246,8 @@ const oi = buildContestRule({
},
showScoreboard: (tdoc, now) => now > tdoc.endAt,
showSelfRecord: (tdoc, now) => now > tdoc.endAt,
showRecord: (tdoc, now) => now > tdoc.endAt,
// eslint-disable-next-line @typescript-eslint/no-use-before-define
showRecord: (tdoc, now) => now > tdoc.endAt && !isLocked(tdoc),
async scoreboardHeader(config, _, tdoc, pdict) {
const columns: ScoreboardNode[] = [
{ type: 'rank', value: '#' },
@ -781,7 +783,7 @@ export function isDone(tdoc: Tdoc, tsdoc?: any) {
export function isLocked(tdoc: Tdoc) {
if (!tdoc.lockAt) return false;
const now = new Date();
return (tdoc.lockAt < now && now < tdoc.endAt);
return tdoc.lockAt < now && !tdoc.unlocked;
}
export function isExtended(tdoc: Tdoc) {

@ -10,13 +10,11 @@
{% if model.contest.isLocked(tdoc) %}
<div class="section__body no-padding">
<blockquote class="note">
{{ _('The scoreboard was frozen with {0} minutes remaining at {1} - submissions in the last {0} minutes of the contest are still shown as pending.').format((tdoc.endAt - tdoc.lockAt) / 1000 / 60, datetimeSpan(tdoc.lockAt))|safe }}
</blockquote>
</div>
{% elif model.contest.isDone(tdoc) and tdoc.lockAt and not tdoc.unlocked %}
<div class="section__body no-padding">
<blockquote class="note">
{% if model.contest.isDone(tdoc) %}
{{ _('Please wait until contest host unfreeze the scoreboard.') }}
{% else %}
{{ _('The scoreboard was frozen with {0} minutes remaining at {1} - submissions in the last {0} minutes of the contest are still shown as pending.').format((tdoc.endAt - tdoc.lockAt) / 1000 / 60, datetimeSpan(tdoc.lockAt))|safe }}
{% endif %}
</blockquote>
</div>
{% endif %}

Loading…
Cancel
Save