Spaces:
Sleeping
Sleeping
File size: 5,165 Bytes
db4d559 3786a3f db4d559 3786a3f db4d559 3786a3f db4d559 f14eb69 db4d559 f14eb69 db4d559 f14eb69 db4d559 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | import re
import logging
from rest_framework import serializers
from django.contrib.auth import get_user_model
from django.contrib.auth.password_validation import validate_password
from .models import Document, QueryLog, EvaluationPair
logger = logging.getLogger(__name__)
User = get_user_model()
DISPOSABLE_DOMAINS = {
'mailinator.com', 'yopmail.com', 'tempmail.com', 'temp-mail.org',
'10minutemail.com', 'guerrillamail.com', 'trashmail.com'
}
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'email')
class RegisterSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True, required=True, style={'input_type': 'password'})
confirm_password = serializers.CharField(write_only=True, required=True, style={'input_type': 'password'})
class Meta:
model = User
fields = ('id', 'username', 'email', 'password', 'confirm_password')
def create(self, validated_data):
validated_data.pop('confirm_password')
return User.objects.create_user(**validated_data)
def validate_email(self, value):
logger.debug("Validating email: %s", value)
# 1. Format normalization
value = value.strip().lower()
# 2. Extract and check domain
try:
domain = value.split('@')[1]
except IndexError:
raise serializers.ValidationError("Invalid email address format.")
if domain in DISPOSABLE_DOMAINS:
logger.warning("Blocked attempt to register with fake/disposable email domain: %s", domain)
raise serializers.ValidationError("Disposable or temporary email accounts are not permitted.")
# 3. Check for uniqueness
if User.objects.filter(email=value).exists():
logger.warning("Registration failed - email already exists: %s", value)
raise serializers.ValidationError("A user with this email already exists.")
return value
def validate(self, attrs):
logger.debug("Checking password policies and password matching...")
password = attrs.get('password')
confirm_password = attrs.get('confirm_password')
# 1. Verify match
if password != confirm_password:
raise serializers.ValidationError({"password": "Passwords do not match."})
# 2. Blank / spaces-only check
if not password or password.strip() == '':
raise serializers.ValidationError({"password": "Password cannot be empty or contain only spaces."})
# 3. Custom Strict Character Check (Uppercase, Lowercase, Number, Special Char)
if not re.search(r"[A-Z]", password):
raise serializers.ValidationError({"password": "Password must contain at least one uppercase letter."})
if not re.search(r"[a-z]", password):
raise serializers.ValidationError({"password": "Password must contain at least one lowercase letter."})
if not re.search(r"[0-9]", password):
raise serializers.ValidationError({"password": "Password must contain at least one number."})
if not re.search(r"[@$!%*?&]", password):
raise serializers.ValidationError({"password": "Password must contain at least one special character (@, $, !, %, *, ?, &)."})
return attrs
class DocumentSerializer(serializers.ModelSerializer):
user = UserSerializer(read_only=True)
file_url = serializers.SerializerMethodField()
class Meta:
model = Document
fields = (
'id', 'user', 'name', 'file', 'file_url', 'status',
'entity_count', 'relationship_count', 'error_message',
'source', 'processing_progress', 'processing_step',
'created_at', 'updated_at'
)
read_only_fields = (
'id', 'user', 'status', 'entity_count', 'relationship_count',
'error_message', 'processing_progress', 'processing_step',
'created_at', 'updated_at'
)
def get_file_url(self, obj):
request = self.context.get('request')
if obj.file and request:
return request.build_absolute_uri(obj.file.url)
return None
class QueryLogSerializer(serializers.ModelSerializer):
user = UserSerializer(read_only=True)
answer_preview = serializers.SerializerMethodField()
class Meta:
model = QueryLog
fields = (
'id', 'user', 'query_text', 'retrieval_mode',
'answer_text', 'answer_preview', 'response_time', 'created_at'
)
read_only_fields = ('id', 'user', 'created_at')
def get_answer_preview(self, obj):
text = obj.answer_text or ""
if len(text) > 200:
return text[:200] + "..."
return text
class EvaluationPairSerializer(serializers.ModelSerializer):
user = UserSerializer(read_only=True)
class Meta:
model = EvaluationPair
fields = ('id', 'user', 'question', 'expected_answer', 'is_active', 'created_at')
read_only_fields = ('id', 'user', 'created_at')
|