Добавил редис
This commit is contained in:
parent
ad1fe5487c
commit
857ff4c780
3 changed files with 103 additions and 30 deletions
|
@ -1,8 +1,12 @@
|
|||
from datetime import timedelta
|
||||
from urllib.parse import urljoin
|
||||
|
||||
from pydantic import ValidationError
|
||||
|
||||
from app.chat.exceptions import UserDontHavePermissionException, UserCanNotReadThisChatException
|
||||
from app.chat.shemas import SAllowedChats, SChangeData, SPinnedChats, SChat
|
||||
from app.config import settings
|
||||
from app.services.redis_service import RedisService
|
||||
from app.services.user_service import UserService
|
||||
from app.utils.unit_of_work import UnitOfWork
|
||||
from app.users.schemas import SInvitationData
|
||||
|
@ -18,9 +22,20 @@ class ChatService:
|
|||
|
||||
@staticmethod
|
||||
async def get_all_chats(uow: UnitOfWork, user_id: int) -> SAllowedChats:
|
||||
async with uow:
|
||||
allowed_chats = await uow.user.get_user_allowed_chats(user_id=user_id)
|
||||
return allowed_chats
|
||||
try:
|
||||
async with RedisService() as redis:
|
||||
allowed_chats = await redis.get_value(key=f"user_allowed_chats: {user_id}", model=SAllowedChats)
|
||||
return allowed_chats
|
||||
except ValidationError:
|
||||
async with uow:
|
||||
allowed_chats = await uow.user.get_user_allowed_chats(user_id=user_id)
|
||||
async with RedisService() as redis:
|
||||
await redis.set_key(
|
||||
key=f"user_allowed_chats: {user_id}",
|
||||
expire_time=timedelta(minutes=30),
|
||||
value=allowed_chats.model_dump_json()
|
||||
)
|
||||
return allowed_chats
|
||||
|
||||
@staticmethod
|
||||
async def create_chat(uow: UnitOfWork, user_id: int, user_to_exclude_id: int, chat_name: str) -> int:
|
||||
|
@ -36,6 +51,8 @@ class ChatService:
|
|||
)
|
||||
await uow.chat.add_user_to_chat(user_id, chat_id)
|
||||
await uow.chat.add_user_to_chat(settings.ADMIN_USER_ID, chat_id)
|
||||
async with RedisService(is_raise=True) as redis:
|
||||
await redis.delete_key(key=f"user_allowed_chats: {user_id}")
|
||||
await uow.commit()
|
||||
return chat_id
|
||||
|
||||
|
@ -48,6 +65,8 @@ class ChatService:
|
|||
await uow.chat.change_data(
|
||||
chat_id=user_data.chat_id, chat_name=user_data.chat_name, avatar_image=user_data.avatar_image
|
||||
)
|
||||
async with RedisService(is_raise=True) as redis:
|
||||
await redis.delete_key(key=f"user_allowed_chats: {user_id}")
|
||||
await uow.commit()
|
||||
|
||||
@staticmethod
|
||||
|
@ -65,6 +84,8 @@ class ChatService:
|
|||
raise UserCanNotReadThisChatException
|
||||
async with uow:
|
||||
await uow.chat.add_user_to_chat(chat_id=invitation_data.chat_id, user_id=user_id)
|
||||
async with RedisService(is_raise=True) as redis:
|
||||
await redis.delete_key(key=f"user_allowed_chats: {user_id}")
|
||||
await uow.commit()
|
||||
|
||||
@classmethod
|
||||
|
@ -74,6 +95,8 @@ class ChatService:
|
|||
raise UserDontHavePermissionException
|
||||
async with uow:
|
||||
await uow.chat.delete_chat(chat_id)
|
||||
async with RedisService(is_raise=True) as redis:
|
||||
await redis.delete_key(key=f"user_allowed_chats: {user_id}")
|
||||
await uow.commit()
|
||||
|
||||
@classmethod
|
||||
|
@ -83,6 +106,8 @@ class ChatService:
|
|||
raise UserDontHavePermissionException
|
||||
async with uow:
|
||||
await uow.chat.delete_user_from_chat(chat_id=chat_id, user_id=user_id_for_delete)
|
||||
async with RedisService(is_raise=True) as redis:
|
||||
await redis.delete_key(key=f"user_allowed_chats: {user_id_for_delete}")
|
||||
await uow.commit()
|
||||
|
||||
@staticmethod
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
from datetime import timedelta
|
||||
|
||||
from pydantic import BaseModel
|
||||
from redis.asyncio.client import Redis
|
||||
from redis.exceptions import RedisError
|
||||
|
||||
from app.config import settings
|
||||
from app.exceptions import BlackPhoenixException
|
||||
|
||||
|
||||
def get_redis_session() -> Redis:
|
||||
|
@ -10,17 +13,26 @@ def get_redis_session() -> Redis:
|
|||
|
||||
|
||||
class RedisService:
|
||||
@staticmethod
|
||||
async def set_verification_code(redis: Redis, user_id: int, verification_code: str) -> None:
|
||||
await redis.setex(f"user_verification_code: {user_id}", timedelta(minutes=5), verification_code)
|
||||
def __init__(self, is_raise=None):
|
||||
self.redis_session_factory = get_redis_session
|
||||
self.is_raise = is_raise
|
||||
|
||||
@staticmethod
|
||||
async def get_verification_code(redis: Redis, user_id: int) -> str:
|
||||
verification_code = await redis.get(f"user_verification_code: {user_id}")
|
||||
return verification_code.decode()
|
||||
async def __aenter__(self):
|
||||
self.redis_session = self.redis_session_factory()
|
||||
return self
|
||||
|
||||
@staticmethod
|
||||
async def delete_verification_code(redis: Redis, user_id: int) -> None:
|
||||
await redis.delete(f"user_verification_code: {user_id}")
|
||||
async def __aexit__(self, exc_type, exc, tb):
|
||||
if isinstance(exc, RedisError):
|
||||
if self.is_raise:
|
||||
raise BlackPhoenixException
|
||||
return True
|
||||
|
||||
async def set_key(self, key: str, expire_time: timedelta, value: str) -> None:
|
||||
await self.redis_session.setex(key, expire_time, value)
|
||||
|
||||
async def get_value[T: type[BaseModel]](self, key: str, model: T | None = None) -> T | str:
|
||||
value = await self.redis_session.get(key)
|
||||
return model.model_validate_json(value) if model else value.decode()
|
||||
|
||||
async def delete_key(self, key: str) -> None:
|
||||
await self.redis_session.delete(key)
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
from datetime import timedelta
|
||||
|
||||
from pydantic import ValidationError
|
||||
|
||||
from app.config import settings
|
||||
from app.services.redis_service import get_redis_session, RedisService
|
||||
from app.services.redis_service import RedisService
|
||||
from app.tasks.tasks import generate_confirmation_code, send_confirmation_email, send_data_change_email
|
||||
from app.utils.unit_of_work import UnitOfWork
|
||||
from app.users.exceptions import PasswordsMismatchException, WrongCodeException
|
||||
|
@ -10,15 +14,33 @@ from app.services.auth_service import AuthService
|
|||
class UserService:
|
||||
@staticmethod
|
||||
async def find_user(uow: UnitOfWork, **find_by) -> SUser:
|
||||
async with uow:
|
||||
user = await uow.user.find_one(**find_by)
|
||||
return user
|
||||
try:
|
||||
async with RedisService() as redis:
|
||||
user = await redis.get_value(key=f"user: {find_by}", model=SUser)
|
||||
return user
|
||||
except ValidationError:
|
||||
async with uow:
|
||||
user = await uow.user.find_one(**find_by)
|
||||
async with RedisService() as redis:
|
||||
await redis.set_key(
|
||||
key=f"user: {find_by}", expire_time=timedelta(hours=1), value=user.model_dump_json()
|
||||
)
|
||||
return user
|
||||
|
||||
@staticmethod
|
||||
async def find_all(uow: UnitOfWork, username: str) -> SUsers:
|
||||
async with uow:
|
||||
users = await uow.user.find_all(username=username)
|
||||
return users
|
||||
try:
|
||||
async with RedisService() as redis:
|
||||
users = await redis.get_value(key=f"users: {username}", model=SUsers)
|
||||
return users
|
||||
except ValidationError:
|
||||
async with uow:
|
||||
users = await uow.user.find_all(username=username)
|
||||
async with RedisService() as redis:
|
||||
await redis.set_key(
|
||||
key=f"users: {username}", expire_time=timedelta(hours=1), value=users.model_dump_json()
|
||||
)
|
||||
return users
|
||||
|
||||
@staticmethod
|
||||
async def add_user(uow: UnitOfWork, user_data: SUserRegister) -> SUser:
|
||||
|
@ -39,10 +61,10 @@ class UserService:
|
|||
|
||||
@staticmethod
|
||||
async def send_confirmation_email(user: SUser, mail_type: str, email: str | None = None) -> None:
|
||||
redis_session = get_redis_session()
|
||||
user_code = generate_confirmation_code()
|
||||
await RedisService.delete_verification_code(redis=redis_session, user_id=user.id)
|
||||
await RedisService.set_verification_code(redis=redis_session, user_id=user.id, verification_code=user_code)
|
||||
async with RedisService(is_raise=True) as redis:
|
||||
await redis.delete_key(key=f"user_verification_code: {user.id}")
|
||||
await redis.set_key(key=f"user_verification_code: {user.id}", expire_time=timedelta(minutes=5), value=user_code)
|
||||
|
||||
user_mail_data = SConfirmationData.model_validate(
|
||||
{
|
||||
|
@ -57,13 +79,20 @@ class UserService:
|
|||
|
||||
@staticmethod
|
||||
async def verificate_user(uow: UnitOfWork, user: SUser, confirmation_code: str) -> None:
|
||||
redis_session = get_redis_session()
|
||||
verification_code = await RedisService.get_verification_code(redis=redis_session, user_id=user.id)
|
||||
|
||||
try:
|
||||
async with RedisService(is_raise=True) as redis:
|
||||
verification_code = await redis.get_value(key=f"user_verification_code: {user.id}")
|
||||
except AttributeError:
|
||||
raise WrongCodeException
|
||||
if verification_code != confirmation_code:
|
||||
raise WrongCodeException
|
||||
async with uow:
|
||||
await uow.user.change_data(user_id=user.id, role=settings.VERIFICATED_USER)
|
||||
async with RedisService() as redis:
|
||||
await redis.delete_key(key=f"user: {dict(id=user.id)}")
|
||||
await redis.set_key(
|
||||
key=f"user: {dict(id=user.id)}", expire_time=timedelta(hours=1), value=user.model_dump_json()
|
||||
)
|
||||
await uow.commit()
|
||||
|
||||
@staticmethod
|
||||
|
@ -74,11 +103,16 @@ class UserService:
|
|||
|
||||
@staticmethod
|
||||
async def change_data(uow: UnitOfWork, user: SUser, user_data: SUserChangeData) -> None:
|
||||
redis_session = get_redis_session()
|
||||
verification_code = await RedisService.get_verification_code(redis=redis_session, user_id=user.id)
|
||||
try:
|
||||
async with RedisService(is_raise=True) as redis:
|
||||
verification_code = await redis.get_value(key=f"user_verification_code: {user.id}")
|
||||
except AttributeError:
|
||||
raise WrongCodeException
|
||||
if verification_code != user_data.verification_code:
|
||||
raise WrongCodeException
|
||||
hashed_password = AuthService.get_password_hash(user_data.new_password) if user_data.new_password else user.hashed_password
|
||||
hashed_password = (
|
||||
AuthService.get_password_hash(user_data.new_password) if user_data.new_password else user.hashed_password
|
||||
)
|
||||
async with uow:
|
||||
await uow.user.change_data(
|
||||
user_id=user.id,
|
||||
|
@ -90,5 +124,7 @@ class UserService:
|
|||
(await uow.user.add_user_avatar(user_id=user.id, avatar=str(user_data.avatar_url))) if user_data.avatar_url else None
|
||||
await uow.commit()
|
||||
|
||||
async with RedisService() as redis:
|
||||
await redis.delete_key(key=f"user: {dict(id=user.id)}")
|
||||
|
||||
send_data_change_email.delay(user_data.username, user_data.email)
|
||||
await RedisService.delete_verification_code(redis=redis_session, user_id=user.id)
|
||||
|
|
Loading…
Add table
Reference in a new issue