-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from JohnGrubba/dev
Google OAuth
- Loading branch information
Showing
14 changed files
with
209 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
**.venv | ||
**.env | ||
**config.json | ||
**.pyc | ||
**.pyc | ||
|
||
**.env** |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
## Google OAuth | ||
### Setup Google OAuth | ||
1. Go to the [Google Cloud Console](https://console.cloud.google.com/). | ||
2. Create a new project. | ||
3. Go to the [APIs & Services -> Credentials](https://console.cloud.google.com/apis/credentials) section. | ||
4. Click on `Create credentials` and select `OAuth client ID`. | ||
5. Select `Web application` as the application type. | ||
6. Add the following URIs to the `Authorized redirect URIs`: | ||
- `http://localhost:3250/oauth/google/callback` | ||
7. Add the following scopes | ||
<img src="/assets/scopes_google.png" style='margin-top: 10px;' /> | ||
|
||
8. Click on `Create` and download the credentials as JSON and place them in the `config` folder. | ||
Make sure the name of the file is `client_secret.env.json`. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
from fastapi import APIRouter | ||
import importlib | ||
from tools.conf import SignupConfig | ||
|
||
router = APIRouter( | ||
prefix="/oauth", | ||
tags=["OAuth"], | ||
dependencies=[], | ||
) | ||
|
||
|
||
if "google" in SignupConfig.oauth_providers: | ||
from .google import router as ggl | ||
|
||
router.include_router(ggl) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
from fastapi import APIRouter, Request, BackgroundTasks, Response, HTTPException | ||
from fastapi.responses import RedirectResponse | ||
from google_auth_oauthlib.flow import Flow | ||
from tools.conf import SignupConfig | ||
import os, re | ||
from crud.user import ( | ||
create_user, | ||
get_user_by_google_uid, | ||
get_user_email_or_username, | ||
link_google_account, | ||
) | ||
from api.model import LoginResponse | ||
import jwt | ||
from crud.sessions import create_login_session | ||
from tools import SignupConfig, SessionConfig | ||
|
||
# Required for HTTP | ||
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1" | ||
|
||
router = APIRouter( | ||
prefix="/google", | ||
dependencies=[], | ||
) | ||
|
||
# Initialize Googles OAuth Flow | ||
flow = Flow.from_client_secrets_file( | ||
client_secrets_file="/src/app/config/client_secret.env.json", | ||
scopes=[ | ||
"https://www.googleapis.com/auth/userinfo.email", | ||
"openid", | ||
"https://www.googleapis.com/auth/userinfo.profile", | ||
], | ||
redirect_uri=SignupConfig.oauth_base_url + "/oauth/google/callback", | ||
) | ||
|
||
|
||
@router.get("/login") | ||
async def oauth_login(): | ||
""" | ||
# OAuth Login | ||
## Description | ||
This endpoint is used to initiate the OAuth login flow. | ||
""" | ||
auth_url, _ = flow.authorization_url() | ||
return RedirectResponse(auth_url) | ||
|
||
|
||
def login_usr(response: Response, usr: dict) -> LoginResponse: | ||
# User already exists | ||
session_token = create_login_session(usr["_id"]) | ||
if SessionConfig.auto_cookie: | ||
response.set_cookie( | ||
SessionConfig.auto_cookie_name, | ||
session_token, | ||
expires=SessionConfig.session_expiry_seconds, | ||
) | ||
return LoginResponse(session_token=session_token) | ||
|
||
|
||
@router.get("/callback") | ||
async def oauth_callback( | ||
request: Request, background_tasks: BackgroundTasks, response: Response | ||
): | ||
""" | ||
# OAuth Callback | ||
## Description | ||
This endpoint is used to handle the OAuth callback. | ||
""" | ||
# Get Information about user from Google | ||
try: | ||
token = flow.fetch_token(authorization_response=request.url.__str__()) | ||
except: | ||
raise HTTPException(status_code=401, detail="Invalid OAuth Token") | ||
jwt_id = token["id_token"] | ||
jwt_decoded = jwt.decode( | ||
jwt_id, algorithms=["RS256"], options={"verify_signature": False} | ||
) | ||
|
||
username = jwt_decoded["name"].replace(" ", "") | ||
# Validate Username | ||
if len(username) < 4 or re.search("[^a-zA-Z0-9]", username) is not None: | ||
username = jwt_decoded["email"].split("@")[0] | ||
|
||
# Check if SignIn Possible | ||
usr = get_user_by_google_uid(jwt_decoded["sub"]) | ||
if usr: | ||
return login_usr(response, usr) | ||
|
||
# If users email already exists, link the google account | ||
usr = get_user_email_or_username(jwt_decoded["email"]) | ||
if usr: | ||
link_google_account(usr["_id"], jwt_decoded["sub"]) | ||
return login_usr(response, usr) | ||
|
||
# Custom SignUp Form (Password Field missing etc.) | ||
signup_form = { | ||
"email": jwt_decoded["email"], | ||
"username": username, | ||
"password": "", | ||
"google_uid": jwt_decoded["sub"], | ||
} | ||
# Persist user in DB | ||
session_token = create_user(signup_form, background_tasks, signup_form) | ||
if SessionConfig.auto_cookie: | ||
response.set_cookie( | ||
SessionConfig.auto_cookie_name, | ||
session_token, | ||
expires=SessionConfig.session_expiry_seconds, | ||
) | ||
return LoginResponse(session_token=session_token) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters