Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
0f61569
Hooked up a Sqlite3 database and implement `/users/register` API endp…
chunqi Feb 19, 2018
219cc21
Modified Dockerfile. Added Dependency for bootstrap.
Feb 24, 2018
b08c8d0
Added frontend for login page, registration page and public diary ent…
Feb 25, 2018
6dd02d6
Update README.md
andytannn Feb 25, 2018
9058389
Changed API implementation to accept JSON
chunqi Feb 25, 2018
c04a538
Implemented `/users/authenticate` endpoint and various cleanup
chunqi Feb 25, 2018
c654100
Fixed `/users/authenticate` make JSON call
chunqi Feb 25, 2018
fc3a1e1
Added implementation for `/users/expire` endpoint
chunqi Feb 25, 2018
6c2d575
Added implementation for `/users` authenticated endpoint
chunqi Feb 25, 2018
5cf48b0
Added some client side validation on login and registration pages. Ad…
Feb 25, 2018
83dfe1d
Added some client side validation on login and registration pages. Ad…
Feb 25, 2018
ad108d8
Delete public_list.html
andytannn Feb 25, 2018
e051b8c
Changed token validity behaviour to match specifications
chunqi Feb 26, 2018
6805af0
Merge branch 'master' of github.com:CS5331-ACKS/rest-api-development
chunqi Feb 26, 2018
d23fda3
Fixed token expired behaviour
chunqi Feb 26, 2018
49211a7
Added `/diary/create` endpoint and refactored common token validation…
chunqi Feb 26, 2018
d2bd48f
Implemented `/diary/delete` endpoint
chunqi Feb 26, 2018
d1803c3
Added `publish_date` attribute to diary entries
chunqi Feb 26, 2018
1c38519
Implemented `/diary` endpoint for both authenticated and unauthentica…
chunqi Feb 26, 2018
934394b
(Fully) Implemented `diary/delete` endpoint
chunqi Feb 26, 2018
8601a1b
Implemented create/delete/adjust/view diary frontend. Enhanced UI for…
Feb 26, 2018
f803d8b
Not required
andytannn Feb 26, 2018
1d6554e
Fixed JSON output for `/diary` endpoints
chunqi Feb 26, 2018
fe7c313
Merge branch 'master' of github.com:CS5331-ACKS/rest-api-development
chunqi Feb 26, 2018
02852ec
Implemented `/diary/permission` endpoint and some refactoring of comm…
chunqi Feb 26, 2018
7e79dd2
Bug fixes
Feb 26, 2018
9551b39
More Bug fixes
Feb 26, 2018
f0bc559
UI Change. Added diary listing
Feb 26, 2018
b057fa6
Added public diary function on authenticated pages
Feb 27, 2018
e643d4f
Implemented hashing of passwords using bcrypt
chunqi Feb 27, 2018
3c99faf
Merge branch 'master' of github.com:CS5331-ACKS/rest-api-development
chunqi Feb 27, 2018
b2c2be6
Update README.md
andytannn Feb 27, 2018
a4f750c
minor changes to user endpoints for new json structure
ngsikai Mar 1, 2018
ed60ba9
invalid or expired token should just return false
ngsikai Mar 1, 2018
9878178
changed json structure of /diary/create to follow new specs
ngsikai Mar 1, 2018
c814595
moved auth token to localstorage
ngsikai Mar 1, 2018
d780283
Merge remote-tracking branch 'upstream/master'
luyangkenneth Mar 1, 2018
06a75ab
Update readme
luyangkenneth Mar 4, 2018
9908d86
Remove duplicate demo.js file
luyangkenneth Mar 4, 2018
44727fc
Fix typo in filename
luyangkenneth Mar 4, 2018
5591bd2
Shift frontend dependencies into separate folders
luyangkenneth Mar 4, 2018
dc26e59
Update README.md
andytannn Mar 4, 2018
fcca266
updated list of api endpoints
ngsikai Mar 4, 2018
7455abc
Moved variable return_first within function. Cause else if statement …
Mar 4, 2018
9955737
Moved variable return_first within function. Cause else if statement …
Mar 4, 2018
f61a92c
more details
andytannn Mar 4, 2018
3f0027f
Remove userhome.html
luyangkenneth Mar 4, 2018
257daa5
Refactor index.html
luyangkenneth Mar 4, 2018
f85c4f4
Refactor registration.html
luyangkenneth Mar 4, 2018
b716dc0
Refactor create_entry.html
luyangkenneth Mar 4, 2018
ee9616f
Refactor public_entries.html
luyangkenneth Mar 4, 2018
2574a52
Verify authentication with auth.js
luyangkenneth Mar 4, 2018
e16110f
Refactor private_entries.html
luyangkenneth Mar 4, 2018
bac20e2
Update individual contributions
luyangkenneth Mar 4, 2018
1611317
Add screenshots to README
luyangkenneth Mar 4, 2018
a3ea6e3
answering questions
andytannn Mar 5, 2018
0a3f7d9
Added declaration
ngsikai Mar 5, 2018
9fbc2df
Updated Postman collection w.r.t changed API specifications
chunqi Mar 5, 2018
418b482
Update README.md
luyangkenneth Mar 5, 2018
0e6be08
Update README.md
luyangkenneth Mar 5, 2018
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
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -y python-pip
RUN apt-get install -y apache2
RUN apt-get install -y npm
RUN npm install [email protected] --save
RUN pip install -U pip
RUN pip install -U flask
RUN pip install -U flask-cors
RUN pip install -U bcrypt
RUN echo "ServerName localhost " >> /etc/apache2/apache2.conf
RUN echo "$user hard nproc 20" >> /etc/security/limits.conf
ADD ./src/service /service
Expand Down
152 changes: 80 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,21 @@
# rest-api-development
# CS5331 Assignment 1: REST API Development

