| """Validation rules for registration contact details.""" |
|
|
| import re |
|
|
|
|
| |
| |
| |
| COMMON_PERSONAL_EMAIL_DOMAINS = frozenset( |
| { |
| "126.com", |
| "163.com", |
| "aol.com", |
| "daum.net", |
| "gmail.com", |
| "gmx.com", |
| "hotmail.com", |
| "icloud.com", |
| "mail.com", |
| "mail.ru", |
| "naver.com", |
| "outlook.com", |
| "proton.me", |
| "protonmail.com", |
| "qq.com", |
| "rediffmail.com", |
| "yahoo.com", |
| "yandex.com", |
| "yandex.ru", |
| "zoho.com", |
| } |
| ) |
|
|
| DOMAIN_LABEL_RE = re.compile(r"^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$") |
| ASCII_LETTER_RE = re.compile(r"[A-Za-z]") |
|
|
|
|
| def email_domain(email: str) -> str | None: |
| """Return a normalized domain for a basic, usable email address.""" |
| email = (email or "").strip() |
| if len(email) > 254 or email.count("@") != 1 or any(char.isspace() for char in email): |
| return None |
|
|
| local_part, domain = email.rsplit("@", 1) |
| domain = domain.rstrip(".").casefold() |
| if not local_part or len(local_part) > 64 or not domain or "." not in domain: |
| return None |
|
|
| try: |
| domain = domain.encode("idna").decode("ascii") |
| except UnicodeError: |
| return None |
|
|
| labels = domain.split(".") |
| if any(not DOMAIN_LABEL_RE.fullmatch(label) for label in labels): |
| return None |
| return domain |
|
|
|
|
| def uses_common_personal_email_service(email: str) -> bool: |
| """Whether an address belongs to one of the blocked consumer services.""" |
| domain = email_domain(email) |
| if domain is None: |
| return False |
|
|
| parts = domain.split(".") |
| return any( |
| ".".join(parts[index:]) in COMMON_PERSONAL_EMAIL_DOMAINS |
| for index in range(len(parts) - 1) |
| ) |
|
|
|
|
| def registration_contact_error( |
| profile_email: str, |
| organization: str, |
| ) -> str | None: |
| """Return a user-facing error for the OAuth-provided contact email.""" |
| if not (organization or "").strip(): |
| return "Organization / Affiliation is required." |
| if not ASCII_LETTER_RE.search(organization): |
| return ( |
| "Organization / Affiliation must include an English or Romanized Latin " |
| "name for registration review." |
| ) |
|
|
| profile_email = (profile_email or "").strip() |
| if email_domain(profile_email) is None: |
| return "Your Hugging Face account must provide a valid primary email address." |
| if uses_common_personal_email_service(profile_email): |
| return ( |
| "Your Hugging Face primary email must be an academic, company, or " |
| "organization address. Addresses from common personal email services " |
| "are not accepted." |
| ) |
| return None |
|
|