Auth works again; relationships between Trashbox and User added

This commit is contained in:
DmitryGantimurov 2023-08-08 01:22:47 +03:00
parent d3d7760c5b
commit 832a2ce985
8 changed files with 185 additions and 43 deletions

View File

@ -77,31 +77,30 @@ def single_annoncement(user_id:int):
# Занести объявление в базу данных
@app.put("/api/announcement")#адрес объявлений
def put_in_db(name: Annotated[str, Form()], category: Annotated[str, Form()], bestBy: Annotated[datetime.date, Form()],
address: Annotated[str, Form()], longtitude: Annotated[float, Form()], latitude: Annotated[float, Form()],
description: Annotated[str, Form()], src: UploadFile, metro: Annotated[str, Form()],
trashId: Annotated[int, Form()] = None):
# try:
userId = 1 # temporary
address: Annotated[str, Form()], longtitude: Annotated[float, Form()], latitude: Annotated[float, Form()],
description: Annotated[str, Form()], metro: Annotated[str, Form()], current_user: Annotated[schemas.User, Depends(utils.get_current_active_user)],
src: Union[UploadFile, None] = None, trashId: Annotated[int, Form()] = None):
try:
uploaded_name = ""
if src:
f = src.file
f.seek(0, os.SEEK_END)
if f.tell() > 0:
f.seek(0)
destination = pathlib.Path("./uploads/" + str(hash(f)) + pathlib.Path(src.filename).suffix.lower())
with destination.open('wb') as buffer:
shutil.copyfileobj(f, buffer)
f = src.file
f.seek(0, os.SEEK_END)
if f.tell() > 0:
f.seek(0)
destination = pathlib.Path("./uploads/" + str(hash(src.file)) + pathlib.Path(src.filename).suffix.lower())
with destination.open('wb') as buffer:
shutil.copyfileobj(src.file, buffer)
uploaded_name = "/uploads/"+destination.name
uploaded_name = "/uploads/"+destination.name
temp_ancmt = models.Announcement(user_id=userId, name=name, category=category, best_by=bestBy, address=address, longtitude=longtitude, latitude=latitude, description=description, src=uploaded_name, metro=metro, trashId=trashId, booked_by=-1)
temp_ancmt = models.Announcement(user_id=current_user.id, name=name, category=category, best_by=bestBy,
address=address, longtitude=longtitude, latitude=latitude, description=description, metro=metro, trashId=trashId)
database.add(temp_ancmt) # добавляем в бд
database.commit() # сохраняем изменения
database.refresh(temp_ancmt) # обновляем состояние объекта
return {"Answer" : True}
# except:
# return {"Answer" : False}
except:
return {"Answer" : False}
# Удалить объявления из базы
@ -130,12 +129,13 @@ def change_book_status(data: schemas.Book):
# reginstration
# {"id":1, "email":"poopka@mail.ru", "password":"good", "name":"Vasya", "surname":"Poopkin"}
@app.post("/api/signup")
def create_user(data = Body()):
if database.query(models.User).filter(models.User.email == data["email"]).first() == None:
new_user = models.User(email=data["email"], hashed_password=get_password_hash(data["password"]),
name=data["name"], surname=data["surname"])
def create_user(nickname: Annotated[str, Form()], password: Annotated[str, Form()], name: Annotated[str, Form()]=None,
surname: Annotated[str, Form()]=None, avatar: Annotated[UploadFile, Form()]=None):
if database.query(models.User).filter(models.User.nickname == nickname).first() == None:
new_user = models.User(nickname=nickname, hashed_password=utils.get_password_hash(password),
name=name, surname=surname)
database.add(new_user)
database.commit()
database.refresh(new_user) # обновляем состояние объекта

View File

@ -4,21 +4,11 @@ from .db import Base, engine
from sqlalchemy.orm import relationship
# импортируем модуль для создания перечислений
import enum
# # класс, необходимый для создания перечисления
# class State(enum.Enum):
# published = 1
# taken = 2
# obsolete = 3
class User(Base):#класс пользователя
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True, unique=True)#айди пользователя
email = Column(String)#электронная почта пользователя
nickname = Column(String) # никнейм пользователя
hashed_password = Column(String)
name = Column(String, nullable=True)#имя пользователя
surname = Column(String)#фамилия пользователя
@ -28,6 +18,7 @@ class User(Base):#класс пользователя
reg_date = Column(Date) # дата регистрации
announcements = relationship("Announcement", back_populates="user")
trashboxes_chosen = relationship("Trashbox", back_populates="user")
class Announcement(Base): #класс объявления
__tablename__ = "announcements"
@ -55,11 +46,15 @@ class Trashbox(Base): #класс мусорных баков
__tablename__ = "trashboxes"
id = Column(Integer, primary_key=True, index=True)#айди
user_id = Column(Integer, ForeignKey("users.id")) # айди выбравшего мусорку
name = Column(String, nullable=True)#имя пользователя
address = Column(String)
latitude = Column(Integer)
longtitude = Column(Integer)
category = Column(String) #категория продукта из объявления
date_of_chose = Column(Date) # Дата выбора мусорки пользователем
user = relationship("User", back_populates="trashboxes_chosen")
class Poems(Base):#класс поэзии

View File

