fix(users): sync google profile data to user records
This commit is contained in:
@@ -4,10 +4,12 @@ import secrets
|
||||
from dataclasses import asdict, dataclass, is_dataclass
|
||||
from typing import Any
|
||||
from urllib.parse import urlencode
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import requests
|
||||
from django.conf import settings
|
||||
from django.core.cache import cache
|
||||
from django.core.files.base import ContentFile
|
||||
from rest_framework.exceptions import APIException, ValidationError
|
||||
|
||||
from apps.users.email_identity import mask_mobile, normalize_email_identity
|
||||
@@ -111,6 +113,46 @@ def _normalize_mobile(mobile: str) -> str:
|
||||
return normalized
|
||||
|
||||
|
||||
def _avatar_file_extension(profile: GoogleProfile) -> str:
|
||||
path = urlparse(profile.avatar_url or "").path
|
||||
if "." in path:
|
||||
suffix = path.rsplit(".", 1)[-1].lower()
|
||||
if suffix in {"jpg", "jpeg", "png", "webp", "gif"}:
|
||||
return suffix
|
||||
return "jpg"
|
||||
|
||||
|
||||
def sync_user_from_google_profile(user: User, profile: GoogleProfile) -> None:
|
||||
update_fields: list[str] = []
|
||||
|
||||
if not user.first_name and profile.first_name:
|
||||
user.first_name = profile.first_name
|
||||
update_fields.append("first_name")
|
||||
|
||||
if not user.last_name and profile.last_name:
|
||||
user.last_name = profile.last_name
|
||||
update_fields.append("last_name")
|
||||
|
||||
if normalize_email_identity(user.email) is None and profile.email:
|
||||
user.email = profile.email
|
||||
update_fields.append("email")
|
||||
|
||||
if not user.profile_picture and profile.avatar_url:
|
||||
try:
|
||||
avatar_response = requests.get(profile.avatar_url, timeout=10)
|
||||
avatar_response.raise_for_status()
|
||||
except requests.RequestException:
|
||||
avatar_response = None
|
||||
|
||||
if avatar_response and avatar_response.content:
|
||||
filename = f"google-{profile.provider_user_id}.{_avatar_file_extension(profile)}"
|
||||
user.profile_picture.save(filename, ContentFile(avatar_response.content), save=False)
|
||||
update_fields.append("profile_picture")
|
||||
|
||||
if update_fields:
|
||||
user.save(update_fields=update_fields)
|
||||
|
||||
|
||||
def _build_claim_required_payload(
|
||||
*,
|
||||
profile: GoogleProfile,
|
||||
@@ -379,6 +421,7 @@ def complete_google_signup(flow: str, mobile: str) -> dict[str, Any]:
|
||||
)
|
||||
user.set_unusable_password()
|
||||
user.save(update_fields=["password"])
|
||||
sync_user_from_google_profile(user, profile)
|
||||
|
||||
UserSocialAccount.objects.create(
|
||||
user=user,
|
||||
@@ -457,6 +500,8 @@ def verify_google_claim(flow: str, code: str) -> dict[str, Any]:
|
||||
user.email = profile.email
|
||||
user.save(update_fields=["email"])
|
||||
|
||||
sync_user_from_google_profile(user, profile)
|
||||
|
||||
if existing_link:
|
||||
existing_link.email = profile.email
|
||||
existing_link.email_verified = profile.email_verified
|
||||
|
||||
Reference in New Issue
Block a user