Skip to content

Commit 67eb9fc

Browse files
authored
Merge pull request #61 from igorbenav/logout-deleted-user
Now deleted users are logged out
2 parents f80f4ba + 3bc57c3 commit 67eb9fc

File tree

4 files changed

+25
-19
lines changed

4 files changed

+25
-19
lines changed

src/app/api/v1/logout.py

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@
44

55
from fastapi import APIRouter, Depends
66
from sqlalchemy.ext.asyncio import AsyncSession
7-
from jose import jwt, JWTError
7+
from jose import JWTError
88

9-
from app.core.security import oauth2_scheme, SECRET_KEY, ALGORITHM
9+
from app.core.security import oauth2_scheme, blacklist_token
1010
from app.core.db.database import async_get_db
11-
from app.core.db.crud_token_blacklist import crud_token_blacklist
12-
from app.core.schemas import TokenBlacklistCreate
1311
from app.core.exceptions.http_exceptions import UnauthorizedException
1412

1513
router = APIRouter(tags=["login"])
@@ -20,14 +18,7 @@ async def logout(
2018
db: AsyncSession = Depends(async_get_db)
2119
) -> Dict[str, str]:
2220
try:
23-
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
24-
expires_at = datetime.fromtimestamp(payload.get("exp"))
25-
await crud_token_blacklist.create(
26-
db,
27-
object=TokenBlacklistCreate(
28-
**{"token": token, "expires_at": expires_at}
29-
)
30-
)
21+
await blacklist_token(token=token, db=db)
3122
return {"message": "Logged out successfully"}
3223

3324
except JWTError:

src/app/api/v1/users.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Annotated, Union, Dict, Any
22

3-
from fastapi import Depends, HTTPException
3+
from fastapi import Depends
44
from sqlalchemy.ext.asyncio import AsyncSession
55
from fastapi import Request
66
import fastapi
@@ -9,7 +9,7 @@
99
from app.core.exceptions.http_exceptions import DuplicateValueException, NotFoundException, ForbiddenException
1010
from app.api.paginated import PaginatedListResponse, paginated_response, compute_offset
1111
from app.core.db.database import async_get_db
12-
from app.core.security import get_password_hash
12+
from app.core.security import get_password_hash, blacklist_token, oauth2_scheme
1313
from app.crud.crud_users import crud_users
1414
from app.crud.crud_tier import crud_tiers
1515
from app.crud.crud_rate_limit import crud_rate_limits
@@ -116,9 +116,10 @@ async def patch_user(
116116
@router.delete("/user/{username}")
117117
async def erase_user(
118118
request: Request,
119-
username: str,
119+
username: str,
120120
current_user: Annotated[UserRead, Depends(get_current_user)],
121-
db: Annotated[AsyncSession, Depends(async_get_db)]
121+
db: Annotated[AsyncSession, Depends(async_get_db)],
122+
token: str = Depends(oauth2_scheme)
122123
) -> Dict[str, str]:
123124
db_user = await crud_users.get(db=db, schema_to_select=UserRead, username=username)
124125
if not db_user:
@@ -128,20 +129,23 @@ async def erase_user(
128129
raise ForbiddenException()
129130

130131
await crud_users.delete(db=db, db_row=db_user, username=username)
132+
await blacklist_token(token=token, db=db)
131133
return {"message": "User deleted"}
132134

133135

134136
@router.delete("/db_user/{username}", dependencies=[Depends(get_current_superuser)])
135137
async def erase_db_user(
136138
request: Request,
137139
username: str,
138-
db: Annotated[AsyncSession, Depends(async_get_db)]
140+
db: Annotated[AsyncSession, Depends(async_get_db)],
141+
token: str = Depends(oauth2_scheme)
139142
) -> Dict[str, str]:
140143
db_user = await crud_users.exists(db=db, username=username)
141144
if not db_user:
142145
raise NotFoundException("User not found")
143146

144147
db_user = await crud_users.db_delete(db=db, username=username)
148+
await blacklist_token(token=token, db=db)
145149
return {"message": "User deleted from the database"}
146150

147151

src/app/core/security.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from fastapi.security import OAuth2PasswordBearer
88

99
from app.core.config import settings
10-
from app.core.schemas import TokenData
10+
from app.core.schemas import TokenData, TokenBlacklistCreate
1111
from app.core.db.crud_token_blacklist import crud_token_blacklist
1212
from app.crud.crud_users import crud_users
1313

@@ -79,3 +79,13 @@ async def verify_token(token: str, db: AsyncSession) -> TokenData | None:
7979

8080
except JWTError:
8181
return None
82+
83+
async def blacklist_token(token: str, db: AsyncSession) -> None:
84+
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
85+
expires_at = datetime.fromtimestamp(payload.get("exp"))
86+
await crud_token_blacklist.create(
87+
db,
88+
object=TokenBlacklistCreate(
89+
**{"token": token, "expires_at": expires_at}
90+
)
91+
)

src/app/crud/crud_base.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,9 @@ async def get(
9090
result: Row = db_row.first()
9191
if result is not None:
9292
out: dict = dict(result._mapping)
93+
return out
9394

94-
return out
95+
return None
9596

9697
async def exists(
9798
self,

0 commit comments

Comments
 (0)