Skip to content

Commit

Permalink
Skeleton OAuth implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
faisal-fawad committed Nov 3, 2024
1 parent b93ca43 commit 137bb19
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 10 deletions.
5 changes: 4 additions & 1 deletion imaginate_api/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@ class Config:
"token_url": "https://accounts.google.com/o/oauth2/token",
"user_info": {
"url": "https://www.googleapis.com/oauth2/v3/userinfo",
"data": lambda json: {"email": json["email"]},
"data": lambda json: {"email": json["email"], "id": json["sub"]},
},
"scopes": ["https://www.googleapis.com/auth/userinfo.email"],
}
}
BASE_URL = (
"https://playimaginate.com" if DB_ENV == "prod" else "http://127.0.0.1:5000"
)
TESTING = False
18 changes: 15 additions & 3 deletions imaginate_api/schemas/user_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def is_active(self):

@property
def is_anonymous(self):
return True # Always return True based on spec
return False # Always return False based on specification

def get_id(self):
return str(self.user_data["_id"])
Expand All @@ -37,15 +37,27 @@ def deactivate_user(self):
COLLECTION.update_one({"_id": self.user_data["_id"]}, {"$set": {"active": False}})
self.user_data["active"] = False

# Create or find user by data -> email
@classmethod
def find_or_create_user(cls, data):
def find_or_create_user(cls, data, provider=None):
# Primary identifier: Try to find the existing user by using the unique ID from the provider
if provider:
existing_user = COLLECTION.find_one({f"{provider}_id": data["id"]})
if existing_user:
return User(user_data=existing_user)

# Secondary identifier: Try to find the existing user by using the email from the provider
existing_user = COLLECTION.find_one({"email": data["email"]})
if existing_user:
if provider:
COLLECTION.update_one(
{"_id": existing_user["_id"]}, {"$set": {f"{provider}_id": data["id"]}}
)
return User(user_data=existing_user)

# If no user is found, create a new one
data["authenticated"] = False
data["active"] = True
data[f"{provider}_id"] = data.pop("id")
new_user = COLLECTION.insert_one(data)
return User.get(new_user.inserted_id)

Expand Down
10 changes: 4 additions & 6 deletions imaginate_api/user/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@
import requests

bp = Blueprint("user", __name__)
reroute_url = "index" # Currently set to index, but will be changed to imaginate home page in the future


# Initiates the authorization process with the specified provider
@bp.route("/authorize/<provider>")
def user_authorize(provider):
if not current_user.is_anonymous:
return redirect(url_for("index"))
return redirect(current_app.config["BASE_URL"])

provider_data = current_app.config["AUTH_PROVIDERS"].get(provider)
if not provider_data:
Expand All @@ -24,7 +23,6 @@ def user_authorize(provider):
)

session["oauth_state"] = secrets.token_urlsafe(32)
print(url_for("user.user_callback", provider=provider, _external=True))
query = urlencode(
{
"client_id": provider_data["client_id"],
Expand All @@ -42,7 +40,7 @@ def user_authorize(provider):
@bp.route("/callback/<provider>")
def user_callback(provider):
if not current_user.is_anonymous:
return redirect(url_for("index"))
return redirect(current_app.config["BASE_URL"])

provider_data = current_app.config["AUTH_PROVIDERS"].get(provider)
if not provider_data:
Expand Down Expand Up @@ -91,9 +89,9 @@ def user_callback(provider):

# Login user and map requested data
user_data = provider_data["user_info"]["data"](response.json())
user = User.find_or_create_user(user_data)
user = User.find_or_create_user(user_data, provider)
success = login_user(user)
if success:
user.authenticate_user()

return redirect(url_for("index"))
return redirect(current_app.config["BASE_URL"])

0 comments on commit 137bb19

Please sign in to comment.