-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use HumanHandle to validate emails in the application
- Loading branch information
Showing
3 changed files
with
39 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Fix email validation in the application for some special cases |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -113,16 +113,35 @@ def validate(self, string: str, pos: int) -> tuple[QValidator.State, str, int]: | |
# HumanHandle raises the same ValueError if either email or label are incorrect. | ||
# We trick it by using an email we know will be valid, so that the only ValueError | ||
# that can be raised will be because of an incorrect label. | ||
HumanHandle(email="[email protected]", label=string) | ||
HumanHandle(email="[email protected]", label=string) | ||
return QValidator.Acceptable, string, pos | ||
except ValueError: | ||
return QValidator.Invalid, string, pos | ||
|
||
|
||
class EmailValidator(QRegularExpressionValidator): | ||
# We don't use the HumanHandle to validate the email because it's way too permissive. | ||
def __init__(self) -> None: | ||
super().__init__(QRegularExpression(r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$")) | ||
# Note: this regex is very approximative, but it's used for two reasons: | ||
# - to get a sensible `QValidator.Intermediate` status | ||
# - to ban weird-but-valid email addresses such as `[email protected]#` and `[email protected]` | ||
# However, it might not be able to accurately detect invalid email addresses. | ||
# For instance, it will falsely report `[email protected]` as a valid email. | ||
# It will also report email with excessively long domain names as valid, although they are not. | ||
# Ultimately, the actual validation is performed by ANDing the results of the regex | ||
# and the `HumanHandle` constructor, which in turn uses the `email_address_parser` crate. | ||
email_regex = r"^([a-zA-Z0-9_%+-]+\.)*([a-zA-Z0-9_%+-]+)@([a-zA-Z0-9-]+\.)+([a-zA-Z]{2,})$" | ||
super().__init__(QRegularExpression(email_regex)) | ||
|
||
def validate(self, input: str, pos: int) -> tuple[QValidator.State, str, int]: | ||
status, string, pos = super().validate(input, pos) | ||
if status != QValidator.Acceptable: | ||
return status, string, pos | ||
try: | ||
HumanHandle(email=input, label="Some Label") | ||
except ValueError: | ||
return QValidator.Invalid, string, pos | ||
else: | ||
return QValidator.Acceptable, string, pos | ||
|
||
|
||
class WorkspaceNameValidator(QValidator): | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,6 +49,22 @@ def test_email_validator(qtbot, core_config): | |
assert not le.is_input_valid() | ||
assert le.property("validity") == QtGui.QValidator.Invalid | ||
|
||
le.clear() | ||
qtbot.keyClicks(le, "example.") | ||
qtbot.wait_until(lambda: le.text() == "example.") | ||
assert not le.is_input_valid() | ||
assert le.property("validity") == QtGui.QValidator.Intermediate | ||
|
||
qtbot.keyClicks(le, "@") | ||
qtbot.wait_until(lambda: le.text() == "example.@") | ||
assert not le.is_input_valid() | ||
assert le.property("validity") == QtGui.QValidator.Invalid | ||
|
||
qtbot.keyClicks(le, "example.com") | ||
qtbot.wait_until(lambda: le.text() == "[email protected]") | ||
assert not le.is_input_valid() | ||
assert le.property("validity") == QtGui.QValidator.Invalid | ||
|
||
|
||
@pytest.mark.gui | ||
def test_organization_validator(qtbot, core_config): | ||
|