From 866aa56f780a1892277f47c1a202d2c84838778d Mon Sep 17 00:00:00 2001 From: undefined Date: Sat, 8 May 2021 22:44:04 +0800 Subject: [PATCH] core: restore PERM_EDIT_PROBLEM_SELF --- packages/hydrooj/package.json | 2 +- packages/hydrooj/src/handler/problem.ts | 15 +++++++-------- packages/hydrooj/src/interface.ts | 5 +++++ packages/hydrooj/src/model/builtin.ts | 1 - packages/hydrooj/src/model/user.ts | 5 +++-- packages/ui-default/package.json | 2 +- .../partials/problem_sidebar_contest.html | 2 +- .../partials/problem_sidebar_homework.html | 2 +- .../partials/problem_sidebar_normal.html | 2 +- packages/ui-default/templates/problem_edit.html | 2 +- packages/ui-default/templates/problem_files.html | 8 ++++---- 11 files changed, 25 insertions(+), 21 deletions(-) diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index eca335524..e1e6f093d 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.25.5", + "version": "2.25.6", "bin": "bin/hydrooj.js", "main": "dist/loader.js", "typings": "dist/loader.d.ts", diff --git a/packages/hydrooj/src/handler/problem.ts b/packages/hydrooj/src/handler/problem.ts index 02df1b786..a6b84287d 100644 --- a/packages/hydrooj/src/handler/problem.ts +++ b/packages/hydrooj/src/handler/problem.ts @@ -126,7 +126,7 @@ export class ProblemMainHandler extends ProblemHandler { for (const pid of pids) { // eslint-disable-next-line no-await-in-loop const pdoc = await problem.get(domainId, pid); - if (!this.user.own(pdoc)) this.checkPerm(PERM.PERM_EDIT_PROBLEM); + if (!this.user.own(pdoc, PERM.PERM_EDIT_PROBLEM_SELF)) this.checkPerm(PERM.PERM_EDIT_PROBLEM); // eslint-disable-next-line no-await-in-loop await problem.del(domainId, pid); } @@ -138,7 +138,7 @@ export class ProblemMainHandler extends ProblemHandler { for (const pid of pids) { // eslint-disable-next-line no-await-in-loop const pdoc = await problem.get(domainId, pid); - if (!this.user.own(pdoc)) this.checkPerm(PERM.PERM_EDIT_PROBLEM); + if (!this.user.own(pdoc, PERM.PERM_EDIT_PROBLEM_SELF)) this.checkPerm(PERM.PERM_EDIT_PROBLEM); // eslint-disable-next-line no-await-in-loop await problem.edit(domainId, pid, { hidden: true }); } @@ -150,7 +150,7 @@ export class ProblemMainHandler extends ProblemHandler { for (const pid of pids) { // eslint-disable-next-line no-await-in-loop const pdoc = await problem.get(domainId, pid); - if (!this.user.own(pdoc)) this.checkPerm(PERM.PERM_EDIT_PROBLEM); + if (!this.user.own(pdoc, PERM.PERM_EDIT_PROBLEM_SELF)) this.checkPerm(PERM.PERM_EDIT_PROBLEM); // eslint-disable-next-line no-await-in-loop await problem.edit(domainId, pid, { hidden: false }); } @@ -232,7 +232,7 @@ export class ProblemDetailHandler extends ProblemHandler { } async postDelete() { - if (!this.user.own(this.pdoc)) this.checkPerm(PERM.PERM_EDIT_PROBLEM); + if (!this.user.own(this.pdoc, PERM.PERM_EDIT_PROBLEM_SELF)) this.checkPerm(PERM.PERM_EDIT_PROBLEM); await problem.del(this.pdoc.domainId, this.pdoc.docId); this.response.redirect = this.url('problem_main'); } @@ -340,8 +340,7 @@ export class ProblemStatisticsHandler extends ProblemDetailHandler { export class ProblemManageHandler extends ProblemDetailHandler { async prepare() { - if (!this.user.own(this.pdoc)) this.checkPerm(PERM.PERM_EDIT_PROBLEM); - else this.checkPerm(PERM.PERM_EDIT_PROBLEM_SELF); + if (!this.user.own(this.pdoc, PERM.PERM_EDIT_PROBLEM_SELF)) this.checkPerm(PERM.PERM_EDIT_PROBLEM); } } @@ -413,7 +412,7 @@ export class ProblemFilesHandler extends ProblemDetailHandler { if (!this.request.files.file) throw new ValidationError('file'); if (!filename) filename = this.request.files.file.name || String.random(16); if (filename.includes('/') || filename.includes('..')) throw new ValidationError('filename', 'Bad filename'); - if (!this.user.own(this.pdoc)) this.checkPerm(PERM.PERM_EDIT_PROBLEM); + if (!this.user.own(this.pdoc, PERM.PERM_EDIT_PROBLEM_SELF)) this.checkPerm(PERM.PERM_EDIT_PROBLEM); if (filename.endsWith('.zip')) { const zip = new AdmZip(this.request.files.file.path); const entries = zip.getEntries(); @@ -438,7 +437,7 @@ export class ProblemFilesHandler extends ProblemDetailHandler { @post('files', Types.Array) @post('type', Types.Range(['testdata', 'additional_file']), true) async postDeleteFiles(domainId: string, files: string[], type = 'testdata') { - if (!this.user.own(this.pdoc)) this.checkPerm(PERM.PERM_EDIT_PROBLEM); + if (!this.user.own(this.pdoc, PERM.PERM_EDIT_PROBLEM_SELF)) this.checkPerm(PERM.PERM_EDIT_PROBLEM); if (type === 'testdata') await problem.delTestdata(domainId, this.pdoc.docId, files); else await problem.delAdditionalFile(domainId, this.pdoc.docId, files); this.back(); diff --git a/packages/hydrooj/src/interface.ts b/packages/hydrooj/src/interface.ts index 3c4b004e8..4185ef855 100644 --- a/packages/hydrooj/src/interface.ts +++ b/packages/hydrooj/src/interface.ts @@ -72,6 +72,8 @@ export interface Udoc extends Dictionary { loginip: string, } +export type ownerInfo = { owner: number, maintainer?: number[] }; + export interface User extends Record { _id: number, _udoc: Udoc, @@ -90,6 +92,9 @@ export interface User extends Record { perm: bigint, scope: bigint, role: string, + own(doc: T, checkPerm: bigint): boolean + own(doc: T, exact: boolean): boolean + own(doc: T): boolean own(doc: T): boolean; hasPerm: (...perm: bigint[]) => boolean, hasPriv: (...priv: number[]) => boolean, diff --git a/packages/hydrooj/src/model/builtin.ts b/packages/hydrooj/src/model/builtin.ts index 7f39e27ba..1c188f867 100644 --- a/packages/hydrooj/src/model/builtin.ts +++ b/packages/hydrooj/src/model/builtin.ts @@ -26,7 +26,6 @@ export const PERM = { // Problem and Record PERM_CREATE_PROBLEM: 1n << 4n, PERM_EDIT_PROBLEM: 1n << 5n, - /** @deprecated */ PERM_EDIT_PROBLEM_SELF: 1n << 6n, PERM_VIEW_PROBLEM: 1n << 7n, PERM_VIEW_PROBLEM_HIDDEN: 1n << 8n, diff --git a/packages/hydrooj/src/model/user.ts b/packages/hydrooj/src/model/user.ts index 174fc9a0e..c909367aa 100644 --- a/packages/hydrooj/src/model/user.ts +++ b/packages/hydrooj/src/model/user.ts @@ -87,8 +87,9 @@ class User implements _User { return this; } - own(doc: T, exact = false) { - return exact + own(doc: any, arg1: any = false): boolean { + if (typeof arg1 === 'bigint' && !this.hasPerm(arg1)) return false; + return (typeof arg1 === 'boolean' && arg1) ? doc.owner === this._id : doc.owner === this._id || (doc.maintainer || []).includes(this._id); } diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index 4004fcb69..c2fc07648 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.8.3", + "version": "4.8.4", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js", diff --git a/packages/ui-default/templates/partials/problem_sidebar_contest.html b/packages/ui-default/templates/partials/problem_sidebar_contest.html index fbc760e3e..bf7904cbf 100644 --- a/packages/ui-default/templates/partials/problem_sidebar_contest.html +++ b/packages/ui-default/templates/partials/problem_sidebar_contest.html @@ -28,7 +28,7 @@ {{ _('Open in Problem Set') }} {% endif %} - {% if handler.user.own(pdoc) or handler.user.hasPerm(perm.PERM_EDIT_PROBLEM) %} + {% if handler.user.own(pdoc, perm.PERM_EDIT_PROBLEM_SELF) or handler.user.hasPerm(perm.PERM_EDIT_PROBLEM) %} {% endif %} - {% if handler.user.own(pdoc) or handler.user.hasPerm(perm.PERM_EDIT_PROBLEM) %} + {% if handler.user.own(pdoc, perm.PERM_EDIT_PROBLEM_SELF) or handler.user.hasPerm(perm.PERM_EDIT_PROBLEM) %} - {% if (handler.user.own(pdoc) and handler.user.hasPerm(perm.PERM_EDIT_PROBLEM_SELF)) or handler.user.hasPerm(perm.PERM_EDIT_PROBLEM) %} + {% if handler.user.own(pdoc, perm.PERM_EDIT_PROBLEM_SELF) or handler.user.hasPerm(perm.PERM_EDIT_PROBLEM) %}