diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml index aa1f97680..c2e66efdc 100644 --- a/.github/workflows/pylint.yml +++ b/.github/workflows/pylint.yml @@ -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') diff --git a/.gitignore b/.gitignore index 6ea2c11e2..12dd8c88a 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/src/backend/app.py b/src/backend/app.py index 25d1c7e66..9eb624a92 100644 --- a/src/backend/app.py +++ b/src/backend/app.py @@ -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"]) @@ -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 @@ -45,6 +49,7 @@ def register(): result = user_login.register(username, email, password, phone) if not result.status: return result.message, 400 + session["username"] = username return result.message, 201 return "", 400 @@ -52,8 +57,9 @@ def register(): @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": @@ -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") @@ -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 diff --git a/src/backend/database/database_test.db b/src/backend/database/database_test.db index 9b13870a4..6594b330f 100644 Binary files a/src/backend/database/database_test.db and b/src/backend/database/database_test.db differ diff --git a/src/backend/pages/userpage.py b/src/backend/pages/userpage.py index 6c5187985..56568e371 100644 --- a/src/backend/pages/userpage.py +++ b/src/backend/pages/userpage.py @@ -15,18 +15,20 @@ def __init__(self, username: str) -> None: self.user = self.get_user(username) @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 diff --git a/src/backend/requirements.txt b/src/backend/requirements.txt index ddd4af7d5..81e779734 100644 --- a/src/backend/requirements.txt +++ b/src/backend/requirements.txt @@ -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 \ No newline at end of file +Flask_Cors==3.0.10 +Flask-Session2==1.3.1 \ No newline at end of file diff --git a/src/backend/tests/test_app.py b/src/backend/tests/test_app.py index 38e348c4e..7111ebf05 100644 --- a/src/backend/tests/test_app.py +++ b/src/backend/tests/test_app.py @@ -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 @@ -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",)) @@ -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() diff --git a/src/frontend/src/components/mainpageleft/getSearchBarSuggestions.tsx b/src/frontend/src/components/mainpageleft/getSearchBarSuggestions.tsx index 59906234e..2c1a36b52 100644 --- a/src/frontend/src/components/mainpageleft/getSearchBarSuggestions.tsx +++ b/src/frontend/src/components/mainpageleft/getSearchBarSuggestions.tsx @@ -20,6 +20,7 @@ export default function getSuggestions(query: string, search: boolean) { method: 'GET', url: `http://127.0.0.1:5000/?search=${search}&searchQuery=${query}`, cancelToken: source.token, + withCredentials: true, }) .then((res) => { const newNames: { diff --git a/src/frontend/src/components/user/changeInfo.tsx b/src/frontend/src/components/user/changeInfo.tsx index 4506a8d2b..fefa60007 100644 --- a/src/frontend/src/components/user/changeInfo.tsx +++ b/src/frontend/src/components/user/changeInfo.tsx @@ -12,6 +12,7 @@ export function changeEmail(new_email: string) { method: 'POST', url: `${baseURL}`, data: json, + withCredentials: true, }) .then((response) => { console.log(response); @@ -35,6 +36,7 @@ export function changePhone(new_phone: string) { method: 'POST', url: `${baseURL}`, data: json, + withCredentials: true, }) .then((response) => { console.log(response); @@ -51,6 +53,7 @@ export function changePhone(new_phone: string) { export function logout() { axios({ url: 'http://127.0.0.1:5000/logout', + withCredentials: true, }) .then((response) => { console.log(response); diff --git a/src/frontend/src/components/user/getReviewedApts.tsx b/src/frontend/src/components/user/getReviewedApts.tsx index f7b032b04..4c06de113 100644 --- a/src/frontend/src/components/user/getReviewedApts.tsx +++ b/src/frontend/src/components/user/getReviewedApts.tsx @@ -27,6 +27,7 @@ export default function getReviewedApts(username: string) { url: `${baseURL}`, data: json, cancelToken: source.token, + withCredentials: true, }) .then((res) => { setApartments(() => { diff --git a/src/frontend/src/components/user/getUser.tsx b/src/frontend/src/components/user/getUser.tsx index eee540e8f..67af8f3df 100644 --- a/src/frontend/src/components/user/getUser.tsx +++ b/src/frontend/src/components/user/getUser.tsx @@ -20,6 +20,7 @@ export default function getInfo(username: string) { method: 'GET', url: `${baseURL}`, cancelToken: source.token, + withCredentials: true, }) .then((res) => { setUser(() => { diff --git a/src/frontend/src/pages/Login.tsx b/src/frontend/src/pages/Login.tsx index 0faf92651..e8cfbf5ea 100644 --- a/src/frontend/src/pages/Login.tsx +++ b/src/frontend/src/pages/Login.tsx @@ -18,12 +18,13 @@ export default function Login() { const navigate = useNavigate(); const [user, setUser] = useState(''); const [password, setPassword] = useState(''); - const [res, setRes] = useState(''); + const [res, setRes] = useState(); function sendData() { axios({ method: 'post', url: 'http://127.0.0.1:5000/login', + withCredentials: true, data: { user: user, password: password, @@ -31,7 +32,7 @@ export default function Login() { }) .then((response) => { console.log(response); - navigate('/'); + setRes(response.data); }) .catch((error) => { if (error.response) { @@ -49,6 +50,9 @@ export default function Login() { width: 310, margin: '20px auto', }; + if (res === `welcome ${user}`) { + navigate('/'); + } const btnstyle = { margin: '8px 0' }; return ( @@ -81,7 +85,6 @@ export default function Login() { style={btnstyle} onClick={() => { sendData(); - res === '' ? navigate('/') : null; }} fullWidth > @@ -93,7 +96,7 @@ export default function Login() { Sign Up - {res !== '' && ( + {res !== undefined && res !== `welcome ${user}` && ( {res} )} diff --git a/src/frontend/src/pages/MainPage.tsx b/src/frontend/src/pages/MainPage.tsx index 12feb887c..c570a05f7 100644 --- a/src/frontend/src/pages/MainPage.tsx +++ b/src/frontend/src/pages/MainPage.tsx @@ -26,6 +26,7 @@ function MainPage() { function checkLoggedIn() { axios({ url: 'http://127.0.0.1:5000/api/whoami', + withCredentials: true, }) .then((response) => { console.log(response); diff --git a/src/frontend/src/pages/Register.tsx b/src/frontend/src/pages/Register.tsx index c48750986..33a898af5 100644 --- a/src/frontend/src/pages/Register.tsx +++ b/src/frontend/src/pages/Register.tsx @@ -19,7 +19,7 @@ export default function Register() { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [number, setNumber] = useState(''); - const [res, setRes] = useState(''); + const [res, setRes] = useState(); const paperStyle = { padding: 20, height: '70vh', @@ -32,6 +32,7 @@ export default function Register() { axios({ method: 'POST', url: 'http://127.0.0.1:5000/register', + withCredentials: true, data: { username: user, email: email, @@ -41,6 +42,7 @@ export default function Register() { }) .then((response) => { console.log(response); + setRes(response.data); }) .catch((error) => { if (error.response) { @@ -51,6 +53,9 @@ export default function Register() { } }); } + if (res === `Register successful, welcome ${user}`) { + navigate('/'); + } return ( @@ -97,7 +102,6 @@ export default function Register() { style={btnstyle} onClick={() => { sendData(); - res === '' ? navigate('/login') : null; }} fullWidth > @@ -106,7 +110,7 @@ export default function Register() { Already signed up? - {res !== '' && ( + {res !== undefined && res !== `Register successful, welcome ${user}` && ( {res} )}