Skip to content

Commit

Permalink
Merge pull request #51 from CS222-UIUC/minh/userpage_frontend
Browse files Browse the repository at this point in the history
Add userpage UI, overhaul frontend, fix backend session
  • Loading branch information
MinhPhan8803 authored Dec 2, 2022
2 parents 810d730 + 0ad58fe commit ad461e4
Show file tree
Hide file tree
Showing 39 changed files with 1,503 additions and 471 deletions.
1 change: 1 addition & 0 deletions .github/workflows/pylint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
pip install pytest==7.1.3
pip install flask-cors
pip install BeautifulSoup4
pip install Flask-Session2
- name: Analysing the code with pylint
run: |
pylint $(git ls-files '*.py')
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ src/frontend/node_modules
src/backend/.pytest_cache
.pytest_cache
src/backend/__pycache__
src/backend/flask_session

src/frontend/my-app/node_modules
# testing
Expand Down
23 changes: 15 additions & 8 deletions src/backend/app.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
""" Handles routing and HTTP Requests """
import json
import os
import dataclasses
from werkzeug.datastructures import MultiDict
from flask import Flask, request, session
from flask_cors import CORS
from flask_session import Session
from pages.login import Login
from pages.mainpage import MainPage
from pages.userpage import UserPage
from dataholders.mainpage_get import GetRequestType, GetRequestParams

app = Flask(__name__)
app.config["SECRET_KEY"] = os.urandom(24)
CORS(app, resources={r"/*": {"origins": "*"}})
SECRET_KEY = b"xe47Wxcdx86Wxac(mKlxa5xa2,xb3axc6xf1x86Fxc25x94xfc"
SESSION_TYPE = "filesystem"
app.config.from_object(__name__)
Session(app)
CORS(app, resources={r"/*": {"origins": "*"}}, supports_credentials=True)


@app.route("/login", methods=["GET", "POST"])
Expand All @@ -27,6 +30,7 @@ def login():
if user_login.login(username, password):
# session object makes User accessible in the backend
session["username"] = username
print(session.get("username"))
return f"welcome {username}", 200
return "User not found, please try again", 401
return "", 400
Expand All @@ -45,15 +49,17 @@ def register():
result = user_login.register(username, email, password, phone)
if not result.status:
return result.message, 400
session.pop("username", None)
return result.message, 201
return "", 400


@app.route("/user", methods=["GET", "POST"])
def userpage():
"""Handles userpage requests"""
if session.get("username", None) is None:
return "user does not exist", 404
print(session.get("username"))
if session.get("username") is None:
return "user does not exist", 403
name = session.get("username") or ""
page = UserPage(name)
if request.method == "POST":
Expand All @@ -78,7 +84,7 @@ def userpage():
return "success", 201
user = page.get_user(name) # request.method == "GET"
data_dict = dataclasses.asdict(user)
return json.dumps(data_dict), 201
return json.dumps(data_dict), 200


@app.route("/logout")
Expand All @@ -91,8 +97,9 @@ def logout():
@app.route("/api/whoami")
def whoami():
"""Shows whether a user is logged in and returns session username"""
if session.get("username", None) is None:
return "user logged out", 404
print(session.get("username"))
if session.get("username") is None:
return "user logged out", 403
username = session.get("username", "")
return str(username), 201

Expand Down
File renamed without changes.
Binary file modified src/backend/database/database_prod.db
Binary file not shown.
Binary file modified src/backend/database/database_test.db
Binary file not shown.
4 changes: 2 additions & 2 deletions src/backend/pages/login.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
""" Contains Login class """
from dataclasses import dataclass
from decorators import use_database
from tests.auth import validate_email, validate_password, validate_phone
from auth import validate_email, validate_password, validate_phone


