-
Notifications
You must be signed in to change notification settings - Fork 153
What We're Doing
The user pulls up their profile screen and selects which providers they want to have available, and a default primary provider (if there are several enabled). If their providers require any configuration (loading TOTP secrets onto their mobile phone, entering their cell phone number, whatever). Save and they're done.
The default /wp-login.php
login screen has no changes. Once a user authenticates successfully with their username/password, though, we don't set the login cookies, and instead set an interstitial page that prompts for them to do their second-factor.
At this point, if they have more than one method available, they can use a link at the bottom to switch to a different available method.
Once authenticated, the login cookie is finally set, and the user is logged in.
The user enters a name for a new Application Password, and clicks the button to generate it. They then are presented with the Application Password in ???? ???? ???? ????
notation (a chunked version of wp_generate_password( 16, false );
) -- and it is listed in Application Password list table, which identifies each by its provided name, and lists the date it was created, the last IP Address it was used from, and the date it was last used (handy for regularly purging old ones).
Application Passwords cannot be used on wp-login.php
or any sort of interactive login. They are solely for non-interactive uses, such as XML-RPC -- largely as Two-Factor cannot be used on non-interactive prompts.
The whole Application Password system lives purely in class.application-passwords.php
and class.application-passwords-list-table.php
, and apart from complementing the purpose of Two-Factor, has no other cross-dependencies. It could be shipped completely separately or dropped from Two-Factor as need be.
Two-Factor runs primarily off of class.two-factor-core.php
-- a class used primarily for name spacing its functions -- it is never instantiated. On init
, it calls Two_Factor_Core::get_providers()
which filters the default bundled provider list, and gets an instance of each.
Each provider is used as a singleton, through the Class::get_instance()
method. It is recommended, but not necessitated, that they each extend the Two_Factor_Provider
abstract class. Each provider sets up their own actions, and new providers can be added or existing providers dropped simply by including them or not.
The main Two_Factor_Core
class handles the bulk of the work -- storing what providers are enabled and set as primary, handling the base admin ui for each provider, and handling the interstitial login screen creation, leaving some very basic necessary methods that must be handled by each provider:
-
->get_label()
-- The human readable, translated label for the provider. -
->authentication_page( $user )
-- The method that prints the interstitial authentication page. -
->validate_authentication( $user )
-- The method that checks request variables and returns whether the user has cleared the hurdle for authentication. -
->is_available_for_user( $user )
-- Whether the method is available for the specific user. This may check for browser support, whether any codes or secrets are stored, time of day, IP range, anything it likes.
The most basic provider possible -- one that simply approves anyone that comes its way -- can be seen in: providers/class.two-factor-dummy.php
Also, when the Two_Factor_Core::user_two_factor_options( $user )
prints the user options page and iterates through the methods, methods are encouraged to use the 'two-factor-user-options-' . __CLASS__
action to print any further options, messaging, or configurations. For example, Two_Factor_Email::user_options( $user )
displaying a reminder of which email address tokens will be emailed to.