Skip to content

Commit 6c77e46

Browse files
committed
fix: no need to pass refresh token for validation ,only access_token
chore: bump supabase_py_async to 2.5.0
1 parent 421572d commit 6c77e46

13 files changed

Lines changed: 60 additions & 64 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,4 @@ dmypy.json
7878
.pyre/
7979
.pytype/
8080
cython_debug/
81+
/.idea

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,8 @@ ___
143143
- [ ] supafunc integration
144144
- [x] deployment
145145
- [x] Full **Docker** integration (Docker based).
146-
146+
- [ ] clone
147+
- [ ] cookiecutter
147148
## Release Notes 🥸
148149

149150
___

poetry.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/api/api_v1/endpoints/items.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from fastapi import APIRouter
22

3-
from app.api.deps import SessionDep
3+
from app.api.deps import CurrentUser, SessionDep
44
from app.crud import item
55
from app.schemas import Item, ItemCreate, ItemUpdate
66

@@ -23,8 +23,8 @@ async def read_item_by_id(id: str, session: SessionDep) -> Item | None:
2323

2424

2525
@router.get("/get-by-owner")
26-
async def read_item_by_owner(session: SessionDep) -> list[Item]:
27-
return await item.get_multi_by_owner(session)
26+
async def read_item_by_owner(session: SessionDep, user: CurrentUser) -> list[Item]:
27+
return await item.get_multi_by_owner(session, user=user)
2828

2929

3030
@router.put("/update-item")

src/app/api/deps.py

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,51 +8,66 @@
88
import logging
99
from typing import Annotated
1010

11-
from fastapi import Cookie, Depends, HTTPException
11+
from fastapi import Depends, HTTPException
1212
from fastapi.security import OAuth2PasswordBearer
13-
from gotrue import User
1413
from gotrue.errors import AuthApiError
1514
from supabase_py_async import AsyncClient, create_client
1615
from supabase_py_async.lib.client_options import ClientOptions
1716

1817
from app.core.config import settings
19-
from app.schemas import Token
18+
from app.schemas.auth import UserIn
19+
20+
super_client: AsyncClient | None = None
21+
22+
23+
async def init_super_client() -> None:
24+
"""for validation access_token init at life span event"""
25+
global super_client
26+
super_client = await create_client(
27+
settings.SUPABASE_URL,
28+
settings.SUPABASE_KEY,
29+
options=ClientOptions(postgrest_client_timeout=10, storage_client_timeout=10),
30+
)
31+
# await super_client.auth.sign_in_with_password(
32+
# {"email": settings.SUPERUSER_EMAIL, "password": settings.SUPERUSER_PASSWORD}
33+
# )
34+
2035

2136
# auto get access_token from header
2237
reusable_oauth2 = OAuth2PasswordBearer(
2338
tokenUrl="please login by supabase-js to get token"
2439
)
2540
AccessTokenDep = Annotated[str, Depends(reusable_oauth2)]
26-
RefreshTokenDep = Annotated[str | None, Cookie()]
2741

2842

29-
async def get_token(
30-
access_token: AccessTokenDep, refresh_token: RefreshTokenDep
31-
) -> Token | None:
32-
if not access_token:
33-
raise HTTPException(status_code=401, detail="No access token")
34-
if not refresh_token:
35-
raise HTTPException(status_code=401, detail="No refresh token")
36-
return Token(access_token=access_token, refresh_token=refresh_token)
43+
async def get_current_user(access_token: AccessTokenDep) -> UserIn:
44+
"""get current user from access_token and validate same time"""
45+
if not super_client:
46+
raise HTTPException(status_code=500, detail="Super client not initialized")
47+
48+
user_rsp = await super_client.auth.get_user(jwt=access_token)
49+
if not user_rsp:
50+
logging.error("User not found")
51+
raise HTTPException(status_code=404, detail="User not found")
52+
return UserIn(**user_rsp.user.model_dump(), access_token=access_token)
3753

3854

39-
TokenDep = Annotated[Token | None, Depends(get_token)]
55+
CurrentUser = Annotated[UserIn, Depends(get_current_user)]
4056

4157

