Skip to content

Commit b03d161

Browse files
committed
Use joi for validation and add base validator
1 parent def4d72 commit b03d161

File tree

10 files changed

+112
-31
lines changed

10 files changed

+112
-31
lines changed

docs/api_project.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/api_project.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{ "title": "judge-blocks API", "url": "https://judge2.codingblocks.com/api", "sampleUrl": "https://judge2.codingblocks.com/api", "name": "judge-api", "version": "1.2.0", "description": "Judge API", "defaultVersion": "0.0.0", "apidoc": "0.3.0", "generator": { "name": "apidoc", "time": "2020-04-11T15:13:28.923Z", "url": "http://apidocjs.com", "version": "0.17.7" }}
1+
{ "title": "judge-blocks API", "url": "https://judge2.codingblocks.com/api", "sampleUrl": "https://judge2.codingblocks.com/api", "name": "judge-api", "version": "1.2.0", "description": "Judge API", "defaultVersion": "0.0.0", "apidoc": "0.3.0", "generator": { "name": "apidoc", "time": "2020-04-17T14:00:28.777Z", "url": "http://apidocjs.com", "version": "0.17.7" }}

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"license": "Apache-2.0",
99
"private": true,
1010
"dependencies": {
11+
"@hapi/joi": "^17.1.1",
1112
"@types/amqplib": "^0.5.4",
1213
"amqplib": "^0.5.2",
1314
"apidoc": "^0.17.6",
@@ -24,6 +25,7 @@
2425
"@types/chai": "^4.0.4",
2526
"@types/debug": "^0.0.30",
2627
"@types/express": "^4.0.39",
28+
"@types/joi": "^14.3.4",
2729
"@types/minio": "^7.0.1",
2830
"@types/mocha": "^5.0.0",
2931
"@types/sequelize": "^4.0.79",

src/models/Submission.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ export const define = (
4040
allowNull: false
4141
},
4242
results: Sequelize.JSON,
43-
outputs: Sequelize.ARRAY(Sequelize.STRING),
4443
callback: Sequelize.STRING
4544
}, {
4645
paranoid: true, // We do not want to lose any submission data

src/routes/api/run/controller.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,7 @@ class RunController {
5252
}
5353

5454
async onSuccess(result: RunResponse) {
55-
const { url } = await upload(result)
56-
5755
const job = await DB.submissions.findById(result.id)
58-
job.outputs = [url]
59-
await job.save()
6056

6157
switch (job.mode) {
6258
case 'callback':

src/routes/api/run/validators.ts

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,35 @@
1-
import { Request, Response, NextFunction } from 'express'
1+
import { Handler } from 'express'
2+
import BaseValidator from 'validators/baseValidator'
3+
import * as Joi from '@hapi/joi'
24

3-
class RunValidator {
4-
POST(req: Request, res: Response, next: NextFunction) {
5-
if (!req.body.lang || (typeof req.body.lang !== 'string')) {
6-
return new Error('Invalid Language')
7-
}
8-
if (!req.body.source) {
9-
return new Error('Source not found')
10-
}
11-
if (!req.body.stdin) {
12-
req.body.stdin = ''
13-
}
14-
if (!req.body.mode) {
15-
req.body.mode = 'sync'
16-
}
17-
if (!['sync', 'callback'].includes(req.body.mode)) {
18-
return new Error('Mode must be one of sync, callback')
19-
}
20-
if (req.body.mode === 'callback' && !req.body.callback) {
21-
return new Error('Must specify a callback for callback mode')
22-
}
23-
24-
return next()
5+
class RunValidator extends BaseValidator {
6+
POST: Handler
7+
8+
constructor() {
9+
super()
10+
this.POST = this.requestValidator(this.POSTSchema)
2511
}
12+
13+
POSTSchema = Joi.object({
14+
lang: Joi
15+
.string()
16+
.required(),
17+
source: Joi
18+
.string()
19+
.required(),
20+
mode: Joi
21+
.string()
22+
.valid('sync', 'callback', 'poll'),
23+
stdin: Joi
24+
.string()
25+
.default(''),
26+
timelimit: Joi
27+
.number(),
28+
callback: Joi
29+
.string()
30+
.uri()
31+
.when('mode', { is: 'callback', then: Joi.string().required() })
32+
})
2633
}
2734

2835
export default new RunValidator()

src/routes/api/submit/controller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class SubmitController {
5555

5656
async onSuccess(result: SubmitResponse) {
5757
const job = await DB.submissions.findById(result.id)
58-
job.results = result.testcases
58+
job.results = result
5959
await job.save()
6060

6161
switch (job.mode) {

src/routes/api/submit/validators.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

src/validators/baseValidator.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Request, Response, NextFunction } from 'express';
2+
import * as Joi from '@hapi/joi';
3+
4+
export default class BaseValidator {
5+
constructor() {
6+
new Array(
7+
'requestValidator'
8+
).map(_ => {
9+
this[_] = this[_].bind(this)
10+
})
11+
}
12+
13+
forbid(err, res: Response) {
14+
return res
15+
.status(err.code || 400)
16+
.json({
17+
err
18+
})
19+
}
20+
21+
requestValidator(schema, key = 'body') {
22+
return (req: Request, res: Response, next: NextFunction) => {
23+
const { error } = schema.validate(req[key], { allowUnknown: true })
24+
if (error) {
25+
return this.forbid({message: error.details[0].message, code: 400}, res)
26+
}
27+
28+
next()
29+
}
30+
}
31+
}

yarn.lock

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,46 @@
9292
lodash "^4.17.5"
9393
to-fast-properties "^2.0.0"
9494

95+
"@hapi/address@^4.0.1":
96+
version "4.0.1"
97+
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-4.0.1.tgz#267301ddf7bc453718377a6fb3832a2f04a721dd"
98+
integrity sha512-0oEP5UiyV4f3d6cBL8F3Z5S7iWSX39Knnl0lY8i+6gfmmIBj44JCBNtcMgwyS+5v7j3VYavNay0NFHDS+UGQcw==
99+
dependencies:
100+
"@hapi/hoek" "^9.0.0"
101+
102+
"@hapi/formula@^2.0.0":
103+
version "2.0.0"
104+
resolved "https://registry.yarnpkg.com/@hapi/formula/-/formula-2.0.0.tgz#edade0619ed58c8e4f164f233cda70211e787128"
105+
integrity sha512-V87P8fv7PI0LH7LiVi8Lkf3x+KCO7pQozXRssAHNXXL9L1K+uyu4XypLXwxqVDKgyQai6qj3/KteNlrqDx4W5A==
106+
107+
"@hapi/hoek@^9.0.0":
108+
version "9.0.4"
109+
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.0.4.tgz#e80ad4e8e8d2adc6c77d985f698447e8628b6010"
110+
integrity sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw==
111+
112+
"@hapi/joi@^17.1.1":
113+
version "17.1.1"
114+
resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-17.1.1.tgz#9cc8d7e2c2213d1e46708c6260184b447c661350"
115+
integrity sha512-p4DKeZAoeZW4g3u7ZeRo+vCDuSDgSvtsB/NpfjXEHTUjSeINAi/RrVOWiVQ1isaoLzMvFEhe8n5065mQq1AdQg==
116+
dependencies:
117+
"@hapi/address" "^4.0.1"
118+
"@hapi/formula" "^2.0.0"
119+
"@hapi/hoek" "^9.0.0"
120+
"@hapi/pinpoint" "^2.0.0"
121+
"@hapi/topo" "^5.0.0"
122+
123+
"@hapi/pinpoint@^2.0.0":
124+
version "2.0.0"
125+
resolved "https://registry.yarnpkg.com/@hapi/pinpoint/-/pinpoint-2.0.0.tgz#805b40d4dbec04fc116a73089494e00f073de8df"
126+
integrity sha512-vzXR5MY7n4XeIvLpfl3HtE3coZYO4raKXW766R6DZw/6aLqR26iuZ109K7a0NtF2Db0jxqh7xz2AxkUwpUFybw==
127+
128+
"@hapi/topo@^5.0.0":
129+
version "5.0.0"
130+
resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.0.0.tgz#c19af8577fa393a06e9c77b60995af959be721e7"
131+
integrity sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==
132+
dependencies:
133+
"@hapi/hoek" "^9.0.0"
134+
95135
"@types/amqplib@^0.5.4":
96136
version "0.5.13"
97137
resolved "https://registry.yarnpkg.com/@types/amqplib/-/amqplib-0.5.13.tgz#a0dc9be08f38b91e5f7532acf0c89b0e515cdc6c"
@@ -164,6 +204,11 @@
164204
resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.7.tgz#c8fa532b60a0042219cdf173ca21a975ef0666ad"
165205
integrity sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ==
166206

207+
"@types/joi@^14.3.4":
208+
version "14.3.4"
209+
resolved "https://registry.yarnpkg.com/@types/joi/-/joi-14.3.4.tgz#eed1e14cbb07716079c814138831a520a725a1e0"
210+
integrity sha512-1TQNDJvIKlgYXGNIABfgFp9y0FziDpuGrd799Q5RcnsDu+krD+eeW/0Fs5PHARvWWFelOhIG2OPCo6KbadBM4A==
211+
167212
"@types/lodash@*":
168213
version "4.14.149"
169214
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.149.tgz#1342d63d948c6062838fbf961012f74d4e638440"

0 commit comments

Comments
 (0)