A field that validates input as an email address.
| 217 | |
| 218 | |
| 219 | class EmailField(StringField): |
| 220 | """A field that validates input as an email address.""" |
| 221 | |
| 222 | USER_REGEX = LazyRegexCompiler( |
| 223 | # `dot-atom` defined in RFC 5322 Section 3.2.3. |
| 224 | r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*\Z" |
| 225 | # `quoted-string` defined in RFC 5322 Section 3.2.4. |
| 226 | r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"\Z)', |
| 227 | re.IGNORECASE, |
| 228 | ) |
| 229 | |
| 230 | UTF8_USER_REGEX = LazyRegexCompiler( |
| 231 | ( |
| 232 | # RFC 6531 Section 3.3 extends `atext` (used by dot-atom) to |
| 233 | # include `UTF8-non-ascii`. |
| 234 | r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z\u0080-\U0010FFFF]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z\u0080-\U0010FFFF]+)*\Z" |
| 235 | # `quoted-string` |
| 236 | r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"\Z)' |
| 237 | ), |
| 238 | re.IGNORECASE | re.UNICODE, |
| 239 | ) |
| 240 | |
| 241 | DOMAIN_REGEX = LazyRegexCompiler( |
| 242 | r"((?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+)(?:[A-Z0-9-]{2,63}(?<!-))\Z", |
| 243 | re.IGNORECASE, |
| 244 | ) |
| 245 | |
| 246 | error_msg = "Invalid email address: %s" |
| 247 | |
| 248 | def __init__( |
| 249 | self, |
| 250 | domain_whitelist=None, |
| 251 | allow_utf8_user=False, |
| 252 | allow_ip_domain=False, |
| 253 | *args, |
| 254 | **kwargs, |
| 255 | ): |
| 256 | """ |
| 257 | :param domain_whitelist: (optional) list of valid domain names applied during validation |
| 258 | :param allow_utf8_user: Allow user part of the email to contain utf8 char |
| 259 | :param allow_ip_domain: Allow domain part of the email to be an IPv4 or IPv6 address |
| 260 | :param kwargs: Keyword arguments passed into the parent :class:`~mongoengine.StringField` |
| 261 | """ |
| 262 | self.domain_whitelist = domain_whitelist or [] |
| 263 | self.allow_utf8_user = allow_utf8_user |
| 264 | self.allow_ip_domain = allow_ip_domain |
| 265 | super().__init__(*args, **kwargs) |
| 266 | |
| 267 | def validate_user_part(self, user_part): |
| 268 | """Validate the user part of the email address. Return True if |
| 269 | valid and False otherwise. |
| 270 | """ |
| 271 | if self.allow_utf8_user: |
| 272 | return self.UTF8_USER_REGEX.match(user_part) |
| 273 | return self.USER_REGEX.match(user_part) |
| 274 | |
| 275 | def validate_domain_part(self, domain_part): |
| 276 | """Validate the domain part of the email address. Return True if |
no test coverage detected
searching dependent graphs…