42-
async def get_db(token: TokenDep) -> AsyncClient:
58+
async def get_db(user: CurrentUser) -> AsyncClient:
4359
client: AsyncClient | None = None
4460
try:
4561
client = await create_client(
4662
settings.SUPABASE_URL,
4763
settings.SUPABASE_KEY,
64+
access_token=user.access_token,
4865
options=ClientOptions(
4966
postgrest_client_timeout=10, storage_client_timeout=10
5067
),
5168
)
5269
# checks all done in supabase-py !
53-
if not token:
54-
raise HTTPException(status_code=401, detail="Invalid authentication")
55-
await client.auth.set_session(token.access_token, token.refresh_token)
70+
# await client.auth.set_session(token.access_token, token.refresh_token)
5671
# session = await client.auth.get_session()
5772
yield client
5873

@@ -67,14 +82,3 @@ async def get_db(token: TokenDep) -> AsyncClient:
6782

6883

6984
SessionDep = Annotated[AsyncClient, Depends(get_db)]
70-
71-
72-
async def get_current_user(session: SessionDep) -> User:
73-
user = await session.auth.get_user()
74-
if not user:
75-
logging.error("User not found")
76-
raise HTTPException(status_code=404, detail="User not found")
77-
return user
78-
79-
80-
CurrentUser = Annotated[User, Depends(get_current_user)]

src/app/core/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +0,0 @@
1-
from .config import logger
2-
from .events import lifespan

src/app/core/events.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@
77

88
from fastapi import FastAPI
99

10+
from app.api.deps import init_super_client
11+
1012

1113
@asynccontextmanager
1214
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
1315
"""life span events"""
1416
try:
17+
await init_super_client()
1518
yield
1619
finally:
1720
logging.info("lifespan shutdown")

src/app/crud/base.py

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

33
from supabase_py_async import AsyncClient
44

5+
from app.schemas.auth import UserIn
56
from app.schemas.base import CreateBase, ResponseBase, UpdateBase
67

78
ModelType = TypeVar("ModelType", bound=ResponseBase)
@@ -27,14 +28,14 @@ async def get_all(self, db: AsyncClient) -> list[ModelType]:
2728
_, got = data
2829
return [self.model(**item) for item in got]
2930

30-
async def get_multi_by_owner(self, db: AsyncClient) -> list[ModelType]:
31+
async def get_multi_by_owner(
32+
self, db: AsyncClient, *, user: UserIn
33+
) -> list[ModelType]:
3134
"""get by owner,use it if rls failed to use"""
32-
user_rps = await db.auth.get_user()
33-
user_id = user_rps.user.id
3435
data, count = (
3536
await db.table(self.model.table_name)
3637
.select("*")
37-
.eq("user_id", user_id)
38+
.eq("user_id", user.id)
3839
.execute()
3940
)
4041
_, got = data

src/app/crud/crud_item.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from app.crud.base import CRUDBase
44
from app.schemas import Item, ItemCreate, ItemUpdate
5+
from app.schemas.auth import UserIn
56

67

78
class CRUDItem(CRUDBase[Item, ItemCreate, ItemUpdate]):
@@ -14,8 +15,8 @@ async def get(self, db: AsyncClient, *, id: str) -> Item | None:
1415
async def get_all(self, db: AsyncClient) -> list[Item]:
1516
return await super().get_all(db)
1617

17-
async def get_multi_by_owner(self, db: AsyncClient) -> list[Item]:
18-
return await super().get_multi_by_owner(db)
18+
async def get_multi_by_owner(self, db: AsyncClient, *, user: UserIn) -> list[Item]:
19+
return await super().get_multi_by_owner(db, user=user)
1920

2021
async def update(self, db: AsyncClient, *, obj_in: ItemUpdate) -> Item:
2122
return await super().update(db, obj_in=obj_in)

src/app/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
from fastapi.middleware.cors import CORSMiddleware
1111

1212
from app.api.api_v1.api import api_router
13-
from app.core import lifespan
1413
from app.core.config import settings
14+
from app.core.events import lifespan
1515

1616

1717
def create_app() -> FastAPI:

0 commit comments

Comments
 (0)