Bug fixes for uploading docx file

This commit is contained in:
Saurab-Shrestha 2024-02-07 17:00:34 +05:45
parent 2fe78b4b5f
commit 616deec440
11 changed files with 1881 additions and 1764 deletions

13
.env
View File

@ -4,7 +4,7 @@ ENVIRONMENT=dev
DB_HOST=localhost DB_HOST=localhost
DB_USER=postgres DB_USER=postgres
DB_PORT=5432 DB_PORT=5432
DB_PASSWORD=admin DB_PASSWORD=quick
DB_NAME=QuickGpt DB_NAME=QuickGpt
SUPER_ADMIN_EMAIL=superadmin@email.com SUPER_ADMIN_EMAIL=superadmin@email.com
@ -15,9 +15,8 @@ SECRET_KEY=ba9dc3f976cf8fb40519dcd152a8d7d21c0b7861d841711cdb2602be8e85fd7c
ACCESS_TOKEN_EXPIRE_MINUTES=60 ACCESS_TOKEN_EXPIRE_MINUTES=60
REFRESH_TOKEN_EXPIRE_MINUTES = 120 # 7 days REFRESH_TOKEN_EXPIRE_MINUTES = 120 # 7 days
SMTP_SERVER=smtp.gmail.com
SMTP_SERVER=mail.gibl.com.np SMTP_PORT=587
SMTP_PORT=25 SMTP_SENDER_EMAIL=shresthasaurab030@outlook.com
SMTP_SENDER_EMAIL=noreply@gibl.com.np SMTP_USERNAME=shresthasaurab030
SMTP_USERNAME=noreply@gibl.com.np SMTP_PASSWORD=huurxwxeorxjorzw
SMTP_PASSWORD=*G15y^N0reP!y

3539
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -5,10 +5,11 @@ import uvicorn
from private_gpt.main import app from private_gpt.main import app
from private_gpt.settings.settings import settings from private_gpt.settings.settings import settings
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from private_gpt.constants import UPLOAD_DIR
# Set log_config=None to do not use the uvicorn logging configuration, and # Set log_config=None to do not use the uvicorn logging configuration, and
# use ours instead. For reference, see below: # use ours instead. For reference, see below:
# https://github.com/tiangolo/fastapi/discussions/7457#discussioncomment-5141108 # https://github.com/tiangolo/fastapi/discussions/7457#discussioncomment-5141108
app.mount("/static", StaticFiles(directory=r"C:\Users\Dbuser\QuickGPT\backend\privateGPT\private_gpt\static"), name="static") app.mount("/static", StaticFiles(directory=UPLOAD_DIR), name="static")
uvicorn.run(app, host="0.0.0.0", port=settings().server.port, log_config=None) uvicorn.run(app, host="0.0.0.0", port=settings().server.port, log_config=None)

View File

@ -2,4 +2,5 @@ import os
from pathlib import Path from pathlib import Path
PROJECT_ROOT_PATH: Path = Path(__file__).parents[1] PROJECT_ROOT_PATH: Path = Path(__file__).parents[1]
UPLOAD_DIR = r"C:\Users\Dbuser\QuickGPT\backend\privateGPT\private_gpt\static" script_dir = os.path.dirname(os.path.abspath(__file__))
UPLOAD_DIR = os.path.join(script_dir, "static")

View File

