feat: login with google done
This commit is contained in:
parent
a5f9953045
commit
9c3467941b
|
@ -2,8 +2,8 @@ import logging
|
||||||
import sys
|
import sys
|
||||||
from flask import jsonify, request
|
from flask import jsonify, request
|
||||||
from pydantic import ValidationError
|
from pydantic import ValidationError
|
||||||
from app.schemas.basic_response_schema import ResponseSchema
|
from schemas.basic_response_schema import ResponseSchema
|
||||||
from app.schemas.google_login_schema import GoogleLoginSchema
|
from schemas.google_login_schema import GoogleLoginSchema
|
||||||
from schemas import LoginSchema
|
from schemas import LoginSchema
|
||||||
from services import UserService, AuthService
|
from services import UserService, AuthService
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ class AuthController:
|
||||||
|
|
||||||
# Validasi data dengan Pydantic
|
# Validasi data dengan Pydantic
|
||||||
validated_data = GoogleLoginSchema(**data)
|
validated_data = GoogleLoginSchema(**data)
|
||||||
id_token = validated_data.id_token
|
id_token = validated_data.token_id
|
||||||
|
|
||||||
# Verifikasi ID Token ke layanan AuthService
|
# Verifikasi ID Token ke layanan AuthService
|
||||||
user_info = self.auth_service.verify_google_id_token(id_token)
|
user_info = self.auth_service.verify_google_id_token(id_token)
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
from .dto import ApiResponse
|
# app/models/__init__.py
|
||||||
|
from .entities import UserEntity
|
||||||
|
|
||||||
|
__all__ = ["UserEntity", "UserDTO"]
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
from .user_entity import UserEntity
|
||||||
|
|
||||||
|
__all__ = ["UserEntity"]
|
|
@ -0,0 +1,17 @@
|
||||||
|
from typing import Optional
|
||||||
|
from pydantic import BaseModel, EmailStr
|
||||||
|
from datetime import date, datetime
|
||||||
|
|
||||||
|
|
||||||
|
class UserEntity(BaseModel):
|
||||||
|
id: str
|
||||||
|
google_id: Optional[str] = None
|
||||||
|
email: EmailStr
|
||||||
|
password: Optional[str] = None
|
||||||
|
name: str
|
||||||
|
birth_date: Optional[date] = None
|
||||||
|
pic_url: Optional[str] = None
|
||||||
|
phone: Optional[str] = None
|
||||||
|
locale: str = "en-US"
|
||||||
|
created_at: Optional[datetime] = None
|
||||||
|
updated_at: Optional[datetime] = None
|
|
@ -1,4 +1,6 @@
|
||||||
import sys
|
from typing import Optional
|
||||||
|
from bson import ObjectId
|
||||||
|
from models import UserEntity
|
||||||
|
|
||||||
|
|
||||||
class UserRepository:
|
class UserRepository:
|
||||||
|
@ -6,18 +8,47 @@ class UserRepository:
|
||||||
def __init__(self, db):
|
def __init__(self, db):
|
||||||
self.collection = db.users
|
self.collection = db.users
|
||||||
|
|
||||||
def get_all_users(self):
|
def get_all_users(self) -> list[UserEntity]:
|
||||||
try:
|
"""Mengambil semua user dari database."""
|
||||||
|
|
||||||
users = list(self.collection.find({}, {"_id": 0}))
|
users = list(self.collection.find({}, {"_id": 0}))
|
||||||
|
|
||||||
return users if users else []
|
return users if users else []
|
||||||
except Exception as e:
|
|
||||||
return []
|
|
||||||
|
|
||||||
def get_user_by_email(self, email):
|
def get_user_by_email(self, email: str) -> Optional[UserEntity]:
|
||||||
try:
|
"""Mendapatkan user berdasarkan email."""
|
||||||
user = self.collection.find_one({"email": email}, {"_id": 0})
|
user = self.collection.find_one({"email": email}, {"_id": 0})
|
||||||
return user if user else None
|
return user
|
||||||
except Exception as e:
|
|
||||||
return None
|
def get_user_by_id(self, user_id: str) -> Optional[UserEntity]:
|
||||||
|
"""Mendapatkan user berdasarkan ID."""
|
||||||
|
object_id = ObjectId(user_id)
|
||||||
|
user = self.collection.find_one({"_id": object_id})
|
||||||
|
return user
|
||||||
|
|
||||||
|
def get_by_google_id(self, google_id: str) -> Optional[UserEntity]:
|
||||||
|
user = self.collection.find_one({"google_id": google_id})
|
||||||
|
return user
|
||||||
|
|
||||||
|
def insert_user(self, user_data: UserEntity) -> str:
|
||||||
|
"""Menambahkan pengguna baru ke dalam database dan mengembalikan ID pengguna."""
|
||||||
|
result = self.collection.insert_one(user_data.model_dump())
|
||||||
|
return str(result.inserted_id)
|
||||||
|
|
||||||
|
def update_user(self, user_id: str, update_data: dict) -> bool:
|
||||||
|
"""Mengupdate seluruh data user berdasarkan ID."""
|
||||||
|
object_id = ObjectId(user_id)
|
||||||
|
result = self.collection.update_one({"_id": object_id}, {"$set": update_data})
|
||||||
|
return result.modified_count > 0
|
||||||
|
|
||||||
|
def update_user_field(self, user_id: str, field: str, value) -> bool:
|
||||||
|
"""Mengupdate satu field dari user berdasarkan ID."""
|
||||||
|
object_id = ObjectId(user_id)
|
||||||
|
result = self.collection.update_one(
|
||||||
|
{"_id": object_id}, {"$set": {field: value}}
|
||||||
|
)
|
||||||
|
return result.modified_count > 0
|
||||||
|
|
||||||
|
def delete_user(self, user_id: str) -> bool:
|
||||||
|
"""Menghapus user berdasarkan ID."""
|
||||||
|
object_id = ObjectId(user_id)
|
||||||
|
result = self.collection.delete_one({"_id": object_id})
|
||||||
|
return result.deleted_count > 0
|
||||||
|
|
|
@ -4,7 +4,7 @@ from pydantic import BaseModel
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
|
||||||
class MetaSchema:
|
class MetaSchema(BaseModel):
|
||||||
total_page: int
|
total_page: int
|
||||||
current_page: int
|
current_page: int
|
||||||
total_data: int
|
total_data: int
|
||||||
|
|
|
@ -2,4 +2,4 @@ from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
class GoogleLoginSchema(BaseModel):
|
class GoogleLoginSchema(BaseModel):
|
||||||
tokenId: str
|
token_id: str
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
|
from datetime import datetime
|
||||||
import sys
|
import sys
|
||||||
|
import traceback
|
||||||
from schemas import LoginSchema
|
from schemas import LoginSchema
|
||||||
from repositories import UserRepository
|
from repositories import UserRepository
|
||||||
from models import ApiResponse
|
|
||||||
|
# from models import ApiResponse
|
||||||
from google.oauth2 import id_token
|
from google.oauth2 import id_token
|
||||||
from google.auth.transport import requests
|
from google.auth.transport import requests
|
||||||
from configs import Config
|
from configs import Config
|
||||||
|
from models import UserEntity
|
||||||
|
|
||||||
|
|
||||||
class AuthService:
|
class AuthService:
|
||||||
|
@ -13,28 +17,48 @@ class AuthService:
|
||||||
|
|
||||||
def verify_google_id_token(self, id_token_str):
|
def verify_google_id_token(self, id_token_str):
|
||||||
try:
|
try:
|
||||||
|
# Verifikasi token Google
|
||||||
payload = id_token.verify_oauth2_token(
|
payload = id_token.verify_oauth2_token(
|
||||||
id_token_str, requests.Request(), Config.GOOGLE_CLIENT_ID
|
id_token_str, requests.Request(), Config.GOOGLE_CLIENT_ID
|
||||||
)
|
)
|
||||||
|
|
||||||
print(f"output verify {payload}", file=sys.stderr)
|
if not payload:
|
||||||
|
print("Invalid token", file=sys.stderr)
|
||||||
|
return None
|
||||||
|
|
||||||
user_data = {
|
google_id = payload.get("sub")
|
||||||
"_id": payload.get("sub"),
|
email = payload.get("email")
|
||||||
"email": payload.get("email"),
|
|
||||||
"name": payload.get("name"),
|
existing_user = self.user_repository.get_by_google_id(google_id)
|
||||||
"picture": payload.get("picture"),
|
if existing_user:
|
||||||
"given_name": payload.get("given_name"),
|
if existing_user.email == email:
|
||||||
"family_name": payload.get("family_name"),
|
return existing_user
|
||||||
"locale": payload.get("locale"),
|
|
||||||
"email_verified": payload.get("email_verified", False),
|
new_user = UserEntity(
|
||||||
"iat": payload.get("iat"),
|
id=str(google_id),
|
||||||
"exp": payload.get("exp"),
|
google_id=google_id,
|
||||||
}
|
email=email,
|
||||||
|
name=payload.get("name"),
|
||||||
|
pic_url=payload.get("picture"),
|
||||||
|
birth_date=None,
|
||||||
|
phone=None,
|
||||||
|
role="user",
|
||||||
|
is_active=True,
|
||||||
|
address=None,
|
||||||
|
created_at=datetime.now(),
|
||||||
|
updated_at=datetime.now(),
|
||||||
|
verification_token=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Simpan user ke database
|
||||||
|
user_id = self.user_repository.insert_user(user_data=new_user)
|
||||||
|
|
||||||
|
# Ambil user yang baru dibuat berdasarkan ID
|
||||||
|
return self.user_repository.get_user_by_id(user_id=user_id)
|
||||||
|
|
||||||
return payload
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"issue on the verify {e}", file=sys.stderr)
|
traceback.print_exc()
|
||||||
|
print(f"Error verifying Google ID token: {e}", file=sys.stderr)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def login(self, data: LoginSchema):
|
def login(self, data: LoginSchema):
|
||||||
|
@ -43,17 +67,20 @@ class AuthService:
|
||||||
user_data = self.user_repository.get_user_by_email(data.email)
|
user_data = self.user_repository.get_user_by_email(data.email)
|
||||||
|
|
||||||
if user_data == None:
|
if user_data == None:
|
||||||
return ApiResponse(success=False, message="User not found", data=None)
|
# return ApiResponse(success=False, message="User not found", data=None)
|
||||||
|
return None
|
||||||
|
|
||||||
if user_data["password"] == data.password:
|
if user_data["password"] == data.password:
|
||||||
del user_data["password"]
|
del user_data["password"]
|
||||||
return ApiResponse(
|
# return ApiResponse(
|
||||||
success=True, message="Login success", data=user_data
|
# success=True, message="Login success", data=user_data
|
||||||
)
|
# )
|
||||||
|
return None
|
||||||
return ApiResponse(success=False, message="Invalid password", data=None)
|
# return ApiResponse(success=False, message="Invalid password", data=None)
|
||||||
|
return None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"the issue is {e}")
|
print(f"the issue is {e}")
|
||||||
return ApiResponse(
|
# return ApiResponse(
|
||||||
success=False, message="Internal server error", data=None
|
# success=False, message="Internal server error", data=None
|
||||||
)
|
# )
|
||||||
|
return None
|
||||||
|
|
Loading…
Reference in New Issue