There are a number of ways a user can be logged on and it is difficult to add conditions via a plugin which a user might have to satisfy before being logged on.
Some examples of conditions a plugin author might wish to add to authentication:
- ensures user’s email domain follows a certain pattern e.g. university.edu
- passes second factor from 2FA provider (there seem to be quite a few)
- ensures user has an active subscription via a payments provider
Current conditions are variously checked (or not checked) depending on context (non-exhaustive list):
-
- via
create
method: correct password, user approved, user active, user email confirmed, totp second factor, user suspended, correct/incorrect IP address - via
email_login
method: totp second factor, user approved, user suspended, correct/incorrect IP address
- via
-
- via
logon_after_password_reset
: user approved (note this is checked with a newGuardian
instance), user is staff
- via
-
- via
perform_accept_invitation
: user active
- via
A way to insert a custom condition is to prepend a custom module modifying each method, which is not a desirable result from the perspective of maintaining compatibility with discourse, and is also quite ugly.
Suggestion
It would be easier to develop around authentication if it were less distributed throughout the code base. All of the conditions (and error messages in response) one might want to check could be defined as separate methods in the one place. A user who wanted to log in would have to pass each enabled condition. You could add your own methods as a plugin author to this class, which the log_on_user
method would then check. If you wanted to skip a condition in some particular context you could pass a parameter to do so.