Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
6 / 6
CRAP
100.00% covered (success)
100.00%
1 / 1
FilterUser
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
6 / 6
8
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 getAuthority
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUserIdentity
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isSameUserAs
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUser
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getFilterUserName
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace MediaWiki\Extension\AbuseFilter;
4
5use MediaWiki\Permissions\Authority;
6use MediaWiki\User\User;
7use MediaWiki\User\UserGroupManager;
8use MediaWiki\User\UserIdentity;
9use MediaWiki\User\UserNameUtils;
10use MessageLocalizer;
11use Psr\Log\LoggerInterface;
12
13class FilterUser {
14    public const SERVICE_NAME = 'AbuseFilterFilterUser';
15
16    private MessageLocalizer $messageLocalizer;
17    private UserGroupManager $userGroupManager;
18    private UserNameUtils $userNameUtils;
19    private LoggerInterface $logger;
20
21    /**
22     * @param MessageLocalizer $messageLocalizer
23     * @param UserGroupManager $userGroupManager
24     * @param UserNameUtils $userNameUtils
25     * @param LoggerInterface $logger
26     */
27    public function __construct(
28        MessageLocalizer $messageLocalizer,
29        UserGroupManager $userGroupManager,
30        UserNameUtils $userNameUtils,
31        LoggerInterface $logger
32    ) {
33        $this->messageLocalizer = $messageLocalizer;
34        $this->userGroupManager = $userGroupManager;
35        $this->userNameUtils = $userNameUtils;
36        $this->logger = $logger;
37    }
38
39    /**
40     * @return Authority
41     */
42    public function getAuthority(): Authority {
43        return $this->getUser();
44    }
45
46    /**
47     * @return UserIdentity
48     */
49    public function getUserIdentity(): UserIdentity {
50        return $this->getUser();
51    }
52
53    /**
54     * Compares the given $user to see if they are the same as the FilterUser.
55     *
56     * @return bool
57     */
58    public function isSameUserAs( UserIdentity $user ): bool {
59        // Checking the usernames are equal is enough, as this is what is done by
60        // User::equals and UserIdentityValue::equals.
61        return $user->getName() === $this->getFilterUserName();
62    }
63
64    /**
65     * @todo Stop using the User class when User::newSystemUser is refactored.
66     * @return User
67     */
68    private function getUser(): User {
69        $user = User::newSystemUser( $this->getFilterUserName(), [ 'steal' => true ] );
70        '@phan-var User $user';
71
72        // Promote user to 'sysop' so it doesn't look
73        // like an unprivileged account is blocking users
74        if ( !in_array( 'sysop', $this->userGroupManager->getUserGroups( $user ) ) ) {
75            $this->userGroupManager->addUserToGroup( $user, 'sysop' );
76        }
77
78        return $user;
79    }
80
81    /**
82     * Gets the username for the FilterUser.
83     *
84     * @return string
85     */
86    private function getFilterUserName(): string {
87        $username = $this->messageLocalizer->msg( 'abusefilter-blocker' )->inContentLanguage()->text();
88        if ( !$this->userNameUtils->getCanonical( $username ) ) {
89            // User name is invalid. Don't throw because this is a system message, easy
90            // to change and make wrong either by mistake or intentionally to break the site.
91            $this->logger->warning(
92                'The AbuseFilter user\'s name is invalid. Please change it in ' .
93                'MediaWiki:abusefilter-blocker'
94            );
95            // Use the default name to avoid breaking other stuff. This should have no harm,
96            // aside from blocks temporarily attributed to another user.
97            // Don't use the database in case the English onwiki message is broken, T284364
98            $username = $this->messageLocalizer->msg( 'abusefilter-blocker' )
99                ->inLanguage( 'en' )
100                ->useDatabase( false )
101                ->text();
102        }
103        return $username;
104    }
105}