Skip to content

Commit

Permalink
Update logging configuration and user authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
AndPuQing committed Jan 28, 2024
1 parent 4267c59 commit aef0ff3
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 230 deletions.
13 changes: 9 additions & 4 deletions backend/app/app/core/security.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from datetime import datetime, timedelta
from typing import Any, Union
from typing import Any, Optional, Union

from jose import jwt
from passlib.context import CryptContext
Expand All @@ -13,16 +13,21 @@


def create_access_token(
subject: Union[str, Any], expires_delta: timedelta = None
subject: Union[str, Any],
expires_delta: Optional[timedelta] = None,
) -> str:
if expires_delta:
expire = datetime.utcnow() + expires_delta
else:
expire = datetime.utcnow() + timedelta(
minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES
minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES,
)
to_encode = {"exp": expire, "sub": str(subject)}
encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=ALGORITHM)
encoded_jwt = jwt.encode(
to_encode,
settings.SECRET_KEY,
algorithm=ALGORITHM,
)
return encoded_jwt


Expand Down
61 changes: 0 additions & 61 deletions backend/app/app/crud/base.py

This file was deleted.

50 changes: 0 additions & 50 deletions backend/app/app/crud/crud_item.py

This file was deleted.

62 changes: 0 additions & 62 deletions backend/app/app/crud/crud_user.py

This file was deleted.

3 changes: 1 addition & 2 deletions backend/app/app/db/init_db.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from sqlmodel import Session, select

from app.core.config import settings
from app.crud.crud_user import user as crud
from app.models import User, UserCreate # noqa: F401

# make sure all SQLModel models are imported (app.models) before initializing DB
Expand All @@ -23,4 +22,4 @@ def init_db(session: Session) -> None:
password=settings.FIRST_SUPERUSER_PASSWORD,
is_superuser=True,
)
user = crud.create(db=session, obj_in=user_in)
user = User.create(session, user_in)
3 changes: 3 additions & 0 deletions backend/app/app/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ def configure_logging() -> None: # pragma: no cover

logging.getLogger("gunicorn").handlers = [intercept_handler]
logging.getLogger("gunicorn.access").handlers = [intercept_handler]

logging.getLogger("passlib").setLevel(logging.ERROR)

# set logs output, level and format
logger.remove()
logger.add(
Expand Down
44 changes: 41 additions & 3 deletions backend/app/app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from sqlalchemy.orm.exc import FlushError
from sqlmodel import JSON, AutoString, Column, Field, SQLModel, select

from app.core.security import get_password_hash, verify_password


class ActiveRecordMixin:
__config__ = None
Expand Down Expand Up @@ -87,11 +89,10 @@ def create(
update: Optional[dict] = None,
) -> Optional[SQLModel]:
obj = cls.convert_without_saving(source, update)
if obj is None:
return None
if obj.save(session):
return obj
return None
else:
return None

@classmethod
def create_or_update(
Expand Down Expand Up @@ -195,6 +196,43 @@ class User(ActiveRecordMixin, UserBase, table=True):
id: Union[int, None] = Field(default=None, primary_key=True)
hashed_password: str

@classmethod
def authenticate(
cls, session, *, email: str, password: str
) -> Optional["User"]:
user = User.one_by_field(session, "email", email)
if not user:
return None
if not verify_password(password, user.hashed_password):
return None
return user

@classmethod
def create(
cls,
session,
source: Union[UserCreate, UserCreateOpen],
) -> Optional[SQLModel]:
obj = User(
**source.model_dump(exclude={"password"}, exclude_unset=True),
hashed_password=get_password_hash(source.password),
)
if obj.save(session):
return obj
else:
return None

def update(self, session, source: Union[dict, SQLModel]):
if isinstance(source, SQLModel):
source = source.model_dump(exclude_unset=True)

if "password" in source:
source["hashed_password"] = get_password_hash(source["password"])
del source["password"]
for key, value in source.items():
setattr(self, key, value)
self.save(session)


# Properties to return via API, id is always required
class UserOut(UserBase):
Expand Down
23 changes: 11 additions & 12 deletions backend/app/app/web/api/endpoints/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from fastapi import APIRouter, HTTPException
from sqlmodel import select

from app.crud.crud_item import item as crud
from app.models import Item, ItemCreate, ItemOut, ItemUpdate
from app.web.api.deps import CurrentUser, SessionDep

Expand All @@ -28,7 +27,7 @@ def read_item(session: SessionDep, id: int) -> Any:
"""
Get item by ID.
"""
item = session.get(Item, id)
item = Item.one_by_id(session, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
return item
Expand All @@ -39,16 +38,17 @@ def read_item_fuzzy(session: SessionDep, title: str) -> Any:
"""
Get item by fuzzy title.
"""
statement = crud.get_by_fuzzy_title(session, title=title)
return statement
pass


@router.post("/", response_model=ItemOut)
def create_item(*, session: SessionDep, item_in: ItemCreate) -> Any:
"""
Create new item.
"""
item = crud.create(session, obj_in=item_in)
item = Item.create(session, source=item_in)
if not item:
raise HTTPException(status_code=400, detail="Item not created")
return item


Expand All @@ -57,8 +57,7 @@ def create_items(*, session: SessionDep, items_in: list[ItemCreate]) -> Any:
"""
Create new items.
"""
items = crud.create_bulk(session, objs_in=items_in)
return items
pass


@router.put("/{id}", response_model=ItemOut)
Expand All @@ -74,10 +73,10 @@ def update_item(
"""
if not current_user.is_superuser:
raise HTTPException(status_code=400, detail="Not enough permissions")
item = crud.get(session, id=id)
item: Item = Item.one_by_id(session, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
item = crud.update(session, db_obj=item, obj_in=item_in)
item.update(session, item_in)
return item


Expand All @@ -86,14 +85,14 @@ def delete_item(
session: SessionDep,
current_user: CurrentUser,
id: int,
) -> ItemOut:
) -> Any:
"""
Delete an item.
"""
item = crud.get(session, id=id)
item: Item = Item.one_by_id(session, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not current_user.is_superuser:
raise HTTPException(status_code=400, detail="Not enough permissions")
item = crud.remove(session, id=id)
item.delete(session)
return item
Loading

0 comments on commit aef0ff3

Please sign in to comment.