Skip to content

Commit

Permalink
added leaderboard and added pagination in Submission
Browse files Browse the repository at this point in the history
  • Loading branch information
grim-firefly committed Dec 2, 2022
1 parent b514c9b commit 3ccc1de
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 54 deletions.
26 changes: 20 additions & 6 deletions illus1onctf-api/app/Http/Controllers/ChallengeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,24 @@ public function submit(Request $request)

], 400);
}
$flag = Challenge::find($request->input('challenge_id'))->flag;
$solveValue = $request->input('flag') === $flag ? 'correct' : 'wrong';
$challenge = Challenge::find($request->input('challenge_id'));
$solveValue = $request->input('flag') === $challenge->flag ? 'correct' : 'wrong';
$already = $user->submissions()->where('challenge_id', $request->input('challenge_id'))->first();
$success = $user->submissions()->create([
'challenge_id' => $request->input('challenge_id'),
'flag' => $request->input('flag'),
'solved' => $solveValue,
]);
if ($success && $solveValue == 'correct' && !$already) {
if (!$user->scoreboard) {
$user->scoreboard()->create([
'points' => $challenge->points,
]);
} else {

$user->scoreboard->increment('points', $challenge->points);
}
}
if ($success) {
return response()->json([
'status' => 'success',
Expand All @@ -149,13 +160,16 @@ public function submit(Request $request)
public function submissions(Request $request)
{
// ['id', 'flag', 'solved', 'created_at']
$page = $request->input('page', 1);
$pageSize = $request->input('pageSize', 10);
if ($request->user()) {
$submissions = $request->user()->submissions()->with(['challenges'=>function($query){
$query->select('id','title')->get();
}])->get(['id', 'flag', 'solved', 'created_at','challenge_id']);
$submissions = $request->user()->submissions()->offset(($page - 1) * $pageSize)->limit($pageSize)->with(['challenges' => function ($query) {
$query->select('id', 'title')->get();
}])->get(['id', 'flag', 'solved', 'created_at', 'challenge_id']);
$total = $request->user()->submissions()->count();
return response()->json([
'submissions' => $submissions,

'total' => $total,
], 200);
}
}
Expand Down
14 changes: 10 additions & 4 deletions illus1onctf-api/app/Http/Controllers/PublicController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@

namespace App\Http\Controllers;

use App\Models\Scoreboard;
use App\Models\User;
use Illuminate\Http\Request;

class PublicController extends Controller
{
// public function LeaderBoard()
// {

// }
public function leaderboard()
{
$users = Scoreboard::with(['users' => function ($query) {
$query->select('id', 'email');
}])->orderBy('points', 'desc')->get(['id','user_id', 'points']);
return response()->json([
'ScoreList' => $users,
], 200);
}
}
16 changes: 16 additions & 0 deletions illus1onctf-api/app/Models/Scoreboard.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Scoreboard extends Model
{
use HasFactory;
protected $guarded = [];
public function users()
{
return $this->belongsTo(User::class, 'user_id', 'id');
}
}
4 changes: 4 additions & 0 deletions illus1onctf-api/app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,8 @@ public function submissions()
{
return $this->hasMany(Submission::class);
}
public function scoreboard()
{
return $this->hasOne(Scoreboard::class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('scoreboards', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->integer('points')->default(0);
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('scoreboards');
}
};
3 changes: 2 additions & 1 deletion illus1onctf-api/routes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use App\Http\Controllers\AuthController;
use App\Http\Controllers\CategoryController;
use App\Http\Controllers\ChallengeController;
use App\Http\Controllers\PublicController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Expand All @@ -28,7 +29,7 @@

Route::post('submit', [ChallengeController::class, 'submit'])->middleware('auth:api');
Route::get('submissions', [ChallengeController::class, 'submissions'])->middleware('auth:api');

Route::get('leaderboard', [PublicController::class, 'leaderboard']);


Route::prefix('admin')->group(base_path('routes/api/admin.php'));
65 changes: 54 additions & 11 deletions illus1onctf/src/Pages/Leaderboard/Index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,51 @@ import Paginator from '../../Common/Paginator';
import Filters from './Components/Filters/Filters';
import { useEffect } from 'react';
import { PropagateLoader } from 'react-spinners';
import axios from 'axios';
import { Table } from 'antd';

const Leaderboard = () => {
const column = [
{
title: '#',
key: 'id',
render: (text, record, index) => {
return index + 1;
}
}, {
title: 'Email',
dataIndex: 'users',
key: 'id',
render: (text, record) => {
return text ? text.email : 'no email';
}

},
{
title: 'Points',
dataIndex: 'points',
key: 'id'
}
]

const [scoreList, setScoreList] = useState([]);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
setIsLoading(true);
const fetchScoreList = async () => {
const response = await axios.get('/leaderboard');
return response.data;
}
fetchScoreList().then(data => {
setScoreList(data.ScoreList);
console.log(data.ScoreList);
setIsLoading(false);
}).catch(err => {
console.log(err);
setIsLoading(false);
});
}, []);


return (
<>
Expand All @@ -23,7 +66,7 @@ const Leaderboard = () => {
{/* <ChallengeList handleViewChallenge={handleViewChallenge} /> */}
<div className='row'>
<div className='col-12 mt-1'>
{/* <Table
<Table

columns={column}
rowSelection={true}
Expand All @@ -32,22 +75,22 @@ const Leaderboard = () => {
indicator: <PropagateLoader color={"#1B98F5"} />
}}

dataSource={roles}
dataSource={scoreList}
rowKey={record => record.id}

pagination={{
total: totalData,
total: scoreList.length,
showSizeChanger: true,
onChange: (page) => {
setPage(page)
},
onShowSizeChange: (current, size) => {
setPage(current)
setPageSize(size)
}
// onChange: (page) => {
// setPage(page)
// },
// onShowSizeChange: (current, size) => {
// setPage(current)
// setPageSize(size)
// }
}}

/> */}
/>
</div>

</div>
Expand Down
89 changes: 57 additions & 32 deletions illus1onctf/src/Pages/Submissions/Index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,31 @@ import { render } from '@testing-library/react';
const Submissions = () => {
const [submissions, setSubmissions] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [total, setTotal] = useState(0);
const [pageSize, setPageSize] = useState(10);
const [page, setPage] = useState(1);
useEffect(() => {
setIsLoading(true);
const fetchSubmissions = async () => {
const response = await axios.get('/submissions');
const response = await axios.get('/submissions', {
params: {
page,
pageSize
}
});
return response.data;
}
fetchSubmissions().then(data => {
setSubmissions(data.submissions);
setTotal(data.total);
console.log(data);
setIsLoading(false);
}).catch(err => {
console.log(err);
setIsLoading(false);
});

}, []);
}, [page, pageSize]);
const column = [
{
title: 'title',
Expand Down Expand Up @@ -52,42 +62,57 @@ const Submissions = () => {
}
]
return (
<div>
<div className="container">
<div className={s.submissions}>
<h1 className={`${s.heading}`}>
My Submissions
</h1>
<div className='p-2'>
<Table
<> {
isLoading && < PropagateLoader loading={isLoading} color={"#1B98F5"} cssOverride={{
display: "block",
position: "absolute",
left: "50%",
top: "50%",
transform: "translate(-50%, -50%)",
zIndex: "999999999",
borderColor: "red",
}} />
}
{!isLoading && <div>
<div className="container">
<div className={s.submissions}>
<h1 className={`${s.heading}`}>
My Submissions
</h1>
<div className='p-2'>
<Table

columns={column}
rowSelection={true}
loading={{
spinning: isLoading,
indicator: <PropagateLoader color={"#1B98F5"} />
}}
columns={column}
rowSelection={true}
loading={{
spinning: isLoading,
indicator: <PropagateLoader color={"#1B98F5"} />
}}

dataSource={submissions}
rowKey={record => record.id}
pagination={{
total: submissions.length,
// onChange: (page) => {
// setPage(page)
// },
// showSizeChanger: true,
// onShowSizeChange: (current, size) => {
// setPage(current)
// setPageSize(size)
// }
}}
dataSource={submissions}
rowKey={record => record.id}
pagination={{
total: total,
onChange: (page) => {
setPage(page)
},
defaultCurrent: page,
showSizeChanger: true,
defaultPageSize: pageSize,
onShowSizeChange: (current, size) => {
setPage(current)
setPageSize(size)
}
}}

/>
/>
</div>
</div>
</div>
</div>

</div>
</div>
}
</>
);
}
export default Submissions;

0 comments on commit 3ccc1de

Please sign in to comment.