Custom authentication conditions

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):

  • Session Controller

    • 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
  • Users Controller

    • via logon_after_password_reset: user approved (note this is checked with a new Guardian instance), user is staff
  • Invites Controller

    • via perform_accept_invitation: user active

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.

This can be done using the “email domains whitelist” site setting.

4 Likes