Coverage for /home/runner/work/viur-core/viur-core/viur/src/viur/core/bones/email.py: 17%
36 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-13 11:04 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-13 11:04 +0000
1import string
2from encodings import idna
3from viur.core.bones.string import StringBone
4from viur.core import i18n
6class EmailBone(StringBone):
7 """
8 The EmailBone class is a designed to store syntactically validated email addresses.
10 This class provides an email validation method, ensuring that the given email address conforms to the
11 required format and structure.
12 """
13 type = "str.email"
14 """
15 A string representing the type of the bone, in this case "str.email".
16 """
18 def isInvalid(self, value):
19 """
20 Checks if the provided email address is valid or not.
22 :param str value: The email address to be validated.
23 :returns: An error message if the email address is invalid or None if it is valid.
24 :rtype: str, None
26 The method checks if the provided email address is valid according to the following criteria:
28 1. The email address must not be empty.
29 2. The email address must be shorter than 256 characters.
30 3. The local part (account) must be shorter than or equal to 64 characters.
31 4. The email address must contain an "@" symbol, separating the local part (account) and the domain part.
32 5. The domain part must be a valid IDNA-encoded string and should not contain any spaces.
33 6. The local part (account) should only contain valid characters.
34 7. The local part (account) can also contain Unicode characters within the range of U+0080 to U+10FFFF.
35 """
36 if not value:
37 return i18n.translate("core.bones.error.novalueentered", "No value entered")
39 is_valid = True
41 try:
42 assert len(value) < 256
43 account, domain = value.split(u"@")
44 subDomain, tld = domain.rsplit(".", 1)
45 assert account and subDomain and tld
46 assert subDomain[0] != "."
47 assert len(account) <= 64
48 except (ValueError, AssertionError):
49 is_valid = False
51 if is_valid:
52 validChars = string.ascii_letters + string.digits + "!#$%&'*+-/=?^_`{|}~."
53 unicodeLowerBound = u"\u0080"
54 unicodeUpperBound = u"\U0010FFFF"
55 for char in account:
56 if not (char in validChars or (char >= unicodeLowerBound and char <= unicodeUpperBound)):
57 is_valid = False
58 try:
59 idna.ToASCII(subDomain)
60 idna.ToASCII(tld)
61 except Exception:
62 is_valid = False
64 if " " in subDomain or " " in tld:
65 is_valid = False
67 if not is_valid:
68 return i18n.translate("core.bones.error.invalidemail", "Invalid email entered")