diff --git a/poetry.lock b/poetry.lock index 848e248b..3fdfe282 100644 --- a/poetry.lock +++ b/poetry.lock @@ -283,38 +283,32 @@ files = [ [[package]] name = "bcrypt" -version = "4.1.2" +version = "4.0.1" description = "Modern password hashing for your software and your servers" optional = false -python-versions = ">=3.7" +python-versions = ">=3.6" files = [ - {file = "bcrypt-4.1.2-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:ac621c093edb28200728a9cca214d7e838529e557027ef0581685909acd28b5e"}, - {file = "bcrypt-4.1.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea505c97a5c465ab8c3ba75c0805a102ce526695cd6818c6de3b1a38f6f60da1"}, - {file = "bcrypt-4.1.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57fa9442758da926ed33a91644649d3e340a71e2d0a5a8de064fb621fd5a3326"}, - {file = "bcrypt-4.1.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:eb3bd3321517916696233b5e0c67fd7d6281f0ef48e66812db35fc963a422a1c"}, - {file = "bcrypt-4.1.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6cad43d8c63f34b26aef462b6f5e44fdcf9860b723d2453b5d391258c4c8e966"}, - {file = "bcrypt-4.1.2-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:44290ccc827d3a24604f2c8bcd00d0da349e336e6503656cb8192133e27335e2"}, - {file = "bcrypt-4.1.2-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:732b3920a08eacf12f93e6b04ea276c489f1c8fb49344f564cca2adb663b3e4c"}, - {file = "bcrypt-4.1.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1c28973decf4e0e69cee78c68e30a523be441972c826703bb93099868a8ff5b5"}, - {file = "bcrypt-4.1.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b8df79979c5bae07f1db22dcc49cc5bccf08a0380ca5c6f391cbb5790355c0b0"}, - {file = "bcrypt-4.1.2-cp37-abi3-win32.whl", hash = "sha256:fbe188b878313d01b7718390f31528be4010fed1faa798c5a1d0469c9c48c369"}, - {file = "bcrypt-4.1.2-cp37-abi3-win_amd64.whl", hash = "sha256:9800ae5bd5077b13725e2e3934aa3c9c37e49d3ea3d06318010aa40f54c63551"}, - {file = "bcrypt-4.1.2-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:71b8be82bc46cedd61a9f4ccb6c1a493211d031415a34adde3669ee1b0afbb63"}, - {file = "bcrypt-4.1.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e3c6642077b0c8092580c819c1684161262b2e30c4f45deb000c38947bf483"}, - {file = "bcrypt-4.1.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:387e7e1af9a4dd636b9505a465032f2f5cb8e61ba1120e79a0e1cd0b512f3dfc"}, - {file = "bcrypt-4.1.2-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f70d9c61f9c4ca7d57f3bfe88a5ccf62546ffbadf3681bb1e268d9d2e41c91a7"}, - {file = "bcrypt-4.1.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2a298db2a8ab20056120b45e86c00a0a5eb50ec4075b6142db35f593b97cb3fb"}, - {file = "bcrypt-4.1.2-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:ba55e40de38a24e2d78d34c2d36d6e864f93e0d79d0b6ce915e4335aa81d01b1"}, - {file = "bcrypt-4.1.2-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:3566a88234e8de2ccae31968127b0ecccbb4cddb629da744165db72b58d88ca4"}, - {file = "bcrypt-4.1.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b90e216dc36864ae7132cb151ffe95155a37a14e0de3a8f64b49655dd959ff9c"}, - {file = "bcrypt-4.1.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:69057b9fc5093ea1ab00dd24ede891f3e5e65bee040395fb1e66ee196f9c9b4a"}, - {file = "bcrypt-4.1.2-cp39-abi3-win32.whl", hash = "sha256:02d9ef8915f72dd6daaef40e0baeef8a017ce624369f09754baf32bb32dba25f"}, - {file = "bcrypt-4.1.2-cp39-abi3-win_amd64.whl", hash = "sha256:be3ab1071662f6065899fe08428e45c16aa36e28bc42921c4901a191fda6ee42"}, - {file = "bcrypt-4.1.2-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d75fc8cd0ba23f97bae88a6ec04e9e5351ff3c6ad06f38fe32ba50cbd0d11946"}, - {file = "bcrypt-4.1.2-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:a97e07e83e3262599434816f631cc4c7ca2aa8e9c072c1b1a7fec2ae809a1d2d"}, - {file = "bcrypt-4.1.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:e51c42750b7585cee7892c2614be0d14107fad9581d1738d954a262556dd1aab"}, - {file = "bcrypt-4.1.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:ba4e4cc26610581a6329b3937e02d319f5ad4b85b074846bf4fef8a8cf51e7bb"}, - {file = "bcrypt-4.1.2.tar.gz", hash = "sha256:33313a1200a3ae90b75587ceac502b048b840fc69e7f7a0905b5f87fac7a1258"}, + {file = "bcrypt-4.0.1-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:b1023030aec778185a6c16cf70f359cbb6e0c289fd564a7cfa29e727a1c38f8f"}, + {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:08d2947c490093a11416df18043c27abe3921558d2c03e2076ccb28a116cb6d0"}, + {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0eaa47d4661c326bfc9d08d16debbc4edf78778e6aaba29c1bc7ce67214d4410"}, + {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae88eca3024bb34bb3430f964beab71226e761f51b912de5133470b649d82344"}, + {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:a522427293d77e1c29e303fc282e2d71864579527a04ddcfda6d4f8396c6c36a"}, + {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:fbdaec13c5105f0c4e5c52614d04f0bca5f5af007910daa8b6b12095edaa67b3"}, + {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:ca3204d00d3cb2dfed07f2d74a25f12fc12f73e606fcaa6975d1f7ae69cacbb2"}, + {file = "bcrypt-4.0.1-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:089098effa1bc35dc055366740a067a2fc76987e8ec75349eb9484061c54f535"}, + {file = "bcrypt-4.0.1-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:e9a51bbfe7e9802b5f3508687758b564069ba937748ad7b9e890086290d2f79e"}, + {file = "bcrypt-4.0.1-cp36-abi3-win32.whl", hash = "sha256:2caffdae059e06ac23fce178d31b4a702f2a3264c20bfb5ff541b338194d8fab"}, + {file = "bcrypt-4.0.1-cp36-abi3-win_amd64.whl", hash = "sha256:8a68f4341daf7522fe8d73874de8906f3a339048ba406be6ddc1b3ccb16fc0d9"}, + {file = "bcrypt-4.0.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf4fa8b2ca74381bb5442c089350f09a3f17797829d958fad058d6e44d9eb83c"}, + {file = "bcrypt-4.0.1-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:67a97e1c405b24f19d08890e7ae0c4f7ce1e56a712a016746c8b2d7732d65d4b"}, + {file = "bcrypt-4.0.1-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b3b85202d95dd568efcb35b53936c5e3b3600c7cdcc6115ba461df3a8e89f38d"}, + {file = "bcrypt-4.0.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbb03eec97496166b704ed663a53680ab57c5084b2fc98ef23291987b525cb7d"}, + {file = "bcrypt-4.0.1-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:5ad4d32a28b80c5fa6671ccfb43676e8c1cc232887759d1cd7b6f56ea4355215"}, + {file = "bcrypt-4.0.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b57adba8a1444faf784394de3436233728a1ecaeb6e07e8c22c8848f179b893c"}, + {file = "bcrypt-4.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:705b2cea8a9ed3d55b4491887ceadb0106acf7c6387699fca771af56b1cdeeda"}, + {file = "bcrypt-4.0.1-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:2b3ac11cf45161628f1f3733263e63194f22664bf4d0c0f3ab34099c02134665"}, + {file = "bcrypt-4.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3100851841186c25f127731b9fa11909ab7b1df6fc4b9f8353f4f1fd952fbf71"}, + {file = "bcrypt-4.0.1.tar.gz", hash = "sha256:27d375903ac8261cfe4047f6709d16f7d18d39b1ec92aaf72af989552a650ebd"}, ] [package.extras] @@ -6395,4 +6389,4 @@ chroma = ["chromadb"] [metadata] lock-version = "2.0" python-versions = ">=3.11,<3.12" -content-hash = "305eb6301c5ad6fae8ca068bf5c4e121c06a342043320f8f2154761df242d904" +content-hash = "acc455dd6fb59b86b5d3cc26a8d040074370f897f4694edbbe144ef4bc06e18c" diff --git a/private_gpt/server/ingest/ingest_router.py b/private_gpt/server/ingest/ingest_router.py index 875b680f..2aad8d72 100644 --- a/private_gpt/server/ingest/ingest_router.py +++ b/private_gpt/server/ingest/ingest_router.py @@ -1,3 +1,4 @@ +import os import logging from pathlib import Path from typing import Literal, Optional @@ -150,6 +151,11 @@ def delete_file( for doc_id in doc_ids: service.delete(doc_id) + try: + upload_path = Path(f"{UPLOAD_DIR}/{filename}") + os.remove(upload_path) + except: + print("Unable to delete file from the static directory") document = crud.documents.get_by_filename(db,file_name=filename) if document: crud.documents.remove(db=db, id=document.id) diff --git a/private_gpt/users/api/v1/routers/auth.py b/private_gpt/users/api/v1/routers/auth.py index e334e992..7d9326c5 100644 --- a/private_gpt/users/api/v1/routers/auth.py +++ b/private_gpt/users/api/v1/routers/auth.py @@ -14,6 +14,7 @@ from private_gpt.users import crud, models, schemas from private_gpt.users.utils import send_registration_email, Ldap LDAP_SERVER = settings.LDAP_SERVER +LDAP_ENABLE = True router = APIRouter(prefix="/auth", tags=["auth"]) @@ -38,6 +39,15 @@ def register_user( return crud.user.create(db, obj_in=user_in) +def ldap_login(db, username, password): + ldap = Ldap(LDAP_SERVER, username, password) + print("LDAP LOGIN:: ", ldap.who_am_i()) + if not ldap: + raise HTTPException( + status_code=400, detail="Incorrect email or password" + ) + return ldap.who_am_i() + def create_user_role( db: Session, user: models.User, @@ -64,6 +74,27 @@ def create_token_payload(user: models.User, user_role: models.UserRole) -> dict: "company_id": user_role.company.id if user_role.company else None, } +def ad_user_register( + db: Session, + email: str, + fullname: str, + password: str, + +) -> models.User: + """ + Register a new user in the database. + """ + user_in = schemas.UserCreate(email=email, password=password, fullname=fullname, company_id=1) + print("user is: ", user_in) + user = crud.user.create(db, obj_in=user_in) + print("AD user created......................................................................") + user_role_name = Role.GUEST["name"] + company = crud.company.get(db, 1) + + user_role = create_user_role(db, user, user_role_name, company) + print("AD user role created----------------------------------------------------------------") + return user + @router.post("/login", response_model=schemas.TokenSchema) def login_access_token( @@ -73,6 +104,18 @@ def login_access_token( """ OAuth2 compatible token login, get an access token for future requests """ + if LDAP_ENABLE: + existing_user = crud.user.get_by_email(db, email=form_data.username) + + if existing_user: + if existing_user.user_role.role.name == "SUPER_ADMIN": + pass + else: + ldap = ldap_login(db=db, username=form_data.username, password=form_data.password) + else: + ldap = ldap_login(db=db, username=form_data.username, password=form_data.password) + ad_user_register(db=db, email=form_data.username,fullname=ldap, password=form_data.password) + user = crud.user.authenticate( db, email=form_data.username, password=form_data.password ) @@ -80,13 +123,6 @@ def login_access_token( raise HTTPException( status_code=400, detail="Incorrect email or password" ) - - ldap = Ldap(LDAP_SERVER, form_data.username, form_data.password) - print("LDAP LOGIN:: ", ldap.who_am_i()) - if not ldap: - raise HTTPException( - status_code=400, detail="Incorrect email or password" - ) access_token_expires = timedelta( minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES ) @@ -168,6 +204,7 @@ def register( """ Register new user with optional company assignment and role selection. """ + existing_user = crud.user.get_by_email(db, email=email) if existing_user: raise HTTPException( @@ -176,28 +213,35 @@ def register( ) random_password = security.generate_random_password() - if company_id: - # Registering user with a specific company - company = crud.company.get(db, company_id) - if not company: - raise HTTPException( - status_code=404, - detail="Company not found.", - ) - user = register_user(db, email, fullname, random_password, company) - user_role_name = role_name or Role.GUEST["name"] - user_role = create_user_role(db, user, user_role_name, company) - - else: - user = register_user(db, email, fullname, random_password, None) - user_role_name = role_name or Role.ADMIN["name"] - user_role = create_user_role(db, user, user_role_name, None) + try: + if company_id: + # Registering user with a specific company + company = crud.company.get(db, company_id) + if not company: + raise HTTPException( + status_code=404, + detail="Company not found.", + ) + user = register_user(db, email, fullname, random_password, company) + user_role_name = role_name or Role.GUEST["name"] + user_role = create_user_role(db, user, user_role_name, company) + else: + user = register_user(db, email, fullname, random_password, None) + user_role_name = role_name or Role.ADMIN["name"] + user_role = create_user_role(db, user, user_role_name, None) + except Exception as e: + raise HTTPException( + status_code=500, + detail="Unable to create account.", + ) token_payload = create_token_payload(user, user_role) response_dict = { "access_token": security.create_access_token(token_payload, expires_delta=timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)), "refresh_token": security.create_refresh_token(token_payload, expires_delta=timedelta(minutes=settings.REFRESH_TOKEN_EXPIRE_MINUTES)), "token_type": "bearer", + "password": random_password, } - + print("RESPONSE DICT: ", response_dict) return JSONResponse(content=response_dict, status_code=status.HTTP_201_CREATED) + diff --git a/private_gpt/users/utils/utils.py b/private_gpt/users/utils/utils.py index fd9cfb38..fdbe7893 100644 --- a/private_gpt/users/utils/utils.py +++ b/private_gpt/users/utils/utils.py @@ -2,7 +2,7 @@ import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from private_gpt.users.core.config import settings - +from fastapi import HTTPException def send_registration_email(fullname: str, email: str, random_password: str) -> None: """ @@ -29,16 +29,21 @@ def send_registration_email(fullname: str, email: str, random_password: str) -> """ msg = MIMEMultipart() - msg.attach(MIMEText(body, "plain")) + msg.attach(MIMEText(body, "html")) msg["Subject"] = subject msg["From"] = settings.SMTP_SENDER_EMAIL msg["To"] = email print(settings.SMTP_SERVER) print(settings.SMTP_PORT) - - with smtplib.SMTP(settings.SMTP_SERVER, settings.SMTP_PORT) as server: - server.starttls() - server.login(settings.SMTP_USERNAME, settings.SMTP_PASSWORD) - server.sendmail(settings.SMTP_SENDER_EMAIL, email, msg.as_string()) - + + try: + with smtplib.SMTP(settings.SMTP_SERVER, settings.SMTP_PORT) as server: + server.starttls() + server.login(settings.SMTP_USERNAME, settings.SMTP_PASSWORD) + server.sendmail(settings.SMTP_SENDER_EMAIL, email, msg.as_string()) + except Exception as e: + raise HTTPException( + status_code=500, + detail=f"Unable to send email." + ) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 58d35576..147151dd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,7 +19,7 @@ chromadb = {version = "^0.4.13", optional = true} inflect = "^7.0.0" alembic = "^1.13.1" sqlalchemy = "^2.0.25" -bcrypt = "^4.1.2" +bcrypt = "4.0.1" python-jose = "^3.3.0" psycopg2-binary = "^2.9.9" passlib = "^1.7.4"