Page MenuHomePhabricator

Introduce global system users
Open, Needs TriagePublic

Description

When a MediaWiki farm is set up with some concept of global / central accounts, there should be a way to create a central system user account via User::newSystemUser(). The main motivation here is CentralAuth and the AbuseFilter user, but it should apply more widely.

See also:

Event Timeline

Calling AuthManager::autoCreateUser() with AuthManager::AUTOCREATE_SOURCE_MAINT would not work here as CentralAuth (and presumably similar central account management extensions) will reject the account creation if the global account, or the local account on other wikis, is already reserved. So there needs to be a way to steal a central account and to merge/attach local system users accounts on various wikis.

Maybe User::newSystemUser() could call LocalUserCreated with a flag denoting that it's a system user (and possibly the create/steal flags), and extensions like CentralAuth can act on that by stealing or attaching the global account (and presumably implement a global version of T212720: System users should be in a dedicated user group so they can determine when that's safe)?

So there needs to be a way to steal a central account

The central account does get stolen if a local non-system user exists for the name: in that case CentralAuthPrimaryAuthenticationProvider->testUserCanAuthenticate() returns true (and probably the user has a valid email or token too), so User::newSystemUser() will call AuthManager->revokeAccessForUser() and SessionManager->preventSessionsForUser(), both of which will cause CentralAuth to blank the password for the user.

If no local account exists for the name, it'll just create a new unattached local account without messing with the central account. If an unattached local account exists, then CentralAuth similarly shouldn't be messing with it but it looks like CentralAuthSessionProvider::preventSessionsForUser() is missing an ->isAttached() check so it will.

See also {T53837}.

"Stolen" in the sense that the owner is locked out, yes, but the system account will not get attached to it. It would make system users less confusing for editors if they had a proper central account, with a central user page and everything, with the local system user accounts attached to it.

Flow does this manually (in TalkpageManager::getTalkpageManager()) by creating a system user and then calling CentralAuthUser::attach( <wiki id>, 'admin' ).

I propose that we can introduce a new user name format for system user names. For example the abuse filter blocker can be named User:@abusefilter-blocker in every wiki, and a localized named (stored in a MediaWiki message) can be shown in page history, recent changes and logs.

Since @ is not a valid character in new user name there are little risk of conflicts with existing users. There are no conflict with interwiki user name either (which always have a (. )@([^@] ) format). Such accounts can safely be connected to SUL automatically.

I propose that we can introduce a new user name format for system user names. For example the abuse filter blocker can be named User:@abusefilter-blocker in every wiki, and a localized named (stored in a MediaWiki message) can be shown in page history, recent changes and logs.

@ was only disallowed in rMWc75197371c81: * Added $wgInvalidUsernameCharacters to disallow certain characters in…; we do (or at the very least did) have real users with @ in their name (T260222: Can't change user groups if the user has an '@' in their username). That isn't necessarily a problem for merging new system accounts, but does allow for some potential confusion if we have real users.

I propose that we can introduce a new user name format for system user names. For example the abuse filter blocker can be named User:@abusefilter-blocker in every wiki, and a localized named (stored in a MediaWiki message) can be shown in page history, recent changes and logs.

@ was only disallowed in rMWc75197371c81: * Added $wgInvalidUsernameCharacters to disallow certain characters in…; we do (or at the very least did) have real users with @ in their name (T260222: Can't change user groups if the user has an '@' in their username). That isn't necessarily a problem for merging new system accounts, but does allow for some potential confusion if we have real users.

BTW, having real users that can log in (not system users) with @ in username is a problem - since such usernames will break bot password. See T160296#9863168 and T14581.

In proposed account vanishing procedure in https://gerrit.wikimedia.org/r/c/mediawiki/extensions/CentralAuth/ /1050675/3/includes/GlobalRename/GlobalRenameUser.php we used User::newSystemUser() with the steal option to make an account unusable. However it will also make the user displayed as system user (isSystemUser) in various places. (The DisableAccount extension already did revoke user's access this way, though it is was not installed in any SUL wikis before undeployed from Wikimedia.) To differentiate these two kinds of users, I will emphasize my proposed solution of making a special format for system user name at T214722#8845922.
Also the steal option code may be split into a new function such as revokeAccess()

However it will also make the user displayed as system user (isSystemUser) in various places.

isSystemUser() basically just detects whether it is possible to log into the account somehow, so that's hard to avoid.

However it will also make the user displayed as system user (isSystemUser) in various places.

isSystemUser() basically just detects whether it is possible to log into the account somehow, so that's hard to avoid.

So we can instead detect it by matching it with a special username pattern (in my proposal @[a-z-] ); this also matches how we detect temporary users (https://gerrit.wikimedia.org/g/mediawiki/core/ /ced0a26571113d5ac90fff22d75199e432c0cf1f/includes/user/TempUser/RealTempUserConfig.php#127). Of course we need to first migrate existing system user to such format.

An alternative solution is to reopen T212720: System users should be in a dedicated user group, which at least provides a better way to detect system accounts than the current one. Though I still prefer my proposed solution since it will also resolve other issues like T53837.