From 6288f489896bc009de14d70d67ab5496bc2c5ba6 Mon Sep 17 00:00:00 2001 From: Niraj Adhikari Date: Wed, 10 Jul 2024 10:39:28 +0545 Subject: [PATCH 1/6] added user role column in user profile --- src/backend/app/db/db_models.py | 3 +- .../app/migrations/versions/3293e9c98b2a_.py | 67 +++++++++++++++++++ src/backend/app/models/enums.py | 1 - 3 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 src/backend/app/migrations/versions/3293e9c98b2a_.py diff --git a/src/backend/app/db/db_models.py b/src/backend/app/db/db_models.py index 03951131..a2cf8fad 100644 --- a/src/backend/app/db/db_models.py +++ b/src/backend/app/db/db_models.py @@ -44,7 +44,6 @@ class DbUser(Base): profile_img = cast(str, Column(String, nullable=True)) name = cast(str, Column(String)) email_address = cast(str, Column(String, nullable=False, unique=True)) - role = cast(UserRole, Column(Enum(UserRole), default=UserRole.DRONE_PILOT)) date_registered = cast(datetime, Column(DateTime, default=timestamp)) @@ -73,7 +72,6 @@ class DbTask(Base): ) project_task_index = cast(int, Column(Integer)) outline = cast(WKBElement, Column(Geometry("POLYGON", srid=4326))) - task_status = cast(TaskStatus, Column(Enum(TaskStatus), default=TaskStatus.READY)) class DbProject(Base): @@ -269,6 +267,7 @@ class GroundControlPoint(Base): class DbUserProfile(Base): __tablename__ = "user_profile" user_id = cast(str, Column(String, ForeignKey("users.id"), primary_key=True)) + role = cast(UserRole, Column(Enum(UserRole), default=UserRole.DRONE_PILOT)) phone_number = cast(str, Column(String)) country = cast(str, Column(String)) city = cast(str, Column(String)) diff --git a/src/backend/app/migrations/versions/3293e9c98b2a_.py b/src/backend/app/migrations/versions/3293e9c98b2a_.py new file mode 100644 index 00000000..6470009f --- /dev/null +++ b/src/backend/app/migrations/versions/3293e9c98b2a_.py @@ -0,0 +1,67 @@ +""" + +Revision ID: 3293e9c98b2a +Revises: 06668eb5d14a +Create Date: 2024-07-10 04:52:41.412683 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision: str = "3293e9c98b2a" +down_revision: Union[str, None] = "06668eb5d14a" +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.drop_column("tasks", "task_status") + op.add_column( + "user_profile", + sa.Column( + "role", + sa.Enum("PROJECT_CREATOR", "DRONE_PILOT", name="userrole"), + nullable=True, + ), + ) + op.drop_column("users", "role") + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.add_column( + "users", + sa.Column( + "role", + postgresql.ENUM("PROJECT_CREATOR", "DRONE_PILOT", "BOTH", name="userrole"), + autoincrement=False, + nullable=True, + ), + ) + op.drop_column("user_profile", "role") + op.add_column( + "tasks", + sa.Column( + "task_status", + postgresql.ENUM( + "READY", + "LOCKED_FOR_MAPPING", + "MAPPED", + "LOCKED_FOR_VALIDATION", + "VALIDATED", + "INVALIDATED", + "BAD", + "SPLIT", + name="taskstatus", + ), + autoincrement=False, + nullable=True, + ), + ) + # ### end Alembic commands ### diff --git a/src/backend/app/models/enums.py b/src/backend/app/models/enums.py index 41563192..a4943433 100644 --- a/src/backend/app/models/enums.py +++ b/src/backend/app/models/enums.py @@ -113,7 +113,6 @@ class DroneType(IntEnum): class UserRole(IntEnum, Enum): PROJECT_CREATOR = 1 DRONE_PILOT = 2 - BOTH = 3 class State(int, Enum): From 34295b234fa208eb673aa2904551bc1fec8881cc Mon Sep 17 00:00:00 2001 From: Niraj Adhikari Date: Wed, 10 Jul 2024 11:14:04 +0545 Subject: [PATCH 2/6] username field removed from users table --- src/backend/app/db/db_models.py | 5 ++- .../app/migrations/versions/88ae62ec8876_.py | 35 +++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 src/backend/app/migrations/versions/88ae62ec8876_.py diff --git a/src/backend/app/db/db_models.py b/src/backend/app/db/db_models.py index a2cf8fad..d2929a0d 100644 --- a/src/backend/app/db/db_models.py +++ b/src/backend/app/db/db_models.py @@ -37,13 +37,12 @@ class DbUser(Base): __tablename__ = "users" id = cast(str, Column(String, primary_key=True)) - username = cast(str, Column(String, nullable=False, unique=True)) + email_address = cast(str, Column(String, nullable=False, unique=True)) password = cast(str, Column(String)) + name = cast(str, Column(String)) is_active = cast(bool, Column(Boolean, default=False)) is_superuser = cast(bool, Column(Boolean, default=False)) profile_img = cast(str, Column(String, nullable=True)) - name = cast(str, Column(String)) - email_address = cast(str, Column(String, nullable=False, unique=True)) date_registered = cast(datetime, Column(DateTime, default=timestamp)) diff --git a/src/backend/app/migrations/versions/88ae62ec8876_.py b/src/backend/app/migrations/versions/88ae62ec8876_.py new file mode 100644 index 00000000..94758111 --- /dev/null +++ b/src/backend/app/migrations/versions/88ae62ec8876_.py @@ -0,0 +1,35 @@ +""" + +Revision ID: 88ae62ec8876 +Revises: 3293e9c98b2a +Create Date: 2024-07-10 05:21:58.749137 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = "88ae62ec8876" +down_revision: Union[str, None] = "3293e9c98b2a" +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.drop_constraint("users_username_key", "users", type_="unique") + op.drop_column("users", "username") + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.add_column( + "users", + sa.Column("username", sa.VARCHAR(), autoincrement=False, nullable=False), + ) + op.create_unique_constraint("users_username_key", "users", ["username"]) + # ### end Alembic commands ### From 2ea77554f0e9d37224c97b28cb521e80b7e3b07c Mon Sep 17 00:00:00 2001 From: Niraj Adhikari Date: Wed, 10 Jul 2024 11:15:33 +0545 Subject: [PATCH 3/6] name added in auth user schemas --- src/backend/app/users/user_schemas.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/backend/app/users/user_schemas.py b/src/backend/app/users/user_schemas.py index 9cadc25f..27e23f7a 100644 --- a/src/backend/app/users/user_schemas.py +++ b/src/backend/app/users/user_schemas.py @@ -1,6 +1,7 @@ from pydantic import BaseModel, EmailStr, ValidationInfo, Field from pydantic.functional_validators import field_validator from typing import Optional +from app.models.enums import UserRole class AuthUser(BaseModel): @@ -8,6 +9,7 @@ class AuthUser(BaseModel): id: str email: EmailStr + name: str img_url: Optional[str] = None @@ -85,3 +87,4 @@ class ProfileUpdate(BaseModel): drone_you_own: Optional[str] experience_years: Optional[int] certified_drone_operator: Optional[bool] + role: Optional[UserRole] = UserRole.DRONE_PILOT From 407626b1dbe2402d1b5a2d527caab012fc42d62f Mon Sep 17 00:00:00 2001 From: Niraj Adhikari Date: Wed, 10 Jul 2024 11:16:52 +0545 Subject: [PATCH 4/6] update: get_or_create function --- src/backend/app/users/user_crud.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/backend/app/users/user_crud.py b/src/backend/app/users/user_crud.py index 28fbbf1f..30d25ff4 100644 --- a/src/backend/app/users/user_crud.py +++ b/src/backend/app/users/user_crud.py @@ -7,7 +7,6 @@ from app.users.user_schemas import AuthUser, ProfileUpdate from databases import Database from fastapi import HTTPException -from app.models.enums import UserRole pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") @@ -103,10 +102,10 @@ async def get_or_create_user( try: update_sql = """ INSERT INTO users ( - id, username, email_address, profile_img, role + id, name, email_address, profile_img, is_active, is_superuser, date_registered ) VALUES ( - :user_id, :username, :email_address, :profile_img, :role + :user_id, :name, :email_address, :profile_img, False, False, now() ) ON CONFLICT (id) DO UPDATE SET profile_img = :profile_img; @@ -116,10 +115,9 @@ async def get_or_create_user( update_sql, { "user_id": str(user_data.id), - "username": user_data.email, # FIXME: remove this + "name": user_data.name, "email_address": user_data.email, "profile_img": user_data.img_url, - "role": UserRole.DRONE_PILOT.name, }, ) return user_data @@ -154,12 +152,13 @@ async def update_user_profile( try: profile_query = """ - INSERT INTO user_profile (user_id, phone_number, country, city, organization_name, organization_address, job_title, notify_for_projects_within_km, + INSERT INTO user_profile (user_id, role, phone_number, country, city, organization_name, organization_address, job_title, notify_for_projects_within_km, experience_years, drone_you_own, certified_drone_operator) - VALUES (:user_id, :phone_number, :country, :city, :organization_name, :organization_address, :job_title, :notify_for_projects_within_km , + VALUES (:user_id, :role, :phone_number, :country, :city, :organization_name, :organization_address, :job_title, :notify_for_projects_within_km , :experience_years, :drone_you_own, :certified_drone_operator) ON CONFLICT (user_id) DO UPDATE SET + role = :role, phone_number = :phone_number, country = :country, city = :city, @@ -176,6 +175,7 @@ async def update_user_profile( profile_query, { "user_id": user_id, + "role": profile_update.role, "phone_number": profile_update.phone_number, "country": profile_update.country, "city": profile_update.city, From 1e8b4cacaebd400a49d2e9fe23274b1622eb122f Mon Sep 17 00:00:00 2001 From: Niraj Adhikari Date: Wed, 10 Jul 2024 11:22:01 +0545 Subject: [PATCH 5/6] fix: update user profile --- src/backend/app/users/user_schemas.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/backend/app/users/user_schemas.py b/src/backend/app/users/user_schemas.py index 27e23f7a..d66407bc 100644 --- a/src/backend/app/users/user_schemas.py +++ b/src/backend/app/users/user_schemas.py @@ -77,14 +77,14 @@ class UserCreate(UserBase): class ProfileUpdate(BaseModel): - phone_number: Optional[str] - country: Optional[str] - city: Optional[str] - organization_name: Optional[str] - organization_address: Optional[str] - job_title: Optional[str] - notify_for_projects_within_km: Optional[int] - drone_you_own: Optional[str] - experience_years: Optional[int] - certified_drone_operator: Optional[bool] - role: Optional[UserRole] = UserRole.DRONE_PILOT + phone_number: Optional[str] = None + country: Optional[str] = None + city: Optional[str] = None + organization_name: Optional[str] = None + organization_address: Optional[str] = None + job_title: Optional[str] = None + notify_for_projects_within_km: Optional[int] = None + drone_you_own: Optional[str] = None + experience_years: Optional[int] = None + certified_drone_operator: Optional[bool] = False + role: Optional[UserRole] = UserRole.DRONE_PILOT.name From 779910ad5842a2ab15bfeebd887733143f664604 Mon Sep 17 00:00:00 2001 From: Niraj Adhikari Date: Wed, 10 Jul 2024 11:35:04 +0545 Subject: [PATCH 6/6] update password for users --- src/backend/app/users/user_crud.py | 16 ++++++++++++++++ src/backend/app/users/user_schemas.py | 1 + 2 files changed, 17 insertions(+) diff --git a/src/backend/app/users/user_crud.py b/src/backend/app/users/user_crud.py index 30d25ff4..06da4bec 100644 --- a/src/backend/app/users/user_crud.py +++ b/src/backend/app/users/user_crud.py @@ -188,6 +188,22 @@ async def update_user_profile( "certified_drone_operator": profile_update.certified_drone_operator, }, ) + + # If password is provided, update the users table + if profile_update.password: + password_update_query = """ + UPDATE users + SET password = :password + WHERE id = :user_id; + """ + await db.execute( + password_update_query, + { + "password": get_password_hash(profile_update.password), + "user_id": user_id, + }, + ) + return True except Exception as e: raise HTTPException(status_code=400, detail=str(e)) from e diff --git a/src/backend/app/users/user_schemas.py b/src/backend/app/users/user_schemas.py index d66407bc..92e19f14 100644 --- a/src/backend/app/users/user_schemas.py +++ b/src/backend/app/users/user_schemas.py @@ -88,3 +88,4 @@ class ProfileUpdate(BaseModel): experience_years: Optional[int] = None certified_drone_operator: Optional[bool] = False role: Optional[UserRole] = UserRole.DRONE_PILOT.name + password: Optional[str] = None