User tests: Successful: Unsuccessful:
Pull Request for Issue # .
This PR adds user email domain restrictions. This is an alternative to #20164 with more flexibility added.
Apply patch.
Go to Users configuration.
In Email Domain Options add some rules.
a) Try to register with disallowed email.
b) Try to register with an email that isn't disallowed.
c) Try to change email in user profile to a disallowed email.
d) Try to change email in user profile to an allowed email.
e) Remove all rules and try to register again.
a) Registration fails.
b) Registration successful.
c) Changes not saved.
d) Changes saved.
e) Registration successful.
Document the new option.
Document validDomains attribute usage in EmailRule.
Document message property in FormRule.
Status | New | ⇒ | Pending |
Category | ⇒ | Administration com_admin com_users Language & Strings Front End Libraries |
Labels |
Added:
?
?
|
Added strings. Thanks.
For the Rule, how about making it a radio type with the red/green switcher instead of a list?
@brianteeman previously this was used:
COM_USERS_PROFILE_EMAIL1_MESSAGE="The email address you entered is already in use or invalid. Please enter another email address."
Although we could update it to read "The email address you entered is already in use, not allowed or invalid. Please enter another email address.", a change in this PR allows to output a different message based on which part of validation fails. This is more user friendly, IMO.
@infograf768 Done, thanks.
@Quy There's currently an issue with repeatable subform and button styling. Perhaps #19722 was meant to solve it.
Careful: we already have
JLIB_DATABASE_ERROR_EMAIL_INUSE="This email address is already registered."
(string present in lib.joomla.ini, therefore present in both admin and site)
which is commonly used when creating a user in back-end.
See https://github.com/joomla/joomla-cms/blob/staging/libraries/src/Table/User.php#L255
Therefore it looks like we have some redundancy with your code and I guess we should normalize this.
Global strings were added as per comments at #20164. But they should probably be added to com_users instead. That's how PasswordRule handles it https://github.com/joomla/joomla-cms/blob/staging/libraries/src/Form/Rule/PasswordRule.php#L90
@SharkyKZ
Only one Global string was added on my suggestion in 20164 and it concerned only domains.
Here I talk about redundancy: lib_joomla.ini strings are Global per nature and we have now 2 parts of joomla code dealing with duplicate email addresses.
Please relook at code.
If the code in Table/User/ is redundant, let's get rid of it.
If you think we should keep it, then let's use the lib.joomla.ini string in your patch and just modify it to be nicer. Keep the specific JGLOBAL_domains string as it is fine imho.
EDIT:
After testing this PR, I can see that it is still the lib.joomla.ini string which is used in the Error when editing a user in back-end and trying to change the address to one already used by another user.
Also, are you sure JGLOBAL_EMAIL_INVALID
is really used?
I'd rather not use mixed language sources in one rule. If having similar global and library strings is an issue, I can move them from global to com_users (same as PasswordRule).
After testing this PR, I can see that it is still the lib.joomla.ini string which is used in the Error when editing a user in back-end and trying to change the address to one already used by another user.
This should be fixed with latest commits. Test again please.
Then move them to Library (and improve the value of the existing one). So they will be usable when the email field is not related to com_users.
When you say, "The Wildcards (*) are supported", mean, you need write the wildcard for your emails domains rules work or are optional? I ask because, without the wildcard, the rules no work.
@infograf768 how should the constants be named? Because "domain not allowed" string doesn'tfit JLIB_DATABASE_ERROR_* (not database error) and is too specific for JLIB_FORM_VALIDATE_*.
@carlitorweb Wildcards are used to set rules for entire domain segment. Typically, if you want to set a rule for one domain, you don't need a wildcard. But note that all domains are allowed by default (updated description to better indicate this, still need input). So if you want to allow only one domain, you need two rules: * - Disallow
to block all domains and example.com - Allow
to allow a specific domain.
For this one which will replace JGLOBAL_EMAIL_IN_USE
, use
JLIB_DATABASE_ERROR_EMAIL_INUSE="This email address is already registered."
you just need to update the value to The email address you entered is already in use. Please enter another email address.
For
JGLOBAL_EMAIL_INVALID="The email address you entered is invalid. Please enter another email address."
I would suggest
JLIB_MAIL_FIELD_INVALID="The email address you entered is invalid. Please enter another email address."
For
JGLOBAL_EMAIL_DOMAIN_NOT_ALLOWED="The email domain <strong>%s</strong> is not allowed. Please enter another email address."
I would keep that one as is in both en-GB.ini
There already is JLIB_DATABASE_ERROR_VALID_MAIL="Please enter a valid email address."
. Should it be updated and used instead of JLIB_MAIL_FIELD_INVALID
? Though, again, the constant doesn't fit our context. We're validating a form, not getting a DB error.
I did not think of that one.
For the sake of simplicity, I would indeed use
JLIB_DATABASE_ERROR_VALID_MAIL
and modify its value.
otherwise we do get useless redundancies. The context is less important imho than the value.
@infograf768 language strings updated based on your comments.
It seems wrong to me to reuse a string with an unrelated key. The point of having a key is so that a translator can see the purpose of the string and write the value accordingly. Just because the English value is the same doesn't mean that it will always be so. if a translator wanted to change the text to be more descriptive they can't because it might then be incorrect for the other place it was used. The same is true for the core.
It seems wrong to me to reuse a string with an unrelated key.
The problem is that this PR introduces a new way to accomplish the same goal.
The possible errors are absolutely the same ones. The constant used (what you call the key) has nothing to do with it. If you look at the code you may understand better.
On the backend, when saving a user, the following warning is displayed:
The email address you entered is already in use. Please enter another email address.
Reverted the change that caused this. EmailRule's unique
attribute is not supported in backend. When saving a duplicate email, a different message will appear (shown in #20383 (comment)). This should be expected as we're not using the part of validation rule that sets another message.
I have tested this item
Wondering if this feature should be improved to allow rules not only for domains but for full email addresses and partial matches. For example, this would allow users to block all addresses with spam words in them.
I have tested this item
Status | Pending | ⇒ | Ready to Commit |
Ready to Commit after two successful tests.
I'm not entirely sure how to feel on the $message
property in the FormRule
class yet. On one hand, we absolutely need the ability to define a validation failed message. On the other hand, I don't think accessing the message in this way is really the right way to go about it.
Even though it's undocumented, there are already form rule classes which return an Exception
object (which can hold an error message), and Form::validateField()
already has code accounting for this return. I'm really inclined here to suggest we fix the documentation of FormRule::test()
(and the doc blocks of subclasses) to note this return capability as the code behavior has existed since JForm
was originally introduced and instead of adding the new class property have everything return an Exception
object with the message.
FormRule::test()
should return an exception instead of false
on validation fail? Do I understand this correctly?
On a related note, documentation suggests directly manipulating message
attribute on field element https://docs.joomla.org/Server-side_form_validation.
For simple cases where you can just use a single message (or the generic one used in the API if one isn't set), you can return boolean false. In cases like the ones here where you have a message specific to a failure condition, you can return an Exception. Both cases are already supported in the code, the latter one not documented at all.
On a related note, documentation suggests directly manipulating message attribute on field element
I can't :eyeroll: at this one hard enough. That part goes away if you use the undocumented Exception return.
I'm just wondering whether field's message
attribute should be respected when Exception
is returned.
Also, $validationtext
property is being added to FormField
for 4.0. It seems it would be used for client-side validation. Do we really need separate strings for client/server-side validation?
A field's message
attribute and what you're trying to do with this PR collide, that message implies you'll have one error message for all validation errors when you're trying to show a contextual error message depending on the error case. So no, I don't think strictly respecting that attribute applies.
I was thinking B/C here. Existing message
attributes should continue to be respected. If contextual messages are to be used, message
attribute should be first removed from the field. Am I overthinking here?
Yes, you're overthinking.
You can really have a $message = !empty($element['message']) ? $element['message'] : $contextualMessage
check if you really want it, but IMO it defeats the purpose of putting contextual messages in the code to begin with. That message attribute is fine for things like the boolean check, or the color check, but in a complex case like this where a rule has 4 different return points based on different conditions without making the message attribute some kind of array it just doesn't carry forward well.
Labels |
Added:
?
|
Needs new tests? Then RTC should be removed. Or is pr on hold?
Status | Ready to Commit | ⇒ | Pending |
Removed RTC
3.8.11-dev, nightly.
A question concerning handling: Blacklist is always overruling Whitelist? Even if the rules are reordered Whitelist rule before Blacklist rule?
E.g.
*.example.org : Allowed
* : Disallowed
(or vice versa) shall never allow registrations from example.org
? That's the case at the moment.
On the other hand a single rule like:
*.example.org : Allowed
allows registration with other domains, too.
Labels |
Removed:
?
|
All domains are allowed by default and rules are executed in order, starting at the top. To allow only specific domain, you must first block all other domains. So to allow only *.example.org
need to swap your rules:
* : Disallowed
*.example.org : Allowed
re-started travis
Travis failure is correct. This needs new unit tests.
All domains are allowed by default and rules are executed in order, starting at the top. To allow only specific domain, you must first block all other domains. So to allow only *.example.org need to swap your rules:
That's why I've asked because I've tested both orderings and could not register with example.org.
I tested also without captcha => same result.
Tested also unsuccessfully without dot, just *example.org
Yes, wildcards currently work on full segments only as per comments #20383 (comment). But this can be improved. Any suggestions welcome (especially for fixing tests).
To clarify: I could not allow tester@example.org
. All tests unsuccessful. Makes no difference if my rule is with (#20383 (comment)) or without dot.
Joomla 3.8.11-dev nightly of yesterday.
I do not confirm your findings here. For me it works as intended. (Latest staging).
Thank you. Maybe I have to install a new staging. I'm using the Joomla upload/update feature for a longer time now with nightly update packages for 3.8.x. Or maybe a conflict with an installed 3rd extension. I will see.
After a new installation of staging nightly build of today I have the same unsuccessful results like in comment #20383 (comment)
Could you please have a look on the settings there?
I've tried it also with other rules/domains than *.example.org
.
* : Disallowed
*.example.org : Allowed
PHP 7.1 and 7.2
PHP Built On | Linux dd1620 3.13.0-151-generic #201-Ubuntu SMP Wed May 30 14:22:13 UTC 2018 x86_64
Database Type | mysql
Database Version | 5.5.58-nmm1-log
Database Collation | utf8_general_ci
Database Connection Collation | utf8mb4_general_ci
PHP Version | 7.2.1
Web Server | Apache
WebServer to PHP Interface | fpm-fcgi
Joomla! Version | Joomla! 3.8.11-dev Development [ Amani ] 26-June-2018 15:45 GMT
Joomla! Platform Version | Joomla Platform 13.1.0 Stable [ Curiosity ] 24-Apr-2013 00:00 GMT
User Agent | Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
After 2 coffees => "Stupid me!"
For allowed email relater@example.org
one have to set
* : Disallowed
example.org : Allowed
I have tested this item
I have tested this item
Tested on J3.9 alpha
Applied the patch and checked various rulesets and rule sorting to check if sorting has the expected behavior.
Works for me
Status | Pending | ⇒ | Ready to Commit |
Ready to Commit after 4 successful tests.
But that's the expected behavior... if the last action is "disallow all" than all is disallowed
Status | Ready to Commit | ⇒ | Fixed in Code Base |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2018-09-08 15:44:19 |
Closed_By | ⇒ | mbabker | |
Labels |
Added:
?
|
Are we just ignoring the fact this breaks the build and unit tests are now failing?
Try deleting the row.
nothing happend when I click on -
IE11.1001.18267.0
On the backend, text not translated
JGLOBAL_EMAIL_DOMAIN_NOT_ALLOWED
.