You've already forked RekomenciBackend
feat(): yandex sign up interactor
This commit is contained in:
@@ -13,6 +13,7 @@ AuthIdentityId = NewType("AuthIdentityId", UUID)
|
||||
|
||||
class AuthMethod(StrEnum):
|
||||
EMAIL = "email"
|
||||
YANDEX = "yandex"
|
||||
|
||||
|
||||
@to_entity
|
||||
|
||||
@@ -12,3 +12,13 @@ class UserAlreadyExistsError(ApplicationError):
|
||||
@override
|
||||
def __str__(self) -> str:
|
||||
return f"User with identifier={self.identifier!r} and auth method={self.auth_method.value} already exists"
|
||||
|
||||
|
||||
@to_error
|
||||
class AuthError(ApplicationError):
|
||||
pass
|
||||
|
||||
|
||||
@to_error
|
||||
class InvalidCodeError(ApplicationError):
|
||||
pass
|
||||
|
||||
@@ -2,10 +2,15 @@ from template_project.application.access_token.cryptographer import AccessTokenC
|
||||
from template_project.application.access_token.entity_factory import AccessTokenFactory
|
||||
from template_project.application.auth_identity.data_gateway import AuthIdentityDataGateway
|
||||
from template_project.application.auth_identity.entity import AuthIdentity, AuthMethod
|
||||
from template_project.application.auth_identity.errors import UserAlreadyExistsError
|
||||
from template_project.application.auth_identity.errors import AuthError, InvalidCodeError, UserAlreadyExistsError
|
||||
from template_project.application.common.containers import SecretString
|
||||
from template_project.application.common.data_structure import to_data_structure
|
||||
from template_project.application.common.interactor import to_interactor
|
||||
from template_project.application.common.oauth.yandex import (
|
||||
OAuthClient as YandexOAuthClient,
|
||||
OAuthExchangeCodeError,
|
||||
OAuthLoadUserInfoError,
|
||||
)
|
||||
from template_project.application.common.unit_of_work import UnitOfWork
|
||||
from template_project.application.user.entity import User, UserId
|
||||
from template_project.application.user.password_utils import PasswordHasher
|
||||
@@ -24,18 +29,19 @@ class AuthIdentityInteractor:
|
||||
auth_identity_data_gateway: AuthIdentityDataGateway
|
||||
access_token_factory: AccessTokenFactory
|
||||
access_token_cryptographer: AccessTokenCryptographer
|
||||
yandex_oauth_client: YandexOAuthClient
|
||||
|
||||
async def sign_up_email(
|
||||
self,
|
||||
email: str,
|
||||
password: SecretString,
|
||||
) -> UserSignUpResponse:
|
||||
existing_user = await self.auth_identity_data_gateway.load_by_method_and_identifier(
|
||||
existing_auth_identity = await self.auth_identity_data_gateway.load_by_method_and_identifier(
|
||||
method=AuthMethod.EMAIL,
|
||||
identifier=email,
|
||||
)
|
||||
|
||||
if existing_user:
|
||||
if existing_auth_identity:
|
||||
raise UserAlreadyExistsError(identifier=email, auth_method=AuthMethod.EMAIL)
|
||||
|
||||
hashed_password = self.password_hasher.hash(password)
|
||||
@@ -61,3 +67,47 @@ class AuthIdentityInteractor:
|
||||
await self.unit_of_work.commit()
|
||||
|
||||
return UserSignUpResponse(user_id=user.id, access_token=crypted_access_token)
|
||||
|
||||
async def sign_up_yandex(self, code: str) -> UserSignUpResponse:
|
||||
try:
|
||||
token_response = await self.yandex_oauth_client.exchange_code(code)
|
||||
access_token_yandex = token_response.access_token
|
||||
|
||||
except OAuthExchangeCodeError as error:
|
||||
raise InvalidCodeError from error
|
||||
|
||||
try:
|
||||
user_info = await self.yandex_oauth_client.load_user_info(access_token_yandex)
|
||||
|
||||
except OAuthLoadUserInfoError as error:
|
||||
raise AuthError from error
|
||||
|
||||
existing_auth_identity = await self.auth_identity_data_gateway.load_by_method_and_identifier(
|
||||
method=AuthMethod.YANDEX,
|
||||
identifier=user_info.user_id,
|
||||
)
|
||||
|
||||
if existing_auth_identity:
|
||||
user_id = existing_auth_identity.user_id
|
||||
|
||||
else:
|
||||
user = User.factory()
|
||||
user_id = user.id
|
||||
|
||||
auth_identity = AuthIdentity.factory(
|
||||
user_id=user_id,
|
||||
method=AuthMethod.YANDEX,
|
||||
identifier=user_info.user_id,
|
||||
secret_key=None,
|
||||
)
|
||||
|
||||
await self.unit_of_work.add(user)
|
||||
await self.unit_of_work.add(auth_identity)
|
||||
|
||||
access_token = self.access_token_factory.execute(user_id)
|
||||
crypted_access_token = self.access_token_cryptographer.crypto(access_token.id)
|
||||
|
||||
await self.unit_of_work.add(access_token)
|
||||
await self.unit_of_work.commit()
|
||||
|
||||
return UserSignUpResponse(user_id=user_id, access_token=crypted_access_token)
|
||||
|
||||
Reference in New Issue
Block a user