Skip to content

Commit

Permalink
0.8.5
Browse files Browse the repository at this point in the history
- Fixed a bug with normal code blocks
- Delete many challenges/users/announcements at once
- Edit visibility of multiple challenges at once
- Pagination preservation in admin panel
  • Loading branch information
Tkaixiang committed Jun 2, 2021
1 parent 2866026 commit 276c470
Show file tree
Hide file tree
Showing 7 changed files with 402 additions and 276 deletions.
166 changes: 115 additions & 51 deletions api/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,10 @@ MongoDB.MongoClient.connect('mongodb://localhost:27017', {
const username = signer.unsign(req.headers.authorization);
if (await checkPermissions(username) === false) throw new Error('BadToken');
let userToDelete = username;
if (req.body.username) {
if (req.body.users) {
if (!Array.isArray(req.body.users)) throw new Error('Validation');
const usersToDelete = req.body.users;
if (usersToDelete.includes(username)) return res.send({ success: false, error: 'delete_self'})
if (checkPermissions(username) < 2) {
res.status(403);
res.send({
Expand All @@ -257,34 +260,64 @@ MongoDB.MongoClient.connect('mongodb://localhost:27017', {
});
return;
}
userToDelete = req.body.username;
}
if ((await collections.users.deleteOne({ username: userToDelete.toLowerCase() })).deletedCount == 0) {
res.status(400);
res.send({
success: false,
error: 'not_found'

if ((await collections.users.deleteMany({ username: {$in: usersToDelete} })).deletedCount == 0) {
res.status(400);
res.send({
success: false,
error: 'not_found'
});
return;
}
await collections.challs.updateMany({}, {
$pull: {
solves: {$in: usersToDelete}
}
});
return;
await collections.challs.updateMany({
hints: {
$exists: true
}
}, {
$pull: {
'hints.$[].purchased': {$in: usersToDelete}
}
});
await collections.challs.deleteMany({ author: {$in: usersToDelete} });
await collections.transactions.deleteMany({ author: {$in: usersToDelete} });
usersToDelete.forEach(username => {if (permissions.includes(username)) delete permissions[username]})

res.send({ success: true });
}
await collections.challs.updateMany({}, {
$pull: {
solves: userToDelete
}
});
await collections.challs.updateMany({
hints: {
$exists: true
}
}, {
$pull: {
'hints.$[].purchased': userToDelete
else {
if ((await collections.users.deleteOne({ username: userToDelete.toLowerCase() })).deletedCount == 0) {
res.status(400);
res.send({
success: false,
error: 'not_found'
});
return;
}
});
await collections.challs.deleteMany({ author: userToDelete });
await collections.transactions.deleteMany({ author: userToDelete });
if (permissions.includes(username)) delete permissions[username];
res.send({ success: true });
await collections.challs.updateMany({}, {
$pull: {
solves: userToDelete
}
});
await collections.challs.updateMany({
hints: {
$exists: true
}
}, {
$pull: {
'hints.$[].purchased': userToDelete
}
});
await collections.challs.deleteMany({ author: userToDelete });
await collections.transactions.deleteMany({ author: userToDelete });
if (permissions.includes(username)) delete permissions[username];
res.send({ success: true });
}

}
catch (err) {
errors(err, res);
Expand Down Expand Up @@ -468,7 +501,9 @@ MongoDB.MongoClient.connect('mongodb://localhost:27017', {
if (req.headers.authorization == undefined) throw new Error('MissingToken');
const username = signer.unsign(req.headers.authorization);
if (await checkPermissions(username) < 2) throw new Error('Permissions');
const delReq = await collections.announcements.deleteOne({ _id: MongoDB.ObjectID(req.body.id) });
if (!Array.isArray(req.body.ids)) throw new Error('Validation');
let ids = req.body.ids.map((id) => {return MongoDB.ObjectID(id)})
const delReq = await collections.announcements.deleteMany({ _id: {$in: ids}});
if (!delReq.result.ok) throw new Error('Unknown');
if (delReq.deletedCount === 0) throw new Error('NotFound');
res.send({
Expand Down Expand Up @@ -973,6 +1008,32 @@ MongoDB.MongoClient.connect('mongodb://localhost:27017', {
errors(err, res);
}
});
app.post('/v1/challenge/edit/visibility', async (req, res) => {
try {
if (req.headers.authorization == undefined) throw new Error('MissingToken');
const username = signer.unsign(req.headers.authorization);
if (await checkPermissions(username) < 2) throw new Error('Permissions');
if (!Array.isArray(req.body.challenges)) throw new Error('Validation');
if ((await collections.challs.updateMany({
name: {
$in: req.body.challenges
}
}, {
$set: { visibility: req.body.visibility }
})).matchedCount > 0) res.send({ success: true });
else throw new Error('NotFound');
}
catch (err) {
if (err.message == 'MissingHintCost') {
res.status(400);
res.send({
success: false,
error: 'validation'
});
}
errors(err, res);
}
});
app.post('/v1/challenge/edit/category', async (req, res) => {
try {
if (req.headers.authorization == undefined) throw new Error('MissingToken');
Expand Down Expand Up @@ -1005,32 +1066,35 @@ MongoDB.MongoClient.connect('mongodb://localhost:27017', {
if (req.headers.authorization == undefined) throw new Error('MissingToken');
const username = signer.unsign(req.headers.authorization);
if (await checkPermissions(username) < 2) throw new Error('Permissions');
const delReq = await collections.challs.findOneAndDelete({
name: req.body.chall
}, {
solves: 1,
points: 1,
hints: 1,
_id: 0
});
if (!delReq.ok) throw new Error('Unknown');
if (delReq.value === null) throw new Error('NotFound');
const timestamp = new Date();
await collections.transactions.deleteMany({ challenge: req.body.chall });
await collections.users.updateMany({
username: { $in: delReq.value.solves }
}, {
$inc: { score: -delReq.value.points }
});
if (delReq.value.hints) {
for (hint of delReq.value.hints) {
await collections.users.updateMany({
username: { $in: hint.purchased }
}, {
$inc: { score: hint.cost }
});
for (let i = 0; i < req.body.chall.length; i++) {
const delReq = await collections.challs.findOneAndDelete({
name: req.body.chall[i]
}, {
solves: 1,
points: 1,
hints: 1,
_id: 0
});
if (!delReq.ok) throw new Error('Unknown');
if (delReq.value === null) throw new Error('NotFound');
const timestamp = new Date();
await collections.transactions.deleteMany({ challenge: req.body.chall });
await collections.users.updateMany({
username: { $in: delReq.value.solves }
}, {
$inc: { score: -delReq.value.points }
});
if (delReq.value.hints) {
for (hint of delReq.value.hints) {
await collections.users.updateMany({
username: { $in: hint.purchased }
}, {
$inc: { score: hint.cost }
});
}
}
}

res.send({
success: true
});
Expand Down
4 changes: 3 additions & 1 deletion client/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ const Login = lazy(() => import("./login.js"));
const Admin = lazy(() => import("./admin.js"));
const Oops = lazy(() => import("./oops.js"));

var ctfxVersion = "0.8.5"


class App extends React.Component {
constructor(props) {
Expand Down Expand Up @@ -264,7 +266,7 @@ class App extends React.Component {

</Menu>
<div style={{ textAlign: "center", marginTop: "3ch", color: "#8c8c8c" }}>
<p>Sieberrsec CTF Platform 0.8.1 <a href="https://github.com/IRS-Cybersec/ctf_platform" target="_blank">Contribute <GithubOutlined /></a></p>
<p>Sieberrsec CTF Platform {ctfxVersion} <a href="https://github.com/IRS-Cybersec/ctf_platform" target="_blank">Contribute <GithubOutlined /></a></p>
</div>
</Sider>

Expand Down
2 changes: 1 addition & 1 deletion client/src/MarkdownRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function MarkdownRender(props) {
return !inline && match ? (
<SyntaxHighlighter style={{ ...atomDark }} language={match[1]} PreTag="div" children={String(children).replace(/\n$/, '')} {...props} />
) : (
<code className={className} {...props} />
<code className={className} {...props} children={String(children)} />
)
}
}
Expand Down
Loading

0 comments on commit 276c470

Please sign in to comment.