@ -28,7 +28,12 @@ def register_user(
""" """
print(f"{email} {fullname} {password} {company.id}") print(f"{email} {fullname} {password} {company.id}")
user_in = schemas.UserCreate(email=email, password=password, fullname=fullname, company_id=company.id) user_in = schemas.UserCreate(email=email, password=password, fullname=fullname, company_id=company.id)
try:
send_registration_email(fullname, email, password) send_registration_email(fullname, email, password)
except Exception as e:
print(f"Failed to send registration email: {str(e)}")
raise HTTPException(
status_code=500, detail=f"Failed to send registration email.")
return crud.user.create(db, obj_in=user_in) return crud.user.create(db, obj_in=user_in)
@ -159,7 +164,7 @@ def register(
if existing_user: if existing_user:
raise HTTPException( raise HTTPException(
status_code=409, status_code=409,
detail="The user with this email already exists in the system", detail="The user with this email already exists!",
) )
random_password = security.generate_random_password() random_password = security.generate_random_password()
@ -174,7 +179,7 @@ def register(
if current_user.user_role.role.name not in {Role.SUPER_ADMIN["name"], Role.ADMIN["name"]}: if current_user.user_role.role.name not in {Role.SUPER_ADMIN["name"], Role.ADMIN["name"]}:
raise HTTPException( raise HTTPException(
status_code=403, status_code=403,
detail="You do not have permission to register users for a specific company.", detail="You do not have permission to register users!",
) )
user = register_user(db, email, fullname, random_password, company) user = register_user(db, email, fullname, random_password, company)
user_role_name = role_name or Role.GUEST["name"] user_role_name = role_name or Role.GUEST["name"]

View File

@ -31,9 +31,9 @@ def read_users(
return users return users
@router.get("/company/{company_name}", response_model=List[schemas.User]) @router.get("/company/{company_id}", response_model=List[schemas.User])
def read_users_by_company( def read_users_by_company(
company_name: Optional[str] = Path(..., title="Company Name", company_id: int = Path(..., title="Company ID",
description="Only for company admin"), description="Only for company admin"),
db: Session = Depends(deps.get_db), db: Session = Depends(deps.get_db),
current_user: models.User = Security( current_user: models.User = Security(
@ -42,12 +42,12 @@ def read_users_by_company(
), ),
): ):
"""Retrieve all users of that company only""" """Retrieve all users of that company only"""
company = crud.company.get_by_company_name(db, company_name=company_name) company = crud.company.get(db, company_id)
if company is None: if company is None:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, status_code=status.HTTP_404_NOT_FOUND,
detail=f"Company with name '{company_name}' not found", detail=f"Company with ID '{company_id}' not found",
) )
users = crud.user.get_multi_by_company_id(db, company_id=company.id) users = crud.user.get_multi_by_company_id(db, company_id=company.id)
@ -262,11 +262,11 @@ def admin_change_password(
) )
@router.delete("/{user_id}") @router.post("/delete")
def delete_user( def delete_user(
*, *,
db: Session = Depends(deps.get_db), db: Session = Depends(deps.get_db),
user_id: int, delete_user: schemas.DeleteUser,
current_user: models.User = Security( current_user: models.User = Security(
deps.get_current_user, deps.get_current_user,
scopes=[Role.ADMIN["name"], Role.SUPER_ADMIN["name"]], scopes=[Role.ADMIN["name"], Role.SUPER_ADMIN["name"]],
@ -275,6 +275,7 @@ def delete_user(
""" """
Delete a user by ID. Delete a user by ID.
""" """
user_id = delete_user.id
user = crud.user.get(db, id=user_id) user = crud.user.get(db, id=user_id)
if user is None: if user is None:
raise HTTPException(status_code=404, detail="User not found") raise HTTPException(status_code=404, detail="User not found")
@ -283,3 +284,4 @@ def delete_user(
status_code=status.HTTP_200_OK, status_code=status.HTTP_200_OK,
content={"message": "User deleted successfully"}, content={"message": "User deleted successfully"},
) )

View File

@ -3,9 +3,11 @@ from typing import Any, Dict, List, Optional, Union
from private_gpt.users.core.security import get_password_hash, verify_password from private_gpt.users.core.security import get_password_hash, verify_password
from private_gpt.users.crud.base import CRUDBase from private_gpt.users.crud.base import CRUDBase
from private_gpt.users.models.user import User from private_gpt.users.models.user import User
from private_gpt.users.schemas.user import UserCreate, UserUpdate from private_gpt.users.schemas.user import UserCreate, UserUpdate, AdminUpdate
from private_gpt.users.models.user_role import UserRole
from private_gpt.users.models.role import Role
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlalchemy.orm import joinedload
class CRUDUser(CRUDBase[User, UserCreate, UserUpdate]): class CRUDUser(CRUDBase[User, UserCreate, UserUpdate]):
def get_by_email(self, db: Session, *, email: str) -> Optional[User]: def get_by_email(self, db: Session, *, email: str) -> Optional[User]:
@ -27,7 +29,7 @@ class CRUDUser(CRUDBase[User, UserCreate, UserUpdate]):
db: Session, db: Session,
*, *,
db_obj: User, db_obj: User,
obj_in: Union[UserUpdate, Dict[str, Any]], obj_in: Union[AdminUpdate, Dict[str, Any]],
) -> User: ) -> User:
if isinstance(obj_in, dict): if isinstance(obj_in, dict):
update_data = obj_in update_data = obj_in
@ -73,15 +75,19 @@ class CRUDUser(CRUDBase[User, UserCreate, UserUpdate]):
.all() .all()
) )
def get_multi_by_company_id( def get_multi_by_company_id(
self, db: Session, *, company_id: str, skip: int = 0, limit: int = 100 self, db: Session, *, company_id: str, skip: int = 0, limit: int = 100
) -> List[User]: ) -> List[User]:
return ( return (
db.query(self.model) db.query(self.model)
.filter(User.company_id == company_id) .join(User.user_role)
.filter(UserRole.company_id == company_id)
.options(joinedload(User.user_role).joinedload(UserRole.role))
.offset(skip) .offset(skip)
.limit(limit) .limit(limit)
.all() .all()
) )
user = CRUDUser(User) user = CRUDUser(User)

View File

@ -17,4 +17,9 @@ class CRUDUserRole(CRUDBase[UserRole, UserRoleCreate, UserRoleUpdate]):
)-> Optional[UserRole]: )-> Optional[UserRole]:
return db.query(UserRole).filter(UserRole.user_id == user_id).delete() return db.query(UserRole).filter(UserRole.user_id == user_id).delete()
# def update_user_role(
# self, db: Session, *, user_id: int, role_id: int
# ) -> Optional[UserRole]:
# return self.update(db, )
user_role = CRUDUserRole(UserRole) user_role = CRUDUserRole(UserRole)

