Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.65% covered (success)
95.65%
22 / 23
80.00% covered (warning)
80.00%
4 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
PreviouslyRenamedAccountPreAuthenticationProvider
95.65% covered (success)
95.65%
22 / 23
80.00% covered (warning)
80.00%
4 / 5
15
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAuthenticationRequests
87.50% covered (warning)
87.50%
7 / 8
0.00% covered (danger)
0.00%
0 / 1
5.05
 testForAccountCreation
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
 testUserForCreation
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 previouslyRenamedAccountStatus
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace MediaWiki\Auth;
4
5use MediaWiki\RenameUser\RenameuserSQL;
6use MediaWiki\User\UserFactory;
7use StatusValue;
8use Wikimedia\Rdbms\DBAccessObjectUtils;
9use Wikimedia\Rdbms\IConnectionProvider;
10use Wikimedia\Rdbms\IDBAccessObject;
11
12/**
13 * @stable to extend
14 */
15class PreviouslyRenamedAccountPreAuthenticationProvider extends AbstractPreAuthenticationProvider {
16
17    public function __construct(
18        private readonly IConnectionProvider $dbProvider,
19        private readonly UserFactory $userFactory,
20        array $params = [],
21    ) {
22    }
23
24    /**
25     * @inheritDoc
26     * @stable to override
27     */
28    public function getAuthenticationRequests( $action, array $options ) {
29        if ( $action === AuthManager::ACTION_CREATE ) {
30            if ( $options['username'] ) {
31                $creator = $this->userFactory->newFromName( $options['username'] )
32                    ?: $this->userFactory->newAnonymous();
33            } else {
34                $creator = $this->userFactory->newAnonymous();
35            }
36            if ( $creator->isAllowed( 'createpreviouslyrenamedaccount' ) ) {
37                return [ new PreviouslyRenamedAccountAuthenticationRequest() ];
38            }
39        }
40        return [];
41    }
42
43    /**
44     * @inheritDoc
45     * @stable to override
46     */
47    public function testForAccountCreation( $user, $creator, array $reqs ) {
48        /** @var ?PreviouslyRenamedAccountAuthenticationRequest $req */
49        $req = AuthenticationRequest::getRequestByClass( $reqs,
50            PreviouslyRenamedAccountAuthenticationRequest::class );
51        if (
52            $req instanceof PreviouslyRenamedAccountAuthenticationRequest &&
53            $req->allowPreviouslyRenamedAccount &&
54            $creator->authorizeAction( 'createpreviouslyrenamedaccount' )
55        ) {
56            // Check overridden by the user
57            return StatusValue::newGood();
58        }
59        return $this->previouslyRenamedAccountStatus( $user->getName(), IDBAccessObject::READ_LATEST );
60    }
61
62    /**
63     * @inheritDoc
64     * @stable to override
65     */
66    public function testUserForCreation( $user, $autocreate, array $options = [] ) {
67        // This is used by the "cancreate" API, so don't check permissions here to allow users
68        // who can override to still see whether normal registration attempt would be an error.
69        if ( $autocreate || !empty( $options['creating'] ) ) {
70            return StatusValue::newGood();
71        }
72        return $this->previouslyRenamedAccountStatus( $user->getName(), IDBAccessObject::READ_NORMAL );
73    }
74
75    /**
76     * @param string $username Username. Make sure to handle spaces and underscores correctly,
77     *   as usernames are stored in different formats in different places.
78     * @param int $flags See DBAccessObjectUtils::getDBFromRecency()
79     * @stable to override
80     */
81    protected function previouslyRenamedAccountStatus( string $username, int $flags ): StatusValue {
82        $db = DBAccessObjectUtils::getDBFromRecency( $this->dbProvider, $flags );
83        if ( RenameuserSQL::isPreviouslyRenamedAccount( $username, $db ) ) {
84            return StatusValue::newFatal( 'username-previously-renamed-account' );
85        }
86        return StatusValue::newGood();
87    }
88}