Skip to content

Commit

Permalink
[71] Get user with token; sync FB and BE on sign in
Browse files Browse the repository at this point in the history
  • Loading branch information
nxabdullah committed Dec 12, 2023
1 parent 5b61e69 commit a5f26c2
Show file tree
Hide file tree
Showing 10 changed files with 366 additions and 284 deletions.
39 changes: 27 additions & 12 deletions backend/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,23 @@ class User(DB_MODEL):
household: int
fuel_efficiency: float

def __init__(self, oid: ObjectId, full_name: str, email: str, badges: list[str], friends: list[str], score:int, province:str, household:int, fuel_efficiency: float) -> None:
def __init__(
self,
oid: ObjectId,
full_name: str,
email: str,
uid: str,
badges: list[str],
friends: list[str],
score: int,
province: str,
household: int,
fuel_efficiency: float,
) -> None:
super().__init__(oid)
self.full_name = str(full_name)
self.email = str(email)
self.uid = uid
self.badges = badges
self.friends = friends
self.score = score
Expand All @@ -32,15 +45,16 @@ def __init__(self, oid: ObjectId, full_name: str, email: str, badges: list[str],

def to_json(self) -> json:
return {
'_id': self.oid,
'full_name': self.full_name,
'email': self.email,
'badges': self.badges,
'friends': self.friends,
'score': self.score,
'province': self.province,
'household': self.household,
'fuel_efficiency': self.fuel_efficiency
"_id": self.oid,
"full_name": self.full_name,
"email": self.email,
"uid": self.uid,
"badges": self.badges,
"friends": self.friends,
"score": self.score,
"province": self.province,
"household": self.household,
"fuel_efficiency": self.fuel_efficiency,
}

@staticmethod
Expand All @@ -49,13 +63,14 @@ def from_json(doc: json) -> User:
oid=ObjectId(doc["_id"]),
full_name=doc["full_name"],
email=doc["email"],
uid=doc["uid"],
badges=doc["badges"],
friends=doc["friends"],
score=doc["score"],
province=doc["province"],
household=doc["household"],
fuel_efficiency=doc["fuel_efficiency"]
fuel_efficiency=doc["fuel_efficiency"],
)

def __repr__(self) -> str:
return f'User ID: {self.oid.__str__()}'
return f"User ID: {self.oid.__str__()}"
15 changes: 11 additions & 4 deletions backend/routes/carbon_auth.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
from flask_httpauth import HTTPTokenAuth
from utils.FirebaseAPI import FirebaseAPI
from flask import g

auth = HTTPTokenAuth(scheme='Bearer')
auth = HTTPTokenAuth(scheme="Bearer")


@auth.verify_token
def verify_token(token: str) -> bool:
d = FirebaseAPI.verify_google_token(token)
print(f"USER AUTHENTICATED: {bool(d)}")
return bool(d)
user_info = FirebaseAPI.verify_google_token(token)

print(f"USER AUTHENTICATED: {bool(user_info)}")

if user_info:
g.current_user = user_info # Setting the current user in Flask's global object
return True
else:
return False


@auth.error_handler
Expand Down
91 changes: 66 additions & 25 deletions backend/routes/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,73 @@
from mongodb_api.carbon_track_db import CarbonTrackDB
from routes import carbon_auth
from utils.carbon_track_errors import CarbonTrackError
from pymongo.collection import ReturnDocument
from flask import g

users = Blueprint('/users', __name__)
users = Blueprint("/users", __name__)


@users.route("/user/<user_id>", methods=['GET'])
@users.route("/user/<user_id>", methods=["GET"])
@carbon_auth.auth.login_required
def get_user(user_id: str) -> Response:
try:
query = {"_id": ObjectId(user_id)}
item = CarbonTrackDB.users_coll.find_one(query)
item = User.from_json(item).to_json()
return jsonify({'user': item})
return jsonify({"user": item})
except CarbonTrackError as e:
abort(code=400, description=f"{e}")


@users.route("/user_email/<user_email>", methods=['GET'])
@users.route("/user_email/<user_email>", methods=["GET"])
@carbon_auth.auth.login_required
def get_user_by_email(user_email: str) -> Response:
try:
query = {"email": user_email}
item = CarbonTrackDB.users_coll.find_one(query)
item = User.from_json(item).to_json()
return jsonify({'user': item})
return jsonify({"user": item})
except CarbonTrackError as e:
abort(code=400, description=f"{e}")


@users.route("/user", methods=['PUT'])
@users.route("/current", methods=["GET"])
@carbon_auth.auth.login_required
def get_current_user() -> Response:
try:
current_user = g.current_user

print(current_user)

# Construct the query to find the user in MongoDB
query = {"uid": current_user["uid"]}

# Fetch user data from MongoDB
mongo_user = CarbonTrackDB.users_coll.find_one(query)

# Check if user exists in MongoDB and update if necessary
if mongo_user is not None:
# Check if the email in Firebase and MongoDB are different
if mongo_user.get("email") != current_user["email"]:
update = {"$set": {"email": current_user["email"]}}
mongo_user = CarbonTrackDB.users_coll.find_one_and_update(
query, update, return_document=ReturnDocument.AFTER
)
else:
# Handle case where user is not found in MongoDB
abort(code=404, description="User not found in database")

