Skip to content

Commit

Permalink
Merge pull request #17 from CEN3031-SIT-WEB-APP/writeups
Browse files Browse the repository at this point in the history
Added badges and ability to delete writeups and files
  • Loading branch information
JKomskis authored Apr 17, 2018
2 parents 4a90698 + cc6f312 commit ac355e1
Show file tree
Hide file tree
Showing 27 changed files with 269 additions and 49 deletions.
42 changes: 37 additions & 5 deletions api/db/db_mgmt.js
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,36 @@ let db_mgmt_module = function () {

/* Get a specific writeup, given its id */
async function get_writeup(id) {
return await queryAsync('SELECT `name`,`full_name` FROM `writeup_submissions`,`account` WHERE `writeup_submissions`.account_id = `account`.id AND `writeup_submissions`.id = ?', id);
return await queryAsync('SELECT `name`,`full_name`,`description` FROM `writeup_submissions`,`account` WHERE `writeup_submissions`.account_id = `account`.id AND `writeup_submissions`.id = ?',
id);
}

/* Deletes a specific writeup, given its id */
async function delete_writeup(id, account_id, isAdmin) {
let result = await queryAsync('SELECT * FROM `writeup_submissions` WHERE account_id = ? AND id = ?',
[account_id, id]);

if(result.length === 0 && !isAdmin) {
throw new createError.BadRequest('You do not own this writeup.');
}

await queryAsync('DELETE FROM `writeup_clicks` WHERE writeup_id = ?',
id);
return await queryAsync('DELETE FROM `writeup_submissions` WHERE account_id = ? AND id = ?',
[account_id, id]);
}

/* Deletes a specific file, given its id */
async function delete_file(id, account_id, isAdmin) {
let result = await queryAsync('SELECT * FROM `file_uploads` WHERE account_id = ? AND id = ?',
[account_id, id]);

if(result.length === 0 && !isAdmin) {
throw new createError.BadRequest('You do not own this file.');
}

return await queryAsync('DELETE FROM `file_uploads` WHERE account_id = ? AND id = ?',
[account_id, id]);
}

/* Get a list of the user's writeup submissions */
Expand All @@ -529,26 +558,27 @@ let db_mgmt_module = function () {
}

/* Records a writeup submission */
async function record_writeup_submission(account_id, name) {
async function record_writeup_submission(account_id, name, description) {
const values = {
account_id: account_id,
name: name,
description: description,
time_created: new Date(),
time_updated: new Date(),
};
return await queryAsync('INSERT INTO `writeup_submissions` SET ?', values);
}

/* Records a writeup submission */
async function update_writeup_submission(account_id, name, id) {
async function update_writeup_submission(account_id, name, description, id) {
let results = await queryAsync('SELECT * FROM `writeup_submissions` WHERE `account_id` = ? AND `id` = ?',
[account_id, id]);
if (results.length === 0) {
throw new createError.BadRequest('Cannot update a different user\'s writeup');
}

return await queryAsync('UPDATE `writeup_submissions` SET `name` = ?, `time_updated` = ? WHERE `account_id` = ? AND `id` = ?',
[name, new Date(), account_id, id]);
return await queryAsync('UPDATE `writeup_submissions` SET `name` = ?, `time_updated` = ?, `description`=? WHERE `account_id` = ? AND `id` = ?',
[name, new Date(), description, account_id, id]);
}

/* Records a file upload */
Expand Down Expand Up @@ -626,6 +656,8 @@ let db_mgmt_module = function () {
there_are_results: there_are_results,
get_election_results: get_election_results,
clear_database: clear_database,
delete_writeup: delete_writeup,
delete_file: delete_file
});
};

Expand Down
4 changes: 2 additions & 2 deletions api/upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ routes.post('/upload/writeup', async (req, res, next) => {
if (req.body.writeupId == 0) {
let result = '';
try {
result = await db_mgmt.record_writeup_submission(req.session.account_id, req.body.writeupName);
result = await db_mgmt.record_writeup_submission(req.session.account_id, req.body.writeupName, req.body.writeupDescription);
} catch (error) {
return next(error);
}
Expand All @@ -32,7 +32,7 @@ routes.post('/upload/writeup', async (req, res, next) => {
} else {
try {
await db_mgmt.update_writeup_submission(req.session.account_id, req.body.writeupName,
req.body.writeupId);
req.body.writeupDescription, req.body.writeupId);
} catch (error) {
return next(error);
}
Expand Down
142 changes: 107 additions & 35 deletions api/writeups.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,49 +30,85 @@ routes.get('/writeups/all', async (req, res, next) => {

// returns a writeup
routes.get('/writeups/get/:id', async (req, res) => {
// configure s3
const s3 = new aws.S3({
region: aws_credentials.region,
accessKeyId: aws_credentials.accessKeyId,
secretAccessKey: aws_credentials.secretAccessKey,
Bucket: aws_credentials.s3Bucket,
});

// configure the parameters
const params = {
Bucket: aws_credentials.s3Bucket,
Key: 'writeups/' + req.params.id + '.md',
};

// get the writeup
s3.getObject(params, async (err, data, next) => {
// if the writeup doesn't exist, send an error
if (err) {
res.status(500).send('Error while getting writeup, please contact the developers.');
// otherwise, return the writeup
} else {
let dbEntry = undefined;
try {
dbEntry = await db_mgmt.get_writeup(req.params.id);
} catch (error) {
return next(error);
}

if (dbEntry == undefined) {
res.status(200).json({
name: '',
text: '',
user_name: '',
description: ''
});
}
res.status(200).json({
name: dbEntry[0].name,
text: data.Body.toString(),
user_name: dbEntry[0].full_name,
description: dbEntry[0].description});
}
});
});

routes.delete('/writeups/get/:id', async (req, res, next) => {

try {
await db_mgmt.delete_writeup(req.params.id, req.session.account_id,
util.account_has_admin(req.account));
} catch (error) {
return next(error);
}

// configure s3
const s3 = new aws.S3({
region: aws_credentials.region,
accessKeyId: aws_credentials.accessKeyId,
secretAccessKey: aws_credentials.secretAccessKey,
Bucket: aws_credentials.s3Bucket,
region: aws_credentials.region,
accessKeyId: aws_credentials.accessKeyId,
secretAccessKey: aws_credentials.secretAccessKey,
Bucket: aws_credentials.s3Bucket,
});

// configure the parameters
const params = {
Bucket: aws_credentials.s3Bucket,
Key: 'writeups/' + req.params.id + '.md',
Bucket: aws_credentials.s3Bucket,
Key: 'writeups/' + req.params.id + '.md',
};

// get the writeup
s3.getObject(params, async (err, data, next) => {
// if the writeup doesn't exist, send an error
if (err) {
res.status(500).send('Error while getting writeup, please contact the developers.');
// otherwise, return the writeup
} else {
let dbEntry = undefined;
try {
dbEntry = await db_mgmt.get_writeup(req.params.id);
} catch (error) {
return next(error);
}

if (dbEntry == undefined) {
res.status(200).json({
name: '',
text: '',
user_name: '',
});
}
res.status(200).json({
name: dbEntry[0].name,
text: data.Body.toString(),
user_name: dbEntry[0].full_name
});
}
s3.deleteObject(params, async (err, data, next) => {
// if the writeup doesn't exist, send an error
if (err) {
res.status(500).json('Error while deleting writeup, please contact the developers.');
// otherwise, return the writeup
} else {
res.status(200).json('Writeup deleted');
}
});
});
});

// returns a list of files the user has submitted
routes.get('/writeups/files/uploaded', async (req, res, next) => {
Expand Down Expand Up @@ -118,6 +154,42 @@ routes.get('/writeups/files/:fileName', async (req, res) => {
});
});

routes.delete('/writeups/files/:fileName', async (req, res, next) => {
let id = req.params.fileName.split('.')[0];

try {
await db_mgmt.delete_file(id, req.session.account_id,
util.account_has_admin(req.account));
} catch (error) {
return next(error);
}

// configure s3
const s3 = new aws.S3({
region: aws_credentials.region,
accessKeyId: aws_credentials.accessKeyId,
secretAccessKey: aws_credentials.secretAccessKey,
Bucket: aws_credentials.s3Bucket,
});

// configure the parameters
const params = {
Bucket: aws_credentials.s3Bucket,
Key: 'writeups/files/' + req.params.fileName,
};

// get the writeup
s3.deleteObject(params, async (err, data, next) => {
// if the writeup doesn't exist, send an error
if (err) {
res.status(500).json('Error while deleting file, please contact the developers.');
// otherwise, return the writeup
} else {
res.status(200).json('File deleted');
}
});
});

// show(true)/hide(false) writeup submissions on ctf page
routes.post('/writeups/show_hide', async function (req, res, next) {
if (util.account_has_admin(req.account)) { // require admin access
Expand Down
4 changes: 2 additions & 2 deletions src/app/external-file.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export class ExternalFileService {
}

// uploads a writeup
public uploadWriteup(data: string, writeupName: string, writeupId: number) {
return this.restService.uploadWriteup(data, writeupName, writeupId);
public uploadWriteup(data: string, writeupName: string, writeupDescription: string, writeupId: number) {
return this.restService.uploadWriteup(data, writeupName, writeupDescription, writeupId);
}

// gets a writeup
Expand Down
1 change: 1 addition & 0 deletions src/app/home/home.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

<h2 ng-show="show_name">Hello,
<a id="userName" routerLink="/profile">{{getName()}}</a>
<img [src]="getBadge()">
</h2>
<hr>

Expand Down
23 changes: 23 additions & 0 deletions src/app/home/home.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,27 @@ export class HomeComponent implements OnInit {
return this.sessionService.getElection();
}

public getBadge() {
let rank = this.sessionService.getProfile().rank;
if (rank <= 0) {
return '';
} else if (rank < 3) {
return 'assets/images/ranks/white.png';
} else if (rank < 5) {
return 'assets/images/ranks/yellow.png';
} else if (rank < 10) {
return 'assets/images/ranks/green.png';
} else if (rank < 20) {
return 'assets/images/ranks/blue.png';
} else if (rank < 40) {
return 'assets/images/ranks/purple.png';
} else if (rank < 65) {
return 'assets/images/ranks/red.png';
} else if (rank < 100) {
return 'assets/images/ranks/brown.png';
} else {
return 'assets/images/ranks/black.png';
}
}

}
3 changes: 3 additions & 0 deletions src/app/profile/profile.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@

<label class='input-label'>Registered:</label>
<p title="Registered on {{this.getProfile().registration_date | date : 'medium'}}">{{ this.getProfile().registration_date | timeAgo }}</p>
<br>

<label class='input-label'>Points:</label>
<p>{{ this.getProfile().rank }}</p>
<br>

<a id="updateProfileButton" routerLink="{{ this.getEditLink() }}" class="btn btn-info" role="button">Update Profile</a>
Expand Down
18 changes: 17 additions & 1 deletion src/app/rest.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ export class RestService {
return this.http.get(this.baseUrl + relativeUrl, { params: params });
}

// basic get request
private delete(relativeUrl: string, params?: HttpParams): Observable<any> {
return this.http.delete(this.baseUrl + relativeUrl, { params: params });
}

// basic post request
private post(relativeUrl: string, data: any = '', options: any = {}) {
const headers = new HttpHeaders()
Expand Down Expand Up @@ -123,11 +128,12 @@ export class RestService {
}

// api call to upload a writeup
public uploadWriteup(data: string, writeupName: string, writeupId: number) {
public uploadWriteup(data: string, writeupName: string, writeupDescription: string, writeupId: number) {
return this.post('/upload/writeup',
{
data: data,
writeupName: writeupName,
writeupDescription: writeupDescription,
writeupId: writeupId
}
);
Expand All @@ -148,6 +154,11 @@ export class RestService {
return this.get('/writeups/get/' + id);
}

// api call to delete a writeup
public deleteWriteup(id: number) {
return this.delete('/writeups/get/' + id);
}

// api call to upload a file directly
public uploadFile(file: File, url: string) {
const formData = new FormData();
Expand All @@ -165,6 +176,11 @@ export class RestService {
return this.get('/writeups/files/uploaded');
}

// api call to delete a file
public deleteFile(fileName: string) {
return this.delete('/writeups/files/' + fileName);
}

// api call to get the user's resume link
public getResumeLink() {
return this.get('/resume/link');
Expand Down
4 changes: 4 additions & 0 deletions src/app/writeups/writeups.component.css
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,7 @@ ngb-tabset{
#fileBank {
display: contents;
}

.red {
color: red;
}
Loading

0 comments on commit ac355e1

Please sign in to comment.