Skip to content

Commit dfebc6a

Browse files
committed
Department of Logic
1 parent 8ef6266 commit dfebc6a

File tree

7 files changed

+78
-41
lines changed

7 files changed

+78
-41
lines changed

app/api/anotations.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
"""
2-
Anotations
2+
Dependencies
33
"""
44

55
from fastapi import Depends
66
from typing_extensions import Annotated
77

88
from app.core import deps
99

10-
Database = Annotated[deps.db.Database, Depends(deps.get_db)]
10+
Database = Annotated[deps.Database, Depends(deps.get_db)]
1111

1212
Security = Annotated[deps.Security, Depends(deps.get_security)]
1313

14+
Logic = Annotated[deps.Logic, Depends(deps.get_logic)]
15+
1416
CurrentUser = Annotated[deps.User, Depends(deps.get_current_user)]

app/api/endpoints/users/auth.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,15 @@
11
from fastapi import APIRouter
22

33
from app.api import anotations
4-
from app.core import exps
54
from app.models.token import AccessToken
65
from app.models.user import UserCreate
76

87
router = APIRouter(prefix='/auth')
98

109

1110
@router.post('/token/', response_model=AccessToken)
12-
async def token(
13-
data: UserCreate, db: anotations.Database, security: anotations.Security
14-
):
11+
async def token(data: UserCreate, logic: anotations.Logic):
1512
"""
1613
Retrieve new access token
1714
"""
18-
if user := await db.user.retrieve_by_email(data.email):
19-
if not security.pwd.checkpwd(data.password, user.password):
20-
raise exps.USER_IS_CORRECT
21-
access_token = security.jwt.encode_token({'id': user.id}, 1440)
22-
return AccessToken(token=access_token)
23-
24-
raise exps.USER_NOT_FOUND
15+
return await logic.users.generate_token(**data.model_dump())

app/api/endpoints/users/create.py

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,14 @@
11
from fastapi import APIRouter
22

33
from app.api import anotations
4-
from app.core import exps
5-
from app.models.user import User, UserCreate, UserRead
4+
from app.models.user import UserCreate, UserRead
65

76
router = APIRouter(prefix='/create')
87

98

109
@router.post('/', response_model=UserRead)
11-
async def registration(
12-
data: UserCreate, db: anotations.Database, security: anotations.Security
13-
):
10+
async def create(data: UserCreate, logic: anotations.Logic):
1411
"""
1512
Create user
1613
"""
17-
if await db.user.retrieve_by_email(data.email):
18-
raise exps.USER_EXISTS
19-
20-
password_hash = security.pwd.hashpwd(data.password)
21-
model = User(email=data.email, password=password_hash)
22-
user = await db.user.create(model)
23-
return user
14+
return await logic.users.create(**data.model_dump())

app/core/__init__.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
11
"""
22
Core App Module
33
"""
4-
5-
from .security import Security
6-
7-
__all__ = ['Security']

app/core/deps.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,30 @@
66
from fastapi.security import APIKeyHeader
77
from typing_extensions import Annotated, AsyncGenerator
88

9+
from app.core.db import Database, SessionLocal
10+
from app.core.logic import Logic
11+
from app.core.security import Security
912
from app.models.user import User
1013

11-
from . import Security, db, exps
1214

13-
14-
async def get_db() -> AsyncGenerator[db.Database]:
15-
async with db.SessionLocal() as session:
16-
yield db.Database(session)
15+
async def get_db() -> AsyncGenerator[Database]:
16+
async with SessionLocal() as session:
17+
yield Database(session)
1718

1819

1920
async def get_security() -> Security:
2021
return Security()
2122

2223

24+
async def get_logic(
25+
db: Annotated[Database, Depends(get_db)],
26+
security: Annotated[Security, Depends(get_security)],
27+
) -> Logic:
28+
return Logic(db, security)
29+
30+
2331
async def get_current_user(
2432
token: Annotated[str, Depends(APIKeyHeader(name='access-token'))],
25-
security: Annotated[Security, Depends(get_security)],
26-
db: Annotated[db.Database, Depends(get_db)],
33+
logic: Annotated[Logic, Depends(get_logic)],
2734
) -> User | None:
28-
if payload := security.jwt.decode_token(token):
29-
if not (user := await db.user.retrieve_one(ident=payload.get('id'))):
30-
raise exps.USER_NOT_FOUND
31-
else:
32-
return user
35+
return await logic.users.retrieve_by_token(token)

app/core/logic.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from app.core.db import Database
2+
from app.core.security import Security
3+
from app.logic.users import Users
4+
5+
6+
class Logic:
7+
def __init__(self, db: Database, security: Security):
8+
self.users = Users(db, security)
9+
10+
11+
__all__ = ['Logic']

app/logic/users.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from app.core import exps
2+
from app.core.db import Database
3+
from app.core.security import Security
4+
from app.models.token import AccessToken
5+
from app.models.user import User
6+
7+
8+
class Users:
9+
def __init__(self, db: Database, security: Security):
10+
self.db = db
11+
self.security = security
12+
13+
async def create(self, email: str, password: str) -> User | None:
14+
if await self.db.user.retrieve_by_email(email):
15+
raise exps.USER_EXISTS
16+
17+
password_hash = self.security.pwd.hashpwd(password)
18+
model = User(email=email, password=password_hash)
19+
user = await self.db.user.create(model)
20+
return user
21+
22+
async def generate_token(
23+
self, email: str, password: str
24+
) -> AccessToken | None:
25+
if user := await self.db.user.retrieve_by_email(email):
26+
if not self.security.pwd.checkpwd(password, user.password):
27+
raise exps.USER_IS_CORRECT
28+
access_token = self.security.jwt.encode_token(
29+
{'id': user.id}, 1440
30+
)
31+
return AccessToken(token=access_token)
32+
raise exps.USER_NOT_FOUND
33+
34+
async def retrieve_by_token(self, token: str) -> User | None:
35+
if payload := self.security.jwt.decode_token(token):
36+
if not (
37+
user := await self.db.user.retrieve_one(
38+
ident=payload.get('id')
39+
)
40+
):
41+
raise exps.USER_NOT_FOUND
42+
else:
43+
return user

0 commit comments

Comments
 (0)