Skip to content

Commit

Permalink
fix: update user model
Browse files Browse the repository at this point in the history
  • Loading branch information
joboy-dev committed Aug 10, 2024
1 parent 42cfdcd commit c06280d
Show file tree
Hide file tree
Showing 100 changed files with 290 additions and 260 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""update user model from is_super_admin to is_superadmin
Revision ID: 3f455aaf9065
Revises: ff92a0037698
Create Date: 2024-08-10 03:45:26.585225
"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = '3f455aaf9065'
down_revision: Union[str, None] = 'ff92a0037698'
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.add_column('users', sa.Column('is_superadmin', sa.Boolean(), server_default=sa.text('false'), nullable=True))
op.drop_column('users', 'is_super_admin')
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('users', sa.Column('is_super_admin', sa.BOOLEAN(), server_default=sa.text('false'), autoincrement=False, nullable=True))
op.drop_column('users', 'is_superadmin')
# ### end Alembic commands ###
2 changes: 1 addition & 1 deletion api/utils/db_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def check_model_existence(db: Session, model, id):
def check_user_in_org(user: User, organization: Organization):
"""Checks if a user is a member of an organization"""

if user not in organization.users and not user.is_super_admin:
if user not in organization.users and not user.is_superadmin:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="You are not a member of this organization",
Expand Down
2 changes: 1 addition & 1 deletion api/utils/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def get_current_user(

def get_super_admin(db: Session = Depends(get_db), token: str = Depends(oauth2_scheme)):
user = get_current_user(db, token)
if not user.is_super_admin:
if not user.is_superadmin:
logger.error("User is not a super admin")
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
Expand Down
2 changes: 1 addition & 1 deletion api/utils/pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def paginated_response(
results,
exclude={
'password',
'is_super_admin',
'is_superadmin',
'is_deleted',
'is_active'
}
Expand Down
15 changes: 15 additions & 0 deletions api/utils/success_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,18 @@ def success_response(status_code: int, message: str, data: Optional[dict] = None
response_data["data"] = data

return JSONResponse(status_code=status_code, content=jsonable_encoder(response_data))


def auth_response(status_code: int, message: str, access_token: str, data: Optional[dict] = None):
'''Returns a JSON response for successful auth responses'''

response_data = {
"status_code": status_code,
"message": message,
"access_token": access_token
}

if data is not None:
response_data["data"] = data

return JSONResponse(status_code=status_code, content=jsonable_encoder(response_data))
3 changes: 2 additions & 1 deletion api/v1/models/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ class Product(BaseTableModel):
)
archived = Column(Boolean, default=False)
filter_status = Column(
SQLAlchemyEnum(ProductFilterStatusEnum), default=ProductFilterStatusEnum.active)
SQLAlchemyEnum(ProductFilterStatusEnum), default=ProductFilterStatusEnum.active
)

variants = relationship(
"ProductVariant", back_populates="product", cascade="all, delete-orphan"
Expand Down
2 changes: 1 addition & 1 deletion api/v1/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class User(BaseTableModel):
last_name = Column(String, nullable=True)
avatar_url = Column(String, nullable=True)
is_active = Column(Boolean, server_default=text("true"))
is_super_admin = Column(Boolean, server_default=text("false"))
is_superadmin = Column(Boolean, server_default=text("false"))
is_deleted = Column(Boolean, server_default=text("false"))
is_verified = Column(Boolean, server_default=text("false"))

Expand Down
141 changes: 66 additions & 75 deletions api/v1/routes/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from sqlalchemy.orm import Session

from api.core.dependencies.email_sender import send_email
from api.utils.success_response import success_response
from api.utils.success_response import auth_response, success_response
from api.utils.send_mail import send_magic_link
from api.v1.models import User
from api.v1.schemas.user import Token
Expand All @@ -21,16 +21,18 @@
auth = APIRouter(prefix="/auth", tags=["Authentication"])


@auth.post("/register", status_code=status.HTTP_201_CREATED, response_model=success_response)
@auth.post("/register", status_code=status.HTTP_201_CREATED, response_model=auth_response)
def register(background_tasks: BackgroundTasks, response: Response, user_schema: UserCreate, db: Session = Depends(get_db)):
'''Endpoint for a user to register their account'''

# Create user account
user = user_service.create(db=db, schema=user_schema)

# create an organization for the user
org = CreateUpdateOrganization(name=f"{user.first_name}'s Organization",
email=user.email)
org = CreateUpdateOrganization(
name=f"{user.first_name}'s Organization",
email=user.email
)
user_org = organization_service.create(db=db, schema=org, user=user)

# Create access and refresh tokens
Expand All @@ -49,18 +51,15 @@ def register(background_tasks: BackgroundTasks, response: Response, user_schema:
}
)

response = JSONResponse(
response = auth_response(
status_code=201,
content={
'status_code': 201,
'message': 'User created successfully',
'access_token': access_token,
'data': {
'user': jsonable_encoder(
user,
exclude=['password', 'is_super_admin', 'is_deleted', 'is_verified', 'updated_at']
)
}
message='User created successfully',
access_token=access_token,
data={
'user': jsonable_encoder(
user,
exclude=['password', 'is_deleted', 'is_verified', 'updated_at']
)
}
)

Expand All @@ -77,7 +76,7 @@ def register(background_tasks: BackgroundTasks, response: Response, user_schema:
return response


@auth.post(path="/register-super-admin", status_code=status.HTTP_201_CREATED)
@auth.post(path="/register-super-admin", status_code=status.HTTP_201_CREATED, response_model=auth_response)
def register_as_super_admin(user: UserCreate, db: Session = Depends(get_db)):
"""Endpoint for super admin creation"""

Expand All @@ -87,18 +86,15 @@ def register_as_super_admin(user: UserCreate, db: Session = Depends(get_db)):
access_token = user_service.create_access_token(user_id=user.id)
refresh_token = user_service.create_refresh_token(user_id=user.id)

response = JSONResponse(
response = auth_response(
status_code=201,
content={
'status_code': 201,
'message': 'User created successfully',
'access_token': access_token,
'data': {
'user': jsonable_encoder(
user,
exclude=['password', 'is_super_admin', 'is_deleted', 'is_verified', 'updated_at']
)
}
message='User created successfully',
access_token=access_token,
data={
'user': jsonable_encoder(
user,
exclude=['password', 'is_deleted', 'is_verified', 'updated_at']
)
}
)

Expand All @@ -115,7 +111,7 @@ def register_as_super_admin(user: UserCreate, db: Session = Depends(get_db)):
return response


@auth.post("/login", status_code=status.HTTP_200_OK, response_model=success_response)
@auth.post("/login", status_code=status.HTTP_200_OK, response_model=auth_response)
def login(login_request: LoginRequest, db: Session = Depends(get_db)):
"""Endpoint to log in a user"""

Expand All @@ -128,18 +124,15 @@ def login(login_request: LoginRequest, db: Session = Depends(get_db)):
access_token = user_service.create_access_token(user_id=user.id)
refresh_token = user_service.create_refresh_token(user_id=user.id)

response = JSONResponse(
response = auth_response(
status_code=200,
content={
'status_code': 200,
'message': 'Login successful',
'access_token': access_token,
'data': {
'user': jsonable_encoder(
user,
exclude=['password', 'is_super_admin', 'is_deleted', 'is_verified', 'updated_at']
)
}
message='Login successful',
access_token=access_token,
data={
'user': jsonable_encoder(
user,
exclude=['password', 'is_deleted', 'is_verified', 'updated_at']
)
}
)

Expand Down Expand Up @@ -186,13 +179,10 @@ def refresh_access_token(
current_refresh_token=current_refresh_token
)

response = success_response(
response = auth_response(
status_code=200,
message="Tokens refreshed successfully",
data={
"access_token": access_token,
"token_type": "bearer",
},
message='Login successful',
access_token=access_token
)

# Add refresh token to cookies
Expand Down Expand Up @@ -228,7 +218,7 @@ async def request_signin_token(
)


@auth.post("/verify-token", status_code=status.HTTP_200_OK)
@auth.post("/verify-token", status_code=status.HTTP_200_OK, response_model=auth_response)
async def verify_signin_token(
token_schema: TokenRequest, db: Session = Depends(get_db)
):
Expand All @@ -240,13 +230,17 @@ async def verify_signin_token(
access_token = user_service.create_access_token(user_id=user.id)
refresh_token = user_service.create_refresh_token(user_id=user.id)

response = success_response(

response = auth_response(
status_code=200,
message="Sign in successful",
message='Login successful',
access_token=access_token,
data={
"access_token": access_token,
"token_type": "bearer",
},
'user': jsonable_encoder(
user,
exclude=['password', 'is_deleted', 'is_verified', 'updated_at']
)
}
)

# Add refresh token to cookies
Expand All @@ -262,23 +256,36 @@ async def verify_signin_token(
return response


# Verify Magic Link
@auth.post("/verify-magic-link")
# TODO: Fix magic link authentication
@auth.post("/magic-link", status_code=status.HTTP_200_OK)
def request_magic_link(
request: MagicLinkRequest, response: Response, db: Session = Depends(get_db)
):
user = user_service.fetch_by_email(db=db, email=request.email)
access_token = user_service.create_access_token(user_id=user.id)
send_magic_link(user.email, access_token)

response = success_response(
status_code=200, message=f"Magic link sent to {user.email}"
)
return response


@auth.post("/magic-link/verify")
async def verify_magic_link(token_schema: Token, db: Session = Depends(get_db)):
user, access_token = AuthService.verify_magic_token(token_schema.access_token, db)

refresh_token = user_service.create_refresh_token(user_id=user.id)

response = success_response(
response = auth_response(
status_code=200,
message='Login successful',
access_token=access_token,
data={
'access_token': access_token,
'token_type': 'bearer',
'user': jsonable_encoder(
user,
exclude=['password', 'is_super_admin', 'is_deleted', 'is_verified', 'updated_at']
),
user,
exclude=['password', 'is_deleted', 'is_verified', 'updated_at']
)
}
)

Expand All @@ -293,19 +300,3 @@ async def verify_magic_link(token_schema: Token, db: Session = Depends(get_db)):
)

return response




@auth.post("/request-magic-link", status_code=status.HTTP_200_OK)
def request_magic_link(
request: MagicLinkRequest, response: Response, db: Session = Depends(get_db)
):
user = user_service.fetch_by_email(db=db, email=request.email)
access_token = user_service.create_access_token(user_id=user.id)
send_magic_link(user.email, access_token)

response = success_response(
status_code=200, message=f"Magic link sent to {user.email}"
)
return response
17 changes: 3 additions & 14 deletions api/v1/routes/faq.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@


@faq.get("", response_model=success_response, status_code=200)
async def get_all_faqs(
db: Session = Depends(get_db),
# limit: int = 10,
# skip: int = 0,
):
async def get_all_faqs(db: Session = Depends(get_db),):
"""Endpoint to get all FAQs"""

faqs = faq_service.fetch_all(db=db)
Expand All @@ -30,13 +26,6 @@ async def get_all_faqs(
data=jsonable_encoder(faqs),
)

# return paginated_response(
# db=db,
# model=FAQ,
# limit=limit,
# skip=skip,
# )


@faq.post("", response_model=success_response, status_code=201)
async def create_faq(
Expand Down Expand Up @@ -80,7 +69,7 @@ async def update_faq(

return success_response(
data=jsonable_encoder(faq),
message="Successfully created FAQ",
message="FAQ created successfully",
status_code=status.HTTP_200_OK,
)

Expand All @@ -96,6 +85,6 @@ async def delete_faq(
faq_service.delete(db, faq_id=id)

return success_response(
message="Successfully deleted FAQ",
message="FAQ successfully deleted",
status_code=200,
)
Loading

0 comments on commit c06280d

Please sign in to comment.