-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(terminate_all_session): Terminate all user sessions #35
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
from typing import Annotated | ||
|
||
from aioredis import Redis, from_url | ||
AlexanderZharyuk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
from pydantic import UUID4 | ||
from fastapi import Depends | ||
|
||
from src.db.storages import BaseStorage | ||
from src.core.config import settings | ||
|
||
|
||
class RedisBlacklistUserSignatureStorage(BaseStorage): | ||
|
||
def __init__(self) -> None: | ||
self.protocol: Redis = from_url(settings.redis_dsn, decode_responses=True) | ||
self.namespace: str = "auth_service" | ||
|
||
async def create(self, user_id: UUID4, signature: str): | ||
signature_key = f"{self.namespace}:{user_id}" | ||
async with self.protocol.client() as conn: | ||
await conn.set(signature_key, signature) | ||
|
||
async def get(self, user_id: UUID4) -> str: | ||
signature_key = f"{self.namespace}:{user_id}" | ||
async with self.protocol.client() as conn: | ||
return await conn.get(signature_key) | ||
|
||
async def delete(self, user_id: UUID4): | ||
signature_key = f"{self.namespace}:{user_id}" | ||
async with self.protocol.client() as conn: | ||
return await conn.delete(signature_key) | ||
|
||
async def delete_all(self, user_id: UUID4, count_size: int = 10) -> int: | ||
pattern = f"{self.namespace}:{user_id}:*" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. возможно я не понимаю как клиент редиса работает, но если мы создаем только пары ключ-значение вида f"{self.namespace}:{user_id}": signature то зачем нам такой паттерн поиска
|
||
cursor = b"0" | ||
deleted_count = 0 | ||
|
||
async with self.protocol.client() as conn: | ||
while cursor: | ||
cursor, keys = await conn.scan(cursor, match=pattern, count=count_size) | ||
deleted_count += await conn.unlink(*keys) | ||
return deleted_count | ||
|
||
|
||
redis_blackist_storage = RedisBlacklistUserSignatureStorage() | ||
BlacklistSignatureStorage = Annotated[ | ||
RedisBlacklistUserSignatureStorage, Depends(redis_blackist_storage) | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,8 @@ | ||
from fastapi import APIRouter, Depends, Request, Response, status | ||
from fastapi.security import APIKeyCookie | ||
|
||
from src.db.postgres import DatabaseSession | ||
from src.db.postgres import RefreshTokensStorage | ||
from src.db.postgres import DatabaseSession, RefreshTokensStorage | ||
from src.db.redis import BlacklistSignatureStorage | ||
from src.v1.auth.schemas import (TokensResponse, UserCreate, UserLogin, | ||
UserResponse, LogoutResponse, UserLogout) | ||
from src.v1.auth.service import AuthService | ||
|
@@ -54,3 +54,25 @@ async def logout( | |
) | ||
return LogoutResponse() | ||
|
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. заметил что в logout методе есть access_token из кук, но он никуда дальше не передается |
||
@router.post( | ||
"/logout_all", | ||
summary="Выход из всех сессий пользователя", | ||
response_model=LogoutResponse | ||
) | ||
async def terminate_all_sessions( | ||
db_session: DatabaseSession, | ||
blacklist_signatures_storage: BlacklistSignatureStorage, | ||
refresh_token_storage: RefreshTokensStorage, | ||
response: Response, | ||
access_token: str | None = Depends(cookie_scheme) | ||
) -> TokensResponse: | ||
"""Выход из всех сессий пользователя""" | ||
await AuthService.terminate_all_sessions( | ||
db_session, | ||
blacklist_signatures_storage, | ||
refresh_token_storage, | ||
response, | ||
access_token | ||
) | ||
return LogoutResponse() | ||
AlexanderZharyuk marked this conversation as resolved.
Show resolved
Hide resolved
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Тут лучше оставить имя контейнера по умолчанию
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
имхо, когда будем собирать докер - это может усложнить работу, лучше 'redis'
то же самое с postgres, но я могу это поправить в ветке с докером