Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions _DEFAULTconfig.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ JUDGE:
CONTEST:
MODE: false
SUBMIT_LIMIT: 15
VALID_CLASS: ["4"]
VALID_IP: ["::ffff:140.112.16.155", "::ffff:140.112.16.156", "::ffff:140.112.16.158", "::1"]

# DATABASE Setting, MySQL
Expand Down
28 changes: 27 additions & 1 deletion lib/components/RedisClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,32 @@ class RedisClient {
});
});
}
scanKeys(pattern) {
return new Promise((resolve, reject) => {
let cursor = '0';
let keys = [];

const scan = () => {
this.client.scan(cursor, 'MATCH', pattern, (err, res) => {
if (err) {
reject(err);
return;
}

cursor = res[0];
keys = keys.concat(res[1]);

if (cursor === '0') {
resolve(keys);
} else {
scan();
}
});
};

scan();
});
}
}

module.exports = { redisClient: new RedisClient() };
module.exports = { redisClient: new RedisClient() };
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
"version": "0.0.0",
"private": true,
"scripts": {
"start": "ulimit -n 4096 && NODE_PATH=./ nodejs ./bin/www",
"start": "ulimit -n 4096 && NODE_PATH=./ node ./bin/www",
"flush-redis": "redis-cli flushall",
"fresh-start": "redis-cli flushall && ulimit -n 4096 && NODE_PATH=./ nodejs ./bin/www",
"test": "NODE_PATH=./ NODE_ENV=test mocha --recursive --exit",
"test-log": "NODE_PATH=./ NODE_ENV=test-log mocha --recursive --exit",
"build": "node ./node_modules/gulp/bin/gulp.js build"
},
"dependencies": {
"archiver": "^7.0.1",
"body-parser": "^1.18.3",
"bower": "^1.8.4",
"child_process": "^1.0.2",
Expand Down
29 changes: 29 additions & 0 deletions public/runTest.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash

if [ -z "$1" ]; then
echo "Usage: $0 <source_file.c>"
exit 1
fi

PROGRAM="$1"
EXECUTABLE="${PROGRAM%.c}"

gcc -std=c99 -O2 -o $EXECUTABLE $PROGRAM
if [ $? -ne 0 ]; then
echo "Compilation failed"
exit 1
fi

for infile in *.in; do
outfile="${infile%.in}.out"
my_output="my_${infile%.in}.out"

./$EXECUTABLE < $infile > $my_output

diff -Z $outfile $my_output
if [ $? -eq 0 ]; then
echo "Test $infile: PASS"
else
echo "Test $infile: FAIL"
fi
done
21 changes: 20 additions & 1 deletion routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ router.post('/login', function(req, res, next) {
let logger = loggerFactory.getLogger(module.id);
logger.info(`Login request: (${user["lgn"]}, ${ip})`);

dblink.user.login(user, req.session, function(status) {
dblink.user.login(user, req.session, async function(status) {
/* login fail */
if (status == 0) {
logger.info('Wrong password.');
Expand All @@ -99,8 +99,27 @@ router.post('/login', function(req, res, next) {
var filter_ip = iplist.filter(function(valid_ip) {
return ip == valid_ip;
});
logger.info(`previous IP : ${filter_ip}`);
var isAdmin = req.session['class'] == null;
var isValidClass = classlist.includes(req.session['class']);

const { redisClient } = require('../lib/components/RedisClient');

logger.info(`${redisClient.getClient()}`);
const sessionKeys = await redisClient.scanKeys('sess:*');

for (const key of sessionKeys) {
const sessionData = await redisClient.getValue(key);
if (sessionData) {
const session = JSON.parse(sessionData);
if (session.uid === uid && session.ip && session.ip !== ip) {
await redisClient.deleteKey(key);
logger.info(`Terminated session from previous IP. Session key: ${key}`);
}
}
}

req.session.ip = ip;
/**
enter judge privilege:
1. contest not running
Expand Down
8 changes: 2 additions & 6 deletions routes/submit.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,8 @@ function submitStep(req, res, uid, pid, cid, lng) {
let file_size = 0;
if (req.files['code' + i] == null || req.files['code' + i] == undefined ||
req.files['code' + i][0] == null || req.files['code' + i][0] == undefined) {
if (req.body['paste_code' + i].length > 65536 || req.body['paste_code' + i].trim().length == 0) {
loggerFactory.getLogger(module.id).debug('NOT FOUND FILE ' + i);
return res.redirect(utils.url_for('/'));
} else {
file_size = req.body['paste_code' + i].length;
}
loggerFactory.getLogger(module.id).debug('NOT FOUND FILE ' + i);
return res.redirect(req.headers.referer);
} else {
file_size = req.files['code' + i][0].size;
}
Expand Down
44 changes: 44 additions & 0 deletions routes/testdata.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
var express = require('express');
var router = express.Router();
const archiver = require('archiver');
const fs = require('fs');
const path = require('path');
var dblink = require('../lib/components/dblink');
var _config = require('../lib/config').config;

router.get('/download/:pid', function(req, res, next) {
var pid = req.params.pid;
Expand All @@ -19,6 +23,46 @@ router.get('/download/:pid', function(req, res, next) {
});
});

router.get('/download-all/:pid', (req, res) => {
const pid = req.params.pid;
const testdataDir = path.join(_config.RESOURCE.public.testdata, pid);
const publicDir = path.join(__dirname, '../public'); // Adjust this path if needed

// Ensure the directory exists
if (!fs.existsSync(testdataDir)) {
return res.status(404).send('Testdata not found.');
}

const zipFileName = `p${pid}_testdata.zip`;
const testScriptName = 'runTest.sh';

// Set headers to trigger download in browser
res.setHeader('Content-Disposition', `attachment; filename=${zipFileName}`);
res.setHeader('Content-Type', 'application/zip');

const archive = archiver('zip', {
zlib: { level: 9 }
});

archive.on('error', function(err) {
res.status(500).send({ error: err.message });
});

archive.pipe(res);

dblink.problemManager.downloadList(pid, function(file_list) {
file_list.forEach(file => {
const filePath = path.join(testdataDir, file);
archive.file(filePath, { name: file });
});
if (!fs.existsSync(path.join(testdataDir, testScriptName))) {
archive.file(path.join(publicDir, testScriptName), {name: testScriptName});
}
archive.finalize();
});

});

// router.get('/manage', function(req, res, next) {
// var uid = req.session.uid;
// dblink.helper.isAdmin(uid, function(isadmin) {
Expand Down
15 changes: 14 additions & 1 deletion views/_partial/_problem/problem.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,20 @@
</div>
<div class="pure-u-1 pure-u-lg-1" data-step="16" data-intro="每一筆測資的<b>運行時間</b>、<b>空間大小限制</b>。部分題目提供測試資料下載,若尚未公布,請向助教詢問是否可公布測試資料。">
<h2 class="content-subhead">Testdata Set</h2>
<a class="pure-button pure-button-primary" href="<%= site.url_for('testdata/download-all/' + pid) %>">
<i class="fa fa-download"></i> Download All Testdata
</a>
<!--
<br>
<a class="pure-button pure-button-secondary" href="<%= site.url_for('runTest.sh') %>">
<i class="fa fa-file-code-o"></i> Download Test Script
</a>
-->


<!--
<a href="<%= site.url_for('testdata/download/' + pid) %>"><i class="fa fa-download"></i> Download Testdata</a>
<div class="pure-menu">
<div class="pure-menu">
<ul class="pure-menu-list">
<% for (var i in testdata_config) { %>
<% var testset = testdata_config[i]; %>
Expand All @@ -239,6 +251,7 @@
<% } %>
</ul>
</div>
-->
</div>
</div>

Expand Down