Talk:Community Wishlist Survey 2019/Admins and patrollers/Allow De-Privileged logons to webui
Since this proposal seems to be getting several votes, I thought I'd drop some implementation notes based on OAuth and BotPasswords for the Community Tech team to consider. Familiarity with mw:Manual:SessionManager and AuthManager will be helpful.
Both OAuth and BotPasswords work primarily on the Session level: they have their own SessionProviders that override the standard provider. For OAuth this session exists whenever the client sends the appropriate HTTP Authorization header, while for BotPasswords the session uses its own cookie. Neither allows "logging in" via AuthManager / Special:UserLogin, and for a Session using either one we in fact disable Special:UserLogin and API login. OAuth doesn't have any concept of "logging in" at all, while BotPasswords has special handling in ApiLogin to bypass AuthManager.
I see two ways that this proposal might be implemented:
- Like BotPasswords, bypass AuthManager completely. This would necessarily bypass captchas, 2FA, the standard Special:ChangePassword, and anything else that works through AuthManager.
- The login could either be a special case in SpecialUserLogin (and presumably ApiLogin and ApiClientLogin), which would greatly complicate the form generation logic for SpecialUserLogin and ApiClientLogin, or it could be a separate special page with its own form (and presumably just add to the logic in ApiLogin).
- You'd also need to implement proper password-setting logic in your special page for managing these credentials. Special:BotPasswords avoids all that by not letting users choose their own passwords, but humans probably won't accept being forced to use a randomly-generated password like "47no0v2s28ji8il0eps093rblpri7jn8".
- Add several new things to AuthManager:
- Rather than just setting the logged-in user in the existing Session, you'd need your PrimaryAuthenticationProvider to be able to specify that the session be replaced with a specific other session at the end of the login process. Note the code for this should be done generically, not as a special case just for your provider.
- You'd also need log out to be sure to unpersist the replacement session, as is done for BotPasswords in ApiLogout. Again, this should be done generically and BotPasswordSessionProvider should then use the new generic logic.
- To fulfill the request that these logins bypass 2FA, you'd also need to have your PrimaryAuthenticationProvider post a "signal" that stuff should be bypassed and have each relevant SecondaryAuthenticationProvider check for that signal.
- This should probably work like the 'reset-pass' signal set by AbstractPasswordPrimaryAuthenticationProvider::setPasswordResetFlag() and checked by ResetPasswordSecondaryAuthenticationProvider.
- If you want to allow users to log in as a different user (or with a different sub-account) without explicitly logging out first, that would be more complexity to add to SessionManager and AuthManager. Although it might be able to piggy-back on the unpersist-on-logout logic described above.
- Be careful not to accidentally allow reauthentication (for security-sensitive operations like changing the email address) using differently-privileged credentials.
- The simplest thing might be to be sure reauthentication can't happen with a deprivileged Session and deprivileged credentials aren't even checked when reauthenticating.
- Managing the deprivileged credentials should be able to be done through the existing Special:ChangeCredentials.