operations_project/apps/gmail/serializers.py

69 lines
3.3 KiB
Python
Raw Normal View History

2025-05-13 11:58:17 +08:00
from rest_framework import serializers
from .models import GmailCredential
import json
class GmailCredentialSerializer(serializers.ModelSerializer):
client_secret_json = serializers.JSONField(write_only=True, required=False, allow_null=True)
client_secret_file = serializers.FileField(write_only=True, required=False, allow_null=True)
auth_code = serializers.CharField(write_only=True, required=False, allow_blank=True)
email = serializers.EmailField(required=False, allow_blank=True) # Make email optional
class Meta:
model = GmailCredential
fields = ['id', 'email', 'is_default', 'created_at', 'updated_at', 'is_valid',
'client_secret_json', 'client_secret_file', 'auth_code']
read_only_fields = ['created_at', 'updated_at', 'is_valid']
def validate(self, data):
"""Validate client_secret input (either JSON or file)."""
client_secret_json = data.get('client_secret_json')
client_secret_file = data.get('client_secret_file')
auth_code = data.get('auth_code')
# For auth initiation, only client_secret is required
if not auth_code: # Initiation phase
if not client_secret_json and not client_secret_file:
raise serializers.ValidationError(
"Either client_secret_json or client_secret_file is required."
)
if client_secret_json and client_secret_file:
raise serializers.ValidationError(
"Provide only one of client_secret_json or client_secret_file."
)
# For auth completion, both auth_code and client_secret are required
if auth_code and not (client_secret_json or client_secret_file):
raise serializers.ValidationError(
"client_secret_json or client_secret_file is required with auth_code."
)
# Parse client_secret_json if provided
if client_secret_json:
try:
json.dumps(client_secret_json)
except (TypeError, ValueError):
raise serializers.ValidationError("client_secret_json must be valid JSON.")
# Parse client_secret_file if provided
if client_secret_file:
try:
content = client_secret_file.read().decode('utf-8')
client_secret_json = json.loads(content)
data['client_secret_json'] = client_secret_json
except (json.JSONDecodeError, UnicodeDecodeError):
raise serializers.ValidationError("client_secret_file must contain valid JSON.")
return data
def validate_email(self, value):
"""Ensure email is unique for the user (only for completion)."""
if not value: # Email is optional during initiation
return value
user = self.context['request'].user
if self.instance: # Update case
if GmailCredential.objects.filter(user=user, email=value).exclude(id=self.instance.id).exists():
raise serializers.ValidationError("This Gmail account is already added.")
else: # Create case
if GmailCredential.objects.filter(user=user, email=value).exists():
raise serializers.ValidationError("This Gmail account is already added.")
return value