user_data = User.from_json(mongo_user).to_json()
return jsonify({"user": user_data})
except CarbonTrackError as e:
abort(code=400, description=str(e))


@users.route("/user", methods=["PUT"])
@carbon_auth.auth.login_required
def create_user() -> Response:
try:
res: dict = request.get_json()['user']
res: dict = request.get_json()["user"]
user = User.from_json(res)
user.email = user.email.lower()

Expand All @@ -46,23 +80,27 @@ def create_user() -> Response:
if item is None:
user = user.to_json()
inserted_id = CarbonTrackDB.users_coll.insert_one(user).inserted_id
user = User.from_json(CarbonTrackDB.users_coll.find_one({"_id": inserted_id})).to_json()
return jsonify({'user': user})
user = User.from_json(
CarbonTrackDB.users_coll.find_one({"_id": inserted_id})
).to_json()
return jsonify({"user": user})
else:
return jsonify({'error': "User Already Exits With Same Email, Please Log In"})
return jsonify(
{"error": "User Already Exits With Same Email, Please Log In"}
)
except CarbonTrackError as e:
abort(code=400, description=f"{e}")


@users.route("/user/<user_id>", methods=['DELETE'])
@users.route("/user/<user_id>", methods=["DELETE"])
@carbon_auth.auth.login_required
def delete_user(user_id: str) -> Response:
try:
query = {"_id": ObjectId(user_id)}
item = CarbonTrackDB.users_coll.find_one(query)
item = User.from_json(item).to_json()
CarbonTrackDB.users_coll.delete_one(query)
return jsonify({'deleted user': item})
return jsonify({"deleted user": item})
except CarbonTrackError as e:
abort(code=400, description=f"{e}")

Expand All @@ -72,29 +110,32 @@ def delete_user(user_id: str) -> Response:
def update_user(user_id: str) -> Response:
try:
query = {"_id": ObjectId(user_id)}
user = User.from_json(request.get_json()['user']).to_json()
del user['_id']
del user['email']
CarbonTrackDB.users_coll.update_one(query, {'$set': user})
user = User.from_json(request.get_json()["user"]).to_json()
del user["_id"]
del user["email"]
CarbonTrackDB.users_coll.update_one(query, {"$set": user})
item = CarbonTrackDB.users_coll.find_one(query)
item = User.from_json(item).to_json()
return jsonify({'user': item})
return jsonify({"user": item})
except CarbonTrackError as e:
abort(code=400, description=f"{e}")


@users.route("/user/update_email/<user_id>", methods=["PATCH"])
@carbon_auth.auth.login_required
def update_user_email(user_id: str) -> Response:
def update_user_email(uid: str) -> Response:
try:
query = {"_id": ObjectId(user_id)}
new_email = request.get_json().get('email', '')
query = {"uid": uid}
new_email = request.get_json().get("email", "")

current_user = carbon_auth.auth.current_user()
new_token = FirebaseAPI.refresh_token(current_user.uid)
CarbonTrackDB.users_coll.update_one(query, {'$set': {'email': new_email}})

CarbonTrackDB.users_coll.update_one(query, {"$set": {"email": new_email}})

item = CarbonTrackDB.users_coll.find_one(query)

item = User.from_json(item).to_json()
return jsonify({'user': item})

return jsonify({"user": item})
except CarbonTrackError as e:
abort(code=400, description=f"{e}")


36 changes: 20 additions & 16 deletions frontend/src/APIs/FLASK_API.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import axios from "axios";
import firebaseService from "../utilities/firebase";
const FLASK_LOCAL_ADDRESS: string = "http://192.168.2.12:6050";
import axios from 'axios';
import firebaseService from '../utilities/firebase';
const FLASK_LOCAL_ADDRESS: string = 'http://192.168.68.104:6050';

// Function to get the Firebase authentication token
const getFirebaseAuthToken = async (): Promise<string | null> => {
// Assume you have a Firebase authentication instance
const firebaseUser = await firebaseService.getFirebaseUser()
const firebaseUser = await firebaseService.getFirebaseUser();
if (firebaseUser != null) {
// Get the user token
const token = await firebaseUser.getIdToken();
// Get the user token
const token = await firebaseUser.getIdToken(true);
return token;
} else {
// Handle the case when the user is not signed in
Expand All @@ -24,17 +24,21 @@ const instance = axios.create({
});

// Add an interceptor to include the token in the headers of each request
instance.interceptors.request.use(async (config) => {
const token = await getFirebaseAuthToken();
instance.interceptors.request.use(
async (config) => {
const token = await getFirebaseAuthToken();
console.log(token);

if (token != null) {
config.headers.Authorization = `Bearer ${token}`;
}
if (token != null) {
config.headers.Authorization = `Bearer ${token}`;
}

return config;
}, async (error) => {
// Handle request error
return await Promise.reject(error);
});
return config;
},
async (error) => {
// Handle request error
return await Promise.reject(error);
}
);

export default instance;
Loading

0 comments on commit a5f26c2

Please sign in to comment.