View File

@ -1,6 +1,6 @@
from .role import Role, RoleCreate, RoleInDB, RoleUpdate from .role import Role, RoleCreate, RoleInDB, RoleUpdate
from .token import TokenSchema, TokenPayload from .token import TokenSchema, TokenPayload
from .user import User, UserCreate, UserInDB, UserUpdate, UserBaseSchema, Profile, UsernameUpdate from .user import User, UserCreate, UserInDB, UserUpdate, UserBaseSchema, Profile, UsernameUpdate, DeleteUser, AdminUpdate
from .user_role import UserRole, UserRoleCreate, UserRoleInDB, UserRoleUpdate from .user_role import UserRole, UserRoleCreate, UserRoleInDB, UserRoleUpdate
from .subscription import Subscription, SubscriptionBase, SubscriptionCreate, SubscriptionUpdate from .subscription import Subscription, SubscriptionBase, SubscriptionCreate, SubscriptionUpdate
from .company import Company, CompanyBase, CompanyCreate, CompanyUpdate from .company import Company, CompanyBase, CompanyCreate, CompanyUpdate

View File

@ -54,3 +54,10 @@ class UserInDB(UserSchema):
class Profile(UserBaseSchema): class Profile(UserBaseSchema):
role: str role: str
class DeleteUser(BaseModel):
id: int
class AdminUpdate(BaseModel):
fullname: str
role: int

View File

@ -9,12 +9,24 @@ def send_registration_email(fullname: str, email: str, random_password: str) ->
Send a registration email with a random password. Send a registration email with a random password.
""" """
subject = "Welcome to QuickGPT - Registration Successful" subject = "Welcome to QuickGPT - Registration Successful"
body = f"Hello {fullname},\n\nThank you for registering with QuickGPT!\n\n"\ body = f"""
f"Your temporary password is: {random_password}\n"\ <html>
f"Please login to the QuickGPT: http://quickgpt.gibl.com.np\n"\ <body>
f"Please use this password to log in and consider changing it"\ <p>Hello {fullname},</p>
" to a more secure one after logging in.\n\n"\
"Best regards,\nQuickGPT Team" <p>Thank you for registering with QuickGPT!</p>
<p>Your temporary password is: <strong>{random_password}</strong></p>
<p>Please log in to QuickGPT <a href="http://quickgpt.gibl.com.np">here</a>.</p>
<p>Please use this password to log in and consider changing it to a more secure one after logging in.</p>
<p>Best regards,<br>
QuickGPT Team</p>
</body>
</html>
"""
msg = MIMEMultipart() msg = MIMEMultipart()
msg.attach(MIMEText(body, "plain")) msg.attach(MIMEText(body, "plain"))
@ -26,7 +38,7 @@ def send_registration_email(fullname: str, email: str, random_password: str) ->
print(settings.SMTP_PORT) print(settings.SMTP_PORT)
with smtplib.SMTP(settings.SMTP_SERVER, settings.SMTP_PORT) as server: with smtplib.SMTP(settings.SMTP_SERVER, settings.SMTP_PORT) as server:
# server.starttls() server.starttls()
# server.login(settings.SMTP_USERNAME, settings.SMTP_PASSWORD) server.login(settings.SMTP_USERNAME, settings.SMTP_PASSWORD)
server.sendmail(settings.SMTP_SENDER_EMAIL, email, msg.as_string()) server.sendmail(settings.SMTP_SENDER_EMAIL, email, msg.as_string())