@ -2,6 +2,7 @@ from pydantic import BaseModel
from typing import Annotated, Union
from datetime import date
from typing import List
from fastapi import UploadFile, Form
class Book(BaseModel):
id: int
@ -21,16 +22,29 @@ class Announcement(BaseModel):
longtitude: float
latitude: float
description: str
# src: Union[UploadFile, None] = None #изображение продукта в объявлении
src: Union[str, None] = None #изображение продукта в объявлении
metro: str #ближайщее метро от адреса нахождения продукта
trashId: Union[int, None] = None
booked_by: int #статус бронирования (либо -1, либо айди бронирующего)
booked_by: Union[int, None] = 0 #статус бронирования (либо 0, либо айди бронирующего)
class Config:
orm_mode = True
arbitrary_types_allowed=True
class PutAnnInDB(BaseModel):
name: Annotated[str, Form()]
category: Annotated[str, Form()]
best_by: Annotated[date, Form()]
address: Annotated[str, Form()]
longtitude: Annotated[float, Form()]
latitude: Annotated[float, Form()]
description: Annotated[str, Form()]
src: Annotated[Union[UploadFile, None], Form()] = None #изображение продукта в объявлении
metro: Annotated[str, Form()] #ближайщее метро от адреса нахождения продукта
class Token(BaseModel):
access_token: str
# token_type: str
@ -42,9 +56,9 @@ class TokenData(BaseModel):
class User(BaseModel):
id: int
email: str
nickname: str
name: Union[str, None] = None
surname: str
surname: Union[str, None] = None
disabled: Union[bool, None] = False
items: list[Announcement] = []

View File

@ -17,7 +17,7 @@ SECRET_KEY = "SECRET"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/token")
def get_db():
@ -36,15 +36,22 @@ def get_password_hash(password):
return pwd_context.hash(password)
def get_user(db: Annotated[Session, Depends(get_db)], user_id: int):
def get_user_by_nickname(db: Annotated[Session, Depends(get_db)], nickname: str):
user_with_required_id = db.query(models.User).filter(models.User.nickname == nickname).first()
if user_with_required_id:
return user_with_required_id
return None
def get_user_by_id(db: Annotated[Session, Depends(get_db)], user_id: int):
user_with_required_id = db.query(models.User).filter(models.User.id == user_id).first()
if user_with_required_id:
return user_with_required_id
return None
def authenticate_user(db: Annotated[Session, Depends(get_db)], email: str, password: str):
user = get_user(user_id = user_id)
def authenticate_user(db: Annotated[Session, Depends(get_db)], nickname: str, password: str):
user = get_user_by_nickname(db=db, nickname=nickname)
if not user:
return False
if not verify_password(password, user.hashed_password):
@ -77,10 +84,10 @@ async def get_current_user(db: Annotated[Session, Depends(get_db)], token: Annot
token_data = schemas.TokenData(user_id=user_id)
except JWTError:
raise credentials_exception
user = get_user(db, user_id=token_data.user_id)
user = get_user_by_id(db, user_id=token_data.user_id)
if user is None:
raise credentials_exception
return schemas.User(id=user.id, email=user.email, name=user.name, surname=user.surname, disabled=user.disabled, items=user.items)
return schemas.User(id=user.id, nickname=user.nickname, name=user.name, surname=user.surname, disabled=user.disabled, items=user.announcements)
async def get_current_active_user(

View File

@ -0,0 +1,34 @@
"""email->nickname in User model
Revision ID: 58290a82b821
Revises: 9c19b9658512
Create Date: 2023-08-07 23:37:58.017279
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '58290a82b821'
down_revision = '9c19b9658512'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('users', schema=None) as batch_op:
batch_op.add_column(sa.Column('nickname', sa.String(), nullable=True))
batch_op.drop_column('email')
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('users', schema=None) as batch_op:
batch_op.add_column(sa.Column('email', sa.VARCHAR(), nullable=True))
batch_op.drop_column('nickname')
# ### end Alembic commands ###

View File

@ -0,0 +1,28 @@
"""created relationships between Trashbox and User
Revision ID: 96470e6327e0
Revises: b806af0cc2cb
Create Date: 2023-08-08 00:06:18.745504
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '96470e6327e0'
down_revision = 'b806af0cc2cb'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###

View File

@ -0,0 +1,28 @@
"""created relationships between Trashbox and User
Revision ID: b806af0cc2cb
Revises: 58290a82b821
Create Date: 2023-08-08 00:05:55.175838
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'b806af0cc2cb'
down_revision = '58290a82b821'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###

View File

@ -0,0 +1,36 @@
"""created relationships between Trashbox and User; (foreign key added to Trashbox table)
Revision ID: ee035dd94fbb
Revises: 96470e6327e0
Create Date: 2023-08-08 00:11:35.443724
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'ee035dd94fbb'
down_revision = '96470e6327e0'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('trashboxes', schema=None) as batch_op:
batch_op.add_column(sa.Column('user_id', sa.Integer(), nullable=True))
batch_op.add_column(sa.Column('date_of_chose', sa.Date(), nullable=True))
# batch_op.create_foreign_key(None, 'users', ['user_id'], ['id'])
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('trashboxes', schema=None) as batch_op:
# batch_op.drop_constraint(None, type_='foreignkey')
batch_op.drop_column('date_of_chose')
batch_op.drop_column('user_id')
# ### end Alembic commands ###