mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-19 09:38:19 +08:00
InvalidOperationError & MethodNotAllowedError
This commit is contained in:
1 parent
e15c05d36b
commit
0de7cd7b59
4 files changed
+48
-26
No files matched your search
+5
-3
@@ -36,6 +36,7 @@ const SystemError = Err('SystemError', HydroError, 'SystemError', 500);
|
|||||||
const BadRequestError = Err('BadRequestError', UserFacingError, 400);
|
const BadRequestError = Err('BadRequestError', UserFacingError, 400);
|
||||||
const ForbiddenError = Err('ForbiddenError', UserFacingError, 403);
|
const ForbiddenError = Err('ForbiddenError', UserFacingError, 403);
|
||||||
const NotFoundError = Err('NotFoundError', UserFacingError, 404);
|
const NotFoundError = Err('NotFoundError', UserFacingError, 404);
|
||||||
|
const MethodNotAllowedError = Err('MethodNotAllowedError', UserFacingError, 405);
|
||||||
const RemoteOnlineJudgeError = Err('RemoteOnlineJudgeError', UserFacingError, 500);
|
const RemoteOnlineJudgeError = Err('RemoteOnlineJudgeError', UserFacingError, 500);
|
||||||
|
|
||||||
const AlreadyVotedError = Err('AlreadyVotedError', ForbiddenError, "You've already voted.");
|
const AlreadyVotedError = Err('AlreadyVotedError', ForbiddenError, "You've already voted.");
|
||||||
@@ -78,6 +79,8 @@ const ContestNotFoundError = Err('ContestNotFoundError', DocumentNotFoundError);
|
|||||||
const DiscussionNotFoundError = Err('DiscussionNotFoundError', DocumentNotFoundError, 'Discussion {0} not found.');
|
const DiscussionNotFoundError = Err('DiscussionNotFoundError', DocumentNotFoundError, 'Discussion {0} not found.');
|
||||||
const DiscussionNodeNotFoundError = Err('DiscussionNodeNotFoundError', DocumentNotFoundError, 'Discussion node {1} not found.');
|
const DiscussionNodeNotFoundError = Err('DiscussionNodeNotFoundError', DocumentNotFoundError, 'Discussion node {1} not found.');
|
||||||
|
|
||||||
|
const InvalidOperationError = Err('InvalidOperationError', MethodNotAllowedError);
|
||||||
|
|
||||||
global.Hydro.error = module.exports = {
|
global.Hydro.error = module.exports = {
|
||||||
Err,
|
Err,
|
||||||
HydroError,
|
HydroError,
|
||||||
@@ -87,6 +90,8 @@ global.Hydro.error = module.exports = {
|
|||||||
NotFoundError,
|
NotFoundError,
|
||||||
LoginError,
|
LoginError,
|
||||||
CsrfTokenError,
|
CsrfTokenError,
|
||||||
|
MethodNotAllowedError,
|
||||||
|
InvalidOperationError,
|
||||||
UserAlreadyExistError,
|
UserAlreadyExistError,
|
||||||
InvalidTokenError,
|
InvalidTokenError,
|
||||||
UserNotFoundError,
|
UserNotFoundError,
|
||||||
@@ -129,9 +134,6 @@ class FileTypeNotAllowedError(ValidationError):
|
|||||||
def message(self):
|
def message(self):
|
||||||
return 'This type of files are not allowed to be uploaded.'
|
return 'This type of files are not allowed to be uploaded.'
|
||||||
|
|
||||||
class InvalidOperationError(ForbiddenError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class InvalidTokenDigestError(ForbiddenError):
|
class InvalidTokenDigestError(ForbiddenError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,12 @@ class MarkdownHandler extends Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SockToken extends Handler {
|
||||||
|
async get() {
|
||||||
|
this.response.body = { token: this.csrfToken };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function apply() {
|
async function apply() {
|
||||||
Route('file_download', '/fs/:docId/:secret', FileDownloadHandler);
|
Route('file_download', '/fs/:docId/:secret', FileDownloadHandler);
|
||||||
Route('file_download_with_name', '/fs/:docId/:name/:secret', FileDownloadHandler);
|
Route('file_download_with_name', '/fs/:docId/:name/:secret', FileDownloadHandler);
|
||||||
@@ -71,6 +77,7 @@ async function apply() {
|
|||||||
Route('status_update', '/status/update', StatusUpdateHandler);
|
Route('status_update', '/status/update', StatusUpdateHandler);
|
||||||
Route('switch_language', '/language/:lang', SwitchLanguageHandler);
|
Route('switch_language', '/language/:lang', SwitchLanguageHandler);
|
||||||
Route('markdown', '/markdown', MarkdownHandler);
|
Route('markdown', '/markdown', MarkdownHandler);
|
||||||
|
Route('token', '/token', SockToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
apply.updateStatus = function updateStatus(args) {
|
apply.updateStatus = function updateStatus(args) {
|
||||||
|
|||||||
+17
-21
@@ -4,7 +4,7 @@ const paginate = require('../lib/paginate');
|
|||||||
const {
|
const {
|
||||||
PERM: {
|
PERM: {
|
||||||
PERM_VIEW_TRAINING, PERM_VIEW_PROBLEM_HIDDEN, PERM_CREATE_TRAINING,
|
PERM_VIEW_TRAINING, PERM_VIEW_PROBLEM_HIDDEN, PERM_CREATE_TRAINING,
|
||||||
PERM_EDIT_TRAINING,
|
PERM_EDIT_TRAINING, PERM_EDIT_TRAINING_SELF,
|
||||||
},
|
},
|
||||||
PRIV: {
|
PRIV: {
|
||||||
PRIV_USER_PROFILE,
|
PRIV_USER_PROFILE,
|
||||||
@@ -57,13 +57,7 @@ async function _parseDagJson(domainId, dag) {
|
|||||||
return parsed;
|
return parsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
class TrainingHandler extends Handler {
|
class TrainingMainHandler extends Handler {
|
||||||
async _prepare() {
|
|
||||||
this.checkPerm(PERM_VIEW_TRAINING);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TrainingMainHandler extends TrainingHandler {
|
|
||||||
async get({ domainId, sort, page }) {
|
async get({ domainId, sort, page }) {
|
||||||
const qs = sort ? 'sort={0}'.format(sort) : '';
|
const qs = sort ? 'sort={0}'.format(sort) : '';
|
||||||
const [tdocs, tpcount] = await paginate(
|
const [tdocs, tpcount] = await paginate(
|
||||||
@@ -102,7 +96,7 @@ class TrainingMainHandler extends TrainingHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TrainingDetailHandler extends TrainingHandler {
|
class TrainingDetailHandler extends Handler {
|
||||||
async get({ domainId, tid }) {
|
async get({ domainId, tid }) {
|
||||||
const tdoc = await training.get(domainId, tid);
|
const tdoc = await training.get(domainId, tid);
|
||||||
const pids = training.getPids(tdoc);
|
const pids = training.getPids(tdoc);
|
||||||
@@ -162,7 +156,7 @@ class TrainingDetailHandler extends TrainingHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TrainingCreateHandler extends TrainingHandler {
|
class TrainingCreateHandler extends Handler {
|
||||||
async get() {
|
async get() {
|
||||||
const path = [
|
const path = [
|
||||||
['Hydro', 'homepage'],
|
['Hydro', 'homepage'],
|
||||||
@@ -201,28 +195,30 @@ class TrainingCreateHandler extends TrainingHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TrainingEditHandler extends TrainingHandler {
|
class TrainingEditHandler extends Handler {
|
||||||
async get({ domainId, tid }) {
|
async prepare({ domainId, tid }) {
|
||||||
const tdoc = await training.get(domainId, tid);
|
this.tdoc = await training.get(domainId, tid);
|
||||||
if (tdoc.owner !== this.user._id) this.checkPerm(PERM_EDIT_TRAINING);
|
if (this.tdoc.owner !== this.user._id) this.checkPerm(PERM_EDIT_TRAINING);
|
||||||
const dag = JSON.stringify(tdoc.dag, null, 2);
|
else this.checkPerm(PERM_EDIT_TRAINING_SELF);
|
||||||
|
}
|
||||||
|
|
||||||
|
async get({ tid }) {
|
||||||
|
const dag = JSON.stringify(this.tdoc.dag, null, 2);
|
||||||
const path = [
|
const path = [
|
||||||
['Hydro', 'homepage'],
|
['Hydro', 'homepage'],
|
||||||
['training_main', 'training_main'],
|
['training_main', 'training_main'],
|
||||||
[tdoc.title, 'training_detail', { tid: tdoc.docId }, true],
|
[this.tdoc.title, 'training_detail', { tid }, true],
|
||||||
['training_edit', null],
|
['training_edit', null],
|
||||||
];
|
];
|
||||||
this.response.template = 'training_edit.html';
|
this.response.template = 'training_edit.html';
|
||||||
this.response.body = {
|
this.response.body = {
|
||||||
tdoc, dag, path, page_name: 'training_edit',
|
tdoc: this.tdoc, dag, path, page_name: 'training_edit',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async post({
|
async post({
|
||||||
domainId, tid, title, content, dag, description,
|
domainId, tid, title, content, dag, description,
|
||||||
}) {
|
}) {
|
||||||
const tdoc = await training.get(domainId, tid);
|
|
||||||
if (!this.user._id === tdoc.owner) this.checkPerm(PERM_EDIT_TRAINING);
|
|
||||||
dag = await _parseDagJson(domainId, dag);
|
dag = await _parseDagJson(domainId, dag);
|
||||||
const pids = training.getPids({ dag });
|
const pids = training.getPids({ dag });
|
||||||
assert(pids.length, new ValidationError('dag'));
|
assert(pids.length, new ValidationError('dag'));
|
||||||
@@ -254,9 +250,9 @@ class TrainingEditHandler extends TrainingHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function apply() {
|
async function apply() {
|
||||||
Route('training_main', '/training', TrainingMainHandler);
|
Route('training_main', '/training', TrainingMainHandler, PERM_VIEW_TRAINING);
|
||||||
Route('training_create', '/training/create', TrainingCreateHandler, PERM_CREATE_TRAINING);
|
Route('training_create', '/training/create', TrainingCreateHandler, PERM_CREATE_TRAINING);
|
||||||
Route('training_detail', '/training/:tid', TrainingDetailHandler);
|
Route('training_detail', '/training/:tid', TrainingDetailHandler, PERM_VIEW_TRAINING);
|
||||||
Route('training_edit', '/training/:tid/edit', TrainingEditHandler);
|
Route('training_edit', '/training/:tid/edit', TrainingEditHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-2
@@ -22,7 +22,7 @@ const opcount = require('../model/opcount');
|
|||||||
const {
|
const {
|
||||||
UserNotFoundError, BlacklistedError, PermissionError,
|
UserNotFoundError, BlacklistedError, PermissionError,
|
||||||
UserFacingError, ValidationError, PrivilegeError,
|
UserFacingError, ValidationError, PrivilegeError,
|
||||||
CsrfTokenError,
|
CsrfTokenError, InvalidOperationError, MethodNotAllowedError,
|
||||||
} = require('../error');
|
} = require('../error');
|
||||||
|
|
||||||
let enableLog = true;
|
let enableLog = true;
|
||||||
@@ -387,10 +387,26 @@ async function handle(ctx, HandlerClass, checker) {
|
|||||||
domainId: 'system', ...ctx.params, ...ctx.query, ...ctx.request.body,
|
domainId: 'system', ...ctx.params, ...ctx.query, ...ctx.request.body,
|
||||||
};
|
};
|
||||||
h.args = args;
|
h.args = args;
|
||||||
|
let operation;
|
||||||
|
if (method === 'post' && ctx.request.body.operation) {
|
||||||
|
operation = `_${ctx.request.body.operation}`
|
||||||
|
.replace(/_([a-z])/gm, (s) => s[1].toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
if (h.___prepare) await h.___prepare(args);
|
if (h.___prepare) await h.___prepare(args);
|
||||||
if (checker) checker.call(h);
|
if (checker) checker.call(h);
|
||||||
if (method === 'post') await h.checkCsrfToken(args.csrfToken);
|
if (method === 'post') {
|
||||||
|
await h.checkCsrfToken(args.csrfToken);
|
||||||
|
if (operation) {
|
||||||
|
if (typeof h[`post${operation}`] !== 'function') {
|
||||||
|
throw new InvalidOperationError(operation);
|
||||||
|
}
|
||||||
|
} else if (typeof h.post !== 'function') {
|
||||||
|
throw new MethodNotAllowedError(method);
|
||||||
|
}
|
||||||
|
} else if (typeof h[method] !== 'function') {
|
||||||
|
throw new MethodNotAllowedError(method);
|
||||||
|
}
|
||||||
|
|
||||||
let checking = '';
|
let checking = '';
|
||||||
try {
|
try {
|
||||||
@@ -404,6 +420,7 @@ async function handle(ctx, HandlerClass, checker) {
|
|||||||
if (e instanceof ValidationError) throw e;
|
if (e instanceof ValidationError) throw e;
|
||||||
throw new ValidationError(`Argument ${checking} check failed`);
|
throw new ValidationError(`Argument ${checking} check failed`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h.__prepare) await h.__prepare(args);
|
if (h.__prepare) await h.__prepare(args);
|
||||||
if (h._prepare) await h._prepare(args);
|
if (h._prepare) await h._prepare(args);
|
||||||
if (h.prepare) await h.prepare(args);
|
if (h.prepare) await h.prepare(args);
|
||||||
|
|||||||
Reference in new issue
Block a user