@dataclass(frozen=True)
Expand Down Expand Up @@ -33,7 +33,7 @@ def register(
return RegisterResult("Invalid phone number, please try again", False)

if not validate_password(password):
return RegisterResult("Password is too short, please try again", False)
return RegisterResult("Password length should be greater than 8", False)

check = self.register.cursor.execute(
"SELECT username FROM Users WHERE username = ?", (username,)
Expand Down
3 changes: 2 additions & 1 deletion src/backend/pages/mainpage.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@ def write_apartment_review(
) -> List[Review]:
"""Write a new review for apartment"""
user_id = self.write_apartment_review.cursor.execute(
"SELECT user_id FROM Users WHERE username = ?", (username,)
"SELECT user_id FROM Users WHERE username = ? OR email = ?",
(username, username),
).fetchone()[0]
today = date.today().strftime("%Y-%m-%d")
self.write_apartment_review.cursor.execute(
Expand Down
35 changes: 19 additions & 16 deletions src/backend/pages/userpage.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Contains the UserPage backend"""
from typing import List
from tests.auth import validate_phone, validate_email, validate_password
from auth import validate_phone, validate_email, validate_password
from dataholders.user import User
from dataholders.apt import Apt
from decorators import use_database
Expand All @@ -9,24 +9,26 @@
class UserPage:
"""UserPage class"""

def __init__(self, username: str) -> None:
def __init__(self, name: str) -> None:
"""Constructor"""
self.username = username
self.user = self.get_user(username)
self.name = name
self.user = self.get_user(name)

@use_database
def get_user(self, username: str) -> User:
def get_user(self, query_sql: str) -> User:
"""Return User object based on username"""
query_sql = username
user_query = self.get_user.cursor.execute(
"SELECT u.user_id, u.password, u.email, u.phone \
"SELECT u.user_id, u.username, u.password, u.email, u.phone \
FROM USERS u\
WHERE u.username = ?",
(query_sql,),
WHERE u.username = ? OR u.email = ?",
(
query_sql,
query_sql,
),
).fetchone()
if user_query is None:
return User("", "", "", "", "")
user_id, password, email, phone = user_query
user_id, username, password, email, phone = user_query
return User(user_id, username, password, email, phone)

@use_database
Expand All @@ -40,8 +42,8 @@ def update_password(self, password: str) -> bool:
self.update_password.cursor.execute(
"UPDATE Users \
SET password = ? \
WHERE (username = ?)",
(password, self.username),
WHERE (username = ? OR email = ?)",
(password, self.name, self.name),
)
self.user.password = password
return True
Expand All @@ -56,8 +58,8 @@ def update_email(self, email: str) -> bool:
self.update_email.cursor.execute(
"UPDATE Users \
SET email = ? \
WHERE username = ?",
(email, self.username),
WHERE (username = ? OR email = ?)",
(email, self.name, self.name),
)
self.user.email = email
return True
Expand All @@ -70,8 +72,9 @@ def update_phone(self, phone: str) -> bool:
if self.user.phone == phone:
return True
self.update_phone.cursor.execute(
"UPDATE Users SET phone = ? WHERE (username = ?)",
(phone, self.username),
"UPDATE Users SET phone = ? \
WHERE (username = ? OR email = ?)",
(phone, self.name, self.name),
)
self.user.phone = phone
return True
Expand Down
3 changes: 2 additions & 1 deletion src/backend/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ pytest==7.1.3
pylint==2.15.2
coverage==6.4.4
black==22.8.0
Flask_Cors==3.0.10
Flask_Cors==3.0.10
Flask-Session2==1.3.1
6 changes: 3 additions & 3 deletions src/backend/tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ def test_userpage_not_logged_in(client):
assert res.status_code == 404
with app.test_request_context("/user/"):
res = userpage()
assert res[1] == 404
assert res[1] == 403


@use_test
Expand All @@ -301,7 +301,7 @@ def test_userpage_get_request(client):
with app.test_request_context("/user/", method="GET"):
session["username"] = "Mike"
res = userpage()
assert res[1] == 201
assert res[1] == 200
connection = sqlite3.connect("database/database_test.db")
cursor = connection.cursor()
cursor.execute("DELETE FROM Users WHERE username = ?", ("Mike",))
Expand Down Expand Up @@ -372,7 +372,7 @@ def test_whoami():
"""Test whoami returns 404 and 201"""
with app.test_request_context("/api/whoami"):
res = whoami()
assert res[1] == 404
assert res[1] == 403
with app.test_request_context("/api/whoami"):
session["username"] = "Mike"
res = whoami()
Expand Down
Loading

3 comments on commit ad461e4

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage

Coverage Report
FileStmtsMissCover
app.py1450100%
auth.py90100%
config.py10100%
decorators.py270100%
dataholders
   apt.py90100%
   mainpage_get.py150100%
   review.py70100%
   user.py80100%
pages
   login.py290100%
   mainpage.py1000100%
   userpage.py530100%
TOTAL4030100%

Tests Skipped Failures Errors Time
49 0 💤 0 ❌ 0 🔥 0.749s ⏱️

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage

Coverage Report
FileStmtsMissCover
app.py1450100%
auth.py90100%
config.py10100%
decorators.py270100%
dataholders
   apt.py90100%
   mainpage_get.py150100%
   review.py70100%
   user.py80100%
pages
   login.py290100%
   mainpage.py1000100%
   userpage.py530100%
TOTAL4030100%

Tests Skipped Failures Errors Time
49 0 💤 0 ❌ 0 🔥 0.834s ⏱️

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage

Coverage Report
FileStmtsMissCover
app.py1450100%
auth.py90100%
config.py10100%
decorators.py270100%
dataholders
   apt.py90100%
   mainpage_get.py150100%
   review.py70100%
   user.py80100%
pages
   login.py290100%
   mainpage.py1000100%
   userpage.py530100%
TOTAL4030100%

Tests Skipped Failures Errors Time
49 0 💤 0 ❌ 0 🔥 1.309s ⏱️

Please sign in to comment.