Skip to content
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

Перенести эндпойнт создания аккаунта к эндпойнтам аккаунта (#158) #159

Merged
merged 1 commit into from
Dec 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions src/auth/controllers.py → src/account/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,16 @@

from typing import TYPE_CHECKING

from src.account import schemas as account_schemas
from src.account import schemas
from src.account.models import Account, PasswordHash
from src.auth import schemas
from src.profile import schemas as profile_schemas
from src.profile.models import Profile


if TYPE_CHECKING:
from sqlalchemy.ext.asyncio import AsyncSession

from src.auth.schemas import NewAccountWithProfile
from src.account.schemas import NewAccountWithProfile


async def create_account(request_data: NewAccountWithProfile, session: AsyncSession) -> schemas.AccountWithProfile:
Expand All @@ -23,6 +22,6 @@ async def create_account(request_data: NewAccountWithProfile, session: AsyncSess
profile = await Profile.create(session, request_data.profile, account_id=account.id)
await PasswordHash.create(session, request_data.account.password, account_id=account.id)
return schemas.AccountWithProfile(
account=account_schemas.Account.from_orm(account),
account=schemas.Account.from_orm(account),
profile=profile_schemas.Profile.from_orm(profile),
)
10 changes: 9 additions & 1 deletion src/account/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from __future__ import annotations

from src.shared.fields import StrField
from src.shared.fields import SecretStrField, StrField


class Email(StrField):
Expand All @@ -21,3 +21,11 @@ class Login(StrField):
LENGTH_MAX = 50
LENGTH_MIN = 1
REGEXP = r"[A-Za-z0-9\-_]*"


class Password(SecretStrField):
"""Password value field."""

FIELD_NAME = "Password"
LENGTH_MIN = 8
LENGTH_MAX = 500
4 changes: 2 additions & 2 deletions src/account/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
if TYPE_CHECKING:
from sqlalchemy.ext.asyncio import AsyncSession

from src.auth.fields import Password
from src.auth.schemas import NewAccount
from src.account.fields import Password
from src.account.schemas import NewAccount


class Account(Base): # pylint: disable=too-few-public-methods
Expand Down
57 changes: 56 additions & 1 deletion src/account/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,71 @@

from fastapi import APIRouter, Body, Depends, Path, status
from fastapi.security import HTTPAuthorizationCredentials
from sqlalchemy.ext.asyncio import AsyncSession

from src.account import schemas
from src.account import controllers, schemas
from src.account.fields import Login
from src.auth.security import get_token
from src.shared import swagger as shared_swagger
from src.shared.database import get_session


router = APIRouter(tags=["account"])


@router.post(
"/accounts",
description="Sign Up - create a new account with profile.",
responses={
status.HTTP_201_CREATED: {
"description": "New account and profile are created.",
"content": {
"application/json": {
"example": {
"account": {
"id": 42,
"email": "john.doe@mail.com",
"login": "john_doe",
"created_at": "2023-06-17T11:47:02.823Z",
},
"profile": {
"account_id": 42,
"avatar_id": None,
"description": "Who da heck is John Doe?",
"name": "John Doe",
},
},
},
},
},
},
response_model=schemas.AccountWithProfile,
status_code=status.HTTP_201_CREATED,
summary="Sign Up - create a new account.",
)
async def create_account(
new_account: Annotated[
schemas.NewAccountWithProfile,
Body(
example={
"account": {
"email": "john.doe@mail.com",
"login": "john_doe",
"password": "qwerty123",
},
"profile": {
"name": "John Doe",
"description": "Who da heck is John Doe?",
},
},
),
],
session: AsyncSession = Depends(get_session),
) -> schemas.AccountWithProfile:
"""Create a new account with profile."""
return await controllers.create_account(new_account, session)


@router.get(
"/accounts/logins/{account_login}/id",
description="Get Account Id by login. Account Id is available for every logged in user.",
Expand Down
25 changes: 24 additions & 1 deletion src/account/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,19 @@

from pydantic import PositiveInt

from src.account.fields import Email, Login
from src.account.fields import Email, Login, Password
from src.profile.schemas import NewProfile, Profile
from src.shared.schemas import Schema


class NewAccount(Schema):
"""Account data which is going to be created during sign up process."""

email: Email
login: Login
password: Password


class Account(Schema):
"""Existing account model."""

Expand All @@ -25,6 +34,20 @@ class Config:
orm_mode = True


class NewAccountWithProfile(Schema):
"""Account and corresponding profile data which are going to be created during sign up process."""

account: NewAccount
profile: NewProfile


class AccountWithProfile(Schema):
"""Account and corresponding profile which have been created during sign up process."""

account: Account
profile: Profile


class AccountId(Schema):
"""Account Id."""

Expand Down
13 changes: 0 additions & 13 deletions src/auth/fields.py

This file was deleted.

57 changes: 1 addition & 56 deletions src/auth/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,70 +8,15 @@
from fastapi import APIRouter, Body, Depends, Path, status
from fastapi.security import HTTPAuthorizationCredentials
from pydantic import PositiveInt
from sqlalchemy.ext.asyncio import AsyncSession

from src.auth import controllers, schemas
from src.auth import schemas
from src.auth.security import get_token
from src.shared import swagger as shared_swagger
from src.shared.database import get_session


router = APIRouter(tags=["auth"])


@router.post(
"/accounts",
description="Sign Up - create a new account with profile.",
responses={
status.HTTP_201_CREATED: {
"description": "New account and profile are created.",
"content": {
"application/json": {
"example": {
"account": {
"id": 42,
"email": "john.doe@mail.com",
"login": "john_doe",
"created_at": "2023-06-17T11:47:02.823Z",
},
"profile": {
"account_id": 42,
"avatar_id": None,
"description": "Who da heck is John Doe?",
"name": "John Doe",
},
},
},
},
},
},
response_model=schemas.AccountWithProfile,
status_code=status.HTTP_201_CREATED,
summary="Sign Up - create a new account.",
)
async def create_account(
new_account: Annotated[
schemas.NewAccountWithProfile,
Body(
example={
"account": {
"email": "john.doe@mail.com",
"login": "john_doe",
"password": "qwerty123",
},
"profile": {
"name": "John Doe",
"description": "Who da heck is John Doe?",
},
},
),
],
session: AsyncSession = Depends(get_session),
) -> schemas.AccountWithProfile:
"""Create a new account with profile."""
return await controllers.create_account(new_account, session)


@router.post(
"/accounts/{account_id}/tokens",
description="Sign In - exchange account credentials to Access and Refresh tokens.",
Expand Down
35 changes: 1 addition & 34 deletions src/auth/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,46 +7,13 @@

from pydantic import root_validator

from src.account.fields import Email, Login
from src.account.schemas import Account
from src.auth.fields import Password
from src.profile.fields import Description, Name
from src.profile.schemas import Profile
from src.account.fields import Email, Login, Password
from src.shared.schemas import Schema


DictT = TypeVar("DictT", bound=dict[str, Any])


class NewAccount(Schema):
"""Account data which is going to be created during sign up process."""

email: Email
login: Login
password: Password


class NewProfile(Schema):
"""Profile data for an account which is going to be created during sign up process."""

name: Name
description: Description | None


class NewAccountWithProfile(Schema):
"""Account and corresponding profile data which are going to be created during sign up process."""

account: NewAccount
profile: NewProfile


class AccountWithProfile(Schema):
"""Account and corresponding profile which have been created during sign up process."""

account: Account
profile: Profile


class Credentials(Schema):
"""Account credentials for sign in process. Can be a pair of password and email or password and login."""

Expand Down
2 changes: 1 addition & 1 deletion src/profile/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
if TYPE_CHECKING:
from sqlalchemy.ext.asyncio import AsyncSession

from src.auth.schemas import NewProfile
from src.profile.schemas import NewProfile


class Profile(Base): # pylint: disable=too-few-public-methods
Expand Down
7 changes: 7 additions & 0 deletions src/profile/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
from src.shared.schemas import Schema


class NewProfile(Schema):
"""Profile data for an account which is going to be created during sign up process."""

name: Name
description: Description | None


class Profile(Schema):
"""Account profile."""

Expand Down
File renamed without changes.
File renamed without changes.