diff --git a/.env b/.env index 5429ab6c..fd07742b 100644 --- a/.env +++ b/.env @@ -4,7 +4,7 @@ ENVIRONMENT=dev DB_HOST=localhost DB_USER=postgres DB_PORT=5432 -DB_PASSWORD=quick +DB_PASSWORD=admin DB_NAME=QuickGpt SUPER_ADMIN_EMAIL=superadmin@email.com @@ -19,4 +19,6 @@ SMTP_SERVER=smtp.gmail.com SMTP_PORT=587 SMTP_SENDER_EMAIL=shresthasaurab030@outlook.com SMTP_USERNAME=shresthasaurab030 -SMTP_PASSWORD=huurxwxeorxjorzw \ No newline at end of file +SMTP_PASSWORD=huurxwxeorxjorzw + +LDAP_SERVER=ldap://192.168.101.111 \ No newline at end of file diff --git a/alembic/versions/0ef554491192_updated_documents_primary_key.py b/alembic/versions/0ef554491192_updated_documents_primary_key.py deleted file mode 100644 index d0614e10..00000000 --- a/alembic/versions/0ef554491192_updated_documents_primary_key.py +++ /dev/null @@ -1,32 +0,0 @@ -"""Updated documents primary key - -Revision ID: 0ef554491192 -Revises: 9ce6871961b5 -Create Date: 2024-02-08 17:06:32.957163 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision: str = '0ef554491192' -down_revision: Union[str, None] = '9ce6871961b5' -branch_labels: Union[str, Sequence[str], None] = None -depends_on: Union[str, Sequence[str], None] = None - - -def upgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.create_index(op.f('ix_document_id'), 'document', ['id'], unique=False) - # op.create_unique_constraint('unique_user_role', 'user_roles', ['user_id', 'role_id', 'company_id']) - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - # op.drop_constraint('unique_user_role', 'user_roles', type_='unique') - op.drop_index(op.f('ix_document_id'), table_name='document') - # ### end Alembic commands ### diff --git a/alembic/versions/488f28da0939_remove_company_from_the_users_table.py b/alembic/versions/488f28da0939_remove_company_from_the_users_table.py deleted file mode 100644 index 811d8dfd..00000000 --- a/alembic/versions/488f28da0939_remove_company_from_the_users_table.py +++ /dev/null @@ -1,36 +0,0 @@ -"""Remove company from the users table - -Revision ID: 488f28da0939 -Revises: 0ef554491192 -Create Date: 2024-02-09 19:08:12.002449 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision: str = '488f28da0939' -down_revision: Union[str, None] = '0ef554491192' -branch_labels: Union[str, Sequence[str], None] = None -depends_on: Union[str, Sequence[str], None] = None - - -def upgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.create_unique_constraint(None, 'document', ['filename']) - # op.create_unique_constraint('unique_user_role', 'user_roles', ['user_id', 'role_id', 'company_id']) - op.drop_constraint('users_company_id_fkey', 'users', type_='foreignkey') - op.drop_column('users', 'company_id') - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.add_column('users', sa.Column('company_id', sa.INTEGER(), autoincrement=False, nullable=True)) - op.create_foreign_key('users_company_id_fkey', 'users', 'companies', ['company_id'], ['id']) - # op.drop_constraint('unique_user_role', 'user_roles', type_='unique') - op.drop_constraint(None, 'document', type_='unique') - # ### end Alembic commands ### diff --git a/alembic/versions/9ce6871961b5_create_document_model.py b/alembic/versions/a5839618494c_create_document.py similarity index 68% rename from alembic/versions/9ce6871961b5_create_document_model.py rename to alembic/versions/a5839618494c_create_document.py index ab8ed48a..c5193d77 100644 --- a/alembic/versions/9ce6871961b5_create_document_model.py +++ b/alembic/versions/a5839618494c_create_document.py @@ -1,8 +1,8 @@ -"""Create document model +"""Create document -Revision ID: 9ce6871961b5 +Revision ID: a5839618494c Revises: -Create Date: 2024-02-08 16:16:31.072913 +Create Date: 2024-02-11 12:35:13.347853 """ from typing import Sequence, Union @@ -12,7 +12,7 @@ import sqlalchemy as sa # revision identifiers, used by Alembic. -revision: str = '9ce6871961b5' +revision: str = 'a5839618494c' down_revision: Union[str, None] = None branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None @@ -21,13 +21,15 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### op.create_table('document', - sa.Column('id', sa.Integer(), autoincrement=True, nullable=False), + sa.Column('id', sa.Integer(), nullable=False), sa.Column('filename', sa.String(length=225), nullable=False), sa.Column('uploaded_by', sa.Integer(), nullable=False), - sa.Column('uploaded_at', sa.DateTime(), nullable=True), + sa.Column('uploaded_at', sa.DateTime(), nullable=False), sa.ForeignKeyConstraint(['uploaded_by'], ['users.id'], ), - sa.PrimaryKeyConstraint('id', 'uploaded_by') + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('filename') ) + op.create_index(op.f('ix_document_id'), 'document', ['id'], unique=False) # op.create_unique_constraint('unique_user_role', 'user_roles', ['user_id', 'role_id', 'company_id']) # ### end Alembic commands ### @@ -35,5 +37,6 @@ def upgrade() -> None: def downgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### # op.drop_constraint('unique_user_role', 'user_roles', type_='unique') + op.drop_index(op.f('ix_document_id'), table_name='document') op.drop_table('document') # ### end Alembic commands ### diff --git a/alembic/versions/ce0f3c4dd625_company_column_users_table.py b/alembic/versions/ce0f3c4dd625_company_column_users_table.py deleted file mode 100644 index 1dc0cc97..00000000 --- a/alembic/versions/ce0f3c4dd625_company_column_users_table.py +++ /dev/null @@ -1,34 +0,0 @@ -"""Company column users table - -Revision ID: ce0f3c4dd625 -Revises: 488f28da0939 -Create Date: 2024-02-09 19:35:09.546805 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision: str = 'ce0f3c4dd625' -down_revision: Union[str, None] = '488f28da0939' -branch_labels: Union[str, Sequence[str], None] = None -depends_on: Union[str, Sequence[str], None] = None - - -def upgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - # op.create_unique_constraint('unique_user_role', 'user_roles', ['user_id', 'role_id', 'company_id']) - op.add_column('users', sa.Column('company_id', sa.Integer(), nullable=True)) - op.create_foreign_key(None, 'users', 'companies', ['company_id'], ['id']) - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.drop_constraint(None, 'users', type_='foreignkey') - op.drop_column('users', 'company_id') - # op.drop_constraint('unique_user_role', 'user_roles', type_='unique') - # ### end Alembic commands ### diff --git a/private_gpt/users/api/v1/routers/auth.py b/private_gpt/users/api/v1/routers/auth.py index b1ad79d4..e334e992 100644 --- a/private_gpt/users/api/v1/routers/auth.py +++ b/private_gpt/users/api/v1/routers/auth.py @@ -11,8 +11,9 @@ from private_gpt.users.core import security from private_gpt.users.constants.role import Role from private_gpt.users.core.config import settings from private_gpt.users import crud, models, schemas -from private_gpt.users.utils import send_registration_email +from private_gpt.users.utils import send_registration_email, Ldap +LDAP_SERVER = settings.LDAP_SERVER router = APIRouter(prefix="/auth", tags=["auth"]) @@ -79,6 +80,13 @@ 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 ) @@ -97,7 +105,7 @@ def login_access_token( if user.user_role.company_id: company_id = user.user_role.company_id else: company_id = None - + token_payload = { "id": str(user.id), "email": str(user.email), diff --git a/private_gpt/users/core/config.py b/private_gpt/users/core/config.py index 39eb981a..ebf21b46 100644 --- a/private_gpt/users/core/config.py +++ b/private_gpt/users/core/config.py @@ -8,7 +8,7 @@ SQLALCHEMY_DATABASE_URI = "postgresql+psycopg2://{username}:{password}@{host}:{p port='5432', db_name='QuickGpt', username='postgres', - password="quick", + password="admin", ) class Settings(BaseSettings): @@ -37,6 +37,7 @@ class Settings(BaseSettings): SMTP_USERNAME: str SMTP_PASSWORD: str + LDAP_SERVER: str @property def SQLALCHEMY_DATABASE_URI(self) -> str: return f"postgresql+psycopg2://{self.DB_USER}:{self.DB_PASSWORD}@{self.DB_HOST}:{self.DB_PORT}/{self.DB_NAME}" diff --git a/private_gpt/users/crud/user_crud.py b/private_gpt/users/crud/user_crud.py index 950d5a4e..8b08ee41 100644 --- a/private_gpt/users/crud/user_crud.py +++ b/private_gpt/users/crud/user_crud.py @@ -13,7 +13,7 @@ from sqlalchemy.orm import joinedload class CRUDUser(CRUDBase[User, UserCreate, UserUpdate]): def get_by_email(self, db: Session, *, email: str) -> Optional[User]: return db.query(self.model).filter(User.email == email).first() - + def create(self, db: Session, *, obj_in: UserCreate) -> User: db_obj = User( email=obj_in.email, diff --git a/private_gpt/users/models/user_role.py b/private_gpt/users/models/user_role.py index 763d9972..9b51a127 100644 --- a/private_gpt/users/models/user_role.py +++ b/private_gpt/users/models/user_role.py @@ -20,7 +20,7 @@ class UserRole(Base): Integer, ForeignKey("companies.id"), primary_key=True, - nullable=True, + nullable=False, ) role = relationship("Role") user = relationship("User", back_populates="user_role", uselist=False) diff --git a/private_gpt/users/utils/__init__.py b/private_gpt/users/utils/__init__.py index eb4eebb8..dc998124 100644 --- a/private_gpt/users/utils/__init__.py +++ b/private_gpt/users/utils/__init__.py @@ -1 +1,2 @@ -from .utils import send_registration_email \ No newline at end of file +from .utils import send_registration_email +from .ad_auth import Ldap \ No newline at end of file diff --git a/private_gpt/users/utils/ad_auth.py b/private_gpt/users/utils/ad_auth.py new file mode 100644 index 00000000..c71f73de --- /dev/null +++ b/private_gpt/users/utils/ad_auth.py @@ -0,0 +1,14 @@ +import ldap3 + +class Ldap: + """Class for LDAP related connections/operations.""" + + def __init__(self, server_uri, ldap_user, ldap_pass): + self.server = ldap3.Server(server_uri, get_info=ldap3.ALL) + print(f"Connected to ldap server: {self.server}") + self.conn = ldap3.Connection(self.server, user=ldap_user, password=ldap_pass, auto_bind=True) + + def who_am_i(self): + return self.conn.extend.standard.who_am_i() + + \ No newline at end of file