diff --git a/auth.py b/auth.py index 590f4ee..25d5cff 100644 --- a/auth.py +++ b/auth.py @@ -5,8 +5,8 @@ from typing import Any, Union import bcrypt import jwt -from fastapi import Depends, HTTPException, status -from fastapi.security import HTTPBearer +from fastapi import Cookie, Depends, HTTPException, status +from fastapi.security import HTTPBearer, OAuth2PasswordRequestForm from jwt.exceptions import InvalidTokenError ACCESS_TOKEN_EXPIRE_MINUTES = 30 # 30 minutes @@ -38,6 +38,7 @@ def get_current_user(token: str = Depends(security)) -> dict: headers={'WWW-Authenticate': 'Bearer'} ) credential = token.credentials + try: payload = jwt.decode(credential, JWT_SECRET_KEY, algorithms=[ALGORITHM]) user_id: str = payload.get("sub") @@ -65,6 +66,40 @@ def get_current_user(token: str = Depends(security)) -> dict: return cur_user +def get_current_user2(token: str = Cookie(default=None)): + credentials_exception = HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Could not validate credentials", + headers={'WWW-Authenticate': 'Bearer'} + ) + print('TOKEN: ', token) + + try: + payload = jwt.decode(token, JWT_SECRET_KEY, algorithms=[ALGORITHM]) + user_id: str = payload.get("sub") + if user_id is None: + raise credentials_exception + + except InvalidTokenError: + raise credentials_exception + + with open('database/users.json', 'r') as f: + text = f.read() + if text: + data = json.loads(text) + else: + raise credentials_exception + + user = [i for i in data if i['id']==user_id] + if not user: + raise credentials_exception + + cur_user = {'id': user_id} + cur_user['username'] = user[0]['username'] + cur_user['encryption_key'] = payload['key'] + + return cur_user + class Hasher: """Class for hashing and verifying passwords""" diff --git a/frontend/src/components/HomePage.vue b/frontend/src/components/HomePage.vue index 64fbe9f..f8b5a57 100644 --- a/frontend/src/components/HomePage.vue +++ b/frontend/src/components/HomePage.vue @@ -29,10 +29,14 @@ export default { methods: { async login() { const url = `${this.apiBaseUrl}/login`; + var formData = new FormData(); + for (var key in this.form) { + formData.append(key, this.form[key]); + } const requestOptions = { method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify(this.form), + // headers: { "Content-Type": "application/json" }, + body: formData, }; const response = await fetch(url, requestOptions) @@ -47,9 +51,10 @@ export default { }); console.log("response: ", response); if ("message" in response) { - if (response.message === "authenticated") { - const token = response.accessToken; - sessionStorage.setItem("token", token); + if (response.message === "Authenticated") { + // const token = response.accessToken; + // sessionStorage.setItem("token", token); + sessionStorage.setItem("authenticated", true); this.$emit("loggedin", true); } } diff --git a/frontend/src/components/ListSecrets.vue b/frontend/src/components/ListSecrets.vue index c2944fd..3860243 100644 --- a/frontend/src/components/ListSecrets.vue +++ b/frontend/src/components/ListSecrets.vue @@ -100,13 +100,14 @@ export default { methods: { async listSecrets() { const url = `${this.apiBaseUrl}/secret`; - const token = sessionStorage.getItem("token"); + // const token = sessionStorage.getItem("token"); const requestOptions = { method: "GET", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${token}`, - }, + credentials: "include", + // headers: { + // // "Content-Type": "application/json", + // // Authorization: `Bearer ${token}`, + // }, }; console.log(requestOptions); const response = await fetch(url, requestOptions) diff --git a/main.py b/main.py index 9ddce9d..7e5d5c8 100644 --- a/main.py +++ b/main.py @@ -1,19 +1,15 @@ import json -from fastapi import Depends, FastAPI, HTTPException, status +from fastapi import Depends, FastAPI, HTTPException, Response, status from fastapi.encoders import jsonable_encoder from fastapi.middleware.cors import CORSMiddleware -from fastapi.security import OAuth2PasswordBearer +from fastapi.security import OAuth2PasswordRequestForm -from auth import Hasher, create_access_token, get_current_user -from crypto import ( - deserialize_into_bytes, - fernet_decrypt, - fernet_encrypt, - generate_random_encryption_key, - generate_user_passkey, - serialize_bytes, -) +from auth import (Hasher, create_access_token, get_current_user, + get_current_user2) +from crypto import (deserialize_into_bytes, fernet_decrypt, fernet_encrypt, + generate_random_encryption_key, generate_user_passkey, + serialize_bytes) from models import Secret, User, UserLogin app = FastAPI() @@ -22,7 +18,7 @@ app = FastAPI() origins = [ 'http://localhost', 'http://localhost:5173', - "*" + # "*" ] app.add_middleware( CORSMiddleware, @@ -81,7 +77,7 @@ async def register(user: User): @app.post('/login') -async def login(user: UserLogin): +async def login(response: Response, form_data: OAuth2PasswordRequestForm = Depends()): """logs in the user""" users = [] @@ -90,7 +86,10 @@ async def login(user: UserLogin): if text: users.extend(json.loads(text)) - cur_user = [i for i in users if i['username']==user.username] + username = form_data.username + password = form_data.password + + cur_user = [i for i in users if i['username']==username] if not cur_user: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, @@ -99,7 +98,7 @@ async def login(user: UserLogin): else: cur_user = cur_user[0] - password_match = Hasher.verify_password(user.password, cur_user['password']) + password_match = Hasher.verify_password(password, cur_user['password']) if not password_match: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, @@ -108,16 +107,16 @@ async def login(user: UserLogin): encrypted_encryption_key = cur_user['encryption_key'].encode() salt = deserialize_into_bytes(cur_user['salt']) - _, master_key = generate_user_passkey(user.password, salt) + _, master_key = generate_user_passkey(password, salt) encryption_key = fernet_decrypt(encrypted_encryption_key, master_key) access_token = create_access_token(subject=cur_user['id'], encryption_key=encryption_key) - response = { - 'message': 'authenticated', - 'accessToken': access_token - } - - return response + # response = { + # 'message': 'authenticated', + # 'accessToken': access_token + # } + response.set_cookie('token', value=access_token, max_age=1800, httponly=True, path='/') + return {'message': 'Authenticated'} @app.post("/secret") @@ -185,9 +184,9 @@ async def update_secret(secret: Secret, current_user: dict = Depends(get_current @app.get('/secret') -async def list_secret(current_user: dict = Depends(get_current_user)): +async def list_secret(current_user: dict = Depends(get_current_user2)): """Returns the encrypted secrets of the user.""" - + print('cuuuuuurrrrr', current_user) data = [] with open('database/secrets.json', 'r') as f: text = f.read() @@ -207,10 +206,11 @@ async def list_secret(current_user: dict = Depends(get_current_user)): @app.get('/validate-token') -async def validate_token(current_user: dict = Depends(get_current_user)): +async def validate_token(current_user: dict = Depends(get_current_user2)): user_id = current_user['id'] print("user_id: ", user_id) if user_id is not None: return {'message': 'authenticated'} - raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED) \ No newline at end of file + raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED) + # return {'message': "hello"} \ No newline at end of file