CS5331 Assignment 1 Project Reference Repository
by [Team CS5331-ACKS](https://github.com/CS5331-ACKS)

## Instructions
Secret Diary is a web application that implements and makes use of the endpoints described in the API specification: https://cs5331-assignments.github.io/rest-api-development/

Your objective is to implement a web application that provides the endpoints
specified here: https://cs5331-assignments.github.io/rest-api-development/.
## Setup

The project has been packaged in an easy to set-up docker container with the
skeleton code implemented in Python Flask. You are not restricted in terms of
which language, web stack, or database you desire to use. However, please note
that very limited support can be given to those who decide to veer off the
beaten path.

You may be required to modify the following files/directories:

- Dockerfile - contains the environment setup scripts to ensure a homogenous
development environment
- src/ - contains the front-end code in `html` and the skeleton Flask API code
in `service`
Important files/directories:
- Dockerfile - contains the environment setup scripts to ensure a homogenous development environment
- src/ - contains the front-end code in `html` and the skeleton Flask API code in `service`
- img/ - contains images used for this README

Assuming you're developing on an Ubuntu 16.04 machine, the quick instructions
to get up and running are:
Assuming you're developing on an Ubuntu 16.04 machine, the quick instructions to get up and running are:

```
# Install Docker
### 1. Install Docker

```bash
sudo apt-get update
sudo apt-get install \
apt-transport-https \
Expand All @@ -40,104 +29,123 @@ sudo add-apt-repository \
stable"
sudo apt-get update
sudo apt-get install docker-ce
```

# Verify Docker Works
(Docker CE installation instructions are from this [link](https://docs.docker.com/install/linux/docker-ce/ubuntu/#install-using-the-repository).)

### 2. Verify Docker Works

```bash
sudo docker run hello-world
```

# Run the skeleton implementation
### 3. Run the app

```bash
sudo ./run.sh
```

(Docker CE installation instructions are from this
[link](https://docs.docker.com/install/linux/docker-ce/ubuntu/#install-using-the-repository).)

**Please consult your assignment hand-out for detailed setup information.**

## Grading

The implementation will be graded in an automated fashion on an Ubuntu 16.04
virtual machine by building the docker container found in your repository and
running it. The grading script will interact with your API.
### 4. Verify that everything runs correctly

The following ports are expected to be accessible:
- 80, on which static HTML content, including the front-end, is served.
- 8080, on which the API is exposed.

1. 80, on which static HTML content, including the front-end, is served.
2. 8080, on which the API is exposed.

To verify this, please run the following commands:
To verify this, run the following commands in a different terminal window:

```
sudo ./run.sh
```

On a different window:

```
```bash
curl http://localhost:80
curl http://localhost:8080
```

If a response is received, you're good to go.

**Please replace the details below with information relevant to your team.**

## Screenshots

Please replace the example screenshots with screenshots of your completed
project. Feel free to include more than one.
### Register
![Register](./img/register.png)

![Sample Screenshot](./img/samplescreenshot.png)
### Login
![Login](./img/login.png)

## Administration and Evaluation
### View Public Entries
![View Public Entries](./img/public_entries.png)

### View Private Entries
![View Private Entries](./img/private_entries.png)

Please fill out this section with details relevant to your team.
### Create New Entry
![Create New Entry](./img/create_entry.png)

## Administration and Evaluation

### Team Members

1. Member 1 Name
2. Member 2 Name
3. Member 3 Name
4. Member 4 Name
1. Andy Tan Guan Ming
2. Zhu Chunqi
3. Lu Yang Kenneth
4. Ng Si Kai

### Short Answer Questions

#### Question 1: Briefly describe the web technology stack used in your implementation.

Answer: Please replace this sentence with your answer.
Back-end tech stack
- Database - Sqlite was used due to its excellent reputation as an embedded database and ease of use.
- Web Framework - Flask, a python web framework was used.

Front-end tech stack
- Bootstrap - For HTML- and CSS-based design template.
- jQuery - JavaScript library to perform AJAX calls and DOM manipulation.

#### Question 2: Are there any security considerations your team thought about?

Answer: Please replace this sentence with your answer.
We have thought about security when implementing the API and web application. However, not all of the higlighted considerations were implemented due to time restriction.
- Passwords were hashed using `bcrypt` before being stored in the database. If an attacker somehow manages to obtain a database dump, he would not be able to gain knowledge of the plaintext password.
- Access control was implemented so as to ensure that authenticated users will not be able to perform horizontal privilege escalation.
- SSL should be implemented to provide confidentiality, integrity and authentication for network data between client and server.
- Input validation should be implemented to prevent potential injection attack such as SQL injection, XSS, Command injection and etc.
- Session management should be implemented in order to reduce the probability of session hijacking attack. e.g. Setting absolute timeout.
- Strong user account policy should be implemented. e.g. account lockout, minimum password length, password complexity and etc.
- A whitelist of specific HTTP methods should be implemented for each endpoint in order to prevent potential abuse.
- Content security policy should be implemented as an additional layer of defense for content injection attacks.

#### Question 3: Are there any improvements you would make to the API specification to improve the security of the web application?

Answer: Please replace this sentence with your answer.
- The authentication token could be implemented as a Authorization HTTP header such that it is easier to program against and prevents accidental leaking of the authentication token.
- HTTPS and HSTS should be enabled on the API endpoint server.
- The API specification should be clearer with regards of the authorization provided by the token. For example, adjusting diary permission was not explicitly stated whether the user associated with the authenticated session is authorized to edit the permissions of a diary entry belonging to another user. Ambiguity should be avoided as much as possible.

#### Question 4: Are there any additional features you would like to highlight?

Answer: Please replace this sentence with your answer.
- The API response always tries to provide informative error responses wherever possible so that the frontend may provide useful feedback to the user.
- Automated API tests were written using `Postman`. This increases developer confidence in the correctness of the application.

#### Question 5: Is your web application vulnerable? If yes, how and why? If not, what measures did you take to secure it?

Answer: Please replace this sentence with your answer.
The web application is vulnerable.

- Account lockout mechanism was not implemented. This would result in successful account bruteforce attack, leading to account compromise.
- Minimum password length not implemented. A short password length would require less effort to compromise an account.
- Vulnerable to eavesdropping and man in the middle attack. This would result in sensitive data exposure and potential integrity impact as the network traffic between client and server is unencrypted.
- Vulnerable to potential DoS attack as rate limiting mechanism was not implemented.
- Absolute session timeout was not implemented. Session token would still be valid unless the 'expire' endpoint is called. This may increase the probability of an attacker hijacking the session and impersonate the victim.

#### Feedback: Is there any other feedback you would like to give?

Answer: Please replace this sentence with your answer.
Nope :smile:

### Declaration

#### Please declare your individual contributions to the assignment:

1. Member 1 Name
- Integrated feature x into component y
- Implemented z
2. Member 2 Name
- Wrote the front-end code
3. Member 3 Name
1. Andy Tan Guan Ming
- Wrote frontend queries to backend for 'login', 'registration', 'view public diary entries', 'view authenticated diary entries' and 'create diary entry'
- Answered security-related questions in README
2. Zhu Chunqi
- Designed the database schema
4. Member 4 Name
- Implemented x

- Implemented the REST API endpoints
3. Lu Yang Kenneth
- Implemented authentication on each page and design of frontend
- Organised README and documents for submission
4. Ng Si Kai
- Refactored all API endpoints to conform to new specifications
- Implemented persistence of auth token in browser localstorage
Binary file added img/create_entry.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/login.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/private_entries.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/public_entries.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/register.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed img/samplescreenshot.png
Binary file not shown.
125 changes: 125 additions & 0 deletions src/html/create_entry.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Secret Diary: New Entry</title>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<script src="/js/jquery/jquery.min.js"></script>
<script src="/js/bootstrap/bootstrap.min.js"></script>
<script src="/js/bootstrap/bootstrap-table.min.js"></script>
<link rel="stylesheet" href="/css/bootstrap/bootstrap.min.css"/>
<link rel="stylesheet" href="/css/bootstrap/bootstrap-table.min.css"/>

<script type="text/javascript">var authUser;</script>
<script src="/js/auth.js"></script>
</head>

<body class="pt-5">
<nav class="navbar fixed-top navbar-expand-sm bg-dark navbar-dark">
<ul class="navbar-nav">
<li class="nav-item">
<a class="navbar-brand" href="">Secret Diary</a>
</li>
</ul>

<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="public_entries.html">Public Entries</a>
</li>
</ul>

<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="private_entries.html">My Entries</a>
</li>
</ul>

<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="create_entry.html">New Entry</a>
</li>
</ul>

<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="#" id="logout">Logout</a>
</li>
</ul>
</nav>

<div class="container-fluid py-5">
<div class="row">

<!-- create diary entry form -->
<div class="col-sm-8 col-md-6 mx-auto">
<div class="card">
<div class="card-header">
<h3 class="mb-0">New Entry</h3>
</div>

<div class="card-body">
<form class="form" role="form" autocomplete="off">
<div class="form-group">
<label>Title</label>
<input type="text" class="form-control" id="entry_title" required>
</div>

<div class="form-group">
<label>Text</label>
<input type="text" class="form-control" id="entry_text" required>
</div>

<input type="submit" id="submit" class="btn btn-success float-right" value="Create">
</form>
</div>
</div>
</div>

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

<script type="text/javascript">
verifyLoggedIn();

$("#submit").on("click", function(e) {
e.preventDefault();
e.returnValue = false;

var titleVar = document.getElementById("entry_title").value;
var textVar = document.getElementById("entry_text").value;

if (titleVar == "" || textVar == "") {
alert("Please fill up all the fields");
return;
}

var entryJson = `{"token": "${authUser.token}", "title": "${titleVar}", "public": false, "text": "${textVar}"}`;

$.ajax({
url: "http://localhost:8080/diary/create",
type: "POST",
dataType: "json",
data: entryJson,
contentType: "application/json",

success: function(response) {
console.log(response);

if (response.status == true) {
alert("New diary entry created!");
window.location.reload();
} else if (response.status == false) {
alert("Invalid authentication token.");
}
},

error: function(xhr, resp, text) {
console.log(xhr, resp, text);
}
});
});
</script>
</html>
Loading