Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Completed Homework 2 #11

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
73 changes: 71 additions & 2 deletions Auth/AuthAPI.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,76 @@
# Score API here
from flask import Blueprint
import sys
from flask import Blueprint, request, current_app, json, jsonify
import sys, jwt
from creds import *
from db import db
sys.path.append("../")

auth_api = Blueprint("auth", __name__)

credsArray = []
secretkey = current_app.config['SECRET_KEY']

@auth_api.route('/register', methods=["POST"])
def Register():
newCred = request.get_json()
# check if username is provided
try:
username = newCred["username"]
except KeyError:
return jsonify({"status": "fail", "message": "No username."})

# check if password is provided
try:
passwordHash = newCred["passwordHash"]
except KeyError:
return jsonify({"status": "fail", "message": "No password."})

credsArray.append(newCred)

return jsonify({"status": "success", "message": "Credentials successfully registered."}), 200


@auth_api.route('/login', methods=["POST"])
def Login():
def checkCred(givenCred):
# check if username is provided
try:
username = givenCred["username"]
except KeyError:
return jsonify({"status": "fail", "message": "No username."})

# check if password is provided
try:
passwordHash = givenCred["passwordHash"]
except KeyError:
return jsonify({"status": "fail", "message": "No password."})
for i in credsArray:
if (username == i["username"] and passwordHash == i["passwordHash"]):
token = jwt.encode({"userID": username, "passwordHash": passwordHash}, secretkey, algorithm="HS256")
return jsonify({"status": "success", "token": token}), 200
else:
return jsonify({"status": "fail", "message": "Authentication failed."}), 401

givenCred = request.get_json()
token = request.arg.get("token")


def checkToken():
if (token != None):
try:
data = jwt.decode(token, secretkey, algorithm=["HS256"])
return checkCred(data)
except:
data = givenCred
try:
return checkToken(data)
except:
return jsonify({"status": "fail", "message": "Bad token"})

# no token provided in URL argument (fresh login)
elif (token == None):
return checkCred(givenCred)




265 changes: 265 additions & 0 deletions Documentation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
# Simulated ExamScore API Documentation

## Profile API

1. **GET** /profiles/<int:id>

- **Description:** To retrieve the information (name and score) of a profile.

- **Function used:** getProfile()

- **Source:** /Profiles/ProfilesAPI.py (Line 9)

- **Parameter(s):**

- ```id``` (required, must be an integer), the ID of the desired profile.

- **Request body:** None, only parameter on endpoint needs to be provided.

- **Response(s):**

- Success (200)

```python
{
"status": "success",
"profile":
{"name": "Nobel",
"scores": [1, 2, 3, 4, 5]
}
}
```

- Fail

```python
{
"status": "fail",
"message": "Profile not found."
}
```

2. **POST** /profiles/

- **Description:** To add a new profile into the database.

- **Function used:** addProfile()

- **Source:** /Profiles/ProfilesAPI.py (Line 19)

- **Parameter(s):** None

- **Request body:**

```python
{
"name": "string"
}
```

- **Response(s):**

- Success (200)

```python
{
"status": "success",
"message": "New profile added."
}
```

- Fail

```python
{
"status": "fail",
"message": "Profile not found."
}
```

3. **DELETE** /profiles/<int:id>

- **Description:** To remove an existing profile from the database.

- **Function used:** deleteProfile()

- **Source:** /Profiles/ProfilesAPI.py (Line 27)

- **Parameter(s):**

- ```id``` (required, must be an integer), the ID of the desired profile.

- **Request body:** None, only parameter on endpoint needs to be provided.

- **Response(s):**

- Success (200)

```python
{
"status": "success",
"message": "Profile deleted."
}
```

- Fail

```python
{
"status": "fail",
"message": "Profile not found."
}
```

4. **GET** /profiles/<int:id>/score

- **Description:** To retrieve the scores of a profile which are greater or equal to the minimum score provided by the requester.

- **Function used:** getMinScore()

- **Source:** /Profiles/ProfilesAPI.py (Line 37)

- **Parameter(s):**

- ```id``` (required, must be an integer), the ID of the desired profile.
- ```minScore``` (optional, must be an integer), the minimum score, given as an argument.

- **Request body:** None, only parameter on endpoint needs to be provided.

- **Response(s):**

- Success (200)

```python
{
"status": "success",
"scores": [3, 4, 5]
}
```

- Fail

```python
{
"status": "fail",
"message": "Profile not found."
}
```

## Authentication API

1. **POST** /auth/register

- **Description:** To register a new credential for API access.

- **Function used:** Register()

- **Source:** /Auth/AuthAPI.py (Line 13)

- **Parameter(s):** None

- **Request body:**

```python
{
"username": "string"
"passwordHash": "string"
}
```

- **Response(s):**

- Success (200)

```python
{
"status": "success",
"message": "Credentials successfully registered."
}
```

- Fail (no username provided)

```python
{
"status": "fail",
"message": "No username."
}
```

- Fail (no password [hash] provided)

```python
{
"status": "fail",
"message": "No password."
}
```

2. **POST** /auth/login

- **Description:** To authorise a credential holder to access the API.

- **Function used:** Login()

- **Source:** /Auth/AuthAPI.py (Line 33)

- **Parameter(s):** None

- **Request body:**

```python
{
"username": "string"
"passwordHash": "string"
}
```

- **Response(s):**

- Success (200)

```python
{
"status": "success",
"message": "Login successful."
}
```

- Fail (401 Not authenticated)

```python
{
"status": "fail",
"message": "Authentication failed."
}
```

- Fail (No username provided)

```python
{
"status": "fail",
"message": "No username."
}
```

- Fail (No password provided)

```python
{
"status": "fail",
"message": "No password."
}
```

- Fail (bad token)

```python
{
"status": "fail",
"message": "Bad token"
}
```

Loading