Skip to content

Commit e4b2445

Browse files
committed
Convert the airnominal to the core app
1 parent 5a40010 commit e4b2445

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+144
-1558
lines changed
File renamed without changes.

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22

33
Easy to setup social authentication mechanism with support for several auth providers.
44

5-
## Examples
5+
## Demo
66

7-
- [airnominal](./examples/airnominal) - [fastapi-sso](https://github.com/tomasvotava/fastapi-sso) based implementation
8-
- [dogeapi](./examples/DogeAPI) - [fastapi-allauth](https://github.com/K-villain/fastapi-allauth) based implementation
7+
This sample application is made to demonstrate the use of the [**fastapi-oauth2**](./fastapi_oauth2) package.
98

10-
Both can be run using the following command:
9+
## Running the application
1110

1211
```bash
1312
uvicorn main:app --reload
1413
```
1514

1615
## TODO
1716

18-
- Segregate the prototype of the `fastapi-oauth2` core.
17+
- Make the [**fastapi-oauth2**](./fastapi_oauth2) depend
18+
on (overuse) the [**social-core**](https://github.com/python-social-auth/social-core)
File renamed without changes.
File renamed without changes.
Lines changed: 5 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,14 @@
1-
import os
2-
from datetime import datetime, timedelta
31
from typing import Optional
42

5-
from fastapi import APIRouter
63
from fastapi import Depends, HTTPException
74
from fastapi.openapi.models import OAuthFlows as OAuthFlowsModel
8-
from fastapi.responses import RedirectResponse
9-
from fastapi.security import HTTPBearer
105
from fastapi.security import OAuth2
116
from fastapi.security.utils import get_authorization_scheme_param
12-
from jose import jwt
13-
from jwt import PyJWTError
7+
from jose import jwt, JWTError
148
from starlette.requests import Request
159
from starlette.status import HTTP_403_FORBIDDEN
1610

17-
from config import CLIENT_ID, CLIENT_SECRET, redirect_url, SECRET_KEY, ALGORITHM, ACCESS_TOKEN_EXPIRE_MINUTES, \
18-
redirect_url_main_page
19-
from fastapi_sso.github import GithubSSO
20-
21-
router = APIRouter()
22-
23-
# config for GitHub SSO
24-
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
25-
26-
sso = GithubSSO(
27-
client_id=CLIENT_ID,
28-
client_secret=CLIENT_SECRET,
29-
redirect_uri=redirect_url,
30-
allow_insecure_http=True,
31-
)
32-
33-
security = HTTPBearer()
34-
35-
36-
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
37-
to_encode = data.copy()
38-
if expires_delta:
39-
expire = datetime.utcnow() + expires_delta
40-
else:
41-
expire = datetime.utcnow() + timedelta(minutes=15)
42-
to_encode.update({"exp": expire})
43-
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
44-
return encoded_jwt
11+
from .config import SECRET_KEY, ALGORITHM
4512

4613

4714
class OAuth2PasswordBearerCookie(OAuth2):
@@ -80,6 +47,8 @@ async def __call__(self, request: Request) -> Optional[str]:
8047

8148
else:
8249
authorization = False
50+
scheme = ""
51+
param = ""
8352

8453
if not authorization or scheme.lower() != "bearer":
8554
if self.auto_error:
@@ -97,49 +66,7 @@ async def __call__(self, request: Request) -> Optional[str]:
9766
async def get_current_user(token: str = Depends(oauth2_scheme)):
9867
try:
9968
return jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
100-
except PyJWTError:
69+
except JWTError:
10170
raise HTTPException(
10271
status_code=HTTP_403_FORBIDDEN, detail="Could not validate credentials"
10372
)
104-
105-
106-
@router.get("/user")
107-
def user(current_user=Depends(get_current_user)):
108-
return current_user
109-
110-
111-
@router.post("/token")
112-
def token(request: Request):
113-
return request.cookies.get("Authorization")
114-
115-
116-
@router.get("/auth/login")
117-
async def auth_init():
118-
"""Initialize auth and redirect"""
119-
return await sso.get_login_redirect()
120-
121-
122-
@router.get("/auth/callback")
123-
async def auth_callback(request: Request):
124-
"""Verify login"""
125-
user = await sso.verify_and_process(request)
126-
access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
127-
access_token = create_access_token(
128-
data=dict(user), expires_delta=access_token_expires
129-
)
130-
response = RedirectResponse(redirect_url_main_page)
131-
response.set_cookie(
132-
"Authorization",
133-
value=f"Bearer {access_token}",
134-
httponly=True,
135-
max_age=1800,
136-
expires=1800,
137-
)
138-
return response
139-
140-
141-
@router.get("/auth/logout")
142-
async def auth_logout():
143-
response = RedirectResponse(redirect_url_main_page)
144-
response.delete_cookie("Authorization")
145-
return response

demo/router.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
from datetime import timedelta
2+
3+
from fastapi import APIRouter
4+
from fastapi import Depends
5+
from fastapi.responses import RedirectResponse
6+
from starlette.requests import Request
7+
8+
from fastapi_oauth2.github import GithubSSO
9+
from .config import (
10+
CLIENT_ID,
11+
CLIENT_SECRET,
12+
redirect_url,
13+
ACCESS_TOKEN_EXPIRE_MINUTES,
14+
redirect_url_main_page,
15+
)
16+
from .dependencies import get_current_user
17+
from .utils import create_access_token
18+
19+
router = APIRouter()
20+
sso = GithubSSO(
21+
client_id=CLIENT_ID,
22+
client_secret=CLIENT_SECRET,
23+
redirect_uri=redirect_url,
24+
allow_insecure_http=True,
25+
)
26+
27+
28+
@router.get("/user")
29+
def user(current_user=Depends(get_current_user)):
30+
return current_user
31+
32+
33+
@router.post("/token")
34+
def token(request: Request):
35+
return request.cookies.get("Authorization")
36+
37+
38+
@router.get("/auth/login")
39+
async def auth_init():
40+
return await sso.get_login_redirect()
41+
42+
43+
@router.get("/auth/callback")
44+
async def auth_callback(request: Request):
45+
user = await sso.verify_and_process(request)
46+
access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
47+
access_token = create_access_token(
48+
data=dict(user), expires_delta=access_token_expires
49+
)
50+
response = RedirectResponse(redirect_url_main_page)
51+
response.set_cookie(
52+
"Authorization",
53+
value=f"Bearer {access_token}",
54+
httponly=sso.allow_insecure_http,
55+
max_age=ACCESS_TOKEN_EXPIRE_MINUTES * 60,
56+
expires=ACCESS_TOKEN_EXPIRE_MINUTES * 60,
57+
)
58+
return response
59+
60+
61+
@router.get("/auth/logout")
62+
async def auth_logout():
63+
response = RedirectResponse(redirect_url_main_page)
64+
response.delete_cookie("Authorization")
65+
return response

demo/utils.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from datetime import datetime, timedelta
2+
from typing import Optional
3+
4+
from jose import jwt
5+
6+
from .config import SECRET_KEY, ALGORITHM
7+
8+
9+
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
10+
to_encode = data.copy()
11+
if expires_delta:
12+
expire = datetime.utcnow() + expires_delta
13+
else:
14+
expire = datetime.utcnow() + timedelta(minutes=15)
15+
to_encode.update({"exp": expire})
16+
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
17+
return encoded_jwt

examples/DogeAPI/.gitignore

Lines changed: 0 additions & 130 deletions
This file was deleted.

0 commit comments

Comments
 (0)